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