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