Mercurial > pidgin
annotate src/buddy.c @ 4934:04ca72a25f75
[gaim-migrate @ 5268]
Morten Brix Pedersen (mbrix) writes:
" When a user has the icons at the bottom turned off, the
buddy list is still resized to a fairly large width
when starting gaim.
When using an i18n version of gaim, the strings in the
button box are usually longer, thus meaning that with
many languages (e.g. Danish), the gaim window will grow
*very* wide.
The solution is to not show() the buttonbox before it's
enabled. Right now it's being show()ed together with
the rest of the buddy list."
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Tue, 01 Apr 2003 00:01:19 +0000 |
parents | 34448ffab4f1 |
children | b89f7c450d6c |
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" |
51 #include "gtkft.h" | |
3630 | 52 |
53 #ifdef _WIN32 | |
54 #include "win32dep.h" | |
55 #endif | |
56 | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
57 static struct gaim_gtk_buddy_list *gtkblist = NULL; |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
58 |
4840 | 59 /* part of the best damn Docklet code this side of Tahiti */ |
4698 | 60 static gboolean gaim_gtk_blist_obscured = FALSE; |
61 | |
4810 | 62 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); |
4687 | 63 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node); |
4724 | 64 static char *gaim_get_tooltip_text(struct buddy *b); |
65 static GdkPixbuf *gaim_gtk_blist_get_status_icon(struct buddy *b, GaimStatusIconSize size); | |
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 { | |
152 show_new_bp(b->name, b->account->gc, b->idle, | |
153 b->uc & UC_UNAVAILABLE, NULL); | |
154 } | |
155 | |
156 static void gtk_blist_menu_showlog_cb(GtkWidget *w, struct buddy *b) | |
157 { | |
158 show_log(b->name); | |
159 } | |
160 | |
161 static void gtk_blist_show_systemlog_cb() | |
162 { | |
163 show_log(NULL); | |
164 } | |
165 | |
4776 | 166 static void gtk_blist_show_onlinehelp_cb() |
167 { | |
4916 | 168 open_url(NULL, WEBSITE "documentation.php"); |
4776 | 169 } |
170 | |
4692 | 171 static void gtk_blist_button_im_cb(GtkWidget *w, GtkTreeView *tv) |
172 { | |
173 GtkTreeIter iter; | |
174 GtkTreeModel *model = gtk_tree_view_get_model(tv); | |
175 GtkTreeSelection *sel = gtk_tree_view_get_selection(tv); | |
176 | |
177 if(gtk_tree_selection_get_selected(sel, &model, &iter)){ | |
178 GaimBlistNode *node; | |
179 | |
180 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
181 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
182 gaim_conversation_new(GAIM_CONV_IM, ((struct buddy*)node)->account, ((struct buddy*)node)->name); | |
183 } | |
4694 | 184 } |
4692 | 185 |
4694 | 186 static void gtk_blist_button_info_cb(GtkWidget *w, GtkTreeView *tv) |
187 { | |
188 GtkTreeIter iter; | |
189 GtkTreeModel *model = gtk_tree_view_get_model(tv); | |
190 GtkTreeSelection *sel = gtk_tree_view_get_selection(tv); | |
4692 | 191 |
4694 | 192 if(gtk_tree_selection_get_selected(sel, &model, &iter)){ |
193 GaimBlistNode *node; | |
194 | |
195 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
196 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
197 serv_get_info(((struct buddy*)node)->account->gc, ((struct buddy*)node)->name); | |
198 return; | |
199 } | |
200 } | |
201 show_info_dialog(); | |
202 } | |
203 | |
204 static void gtk_blist_button_chat_cb(GtkWidget *w, gpointer data) | |
205 { | |
206 /* FIXME: someday, we can check to see if we've selected a chat node */ | |
207 join_chat(); | |
208 } | |
209 | |
210 static void gtk_blist_button_away_cb(GtkWidget *w, gpointer data) | |
211 { | |
212 gtk_menu_popup(GTK_MENU(awaymenu), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME); | |
4692 | 213 } |
214 | |
4687 | 215 static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) { |
216 GaimBlistNode *node; | |
217 GtkTreeIter iter; | |
218 GValue val = { 0, }; | |
3154 | 219 |
4687 | 220 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); |
221 | |
222 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
223 node = g_value_get_pointer(&val); | |
224 | |
225 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
4911 | 226 struct gaim_conversation *conv = |
227 gaim_conversation_new(GAIM_CONV_IM, ((struct buddy*)node)->account, ((struct buddy*)node)->name); | |
228 if(conv) { | |
229 gaim_window_raise(gaim_conversation_get_window(conv)); | |
230 gaim_window_switch_conversation( | |
231 gaim_conversation_get_window(conv), | |
232 gaim_conversation_get_index(conv)); | |
233 } | |
4697 | 234 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
235 if (gtk_tree_view_row_expanded(tv, path)) | |
236 gtk_tree_view_collapse_row(tv, path); | |
237 else | |
238 gtk_tree_view_expand_row(tv,path,FALSE); | |
1 | 239 } |
240 } | |
241 | |
4916 | 242 static void gaim_gtk_blist_add_buddy_cb() |
243 { | |
244 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
245 GtkTreeIter iter; | |
246 GaimBlistNode *node; | |
247 | |
248 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ | |
249 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
250 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
251 show_add_buddy(NULL, NULL, ((struct group*)node->parent)->name, NULL); | |
252 else if (GAIM_BLIST_NODE_IS_GROUP(node)) | |
253 show_add_buddy(NULL, NULL, ((struct group*)node)->name, NULL); | |
254 } | |
255 else { | |
256 show_add_buddy(NULL, NULL, NULL, NULL); | |
257 } | |
258 } | |
4921 | 259 static void |
4916 | 260 gaim_gtk_blist_remove_cb (GtkWidget *w, GaimBlistNode *node) |
261 { | |
262 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
263 struct buddy *b = (struct buddy*)node; | |
264 show_confirm_del(b->account->gc, b->name); | |
265 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
266 struct group *g = (struct group*)node; | |
267 show_confirm_del_group(g); | |
268 } | |
269 } | |
270 | |
4687 | 271 static void gaim_proto_menu_cb(GtkMenuItem *item, struct buddy *b) |
1 | 272 { |
4687 | 273 struct proto_buddy_menu *pbm = g_object_get_data(G_OBJECT(item), "gaimcallback"); |
274 if (pbm->callback) | |
275 pbm->callback(pbm->gc, b->name); | |
1396
df7c3cacac92
[gaim-migrate @ 1406]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1392
diff
changeset
|
276 } |
1 | 277 |
4687 | 278 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
|
279 { |
4687 | 280 GtkTreePath *path; |
281 GaimBlistNode *node; | |
282 GValue val = { 0, }; | |
283 GtkTreeIter iter; | |
284 GtkWidget *menu, *menuitem; | |
285 GtkWidget *image; | |
4702 | 286 GtkTreeSelection *sel; |
4687 | 287 GList *list; |
288 struct prpl *prpl; | |
1391
d606da211acb
[gaim-migrate @ 1401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1376
diff
changeset
|
289 |
4687 | 290 if (event->button != 3) |
291 return FALSE; | |
4718 | 292 |
4687 | 293 /* Here we figure out which node was clicked */ |
294 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL)) | |
295 return FALSE; | |
296 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
297 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
298 node = g_value_get_pointer(&val); | |
299 menu = gtk_menu_new(); | |
3251 | 300 |
4916 | 301 if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
302 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Add a Buddy")); | |
303 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_gtk_blist_add_buddy_cb), node); | |
304 image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU); | |
305 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); | |
306 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
307 | |
308 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Delete Group")); | |
309 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_gtk_blist_remove_cb), node); | |
310 image = gtk_image_new_from_stock(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); | |
311 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); | |
312 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
313 | |
314 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Rename")); | |
315 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(show_rename_group), node); | |
316 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
317 } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
318 | |
319 /* Protocol specific options */ | |
320 prpl = find_prpl(((struct buddy*)node)->account->protocol); | |
321 | |
322 if(prpl && prpl->get_info) { | |
323 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Get Info")); | |
324 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_info_cb), node); | |
325 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
326 } | |
4732 | 327 |
4916 | 328 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_IM")); |
329 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_im_cb), node); | |
330 image = gtk_image_new_from_stock(GAIM_STOCK_IM, GTK_ICON_SIZE_MENU); | |
331 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); | |
332 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
333 | |
334 menuitem = gtk_image_menu_item_new_with_mnemonic(_("Add Buddy _Pounce")); | |
335 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_bp_cb), node); | |
336 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
337 | |
338 menuitem = gtk_image_menu_item_new_with_mnemonic(_("View _Log")); | |
339 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_showlog_cb), node); | |
340 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
341 | |
342 if (prpl) { | |
343 list = prpl->buddy_menu(((struct buddy*)node)->account->gc, ((struct buddy*)node)->name); | |
344 while (list) { | |
345 struct proto_buddy_menu *pbm = list->data; | |
346 menuitem = gtk_menu_item_new_with_mnemonic(pbm->label); | |
347 g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pbm); | |
348 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_proto_menu_cb), node); | |
349 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
350 list = list->next; | |
351 } | |
352 } | |
353 | |
354 gaim_separator(menu); | |
355 | |
356 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Alias")); | |
357 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_alias_cb), node); | |
358 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
359 | |
360 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Remove")); | |
361 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_gtk_blist_remove_cb), node); | |
362 image = gtk_image_new_from_stock(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); | |
363 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); | |
4732 | 364 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
365 } | |
4916 | 366 |
4687 | 367 gtk_widget_show_all(menu); |
368 | |
369 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, event->time); | |
1 | 370 |
4702 | 371 #if (1) /* This code only exists because GTK doesn't work. If we return FALSE here, as would be normal |
372 * the event propoagates down and somehow gets interpreted as the start of a drag event. */ | |
373 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
374 gtk_tree_selection_select_path(sel, path); | |
4721 | 375 gtk_tree_path_free(path); |
4702 | 376 return TRUE; |
377 #endif | |
1 | 378 } |
379 | |
4687 | 380 /* This is called 10 seconds after the buddy logs in. It removes the "logged in" icon and replaces it with |
381 * the normal status icon */ | |
1072
81d19577285a
[gaim-migrate @ 1082]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1070
diff
changeset
|
382 |
4687 | 383 static gboolean gaim_reset_present_icon(GaimBlistNode *b) |
384 { | |
385 ((struct buddy*)b)->present = 1; | |
386 gaim_gtk_blist_update(NULL, b); | |
387 return FALSE; | |
577
aa9a8bcddd80
[gaim-migrate @ 587]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
544
diff
changeset
|
388 } |
4916 | 389 static void edit_mode_cb() { |
390 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH); | |
391 gdk_window_set_cursor(gtkblist->window->window, cursor); | |
392 while (gtk_events_pending()) | |
393 gtk_main_iteration(); | |
4929 | 394 blist_options ^= OPT_BLIST_SHOW_OFFLINE; |
395 save_prefs(); | |
4916 | 396 gdk_cursor_unref(cursor); |
397 cursor = gdk_cursor_new(GDK_LEFT_PTR); | |
398 gdk_window_set_cursor(gtkblist->window->window, cursor); | |
399 gdk_cursor_unref(cursor); | |
400 gaim_gtk_blist_refresh(gaim_get_blist()); | |
401 } | |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4349
diff
changeset
|
402 |
1 | 403 |
4697 | 404 static void gaim_gtk_blist_update_toolbar_icons (GtkWidget *widget, gpointer data) { |
405 if (GTK_IS_IMAGE(widget)) { | |
406 if (blist_options & OPT_BLIST_SHOW_BUTTON_XPM) | |
407 gtk_widget_show(widget); | |
408 else | |
409 gtk_widget_hide(widget); | |
410 } else if (GTK_IS_CONTAINER(widget)) { | |
411 gtk_container_foreach(GTK_CONTAINER(widget), gaim_gtk_blist_update_toolbar_icons, NULL); | |
412 } | |
413 } | |
1 | 414 |
4702 | 415 static void gaim_gtk_blist_drag_data_get_cb (GtkWidget *widget, |
416 GdkDragContext *dc, | |
417 GtkSelectionData *data, | |
418 guint info, | |
419 guint time, | |
420 gpointer *null) | |
421 { | |
4781 | 422 if (data->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE)) { |
4702 | 423 GtkTreeRowReference *ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row"); |
424 GtkTreePath *sourcerow = gtk_tree_row_reference_get_path(ref); | |
425 GtkTreeIter iter; | |
426 GaimBlistNode *node = NULL; | |
427 GValue val = {0}; | |
428 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, sourcerow); | |
429 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
430 node = g_value_get_pointer(&val); | |
4781 | 431 gtk_selection_data_set (data, |
432 gdk_atom_intern ("GAIM_BLIST_NODE", FALSE), | |
433 8, /* bits */ | |
434 (void*)&node, | |
435 sizeof (node)); | |
436 | |
4721 | 437 gtk_tree_path_free(sourcerow); |
4702 | 438 } |
4781 | 439 |
4702 | 440 } |
441 | |
442 static void gaim_gtk_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, | |
443 GtkSelectionData *sd, guint info, guint t) | |
444 { | |
4781 | 445 if (sd->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE) && sd->data) { |
446 GaimBlistNode *n = NULL; | |
4702 | 447 GtkTreePath *path = NULL; |
4704 | 448 GtkTreeViewDropPosition position; |
4781 | 449 memcpy(&n, sd->data, sizeof(n)); |
4704 | 450 if(gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) { |
451 /* if we're here, I think it means the drop is ok */ | |
4770 | 452 GtkTreeIter iter; |
453 GaimBlistNode *node; | |
454 GValue val = {0}; | |
455 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
456 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
457 node = g_value_get_pointer(&val); | |
4781 | 458 |
459 if (GAIM_BLIST_NODE_IS_BUDDY(n)) { | |
460 struct buddy *b = (struct buddy*)n; | |
461 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
4795 | 462 switch(position) { |
463 case GTK_TREE_VIEW_DROP_AFTER: | |
464 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
465 gaim_blist_add_buddy(b, (struct group*)node->parent, node); | |
466 break; | |
467 case GTK_TREE_VIEW_DROP_BEFORE: | |
468 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
469 gaim_blist_add_buddy(b, (struct group*)node->parent, node->prev); | |
470 break; | |
4781 | 471 } |
472 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
473 gaim_blist_add_buddy(b, (struct group*)node, NULL); | |
4795 | 474 } |
4781 | 475 } else if (GAIM_BLIST_NODE_IS_GROUP(n)) { |
476 struct group *g = (struct group*)n; | |
477 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
478 switch (position) { | |
479 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
480 case GTK_TREE_VIEW_DROP_AFTER: | |
481 gaim_blist_add_group(g, node); | |
482 break; | |
483 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
484 case GTK_TREE_VIEW_DROP_BEFORE: | |
485 gaim_blist_add_group(g, node->prev); | |
486 break; | |
487 } | |
488 | |
4770 | 489 } |
4781 | 490 |
4777 | 491 } |
4781 | 492 |
4721 | 493 gtk_tree_path_free(path); |
4704 | 494 } |
4702 | 495 } |
496 } | |
497 | |
4724 | 498 static void gaim_gtk_blist_paint_tip(GtkWidget *widget, GdkEventExpose *event, struct buddy *b) |
499 { | |
500 GtkStyle *style; | |
501 GdkPixbuf *pixbuf = gaim_gtk_blist_get_status_icon(b, GAIM_STATUS_ICON_LARGE); | |
502 PangoLayout *layout; | |
503 char *tooltiptext = gaim_get_tooltip_text(b); | |
504 | |
505 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); | |
506 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); | |
4732 | 507 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); |
4733 | 508 pango_layout_set_width(layout, 300000); |
4724 | 509 style = gtkblist->tipwindow->style; |
4732 | 510 |
4724 | 511 gtk_paint_flat_box (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, |
512 NULL, gtkblist->tipwindow, "tooltip", 0, 0, -1, -1); | |
4729 | 513 |
514 #if GTK_CHECK_VERSION(2,2,0) | |
4724 | 515 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, pixbuf, |
516 0, 0, 4, 4, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); | |
4729 | 517 #else |
4758 | 518 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 | 519 #endif |
4724 | 520 |
521 gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, TRUE, | |
522 NULL, gtkblist->tipwindow, "tooltip", 38, 4, layout); | |
523 | |
524 g_object_unref (pixbuf); | |
525 g_object_unref (layout); | |
526 g_free(tooltiptext); | |
527 return; | |
528 } | |
529 | |
530 static gboolean gaim_gtk_blist_tooltip_timeout(GtkWidget *tv) | |
531 { | |
532 GtkTreePath *path; | |
533 GtkTreeIter iter; | |
534 GaimBlistNode *node; | |
535 GValue val = {0}; | |
536 | |
537 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->rect.x, gtkblist->rect.y, &path, NULL, NULL, NULL)) | |
538 return FALSE; | |
539 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
540 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
541 node = g_value_get_pointer(&val); | |
542 | |
543 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
544 int scr_w,scr_h, w, h, x, y; | |
545 PangoLayout *layout; | |
546 struct buddy *buddy = (struct buddy*)node; | |
547 char *tooltiptext = gaim_get_tooltip_text(buddy); | |
548 gtkblist->tipwindow = gtk_window_new(GTK_WINDOW_POPUP); | |
4907
68e2b07ef8d7
[gaim-migrate @ 5241]
Christian Hammond <chipx86@chipx86.com>
parents:
4883
diff
changeset
|
549 gtkblist->tipwindow->parent = tv; |
4724 | 550 gtk_widget_set_app_paintable(gtkblist->tipwindow, TRUE); |
4729 | 551 gtk_window_set_resizable(GTK_WINDOW(gtkblist->tipwindow), FALSE); |
4724 | 552 gtk_widget_set_name(gtkblist->tipwindow, "gtk-tooltips"); |
4883
3c3bafae42e8
[gaim-migrate @ 5213]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4879
diff
changeset
|
553 gtk_widget_realize(gtkblist->tipwindow); |
4724 | 554 g_signal_connect(G_OBJECT(gtkblist->tipwindow), "expose_event", |
555 G_CALLBACK(gaim_gtk_blist_paint_tip), buddy); | |
556 gtk_widget_ensure_style (gtkblist->tipwindow); | |
557 | |
558 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); | |
4733 | 559 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); |
560 pango_layout_set_width(layout, 300000); | |
4724 | 561 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); |
562 scr_w = gdk_screen_width(); | |
563 scr_h = gdk_screen_height(); | |
564 pango_layout_get_size (layout, &w, &h); | |
565 w = PANGO_PIXELS(w) + 8; | |
566 h = PANGO_PIXELS(h) + 8; | |
567 | |
568 /* 38 is the size of a large status icon plus 4 pixels padding on each side. | |
569 I should #define this or something */ | |
570 w = w + 38; | |
571 h = MAX(h, 38); | |
572 | |
573 gdk_window_get_pointer(NULL, &x, &y, NULL); | |
574 if (GTK_WIDGET_NO_WINDOW(gtkblist->window)) | |
575 y+=gtkblist->window->allocation.y; | |
576 | |
577 x -= ((w >> 1) + 4); | |
578 | |
579 if ((x + w) > scr_w) | |
580 x -= (x + w) - scr_w; | |
581 else if (x < 0) | |
582 x = 0; | |
583 | |
584 if ((y + h + 4) > scr_h) | |
585 y = y - h; | |
586 else | |
587 y = y + 6; | |
588 g_object_unref (layout); | |
589 g_free(tooltiptext); | |
590 gtk_widget_set_size_request(gtkblist->tipwindow, w, h); | |
4729 | 591 gtk_window_move(GTK_WINDOW(gtkblist->tipwindow), x, y); |
4724 | 592 gtk_widget_show(gtkblist->tipwindow); |
593 } | |
4729 | 594 |
4724 | 595 gtk_tree_path_free(path); |
596 return FALSE; | |
597 } | |
598 | |
4730 | 599 static gboolean gaim_gtk_blist_motion_cb (GtkWidget *tv, GdkEventMotion *event, gpointer null) |
4724 | 600 { |
601 GtkTreePath *path; | |
602 if (gtkblist->timeout) { | |
603 if ((event->y > gtkblist->rect.y) && ((event->y - gtkblist->rect.height) < gtkblist->rect.y)) | |
4732 | 604 return FALSE; |
4724 | 605 /* We've left the cell. Remove the timeout and create a new one below */ |
606 if (gtkblist->tipwindow) { | |
607 gtk_widget_destroy(gtkblist->tipwindow); | |
608 gtkblist->tipwindow = NULL; | |
609 } | |
610 | |
611 g_source_remove(gtkblist->timeout); | |
612 } | |
613 | |
614 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL); | |
615 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->rect); | |
616 if (path) | |
617 gtk_tree_path_free(path); | |
618 gtkblist->timeout = g_timeout_add(500, (GSourceFunc)gaim_gtk_blist_tooltip_timeout, tv); | |
4730 | 619 return FALSE; |
4724 | 620 } |
621 | |
622 static void gaim_gtk_blist_leave_cb (GtkWidget *w, GdkEventCrossing *e, gpointer n) | |
623 { | |
624 if (gtkblist->timeout == 0) | |
625 return; | |
626 if (gtkblist->tipwindow) { | |
627 gtk_widget_destroy(gtkblist->tipwindow); | |
628 gtkblist->tipwindow = NULL; | |
629 } | |
630 g_source_remove(gtkblist->timeout); | |
631 gtkblist->timeout = 0; | |
632 } | |
633 | |
4687 | 634 /*************************************************** |
635 * Crap * | |
636 ***************************************************/ | |
637 static GtkItemFactoryEntry blist_menu[] = | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
638 { |
4687 | 639 /* Buddies menu */ |
640 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>" }, | |
4916 | 641 { N_("/Buddies/New _Instant Message..."), "<CTL>I", show_im_dialog, 0, |
4687 | 642 "<StockItem>", GAIM_STOCK_IM }, |
643 { N_("/Buddies/Join a _Chat..."), "<CTL>C", join_chat, 0, | |
644 "<StockItem>", GAIM_STOCK_CHAT }, | |
4834 | 645 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>" }, |
4687 | 646 { N_("/Buddies/Get _User Info..."), "<CTL>J", show_info_dialog, 0, |
647 "<StockItem>", GAIM_STOCK_INFO }, | |
4834 | 648 { "/Buddies/sep2", NULL, NULL, 0, "<Separator>" }, |
4687 | 649 { N_("/Buddies/_Signoff"), "<CTL>D", signoff_all, 0, NULL }, |
650 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0, | |
651 "<StockItem>", GTK_STOCK_QUIT }, | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
652 |
4916 | 653 /* Edit menu */ |
654 { N_("/_Edit"), NULL, NULL, 0, "<Branch>" }, | |
655 { N_("/Edit/_Show Offline Buddies"), NULL, edit_mode_cb, 0, "<CheckItem>"}, | |
656 { N_("/Edit/_Add a Buddy..."), NULL, gaim_gtk_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD }, | |
657 { N_("/Edit/Add a _Group..."), NULL, show_add_group, 0, NULL}, | |
658 { "/Edit/sep", NULL, NULL, 0, "<Separator>" }, | |
659 { N_("/Edit/A_ccounts"), "<CTL>A", account_editor, 0, NULL }, | |
660 { N_("/Edit/Preferences"), "<CTL>P", show_prefs, 0, | |
661 "<StockItem>", GTK_STOCK_PREFERENCES }, | |
662 { N_("/Edit/Pr_ivacy"), NULL, show_privacy_options, 0, NULL }, | |
663 | |
664 | |
4687 | 665 /* Tools */ |
666 { N_("/_Tools"), NULL, NULL, 0, "<Branch>" }, | |
667 { N_("/Tools/_Away"), NULL, NULL, 0, "<Branch>" }, | |
668 { N_("/Tools/Buddy _Pounce"), NULL, NULL, 0, "<Branch>" }, | |
4916 | 669 { N_("/Tools/sep1"), NULL, NULL, 0, "<Separator>" }, |
4698 | 670 { N_("/Tools/_File Transfers"), NULL, gaim_show_xfer_dialog, 0, |
4687 | 671 "<StockItem>", GTK_STOCK_REVERT_TO_SAVED }, |
4834 | 672 { "/Tools/sep2", NULL, NULL, 0, "<Separator>" }, |
4687 | 673 { N_("/Tools/P_rotocol Actions"), NULL, NULL, 0, "<Branch>" }, |
4697 | 674 { N_("/Tools/View System _Log"), NULL, gtk_blist_show_systemlog_cb, 0, NULL }, |
3251 | 675 |
4687 | 676 /* Help */ |
677 { N_("/_Help"), NULL, NULL, 0, "<Branch>" }, | |
4776 | 678 { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, |
4687 | 679 "<StockItem>", GTK_STOCK_HELP }, |
4755 | 680 { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, NULL }, |
4687 | 681 { N_("/Help/_About"), NULL, show_about, 0, NULL }, |
682 | |
683 }; | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
684 |
4687 | 685 /********************************************************* |
686 * Private Utility functions * | |
687 *********************************************************/ | |
688 | |
4724 | 689 static char *gaim_get_tooltip_text(struct buddy *b) |
690 { | |
691 char *text = NULL; | |
692 struct prpl* prpl = find_prpl(b->account->protocol); | |
693 char *statustext = NULL; | |
4867 | 694 char *aliastext = NULL, *nicktext = NULL; |
4724 | 695 char *warning = NULL, *idletime = NULL; |
696 | |
697 if (prpl->tooltip_text) { | |
4815 | 698 const char *end; |
4732 | 699 statustext = prpl->tooltip_text(b); |
4815 | 700 |
701 if(statustext && !g_utf8_validate(statustext, -1, &end)) { | |
702 char *new = g_strndup(statustext, | |
703 g_utf8_pointer_to_offset(statustext, end)); | |
704 g_free(statustext); | |
705 statustext = new; | |
706 } | |
4724 | 707 } |
4732 | 708 |
4724 | 709 if (b->idle) { |
710 int ihrs, imin; | |
711 time_t t; | |
712 time(&t); | |
713 ihrs = (t - b->idle) / 3600; | |
714 imin = ((t - b->idle) / 60) % 60; | |
715 if (ihrs) | |
4744 | 716 idletime = g_strdup_printf(_("%dh%02dm"), ihrs, imin); |
4724 | 717 else |
4744 | 718 idletime = g_strdup_printf(_("%dm"), imin); |
4724 | 719 } |
4732 | 720 |
4867 | 721 if(b->alias) |
722 aliastext = g_markup_escape_text(b->alias, -1); | |
723 | |
724 if(b->server_alias) | |
725 nicktext = g_markup_escape_text(b->server_alias, -1); | |
726 | |
4724 | 727 if (b->evil > 0) |
4744 | 728 warning = g_strdup_printf(_("%d%%"), b->evil); |
4732 | 729 |
4724 | 730 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>" |
4744 | 731 "%s %s" /* Alias */ |
732 "%s %s" /* Nickname */ | |
733 "%s %s" /* Idle */ | |
734 "%s %s" /* Warning */ | |
4916 | 735 "%s" /* Offline */ |
4741 | 736 "%s%s", /* Status */ |
4724 | 737 b->name, |
4867 | 738 aliastext ? _("\n<b>Alias:</b>") : "", aliastext ? aliastext : "", |
739 nicktext ? _("\n<b>Nickname:</b>") : "", nicktext ? nicktext : "", | |
740 b->idle ? _("\n<b>Idle:</b>") : "", b->idle ? idletime : "", | |
4744 | 741 b->evil ? _("\n<b>Warned:</b>") : "", b->evil ? warning : "", |
4916 | 742 !b->present ? _("\n<b>Status:</b> Offline") : "", |
4724 | 743 statustext ? "\n" : "", statustext ? statustext : ""); |
4737 | 744 if(warning) |
745 g_free(warning); | |
746 if(idletime) | |
747 g_free(idletime); | |
748 if(statustext) | |
749 g_free(statustext); | |
4867 | 750 if(nicktext) |
751 g_free(nicktext); | |
752 if(aliastext) | |
753 g_free(aliastext); | |
4737 | 754 |
4724 | 755 return text; |
756 | |
757 } | |
758 | |
759 static GdkPixbuf *gaim_gtk_blist_get_status_icon(struct buddy *b, GaimStatusIconSize size) | |
4687 | 760 { |
761 GdkPixbuf *status = NULL; | |
762 GdkPixbuf *scale = NULL; | |
763 GdkPixbuf *emblem = NULL; | |
4737 | 764 gchar *filename = NULL; |
4687 | 765 const char *protoname = NULL; |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
766 |
4691 | 767 char *se = NULL, *sw = NULL ,*nw = NULL ,*ne = NULL; |
4737 | 768 |
4687 | 769 int scalesize = 30; |
770 | |
771 struct prpl* prpl = find_prpl(b->account->protocol); | |
4916 | 772 |
773 if (!prpl) | |
774 return NULL; | |
775 | |
4687 | 776 if (prpl->list_icon) |
777 protoname = prpl->list_icon(b->account, b); | |
778 if (prpl->list_emblems) | |
779 prpl->list_emblems(b, &se, &sw, &nw, &ne); | |
4916 | 780 |
4724 | 781 if (size == GAIM_STATUS_ICON_SMALL) { |
4687 | 782 scalesize = 15; |
783 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
|
784 } |
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
785 |
4701 | 786 |
4687 | 787 if (b->present == 2) { |
4701 | 788 struct gaim_gtk_blist_node *gtknode; |
4687 | 789 /* If b->present is 2, that means this buddy has just signed on. We use the "login" icon for the |
790 * status, and we set a timeout to change it to a normal icon after 10 seconds. */ | |
791 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); | |
792 status = gdk_pixbuf_new_from_file(filename,NULL); | |
793 g_free(filename); | |
4701 | 794 |
795 gtknode = GAIM_GTK_BLIST_NODE((GaimBlistNode*)b); | |
4773 | 796 if (gtknode->timer > 0) |
797 g_source_remove(gtknode->timer); | |
4701 | 798 gtknode->timer = g_timeout_add(10000, (GSourceFunc)gaim_reset_present_icon, b); |
799 | |
4737 | 800 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and |
4687 | 801 then it will look up protoname from the theme */ |
802 } else { | |
803 char *image = g_strdup_printf("%s.png", protoname); | |
804 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
805 status = gdk_pixbuf_new_from_file(filename,NULL); | |
806 g_free(image); | |
807 g_free(filename); | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
808 |
4687 | 809 } |
4737 | 810 |
4687 | 811 if (!status) |
812 return NULL; | |
4737 | 813 |
4687 | 814 scale = gdk_pixbuf_scale_simple(status, scalesize, scalesize, GDK_INTERP_BILINEAR); |
4737 | 815 |
816 g_object_unref(G_OBJECT(status)); | |
817 | |
4687 | 818 /* Emblems */ |
4737 | 819 |
4687 | 820 /* Each protocol can specify up to four "emblems" to composite over the base icon. "away", "busy", "mobile user" |
821 * are all examples of states represented by emblems. I'm not even really sure I like this yet. */ | |
4737 | 822 |
4687 | 823 /* XXX Clean this crap up, yo. */ |
824 if (se) { | |
825 char *image = g_strdup_printf("%s.png", se); | |
826 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
827 g_free(image); | |
828 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
829 g_free(filename); | |
830 if (emblem) { | |
4724 | 831 if (size == GAIM_STATUS_ICON_LARGE) |
4687 | 832 gdk_pixbuf_composite (emblem, |
833 scale, 15, 15, | |
834 15, 15, | |
835 15, 15, | |
836 1, 1, | |
837 GDK_INTERP_BILINEAR, | |
838 255); | |
839 else | |
840 gdk_pixbuf_composite (emblem, | |
841 scale, 0, 0, | |
842 15, 15, | |
843 0, 0, | |
844 1, 1, | |
845 GDK_INTERP_BILINEAR, | |
846 255); | |
4737 | 847 g_object_unref(G_OBJECT(emblem)); |
4687 | 848 } |
849 } | |
850 if (sw) { | |
851 char *image = g_strdup_printf("%s.png", sw); | |
852 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
853 g_free(image); | |
854 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
855 g_free(filename); | |
856 if (emblem) { | |
4737 | 857 gdk_pixbuf_composite (emblem, |
858 scale, 0, 15, | |
859 15, 15, | |
860 0, 15, | |
861 1, 1, | |
862 GDK_INTERP_BILINEAR, | |
863 255); | |
864 g_object_unref(G_OBJECT(emblem)); | |
4687 | 865 } |
866 } | |
867 if (nw) { | |
868 char *image = g_strdup_printf("%s.png", nw); | |
869 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
870 g_free(image); | |
871 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
872 g_free(filename); | |
873 if (emblem) { | |
874 gdk_pixbuf_composite (emblem, | |
875 scale, 0, 0, | |
876 15, 15, | |
877 0, 0, | |
878 1, 1, | |
879 GDK_INTERP_BILINEAR, | |
880 255); | |
4737 | 881 g_object_unref(G_OBJECT(emblem)); |
4687 | 882 } |
883 } | |
884 if (ne) { | |
885 char *image = g_strdup_printf("%s.png", ne); | |
886 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
887 g_free(image); | |
888 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
889 g_free(filename); | |
890 if (emblem) { | |
891 gdk_pixbuf_composite (emblem, | |
892 scale, 15, 0, | |
893 15, 15, | |
894 15, 0, | |
895 1, 1, | |
896 GDK_INTERP_BILINEAR, | |
897 255); | |
898 } | |
4737 | 899 } |
4687 | 900 |
4737 | 901 |
4718 | 902 /* Idle grey buddies affects the whole row. This converts the status icon to greyscale. */ |
4930 | 903 if (!b->present) |
4928 | 904 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE); |
905 else if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) | |
906 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.25, FALSE); | |
4687 | 907 return scale; |
1 | 908 } |
909 | |
4737 | 910 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b) |
1 | 911 { |
4687 | 912 /* This just opens a file from ~/.gaim/icons/screenname. This needs to change to be more gooder. */ |
4737 | 913 char *file; |
914 GdkPixbuf *buf, *ret; | |
915 | |
4687 | 916 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) |
917 return NULL; | |
4737 | 918 |
4757 | 919 if ((file = gaim_buddy_get_setting(b, "buddy_icon")) == NULL) |
920 return NULL; | |
921 | |
4737 | 922 buf = gdk_pixbuf_new_from_file(file, NULL); |
923 g_free(file); | |
924 | |
925 | |
4687 | 926 if (buf) { |
4930 | 927 if (!b->present) |
4928 | 928 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.0, FALSE); |
929 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) | |
930 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.25, FALSE); | |
931 | |
4737 | 932 ret = gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR); |
933 g_object_unref(G_OBJECT(buf)); | |
934 return ret; | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
935 } |
4687 | 936 return NULL; |
2986 | 937 } |
938 | |
4810 | 939 static gchar *gaim_gtk_blist_get_name_markup(struct buddy *b, gboolean selected) |
1 | 940 { |
4687 | 941 char *name = gaim_get_buddy_alias(b); |
942 char *esc = g_markup_escape_text(name, strlen(name)), *text = NULL; | |
4722 | 943 struct prpl* prpl = find_prpl(b->account->protocol); |
944 | |
4687 | 945 /* XXX Clean up this crap */ |
4699 | 946 |
4687 | 947 int ihrs, imin; |
4724 | 948 char *idletime = NULL, *warning = NULL, *statustext = NULL; |
4732 | 949 time_t t; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
950 |
4687 | 951 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) { |
4929 | 952 if ((b->idle > 0 && blist_options & OPT_BLIST_GREY_IDLERS && !selected) || blist_options & OPT_BLIST_SHOW_OFFLINE) { |
4718 | 953 text = g_strdup_printf("<span color='dim grey'>%s</span>", |
4699 | 954 esc); |
4687 | 955 g_free(esc); |
956 return text; | |
957 } else { | |
958 return esc; | |
959 } | |
1 | 960 } |
961 | |
4687 | 962 time(&t); |
963 ihrs = (t - b->idle) / 3600; | |
964 imin = ((t - b->idle) / 60) % 60; | |
4699 | 965 |
4916 | 966 if (prpl && prpl->status_text) { |
4732 | 967 char *tmp = prpl->status_text(b); |
4815 | 968 const char *end; |
969 | |
970 if(tmp && !g_utf8_validate(tmp, -1, &end)) { | |
971 char *new = g_strndup(tmp, | |
972 g_utf8_pointer_to_offset(tmp, end)); | |
973 g_free(tmp); | |
974 tmp = new; | |
975 } | |
4732 | 976 |
977 if(tmp) { | |
4855 | 978 char buf[32]; |
979 char *c = tmp; | |
980 int length = 0, vis=0; | |
981 gboolean inside = FALSE; | |
4806 | 982 g_strdelimit(tmp, "\n", ' '); |
4852
d1c17e81055e
[gaim-migrate @ 5179]
Christian Hammond <chipx86@chipx86.com>
parents:
4847
diff
changeset
|
983 |
4855 | 984 while(*c && vis < 20) { |
985 if(*c == '&') | |
986 inside = TRUE; | |
4856 | 987 else if(*c == ';') |
988 inside = FALSE; | |
4855 | 989 if(!inside) |
990 vis++; | |
991 length++; | |
992 c++; /* this is fun */ | |
993 } | |
4852
d1c17e81055e
[gaim-migrate @ 5179]
Christian Hammond <chipx86@chipx86.com>
parents:
4847
diff
changeset
|
994 |
4855 | 995 if(vis == 20) |
996 g_snprintf(buf, sizeof(buf), "%%.%ds...", length); | |
997 else | |
998 g_snprintf(buf, sizeof(buf), "%%s "); | |
4852
d1c17e81055e
[gaim-migrate @ 5179]
Christian Hammond <chipx86@chipx86.com>
parents:
4847
diff
changeset
|
999 |
4855 | 1000 statustext = g_strdup_printf(buf, tmp); |
4852
d1c17e81055e
[gaim-migrate @ 5179]
Christian Hammond <chipx86@chipx86.com>
parents:
4847
diff
changeset
|
1001 |
4732 | 1002 g_free(tmp); |
1003 } | |
4722 | 1004 } |
4732 | 1005 |
4687 | 1006 if (b->idle) { |
1007 if (ihrs) | |
4757 | 1008 idletime = g_strdup_printf(_("Idle (%dh%02dm) "), ihrs, imin); |
4687 | 1009 else |
4757 | 1010 idletime = g_strdup_printf(_("Idle (%dm) "), imin); |
4687 | 1011 } |
4757 | 1012 |
4687 | 1013 if (b->evil > 0) |
4757 | 1014 warning = g_strdup_printf(_("Warned (%d%%) "), b->evil); |
1015 | |
4810 | 1016 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS && !selected) { |
4916 | 1017 text = g_strdup_printf("<span color='dim grey'>%s</span>\n" |
1018 "<span color='dim grey' size='smaller'>%s%s%s%s</span>", | |
4687 | 1019 esc, |
4722 | 1020 statustext != NULL ? statustext : "", |
1021 idletime != NULL ? idletime : "", | |
4916 | 1022 warning != NULL ? warning : "", |
1023 !b->present ? _("Offline ") : ""); | |
1024 } else if (statustext == NULL && idletime == NULL && warning == NULL && b->present) { | |
1025 text = g_strdup(esc); | |
4797 | 1026 } else { |
4916 | 1027 text = g_strdup_printf("%s\n" |
1028 "<span %s size='smaller'>%s%s%s%s</span>", esc, | |
1029 selected ? "" : "color='dim grey'", | |
1030 statustext != NULL ? statustext : "", | |
1031 idletime != NULL ? idletime : "", | |
1032 warning != NULL ? warning : "", | |
1033 !b->present ? _("Offline ") : ""); | |
4797 | 1034 } |
4722 | 1035 if (idletime) |
4687 | 1036 g_free(idletime); |
4722 | 1037 if (warning) |
4687 | 1038 g_free(warning); |
4722 | 1039 if (statustext) |
1040 g_free(statustext); | |
4737 | 1041 if (esc) |
1042 g_free(esc); | |
4699 | 1043 |
4687 | 1044 return text; |
1045 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1046 |
4840 | 1047 static void gaim_gtk_blist_restore_position() |
1048 { | |
1049 /* if the window exists, is hidden, we're saving positions, and the position is sane... */ | |
1050 if(gtkblist && gtkblist->window && | |
1051 !GTK_WIDGET_VISIBLE(gtkblist->window) && | |
1052 blist_options & OPT_BLIST_SAVED_WINDOWS && | |
1053 blist_pos.width != 0) { | |
1054 /* ...check position is on screen... */ | |
1055 if (blist_pos.x >= gdk_screen_width()) | |
1056 blist_pos.x = gdk_screen_width() - 100; | |
1057 else if (blist_pos.x < 0) | |
1058 blist_pos.x = 100; | |
1059 | |
1060 if (blist_pos.y >= gdk_screen_height()) | |
1061 blist_pos.y = gdk_screen_height() - 100; | |
1062 else if (blist_pos.y < 0) | |
1063 blist_pos.y = 100; | |
1064 | |
1065 /* ...and move it back. */ | |
1066 gtk_window_move(GTK_WINDOW(gtkblist->window), blist_pos.x, blist_pos.y); | |
1067 gtk_window_resize(GTK_WINDOW(gtkblist->window), blist_pos.width, blist_pos.height); | |
1068 } | |
1069 } | |
1070 | |
1071 | |
4687 | 1072 /********************************************************************************** |
1073 * Public API Functions * | |
1074 **********************************************************************************/ | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1075 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
|
1076 { |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1077 blist->ui_data = g_new0(struct gaim_gtk_buddy_list, 1); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1078 } |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1079 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1080 static void gaim_gtk_blist_new_node(GaimBlistNode *node) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1081 { |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1082 node->ui_data = g_new0(struct gaim_gtk_blist_node, 1); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1083 } |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1084 |
4729 | 1085 void gaim_gtk_blist_update_columns() |
1086 { | |
1087 if (blist_options & OPT_BLIST_SHOW_ICONS) { | |
1088 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, TRUE); | |
1089 gtk_tree_view_column_set_visible(gtkblist->idle_column, FALSE); | |
1090 gtk_tree_view_column_set_visible(gtkblist->warning_column, FALSE); | |
1091 } else { | |
1092 gtk_tree_view_column_set_visible(gtkblist->idle_column, blist_options & OPT_BLIST_SHOW_IDLETIME); | |
1093 gtk_tree_view_column_set_visible(gtkblist->warning_column, blist_options & OPT_BLIST_SHOW_WARN); | |
1094 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, FALSE); | |
1095 } | |
1096 } | |
1097 | |
4702 | 1098 enum {DRAG_BUDDY, DRAG_ROW}; |
1099 | |
4834 | 1100 static char * |
1101 item_factory_translate_func (const char *path, gpointer func_data) | |
1102 { | |
1103 return _(path); | |
1104 } | |
1105 | |
4687 | 1106 static void gaim_gtk_blist_show(struct gaim_buddy_list *list) |
1107 { | |
1108 GtkItemFactory *ift; | |
1109 GtkCellRenderer *rend; | |
1110 GtkTreeViewColumn *column; | |
1111 GtkWidget *sw; | |
1112 GtkWidget *button; | |
4694 | 1113 GtkSizeGroup *sg; |
4810 | 1114 GtkTreeSelection *selection; |
4781 | 1115 GtkTargetEntry gte[] = {{"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW}, |
4702 | 1116 {"application/x-im-contact", 0, DRAG_BUDDY}}; |
4690 | 1117 |
4745 | 1118 if (gtkblist && gtkblist->window) { |
4687 | 1119 gtk_widget_show(gtkblist->window); |
1120 return; | |
1121 } | |
4690 | 1122 |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1123 gtkblist = GAIM_GTK_BLIST(list); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1124 |
4687 | 1125 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
4840 | 1126 gtk_window_set_gravity(GTK_WINDOW(gtkblist->window), GDK_GRAVITY_NORTH_WEST); |
1127 gtk_window_set_role(GTK_WINDOW(gtkblist->window), "buddy_list"); | |
4687 | 1128 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); |
4879
4f5bd9a2da37
[gaim-migrate @ 5209]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4867
diff
changeset
|
1129 gtk_widget_realize(gtkblist->window); |
4690 | 1130 |
4925 | 1131 gtkblist->vbox = gtk_vbox_new(FALSE, 0); |
4687 | 1132 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); |
1 | 1133 |
4840 | 1134 g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gtk_blist_delete_cb), NULL); |
1135 g_signal_connect(G_OBJECT(gtkblist->window), "configure_event", G_CALLBACK(gtk_blist_configure_cb), NULL); | |
1136 g_signal_connect(G_OBJECT(gtkblist->window), "visibility_notify_event", G_CALLBACK(gtk_blist_visibility_cb), NULL); | |
1137 gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK); | |
4698 | 1138 |
4687 | 1139 /******************************* Menu bar *************************************/ |
1140 ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", NULL); | |
4834 | 1141 gtk_item_factory_set_translate_func (ift, |
1142 item_factory_translate_func, | |
1143 NULL, NULL); | |
4687 | 1144 gtk_item_factory_create_items(ift, sizeof(blist_menu) / sizeof(*blist_menu), |
1145 blist_menu, NULL); | |
1146 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtk_item_factory_get_widget(ift, "<GaimMain>"), FALSE, FALSE, 0); | |
1 | 1147 |
4834 | 1148 awaymenu = gtk_item_factory_get_widget(ift, N_("/Tools/Away")); |
4694 | 1149 do_away_menu(); |
1150 | |
4834 | 1151 bpmenu = gtk_item_factory_get_widget(ift, N_("/Tools/Buddy Pounce")); |
4696 | 1152 do_bp_menu(); |
1153 | |
4834 | 1154 protomenu = gtk_item_factory_get_widget(ift, N_("/Tools/Protocol Actions")); |
4696 | 1155 do_proto_menu(); |
1156 | |
4687 | 1157 /****************************** GtkTreeView **********************************/ |
1158 sw = gtk_scrolled_window_new(NULL,NULL); | |
1159 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); | |
1160 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
1161 | |
4847 | 1162 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, |
4687 | 1163 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER); |
4702 | 1164 |
4687 | 1165 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel)); |
4916 | 1166 gtk_widget_set_size_request(gtkblist->treeview, -1, 200); |
4704 | 1167 |
4810 | 1168 /* Set up selection stuff */ |
1169 | |
1170 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
1171 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(gaim_gtk_blist_selection_changed), NULL); | |
1172 | |
1173 | |
4702 | 1174 /* Set up dnd */ |
1175 gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(gtkblist->treeview), GDK_BUTTON1_MASK, gte, | |
1176 2, GDK_ACTION_COPY); | |
4704 | 1177 gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(gtkblist->treeview), gte, 2, |
4702 | 1178 GDK_ACTION_COPY | GDK_ACTION_MOVE); |
4704 | 1179 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-received", G_CALLBACK(gaim_gtk_blist_drag_data_rcv_cb), NULL); |
1180 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-get", G_CALLBACK(gaim_gtk_blist_drag_data_get_cb), NULL); | |
1181 | |
4724 | 1182 /* Tooltips */ |
1183 g_signal_connect(G_OBJECT(gtkblist->treeview), "motion-notify-event", G_CALLBACK(gaim_gtk_blist_motion_cb), NULL); | |
1184 g_signal_connect(G_OBJECT(gtkblist->treeview), "leave-notify-event", G_CALLBACK(gaim_gtk_blist_leave_cb), NULL); | |
4687 | 1185 |
1186 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
1 | 1187 |
4687 | 1188 rend = gtk_cell_renderer_pixbuf_new(); |
1189 column = gtk_tree_view_column_new_with_attributes("Status", rend, "pixbuf", STATUS_ICON_COLUMN, NULL); | |
1190 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
4933 | 1191 g_object_set(rend, "xalign", 0.0, "ypad", 0, NULL); |
4706 | 1192 |
4687 | 1193 rend = gtk_cell_renderer_text_new(); |
1194 column = gtk_tree_view_column_new_with_attributes("Name", rend, "markup", NAME_COLUMN, NULL); | |
1195 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
4797 | 1196 g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL); |
4706 | 1197 |
4687 | 1198 rend = gtk_cell_renderer_text_new(); |
4725 | 1199 gtkblist->warning_column = gtk_tree_view_column_new_with_attributes("Warning", rend, "markup", WARNING_COLUMN, NULL); |
1200 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->warning_column); | |
4796 | 1201 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); |
4687 | 1202 |
1203 rend = gtk_cell_renderer_text_new(); | |
4725 | 1204 gtkblist->idle_column = gtk_tree_view_column_new_with_attributes("Idle", rend, "markup", IDLE_COLUMN, NULL); |
1205 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->idle_column); | |
4796 | 1206 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); |
1 | 1207 |
4687 | 1208 rend = gtk_cell_renderer_pixbuf_new(); |
4725 | 1209 gtkblist->buddy_icon_column = gtk_tree_view_column_new_with_attributes("Buddy Icon", rend, "pixbuf", BUDDY_ICON_COLUMN, NULL); |
4796 | 1210 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); |
4725 | 1211 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->buddy_icon_column); |
4718 | 1212 |
4687 | 1213 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL); |
1214 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
|
1215 |
4687 | 1216 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0); |
1217 gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); | |
4725 | 1218 gaim_gtk_blist_update_columns(); |
4934 | 1219 |
1220 /* OK... let's show this bad boy. */ | |
1221 gaim_gtk_blist_refresh(list); | |
1222 gaim_gtk_blist_restore_position(); | |
1223 gtk_widget_show_all(gtkblist->window); | |
1224 | |
1225 /* the button box below is first added now, the reason is that if we | |
1226 * show() it immediately, the buddy list width will be dependent of | |
1227 * the button box even if the user turned the button box off. */ | |
1228 | |
4687 | 1229 /**************************** Button Box **************************************/ |
4694 | 1230 |
1231 sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH); | |
4687 | 1232 gtkblist->bbox = gtk_hbox_new(TRUE, 0); |
1233 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->bbox, FALSE, FALSE, 0); | |
1234 button = gaim_pixbuf_button_from_stock(_("IM"), GAIM_STOCK_IM, GAIM_BUTTON_VERTICAL); | |
1235 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
1236 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 1237 gtk_size_group_add_widget(sg, button); |
4692 | 1238 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_im_cb), |
4697 | 1239 gtkblist->treeview); |
1240 | |
4687 | 1241 button = gaim_pixbuf_button_from_stock(_("Get Info"), GAIM_STOCK_INFO, GAIM_BUTTON_VERTICAL); |
1242 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
1243 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 1244 gtk_size_group_add_widget(sg, button); |
1245 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_info_cb), | |
4697 | 1246 gtkblist->treeview); |
4729 | 1247 |
4687 | 1248 button = gaim_pixbuf_button_from_stock(_("Chat"), GAIM_STOCK_CHAT, GAIM_BUTTON_VERTICAL); |
1249 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
1250 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 1251 gtk_size_group_add_widget(sg, button); |
1252 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_chat_cb), NULL); | |
1253 | |
4687 | 1254 button = gaim_pixbuf_button_from_stock(_("Away"), GAIM_STOCK_AWAY, GAIM_BUTTON_VERTICAL); |
1255 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
1256 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
4694 | 1257 gtk_size_group_add_widget(sg, button); |
1258 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_blist_button_away_cb), NULL); | |
4687 | 1259 |
4697 | 1260 gaim_gtk_blist_update_toolbar(); |
4687 | 1261 } |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1262 |
4687 | 1263 void gaim_gtk_blist_refresh(struct gaim_buddy_list *list) |
1264 { | |
1265 GaimBlistNode *group = list->root; | |
1266 GaimBlistNode *buddy; | |
4690 | 1267 |
4687 | 1268 while (group) { |
4916 | 1269 buddy = group->child; |
4687 | 1270 gaim_gtk_blist_update(list, group); |
1271 while (buddy) { | |
4699 | 1272 gaim_gtk_blist_update(list, buddy); |
4687 | 1273 buddy = buddy->next; |
1274 } | |
1275 group = group->next; | |
1276 } | |
1277 } | |
1 | 1278 |
4699 | 1279 static gboolean get_iter_from_node_helper(GaimBlistNode *node, GtkTreeIter *iter, GtkTreeIter *root) { |
4867 | 1280 |
4699 | 1281 do { |
1282 GaimBlistNode *n; | |
1283 GtkTreeIter child; | |
1284 | |
1285 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), root, NODE_COLUMN, &n, -1); | |
1286 if(n == node) { | |
1287 *iter = *root; | |
1288 return TRUE; | |
1289 } | |
1290 | |
1291 if(gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &child, root)) { | |
1292 if(get_iter_from_node_helper(node,iter,&child)) | |
1293 return TRUE; | |
1294 } | |
1295 } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), root)); | |
1296 | |
1297 return FALSE; | |
1298 } | |
1299 | |
1300 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter) { | |
1301 GtkTreeIter root; | |
1302 | |
1303 if (!gtkblist) | |
1304 return FALSE; | |
1305 | |
1306 if(!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(gtkblist->treemodel), &root)) | |
1307 return FALSE; | |
1308 | |
1309 return get_iter_from_node_helper(node, iter, &root); | |
1310 } | |
1311 | |
4697 | 1312 void gaim_gtk_blist_update_toolbar() { |
1313 if (!gtkblist) | |
1314 return; | |
4699 | 1315 |
4697 | 1316 gtk_container_foreach(GTK_CONTAINER(gtkblist->bbox), gaim_gtk_blist_update_toolbar_icons, NULL); |
4699 | 1317 |
4697 | 1318 if (blist_options & OPT_BLIST_NO_BUTTONS) |
1319 gtk_widget_hide(gtkblist->bbox); | |
1320 else | |
1321 gtk_widget_show_all(gtkblist->bbox); | |
1322 } | |
1323 | |
4701 | 1324 static void gaim_gtk_blist_remove(struct gaim_buddy_list *list, GaimBlistNode *node) |
1325 { | |
1326 struct gaim_gtk_blist_node *gtknode; | |
1327 GtkTreeIter iter; | |
1328 | |
1329 if (!node->ui_data) | |
1330 return; | |
1331 | |
1332 gtknode = (struct gaim_gtk_blist_node *)node->ui_data; | |
1333 | |
1334 if (gtknode->timer > 0) { | |
1335 g_source_remove(gtknode->timer); | |
1336 gtknode->timer = 0; | |
1337 } | |
1338 | |
4912 | 1339 /* For some reason, we're called before we have a buddy list sometimes */ |
1340 if(!gtkblist) | |
1341 return; | |
1342 | |
4831 | 1343 if(gtkblist->selected_node == node) |
1344 gtkblist->selected_node = NULL; | |
1345 | |
4701 | 1346 if (get_iter_from_node(node, &iter)) { |
1347 gtk_tree_store_remove(gtkblist->treemodel, &iter); | |
4918
553d96cb9b26
[gaim-migrate @ 5252]
Christian Hammond <chipx86@chipx86.com>
parents:
4916
diff
changeset
|
1348 if(GAIM_BLIST_NODE_IS_BUDDY(node) && |
4929 | 1349 !blist_options & OPT_BLIST_SHOW_OFFLINE && |
4918
553d96cb9b26
[gaim-migrate @ 5252]
Christian Hammond <chipx86@chipx86.com>
parents:
4916
diff
changeset
|
1350 gaim_blist_get_group_online_count((struct group *)node->parent) == 0) { |
4701 | 1351 GtkTreeIter groupiter; |
1352 if(get_iter_from_node(node->parent, &groupiter)) | |
1353 gtk_tree_store_remove(gtkblist->treemodel, &groupiter); | |
1354 } | |
1355 } | |
1356 } | |
1357 | |
4810 | 1358 static gboolean do_selection_changed(GaimBlistNode *new_selection) |
1359 { | |
1360 GaimBlistNode *old_selection = gtkblist->selected_node; | |
1361 | |
1362 if(new_selection != gtkblist->selected_node) { | |
1363 gtkblist->selected_node = new_selection; | |
1364 if(new_selection) | |
1365 gaim_gtk_blist_update(NULL, new_selection); | |
1366 if(old_selection) | |
1367 gaim_gtk_blist_update(NULL, old_selection); | |
1368 } | |
1369 | |
1370 return FALSE; | |
1371 } | |
1372 | |
1373 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data) | |
1374 { | |
1375 GaimBlistNode *new_selection = NULL; | |
1376 GtkTreeIter iter; | |
1377 | |
1378 if(gtk_tree_selection_get_selected(selection, NULL, &iter)){ | |
1379 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
1380 NODE_COLUMN, &new_selection, -1); | |
1381 } | |
1382 /* we set this up as a timeout, otherwise the blist flickers */ | |
1383 g_timeout_add(0, (GSourceFunc)do_selection_changed, new_selection); | |
1384 } | |
1385 | |
4701 | 1386 |
4687 | 1387 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node) |
1388 { | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1389 struct gaim_gtk_blist_node *gtknode; |
4699 | 1390 GtkTreeIter iter; |
4687 | 1391 gboolean expand = FALSE; |
4699 | 1392 gboolean new_entry = FALSE; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1393 |
4687 | 1394 if (!gtkblist) |
1395 return; | |
4699 | 1396 |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1397 gtknode = GAIM_GTK_BLIST_NODE(node); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1398 |
4690 | 1399 |
4699 | 1400 if (!get_iter_from_node(node, &iter)) { /* This is a newly added node */ |
1401 new_entry = TRUE; | |
4687 | 1402 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
4929 | 1403 if (((struct buddy*)node)->present || (blist_options & OPT_BLIST_SHOW_OFFLINE && ((struct buddy*)node)->account->gc)) { |
4699 | 1404 GtkTreeIter groupiter; |
1405 GaimBlistNode *oldersibling; | |
1406 GtkTreeIter oldersiblingiter; | |
4690 | 1407 |
4699 | 1408 if(node->parent && !get_iter_from_node(node->parent, &groupiter)) { |
1409 /* This buddy's group has not yet been added. We do that here */ | |
4757 | 1410 GdkPixbuf *groupicon = gtk_widget_render_icon(gtkblist->treeview, |
1411 GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL); | |
4794 | 1412 char *esc = g_markup_escape_text(((struct group*)node->parent)->name, -1); |
1413 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", esc); | |
1414 g_free(esc); | |
4699 | 1415 oldersibling = node->parent->prev; |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1416 |
4687 | 1417 /* We traverse backwards through the buddy list to find the node in the tree to insert it after */ |
4699 | 1418 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) |
1419 oldersibling = oldersibling->prev; | |
4690 | 1420 |
4687 | 1421 /* This is where we create the node and add it. */ |
4699 | 1422 gtk_tree_store_insert_after(gtkblist->treemodel, &groupiter, NULL, oldersibling ? &oldersiblingiter : NULL); |
1423 gtk_tree_store_set(gtkblist->treemodel, &groupiter, | |
4757 | 1424 STATUS_ICON_COLUMN, groupicon, |
4687 | 1425 NAME_COLUMN, mark, |
1426 NODE_COLUMN, node->parent, | |
1427 -1); | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1428 |
4737 | 1429 g_free(mark); |
4757 | 1430 g_object_unref(G_OBJECT(groupicon)); |
4737 | 1431 |
4687 | 1432 expand = TRUE; |
1433 } | |
4810 | 1434 |
4699 | 1435 oldersibling = node->prev; |
4867 | 1436 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) { |
4699 | 1437 oldersibling = oldersibling->prev; |
4867 | 1438 } |
4699 | 1439 |
1440 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, &groupiter, oldersibling ? &oldersiblingiter : NULL); | |
4810 | 1441 |
4767 | 1442 if (blist_options & OPT_BLIST_POPUP) |
1443 gtk_window_present(GTK_WINDOW(gtkblist->window)); | |
4699 | 1444 |
4687 | 1445 if (expand) { /* expand was set to true if this is the first element added to a group. In such case |
1446 * we expand the group node */ | |
4699 | 1447 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter); |
1448 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE); | |
4721 | 1449 gtk_tree_path_free(path); |
4687 | 1450 } |
4699 | 1451 } |
1452 } | |
4929 | 1453 else if (GAIM_BLIST_NODE_IS_GROUP(node) && blist_options & OPT_BLIST_SHOW_OFFLINE) { |
4916 | 1454 GaimBlistNode *oldersibling; |
1455 GtkTreeIter oldersiblingiter; | |
1456 GdkPixbuf *groupicon = gtk_widget_render_icon(gtkblist->treeview, | |
1457 GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL); | |
1458 char *esc = g_markup_escape_text(((struct group*)node)->name, -1); | |
1459 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", esc); | |
1460 g_free(esc); | |
1461 oldersibling = node->prev; | |
1462 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) { | |
1463 oldersibling = oldersibling->prev; | |
1464 } | |
1465 | |
1466 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, NULL, oldersibling ? &oldersiblingiter : NULL); | |
1467 gtk_tree_store_set(gtkblist->treemodel, &iter, | |
1468 STATUS_ICON_COLUMN, groupicon, | |
1469 NAME_COLUMN, mark, | |
1470 NODE_COLUMN, node, | |
1471 -1); | |
1472 g_free(mark); | |
1473 g_object_unref(groupicon); | |
1474 } | |
1475 | |
1476 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
4929 | 1477 if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(gtkblist->treemodel), &iter) == FALSE && blist_options & OPT_BLIST_SHOW_OFFLINE == FALSE) |
4916 | 1478 gtk_tree_store_remove(gtkblist->treemodel, &iter); |
1479 else { | |
1480 char *esc = g_markup_escape_text(((struct group*)node)->name, -1); | |
1481 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", esc); | |
1482 g_free(esc); | |
1483 gtk_tree_store_set(gtkblist->treemodel, &iter, | |
1484 NAME_COLUMN, mark, | |
1485 -1); | |
1486 g_free(mark); | |
1487 } | |
4699 | 1488 } |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1489 |
4929 | 1490 if (GAIM_BLIST_NODE_IS_BUDDY(node) && (((struct buddy*)node)->present || (blist_options & OPT_BLIST_SHOW_OFFLINE && ((struct buddy*)node)->account->gc))) { |
4687 | 1491 GdkPixbuf *status, *avatar; |
1492 char *mark; | |
4697 | 1493 char *warning = NULL, *idle = NULL; |
1494 | |
4810 | 1495 gboolean selected = (gtkblist->selected_node == node); |
1496 | |
1497 status = gaim_gtk_blist_get_status_icon((struct buddy*)node, | |
4724 | 1498 blist_options & OPT_BLIST_SHOW_ICONS ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL); |
4687 | 1499 avatar = gaim_gtk_blist_get_buddy_icon((struct buddy*)node); |
4810 | 1500 mark = gaim_gtk_blist_get_name_markup((struct buddy*)node, selected); |
4697 | 1501 |
4725 | 1502 if (((struct buddy*)node)->idle > 0) { |
4697 | 1503 time_t t; |
1504 int ihrs, imin; | |
1505 time(&t); | |
1506 ihrs = (t - ((struct buddy *)node)->idle) / 3600; | |
1507 imin = ((t - ((struct buddy*)node)->idle) / 60) % 60; | |
4718 | 1508 if(ihrs > 0) |
1509 idle = g_strdup_printf("(%d:%02d)", ihrs, imin); | |
1510 else | |
1511 idle = g_strdup_printf("(%d)", imin); | |
4697 | 1512 } |
1513 | |
4725 | 1514 if (((struct buddy*)node)->evil > 0) |
4699 | 1515 warning = g_strdup_printf("%d%%", ((struct buddy*)node)->evil); |
4810 | 1516 |
4697 | 1517 |
4718 | 1518 if((blist_options & OPT_BLIST_GREY_IDLERS) |
1519 && ((struct buddy *)node)->idle) { | |
4810 | 1520 if(warning && !selected) { |
4718 | 1521 char *w2 = g_strdup_printf("<span color='dim grey'>%s</span>", |
1522 warning); | |
1523 g_free(warning); | |
1524 warning = w2; | |
1525 } | |
1526 | |
4810 | 1527 if(idle && !selected) { |
4718 | 1528 char *i2 = g_strdup_printf("<span color='dim grey'>%s</span>", |
1529 idle); | |
1530 g_free(idle); | |
1531 idle = i2; | |
1532 } | |
1533 } | |
1534 | |
1535 | |
4699 | 1536 gtk_tree_store_set(gtkblist->treemodel, &iter, |
4687 | 1537 STATUS_ICON_COLUMN, status, |
1538 NAME_COLUMN, mark, | |
4697 | 1539 WARNING_COLUMN, warning, |
1540 IDLE_COLUMN, idle, | |
4699 | 1541 BUDDY_ICON_COLUMN, avatar, |
4687 | 1542 NODE_COLUMN, node, |
1543 -1); | |
4699 | 1544 |
4687 | 1545 g_free(mark); |
4697 | 1546 if (idle) |
1547 g_free(idle); | |
1548 if (warning) | |
1549 g_free(warning); | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1550 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1551 if (status != NULL) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1552 g_object_unref(status); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1553 |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1554 if (avatar != NULL) |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1555 g_object_unref(avatar); |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1556 |
4701 | 1557 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && !new_entry) { |
1558 gaim_gtk_blist_remove(list, node); | |
4767 | 1559 if (blist_options & OPT_BLIST_POPUP) |
1560 gtk_window_present(GTK_WINDOW(gtkblist->window)); | |
4781 | 1561 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
1562 GaimBlistNode *afsad = node->child; | |
1563 while (afsad) { | |
1564 gaim_gtk_blist_update(list, afsad); | |
1565 afsad = afsad->next; | |
1566 } | |
4916 | 1567 |
1568 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview)); | |
4687 | 1569 } |
1570 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
1571 |
4687 | 1572 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) |
1573 { | |
4770 | 1574 if (!gtkblist) |
1575 return; | |
4687 | 1576 gtk_widget_destroy(gtkblist->window); |
4745 | 1577 |
1578 gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; | |
1579 gtkblist->treemodel = NULL; | |
1580 gtkblist->idle_column = NULL; | |
1581 gtkblist->warning_column = gtkblist->buddy_icon_column = NULL; | |
1582 gtkblist->bbox = gtkblist->tipwindow = NULL; | |
1583 protomenu = NULL; | |
1584 awaymenu = NULL; | |
1585 bpmenu = NULL; | |
1586 | |
1587 gtkblist->timeout = 0; | |
4687 | 1588 } |
1 | 1589 |
4687 | 1590 static void gaim_gtk_blist_set_visible(struct gaim_buddy_list *list, gboolean show) |
1591 { | |
4840 | 1592 if (!(gtkblist && gtkblist->window)) |
1593 return; | |
1594 | |
4698 | 1595 if (show) { |
4840 | 1596 gaim_gtk_blist_restore_position(); |
4699 | 1597 gtk_window_present(GTK_WINDOW(gtkblist->window)); |
4698 | 1598 } else { |
1599 if (!connections || docklet_count) { | |
1600 #ifdef _WIN32 | |
4711
0c1f3e651d3e
[gaim-migrate @ 5022]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4706
diff
changeset
|
1601 wgaim_systray_minimize(gtkblist->window); |
4698 | 1602 #endif |
1603 gtk_widget_hide(gtkblist->window); | |
1604 } else { | |
1605 gtk_window_iconify(GTK_WINDOW(gtkblist->window)); | |
1606 } | |
1607 } | |
1608 } | |
1609 | |
1610 void gaim_gtk_blist_docklet_toggle() { | |
1611 /* Useful for the docklet plugin and also for the win32 tray icon*/ | |
1612 /* This is called when one of those is clicked--it will show/hide the | |
1613 buddy list/login window--depending on which is active */ | |
4840 | 1614 if (connections) { |
1615 if (gtkblist && gtkblist->window) { | |
1616 if (GTK_WIDGET_VISIBLE(gtkblist->window)) { | |
1617 gaim_blist_set_visible(GAIM_WINDOW_ICONIFIED(gtkblist->window) || gaim_gtk_blist_obscured); | |
1618 } else { | |
4698 | 1619 #if _WIN32 |
4840 | 1620 wgaim_systray_maximize(gtkblist->window); |
4698 | 1621 #endif |
4840 | 1622 gaim_blist_set_visible(TRUE); |
1623 } | |
1624 } else { | |
1625 /* we're logging in or something... do nothing */ | |
1626 /* or should I make the blist? */ | |
1627 debug_printf("docklet_toggle called with connections but no blist!\n"); | |
4698 | 1628 } |
4840 | 1629 } else if (mainwindow) { |
1630 if (GTK_WIDGET_VISIBLE(mainwindow)) { | |
4698 | 1631 if (GAIM_WINDOW_ICONIFIED(mainwindow)) { |
1632 gtk_window_present(GTK_WINDOW(mainwindow)); | |
1633 } else { | |
1634 #if _WIN32 | |
1635 wgaim_systray_minimize(mainwindow); | |
1636 #endif | |
1637 gtk_widget_hide(mainwindow); | |
1638 } | |
1639 } else { | |
1640 #if _WIN32 | |
1641 wgaim_systray_maximize(mainwindow); | |
1642 #endif | |
4833 | 1643 show_login(); |
4698 | 1644 } |
4840 | 1645 } else { |
1646 show_login(); | |
4698 | 1647 } |
1648 } | |
1649 | |
1650 void gaim_gtk_blist_docklet_add() | |
1651 { | |
1652 docklet_count++; | |
1653 } | |
1654 | |
1655 void gaim_gtk_blist_docklet_remove() | |
1656 { | |
1657 docklet_count--; | |
1658 if (!docklet_count) { | |
1659 if (connections) { | |
1660 gaim_blist_set_visible(TRUE); | |
4840 | 1661 } else if (mainwindow) { |
1662 gtk_window_present(GTK_WINDOW(mainwindow)); | |
1663 } else { | |
1664 show_login(); | |
4698 | 1665 } |
1666 } | |
4687 | 1667 } |
1 | 1668 |
4687 | 1669 static struct gaim_blist_ui_ops blist_ui_ops = |
1670 { | |
4695
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1671 gaim_gtk_blist_new_list, |
4bdd9a5fd026
[gaim-migrate @ 5006]
Christian Hammond <chipx86@chipx86.com>
parents:
4694
diff
changeset
|
1672 gaim_gtk_blist_new_node, |
4687 | 1673 gaim_gtk_blist_show, |
1674 gaim_gtk_blist_update, | |
1675 gaim_gtk_blist_remove, | |
1676 gaim_gtk_blist_destroy, | |
1677 gaim_gtk_blist_set_visible | |
1678 }; | |
1 | 1679 |
1680 | |
4687 | 1681 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
|
1682 { |
4687 | 1683 return &blist_ui_ops; |
1037
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
1684 } |
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
1685 |
3131 | 1686 |
1687 | |
4687 | 1688 /********************************************************************* |
1689 * Public utility functions * | |
1690 *********************************************************************/ | |
1058
4927ce25d8cc
[gaim-migrate @ 1068]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1057
diff
changeset
|
1691 |
4687 | 1692 GdkPixbuf * |
1693 create_prpl_icon(struct gaim_account *account) | |
4553
d03fcb3f4be2
[gaim-migrate @ 4833]
Christian Hammond <chipx86@chipx86.com>
parents:
4525
diff
changeset
|
1694 { |
4687 | 1695 struct prpl *prpl = find_prpl(account->protocol); |
1696 GdkPixbuf *status = NULL; | |
1697 char *filename = NULL; | |
1698 const char *protoname = prpl->list_icon(account, NULL); | |
1699 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and | |
1700 then it will look up protoname from the theme */ | |
1701 if (!strcmp(protoname, "aim")) { | |
1702 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "aim.png", NULL); | |
1703 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1704 g_free(filename); | |
1705 } else if (!strcmp(protoname, "yahoo")) { | |
1706 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "yahoo.png", NULL); | |
1707 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1708 g_free(filename); | |
1709 } else if (!strcmp(protoname, "msn")) { | |
1710 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "msn.png", NULL); | |
1711 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1712 g_free(filename); | |
1713 } else if (!strcmp(protoname, "jabber")) { | |
1714 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "jabber.png", NULL); | |
1715 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1716 g_free(filename); | |
1717 } else if (!strcmp(protoname, "icq")) { | |
1718 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "icq.png", NULL); | |
1719 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1720 g_free(filename); | |
1721 } else if (!strcmp(protoname, "gadu-gadu")) { | |
1722 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "gadugadu.png", NULL); | |
1723 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1724 g_free(filename); | |
1725 } else if (!strcmp(protoname, "napster")) { | |
1726 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "napster.png", NULL); | |
1727 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1728 g_free(filename); | |
1729 } else if (!strcmp(protoname, "irc")) { | |
1730 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "irc.png", NULL); | |
1731 status = gdk_pixbuf_new_from_file(filename,NULL); | |
1732 g_free(filename); | |
960
fa681641643d
[gaim-migrate @ 970]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
945
diff
changeset
|
1733 } |
4687 | 1734 return status; |
1 | 1735 } |
4699 | 1736 |