Mercurial > pidgin
annotate src/buddy.c @ 4687:283fb289c510
[gaim-migrate @ 4998]
This is a new buddy list.
Lots of things about it just Don't Work. I probably already know about those
things, and you'd just be wasting my time in submitting a bug report about it.
I decided that instead of getting it to all work perfectly before committing,
that I'd get it in cvs, and slowly fix it with regular commits. That way, it's
easier to keep track of things, and other developers can help. Plus, I'm getting
pissed off at the buddy list and want it to die. It's kinda boring, and doing nothing
but the buddy list for such a long time has just gotten me very bitter.
After 0.60 is released later this week, Gaim will resume being fun. This week is
going to be very stressful, though, I'm sure.
Things you ought to know about this buddy list:
- It crashes
- It leaks
- There's no way to edit the buddy list, or access offline buddies
- Most of the menus and buttons and whatnot just plain ol' don't work.
- Status icons are only implemented for AIM.
That's mostly just because I'm lazy. As such, you may want to be wary of updating this.
If you do decide to update this, you may want to learn "cvs update -D yesterday" as well :)
All the art there is just placeholder art.
You probably won't really have as many problems as it sounds like you will from reading this.
This message is extra-negative to stress that I don't want to be bothered with complaints about
something not working about it :). I'll repeat: If something doesn't work, I probably already
know about it.
If you want to actually help with something, I'd be delighted to have it. IM me.
-s.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Mon, 10 Mar 2003 05:30:31 +0000 |
parents | 42d53c416bb9 |
children | e19f91053ad0 |
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 | |
4687 | 38 #include "pixmaps/no_icon.xpm" |
39 | |
3630 | 40 #ifdef _WIN32 |
41 #include <gdk/gdkwin32.h> | |
42 #else | |
1233
728a90516211
[gaim-migrate @ 1243]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1230
diff
changeset
|
43 #include <unistd.h> |
3630 | 44 #include <gdk/gdkx.h> |
45 #endif | |
1 | 46 |
1634
d029dc28a61e
[gaim-migrate @ 1644]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1625
diff
changeset
|
47 #include <gdk/gdkkeysyms.h> |
1 | 48 #include <gtk/gtk.h> |
1030
38452403563b
[gaim-migrate @ 1040]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1002
diff
changeset
|
49 #include "prpl.h" |
4561 | 50 #include "sound.h" |
1 | 51 #include "gaim.h" |
4687 | 52 #include "gtklist.h" |
53 #include "gtkft.h" | |
3630 | 54 |
55 #ifdef _WIN32 | |
56 #include "win32dep.h" | |
57 #endif | |
58 | |
3939 | 59 static gboolean obscured = FALSE; |
3472 | 60 |
4687 | 61 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node); |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
62 |
4687 | 63 /*************************************************** |
64 * Callbacks * | |
65 ***************************************************/ | |
3869 | 66 |
4687 | 67 static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) { |
68 GaimBlistNode *node; | |
69 GtkTreeIter iter; | |
70 GValue val = { 0, }; | |
3154 | 71 |
4687 | 72 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); |
73 | |
74 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
75 node = g_value_get_pointer(&val); | |
76 | |
77 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
78 gaim_conversation_new(GAIM_CONV_IM, ((struct buddy*)node)->account, ((struct buddy*)node)->name); | |
1 | 79 } |
80 } | |
81 | |
4687 | 82 static void gaim_proto_menu_cb(GtkMenuItem *item, struct buddy *b) |
1 | 83 { |
4687 | 84 struct proto_buddy_menu *pbm = g_object_get_data(G_OBJECT(item), "gaimcallback"); |
85 if (pbm->callback) | |
86 pbm->callback(pbm->gc, b->name); | |
1396
df7c3cacac92
[gaim-migrate @ 1406]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1392
diff
changeset
|
87 } |
1 | 88 |
4687 | 89 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
|
90 { |
4687 | 91 GtkTreePath *path; |
92 GaimBlistNode *node; | |
93 GValue val = { 0, }; | |
94 GtkTreeIter iter; | |
95 GtkWidget *menu, *menuitem; | |
96 GtkWidget *image; | |
97 GList *list; | |
98 struct prpl *prpl; | |
1391
d606da211acb
[gaim-migrate @ 1401]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1376
diff
changeset
|
99 |
4687 | 100 if (event->button != 3) |
101 return FALSE; | |
102 | |
103 /* Here we figure out which node was clicked */ | |
104 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL)) | |
105 return FALSE; | |
106 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
107 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
108 node = g_value_get_pointer(&val); | |
109 | |
110 if (!GAIM_BLIST_NODE_IS_BUDDY(node)) | |
111 return FALSE; | |
112 | |
113 menu = gtk_menu_new(); | |
3251 | 114 |
4687 | 115 /* Protocol specific options */ |
116 prpl = find_prpl(((struct buddy*)node)->account->protocol); | |
117 if (prpl) { | |
118 list = prpl->buddy_menu(((struct buddy*)node)->account->gc, ((struct buddy*)node)->name); | |
119 while (list) { | |
120 struct proto_buddy_menu *pbm = list->data; | |
121 menuitem = gtk_menu_item_new_with_mnemonic(pbm->label); | |
122 g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pbm); | |
123 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_proto_menu_cb), node); | |
124 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
125 list = list->next; | |
3313 | 126 } |
3251 | 127 } |
4687 | 128 |
129 menuitem = gtk_image_menu_item_new_with_mnemonic("_IM"); | |
130 image = gtk_image_new_from_stock(GAIM_STOCK_IM, GTK_ICON_SIZE_MENU); | |
131 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); | |
132 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
133 | |
134 menuitem = gtk_image_menu_item_new_with_mnemonic("_Alias"); | |
135 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
136 | |
137 menuitem = gtk_image_menu_item_new_with_mnemonic("Add Buddy _Pounce"); | |
138 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
139 | |
140 menuitem = gtk_image_menu_item_new_with_mnemonic("View _Log"); | |
141 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
1 | 142 |
4687 | 143 gtk_widget_show_all(menu); |
144 | |
145 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, event->time); | |
1 | 146 |
1030
38452403563b
[gaim-migrate @ 1040]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1002
diff
changeset
|
147 return FALSE; |
1 | 148 } |
149 | |
4687 | 150 static void gaim_gtk_blist_reordered_cb(GtkTreeModel *model, |
151 GtkTreePath *path, | |
152 GtkTreeIter *iter, | |
153 gint *neworder, | |
154 gpointer null) | |
3111 | 155 { |
4687 | 156 debug_printf("This doesn't work because GTK is broken\n"); |
1 | 157 |
158 } | |
159 | |
4687 | 160 /* This is called 10 seconds after the buddy logs in. It removes the "logged in" icon and replaces it with |
161 * the normal status icon */ | |
1072
81d19577285a
[gaim-migrate @ 1082]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1070
diff
changeset
|
162 |
4687 | 163 static gboolean gaim_reset_present_icon(GaimBlistNode *b) |
164 { | |
165 ((struct buddy*)b)->present = 1; | |
166 gaim_gtk_blist_update(NULL, b); | |
167 return FALSE; | |
577
aa9a8bcddd80
[gaim-migrate @ 587]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
544
diff
changeset
|
168 } |
aa9a8bcddd80
[gaim-migrate @ 587]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
544
diff
changeset
|
169 |
4687 | 170 static void gaim_gtk_blist_add_buddy_cb() |
935
5e6ca3dd4d02
[gaim-migrate @ 945]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
921
diff
changeset
|
171 { |
4687 | 172 GtkTreeSelection *sel = gtk_tree_view_get_selection(gtkblist->treeview); |
173 GtkTreeIter iter; | |
174 GaimBlistNode *node; | |
175 GValue val; | |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4349
diff
changeset
|
176 |
4687 | 177 gtk_tree_selection_get_selected(sel, NULL, &iter); |
178 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
179 node = g_value_get_pointer(&val); | |
180 | |
181 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
182 show_add_buddy(NULL, NULL, ((struct group*)node->parent)->name, NULL); | |
183 else if (GAIM_BLIST_NODE_IS_GROUP(node)) | |
184 show_add_buddy(NULL, NULL, ((struct group*)node)->name, NULL); | |
185 | |
1 | 186 } |
187 | |
188 | |
4687 | 189 /*************************************************** |
190 * Crap * | |
191 ***************************************************/ | |
192 static GtkItemFactoryEntry blist_menu[] = | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
193 { |
4687 | 194 /* Buddies menu */ |
195 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>" }, | |
196 { N_("/Buddies/_Add A Buddy..."), "<CTL>B", gaim_gtk_blist_add_buddy_cb, 0, | |
197 "<StockItem>", GTK_STOCK_ADD }, | |
198 { N_("/Buddies/New _Instant Message..."), "<CTL>I", show_im_dialog, 0, | |
199 "<StockItem>", GAIM_STOCK_IM }, | |
200 { N_("/Buddies/Join a _Chat..."), "<CTL>C", join_chat, 0, | |
201 "<StockItem>", GAIM_STOCK_CHAT }, | |
202 { N_("/Buddies/sep1"), NULL, NULL, 0, "<Separator>" }, | |
203 { N_("/Buddies/Get _User Info..."), "<CTL>J", show_info_dialog, 0, | |
204 "<StockItem>", GAIM_STOCK_INFO }, | |
205 { N_("/Buddies/sep2"), NULL, NULL, 0, "<Separator>" }, | |
206 { N_("/Buddies/_Signoff"), "<CTL>D", signoff_all, 0, NULL }, | |
207 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0, | |
208 "<StockItem>", GTK_STOCK_QUIT }, | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
209 |
4687 | 210 /* Tools */ |
211 { N_("/_Tools"), NULL, NULL, 0, "<Branch>" }, | |
212 { N_("/Tools/_Away"), NULL, NULL, 0, "<Branch>" }, | |
213 { N_("/Tools/Buddy _Pounce"), NULL, NULL, 0, "<Branch>" }, | |
214 { N_("/Tools/sep1"), NULL, NULL, 0, "<Separator>" }, | |
215 { N_("/Tools/A_ccounts"), "<CTL>A", account_editor, 0, NULL }, | |
216 { N_("/Tools/Preferences"), "<CTL>P", show_prefs, 0, | |
217 "<StockItem>", GTK_STOCK_PREFERENCES }, | |
218 { N_("/Tools/_File Transfers"), NULL, NULL, 0, | |
219 "<StockItem>", GTK_STOCK_REVERT_TO_SAVED }, | |
220 { N_("/Tools/sep2"), NULL, NULL, 0, "<Separator>" }, | |
221 { N_("/Tools/P_rotocol Actions"), NULL, NULL, 0, "<Branch>" }, | |
222 { N_("/Tools/Pr_ivacy"), NULL, show_privacy_options, 0, NULL }, | |
223 { N_("/Tools/View System _Log"), NULL, NULL, 0, NULL }, | |
3251 | 224 |
4687 | 225 /* Help */ |
226 { N_("/_Help"), NULL, NULL, 0, "<Branch>" }, | |
227 { N_("/Help/Online _Help"), "F1", NULL, 0, | |
228 "<StockItem>", GTK_STOCK_HELP }, | |
229 { N_("/Help/_Debug Window"), NULL, NULL, 0, NULL }, | |
230 { N_("/Help/_About"), NULL, show_about, 0, NULL }, | |
231 | |
232 }; | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
233 |
4687 | 234 /********************************************************* |
235 * Private Utility functions * | |
236 *********************************************************/ | |
237 | |
238 static GdkPixbuf *gaim_gtk_blist_get_status_icon(struct buddy *b) | |
239 { | |
240 GdkPixbuf *status = NULL; | |
241 GdkPixbuf *scale = NULL; | |
242 GdkPixbuf *emblem = NULL; | |
243 gchar *filename = NULL; | |
244 const char *protoname = NULL; | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
245 |
4687 | 246 char *se,*sw,*nw,*ne; |
247 | |
248 int scalesize = 30; | |
249 | |
250 struct prpl* prpl = find_prpl(b->account->protocol); | |
251 if (prpl->list_icon) | |
252 protoname = prpl->list_icon(b->account, b); | |
253 if (prpl->list_emblems) | |
254 prpl->list_emblems(b, &se, &sw, &nw, &ne); | |
255 | |
256 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) { | |
257 scalesize = 15; | |
258 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
|
259 } |
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
260 |
4687 | 261 |
262 if (b->present == 2) { | |
263 /* If b->present is 2, that means this buddy has just signed on. We use the "login" icon for the | |
264 * status, and we set a timeout to change it to a normal icon after 10 seconds. */ | |
265 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); | |
266 status = gdk_pixbuf_new_from_file(filename,NULL); | |
267 g_free(filename); | |
268 g_timeout_add(10000, (GSourceFunc)gaim_reset_present_icon, b); | |
269 | |
270 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and | |
271 then it will look up protoname from the theme */ | |
272 } else { | |
273 char *image = g_strdup_printf("%s.png", protoname); | |
274 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
275 status = gdk_pixbuf_new_from_file(filename,NULL); | |
276 g_free(image); | |
277 g_free(filename); | |
1929
d51ea669d84e
[gaim-migrate @ 1939]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1918
diff
changeset
|
278 |
4687 | 279 } |
280 | |
281 if (!status) | |
282 return NULL; | |
283 | |
284 scale = gdk_pixbuf_scale_simple(status, scalesize, scalesize, GDK_INTERP_BILINEAR); | |
285 | |
286 /* Emblems */ | |
287 | |
288 /* Each protocol can specify up to four "emblems" to composite over the base icon. "away", "busy", "mobile user" | |
289 * are all examples of states represented by emblems. I'm not even really sure I like this yet. */ | |
290 | |
291 /* XXX Clean this crap up, yo. */ | |
292 if (se) { | |
293 char *image = g_strdup_printf("%s.png", se); | |
294 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
295 g_free(image); | |
296 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
297 g_free(filename); | |
298 if (emblem) { | |
299 if (blist_options & OPT_BLIST_SHOW_ICONS) | |
300 gdk_pixbuf_composite (emblem, | |
301 scale, 15, 15, | |
302 15, 15, | |
303 15, 15, | |
304 1, 1, | |
305 GDK_INTERP_BILINEAR, | |
306 255); | |
307 else | |
308 gdk_pixbuf_composite (emblem, | |
309 scale, 0, 0, | |
310 15, 15, | |
311 0, 0, | |
312 1, 1, | |
313 GDK_INTERP_BILINEAR, | |
314 255); | |
315 } | |
316 } | |
317 if (sw) { | |
318 char *image = g_strdup_printf("%s.png", sw); | |
319 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
320 g_free(image); | |
321 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
322 g_free(filename); | |
323 if (emblem) { | |
324 gdk_pixbuf_composite (emblem, | |
325 scale, 0, 15, | |
326 15, 15, | |
327 0, 15, | |
328 1, 1, | |
329 GDK_INTERP_BILINEAR, | |
330 255); | |
331 } | |
332 } | |
333 if (nw) { | |
334 char *image = g_strdup_printf("%s.png", nw); | |
335 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
336 g_free(image); | |
337 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
338 g_free(filename); | |
339 if (emblem) { | |
340 gdk_pixbuf_composite (emblem, | |
341 scale, 0, 0, | |
342 15, 15, | |
343 0, 0, | |
344 1, 1, | |
345 GDK_INTERP_BILINEAR, | |
346 255); | |
347 } | |
348 } | |
349 if (ne) { | |
350 char *image = g_strdup_printf("%s.png", ne); | |
351 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
352 g_free(image); | |
353 emblem = gdk_pixbuf_new_from_file(filename,NULL); | |
354 g_free(filename); | |
355 if (emblem) { | |
356 gdk_pixbuf_composite (emblem, | |
357 scale, 15, 0, | |
358 15, 15, | |
359 15, 0, | |
360 1, 1, | |
361 GDK_INTERP_BILINEAR, | |
362 255); | |
363 } | |
364 } | |
365 | |
366 | |
367 /* Idle gray buddies affects the whole row. This converts the status icon to greyscale. */ | |
368 if (b->idle) | |
369 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0, FALSE); | |
370 return scale; | |
1 | 371 } |
372 | |
4687 | 373 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b) |
1 | 374 { |
4687 | 375 /* This just opens a file from ~/.gaim/icons/screenname. This needs to change to be more gooder. */ |
376 char *file = g_build_filename(gaim_user_dir(), "icons", normalize(b->name), NULL); | |
377 GdkPixbuf *buf = gdk_pixbuf_new_from_file(file, NULL); | |
378 | |
379 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) | |
380 return NULL; | |
381 | |
382 if (buf) { | |
383 if (b->idle) { | |
384 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0, FALSE); | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
385 } |
4687 | 386 return gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR); |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
387 } |
4687 | 388 return NULL; |
2986 | 389 } |
390 | |
4687 | 391 static gchar *gaim_gtk_blist_get_name_markup(struct buddy *b) |
1 | 392 { |
4687 | 393 char *name = gaim_get_buddy_alias(b); |
394 char *esc = g_markup_escape_text(name, strlen(name)), *text = NULL; | |
395 /* XXX Clean up this crap */ | |
396 | |
397 int ihrs, imin; | |
398 char *idletime = ""; | |
399 char *warning = idletime; | |
400 time_t t; | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
401 |
4687 | 402 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) { |
403 if (b->idle > 0) { | |
404 text = g_strdup_printf("<span color='gray'>%s</span>", | |
405 esc); | |
406 g_free(esc); | |
407 return text; | |
408 } else { | |
409 return esc; | |
410 } | |
1 | 411 } |
412 | |
4687 | 413 time(&t); |
414 ihrs = (t - b->idle) / 3600; | |
415 imin = ((t - b->idle) / 60) % 60; | |
416 | |
417 if (b->idle) { | |
418 if (ihrs) | |
419 idletime = g_strdup_printf(_("Idle (%dh%02dm)"), ihrs, imin); | |
420 else | |
421 idletime = g_strdup_printf(_("Idle (%dm)"), imin); | |
422 } | |
423 | |
424 if (b->evil > 0) | |
425 warning = g_strdup_printf(_("Warned (%d%%)"), b->evil); | |
426 | |
427 if (b->idle) | |
428 text = g_strdup_printf("<span color='grey'>%s</span>\n<span color='gray' size='smaller'>%s %s</span>", | |
429 esc, | |
430 idletime, warning); | |
431 else | |
432 text = g_strdup_printf("%s\n<span color='gray' size='smaller'>%s</span>", esc, warning); | |
433 | |
434 if (idletime[0]) | |
435 g_free(idletime); | |
436 if (warning[0]) | |
437 g_free(warning); | |
438 | |
439 return text; | |
440 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
441 |
4687 | 442 /********************************************************************************** |
443 * Public API Functions * | |
444 **********************************************************************************/ | |
445 static void gaim_gtk_blist_show(struct gaim_buddy_list *list) | |
446 { | |
447 GtkItemFactory *ift; | |
448 GtkCellRenderer *rend; | |
449 GtkTreeViewColumn *column; | |
450 GtkWidget *sw; | |
451 GtkWidget *button; | |
452 GValue *val; | |
453 GtkTreeIter iter; | |
454 | |
455 if (gtkblist) { | |
456 gtk_widget_show(gtkblist->window); | |
457 return; | |
458 } | |
459 | |
460 gtkblist = g_new0(struct gaim_gtk_buddy_list , 1); | |
461 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
462 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); | |
463 | |
464 gtkblist->vbox = gtk_vbox_new(FALSE, 6); | |
465 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); | |
1 | 466 |
4687 | 467 /******************************* Menu bar *************************************/ |
468 ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", NULL); | |
469 gtk_item_factory_create_items(ift, sizeof(blist_menu) / sizeof(*blist_menu), | |
470 blist_menu, NULL); | |
471 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtk_item_factory_get_widget(ift, "<GaimMain>"), FALSE, FALSE, 0); | |
1 | 472 |
4687 | 473 /****************************** GtkTreeView **********************************/ |
474 sw = gtk_scrolled_window_new(NULL,NULL); | |
475 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); | |
476 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
477 gtk_widget_set_usize(sw, 200, 200); | |
478 | |
479 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, | |
480 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER); | |
481 /* This is broken because GTK is broken | |
482 g_signal_connect(G_OBJECT(gtkblist->treemodel), "row-reordered", gaim_gtk_blist_reordered_cb, NULL); */ | |
483 | |
484 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel)); | |
485 | |
486 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
1 | 487 |
4687 | 488 rend = gtk_cell_renderer_pixbuf_new(); |
489 column = gtk_tree_view_column_new_with_attributes("Status", rend, "pixbuf", STATUS_ICON_COLUMN, NULL); | |
490 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
491 | |
492 rend = gtk_cell_renderer_text_new(); | |
493 column = gtk_tree_view_column_new_with_attributes("Name", rend, "markup", NAME_COLUMN, NULL); | |
494 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
495 | |
496 rend = gtk_cell_renderer_text_new(); | |
497 column = gtk_tree_view_column_new_with_attributes("Warning", rend, "text", WARNING_COLUMN, NULL); | |
498 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
499 | |
500 rend = gtk_cell_renderer_text_new(); | |
501 column = gtk_tree_view_column_new_with_attributes("Idle", rend, "text", IDLE_COLUMN, NULL); | |
502 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
1 | 503 |
4687 | 504 rend = gtk_cell_renderer_pixbuf_new(); |
505 column = gtk_tree_view_column_new_with_attributes("Buddy Icon", rend, "pixbuf", BUDDY_ICON_COLUMN, NULL); | |
506 g_object_set(rend, "xalign", 1.0, NULL); | |
507 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
508 | |
509 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL); | |
510 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
|
511 |
4687 | 512 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0); |
513 gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); | |
514 | |
515 /**************************** Button Box **************************************/ | |
516 gtkblist->bbox = gtk_hbox_new(TRUE, 0); | |
517 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->bbox, FALSE, FALSE, 0); | |
518 button = gaim_pixbuf_button_from_stock(_("IM"), GAIM_STOCK_IM, GAIM_BUTTON_VERTICAL); | |
519 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
520 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
521 button = gaim_pixbuf_button_from_stock(_("Get Info"), GAIM_STOCK_INFO, GAIM_BUTTON_VERTICAL); | |
522 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
523 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
524 button = gaim_pixbuf_button_from_stock(_("Chat"), GAIM_STOCK_CHAT, GAIM_BUTTON_VERTICAL); | |
525 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
526 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
527 button = gaim_pixbuf_button_from_stock(_("Away"), GAIM_STOCK_AWAY, GAIM_BUTTON_VERTICAL); | |
528 gtk_box_pack_start(GTK_BOX(gtkblist->bbox), button, FALSE, FALSE, 0); | |
529 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | |
530 | |
531 /* OK... let's show this bad boy. */ | |
532 gaim_gtk_blist_refresh(list); | |
533 gtk_widget_show_all(gtkblist->window); | |
534 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
535 |
4687 | 536 void gaim_gtk_blist_refresh(struct gaim_buddy_list *list) |
537 { | |
538 GaimBlistNode *group = list->root; | |
539 GaimBlistNode *buddy; | |
540 | |
541 while (group) { | |
542 gaim_gtk_blist_update(list, group); | |
543 buddy = group->child; | |
544 while (buddy) { | |
545 gaim_gtk_blist_update(list, buddy); | |
546 buddy = buddy->next; | |
547 } | |
548 group = group->next; | |
549 } | |
550 } | |
1 | 551 |
4687 | 552 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node) |
553 { | |
554 GtkTreeIter *iter = node->ui_data; | |
555 GtkTreePath *path; | |
556 GdkPixbuf *buf = NULL; | |
557 gboolean expand = FALSE; | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
558 |
4687 | 559 if (!gtkblist) |
560 return; | |
561 | |
562 if (!iter) { /* This is a newly added node */ | |
563 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
564 if (((struct buddy*)node)->present) { | |
565 if(node->parent && node->parent && !node->parent->ui_data) { | |
566 | |
567 /* This buddy's group has not yet been added. We do that here */ | |
568 | |
569 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", ((struct group*)node->parent)->name); | |
570 GtkTreeIter *iter2 = g_new0(GtkTreeIter, 1); | |
571 GaimBlistNode *insertat = node->parent->prev; | |
572 GtkTreeIter *insertatiter = NULL; | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
573 |
4687 | 574 /* We traverse backwards through the buddy list to find the node in the tree to insert it after */ |
575 while (insertat && !insertat->ui_data) | |
576 insertat = insertat->prev; | |
577 if (insertat) | |
578 insertatiter = insertat->ui_data; | |
579 | |
580 /* This is where we create the node and add it. */ | |
581 gtk_tree_store_insert_after(gtkblist->treemodel, iter2, | |
582 node->parent->parent ? node->parent->parent->ui_data : NULL, insertatiter); | |
583 gtk_tree_store_set(gtkblist->treemodel, iter2, | |
584 STATUS_ICON_COLUMN, gtk_widget_render_icon | |
585 (gtkblist->treeview,GTK_STOCK_OPEN,GTK_ICON_SIZE_LARGE_TOOLBAR,NULL), | |
586 NAME_COLUMN, mark, | |
587 NODE_COLUMN, node->parent, | |
588 -1); | |
589 node->parent->ui_data = iter2; | |
590 expand = TRUE; | |
591 } | |
592 iter = g_new0(GtkTreeIter, 1); | |
593 node->ui_data = iter; | |
594 | |
595 gtk_tree_store_insert_after (gtkblist->treemodel, iter, node->parent ? node->parent->ui_data : NULL, | |
596 node->prev ? node->prev->ui_data : NULL); | |
597 | |
598 | |
599 if (expand) { /* expand was set to true if this is the first element added to a group. In such case | |
600 * we expand the group node */ | |
601 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), node->parent->ui_data); | |
602 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE); | |
603 } | |
604 node->ui_data = iter; | |
605 } | |
606 } | |
607 } | |
608 | |
609 if (GAIM_BLIST_NODE_IS_BUDDY(node) && ((struct buddy*)node)->present) { | |
610 GdkPixbuf *status, *avatar; | |
611 char *mark; | |
612 | |
613 status = gaim_gtk_blist_get_status_icon((struct buddy*)node); | |
614 avatar = gaim_gtk_blist_get_buddy_icon((struct buddy*)node); | |
615 mark = gaim_gtk_blist_get_name_markup((struct buddy*)node); | |
616 | |
617 gtk_tree_store_set(gtkblist->treemodel, iter, | |
618 STATUS_ICON_COLUMN, status, | |
619 NAME_COLUMN, mark, | |
620 WARNING_COLUMN, "", | |
621 IDLE_COLUMN, "", | |
622 BUDDY_ICON_COLUMN, avatar, | |
623 NODE_COLUMN, node, | |
624 -1); | |
625 | |
626 g_free(mark); | |
627 g_object_unref(status); | |
628 if (avatar) { | |
629 g_object_unref(avatar); | |
630 } | |
631 } else if (GAIM_BLIST_NODE_IS_BUDDY(node) && node->ui_data){ | |
632 gtk_tree_store_remove(GTK_TREE_STORE(gtkblist->treemodel), (GtkTreeIter*)(node->ui_data)); | |
633 g_free(node->ui_data); | |
634 node->ui_data = NULL; | |
635 } | |
636 | |
637 } | |
2372
2927c2c26fe6
[gaim-migrate @ 2385]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2334
diff
changeset
|
638 |
4687 | 639 static void gaim_gtk_blist_remove(struct gaim_buddy_list *list, GaimBlistNode *node) |
640 { | |
641 if (!node->ui_data) | |
642 return; | |
643 gtk_tree_store_remove(gtkblist->treemodel, (GtkTreeIter*)(node->ui_data)); | |
644 } | |
645 | |
646 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) | |
647 { | |
648 gtk_widget_destroy(gtkblist->window); | |
649 } | |
1 | 650 |
4687 | 651 static void gaim_gtk_blist_set_visible(struct gaim_buddy_list *list, gboolean show) |
652 { | |
653 if (show) | |
654 gtk_widget_show(gtkblist->window); | |
655 else | |
656 gtk_widget_hide(gtkblist->window); | |
657 } | |
1 | 658 |
4687 | 659 static struct gaim_blist_ui_ops blist_ui_ops = |
660 { | |
661 gaim_gtk_blist_show, | |
662 gaim_gtk_blist_update, | |
663 gaim_gtk_blist_remove, | |
664 gaim_gtk_blist_destroy, | |
665 gaim_gtk_blist_set_visible | |
666 }; | |
1 | 667 |
668 | |
4687 | 669 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
|
670 { |
4687 | 671 return &blist_ui_ops; |
1037
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
672 } |
1c663beef29d
[gaim-migrate @ 1047]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1036
diff
changeset
|
673 |
3131 | 674 |
675 | |
4687 | 676 /********************************************************************* |
677 * Public utility functions * | |
678 *********************************************************************/ | |
1058
4927ce25d8cc
[gaim-migrate @ 1068]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1057
diff
changeset
|
679 |
4687 | 680 GdkPixbuf * |
681 create_prpl_icon(struct gaim_account *account) | |
4553
d03fcb3f4be2
[gaim-migrate @ 4833]
Christian Hammond <chipx86@chipx86.com>
parents:
4525
diff
changeset
|
682 { |
4687 | 683 struct prpl *prpl = find_prpl(account->protocol); |
684 GdkPixbuf *status = NULL; | |
685 char *filename = NULL; | |
686 const char *protoname = prpl->list_icon(account, NULL); | |
687 /* "Hey, what's all this crap?" you ask. Status icons will be themeable too, and | |
688 then it will look up protoname from the theme */ | |
689 if (!strcmp(protoname, "aim")) { | |
690 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "aim.png", NULL); | |
691 status = gdk_pixbuf_new_from_file(filename,NULL); | |
692 g_free(filename); | |
693 } else if (!strcmp(protoname, "yahoo")) { | |
694 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "yahoo.png", NULL); | |
695 status = gdk_pixbuf_new_from_file(filename,NULL); | |
696 g_free(filename); | |
697 } else if (!strcmp(protoname, "msn")) { | |
698 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "msn.png", NULL); | |
699 status = gdk_pixbuf_new_from_file(filename,NULL); | |
700 g_free(filename); | |
701 } else if (!strcmp(protoname, "jabber")) { | |
702 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "jabber.png", NULL); | |
703 status = gdk_pixbuf_new_from_file(filename,NULL); | |
704 g_free(filename); | |
705 } else if (!strcmp(protoname, "icq")) { | |
706 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "icq.png", NULL); | |
707 status = gdk_pixbuf_new_from_file(filename,NULL); | |
708 g_free(filename); | |
709 } else if (!strcmp(protoname, "gadu-gadu")) { | |
710 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "gadugadu.png", NULL); | |
711 status = gdk_pixbuf_new_from_file(filename,NULL); | |
712 g_free(filename); | |
713 } else if (!strcmp(protoname, "napster")) { | |
714 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "napster.png", NULL); | |
715 status = gdk_pixbuf_new_from_file(filename,NULL); | |
716 g_free(filename); | |
717 } else if (!strcmp(protoname, "irc")) { | |
718 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "irc.png", NULL); | |
719 status = gdk_pixbuf_new_from_file(filename,NULL); | |
720 g_free(filename); | |
960
fa681641643d
[gaim-migrate @ 970]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
945
diff
changeset
|
721 } |
4687 | 722 return status; |
1 | 723 } |