Mercurial > pidgin.yaz
annotate src/gtkblist.c @ 10147:a485dedd6ba2
[gaim-migrate @ 11224]
Minor privacy dialog changes from Bleeter.
1. Force-save blist.xml when privacy stuff changes instead of when Gaim
shutdowns (or when something else triggers a blist-save)
2. Don't redraw stuff in the dialog if you select the same privacy option
that was previously selected.
Someone can commit this to oldstatus, if you really want. I'm not
going to because I don't want to test it and I don't want to be
responsible if it breaks something there, and I don't consider the
changes to be that dire.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Wed, 27 Oct 2004 22:24:51 +0000 |
parents | 757a7c088801 |
children | 96a850ab30c8 |
rev | line source |
---|---|
5228 | 1 /* |
2 * gaim | |
3 * | |
8046 | 4 * Gaim is the legal property of its developers, whose names are too numerous |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
5228 | 7 * |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 * | |
22 */ | |
9791 | 23 #include "internal.h" |
24 #include "gtkgaim.h" | |
7620 | 25 |
26 #include "account.h" | |
9015 | 27 #include "connection.h" |
7620 | 28 #include "core.h" |
29 #include "debug.h" | |
30 #include "notify.h" | |
31 #include "prpl.h" | |
32 #include "prefs.h" | |
8986 | 33 #include "plugin.h" |
7620 | 34 #include "request.h" |
35 #include "signals.h" | |
36 #include "sound.h" | |
37 #include "stock.h" | |
38 #include "util.h" | |
39 | |
40 #include "gtkaccount.h" | |
41 #include "gtkblist.h" | |
42 #include "gtkconv.h" | |
43 #include "gtkdebug.h" | |
9709 | 44 #include "gtkdialogs.h" |
7620 | 45 #include "gtkft.h" |
46 #include "gtklog.h" | |
47 #include "gtkpounce.h" | |
48 #include "gtkprefs.h" | |
49 #include "gtkprivacy.h" | |
8113 | 50 #include "gtkroomlist.h" |
10074 | 51 #include "gtksound.h" |
7620 | 52 #include "gtkutils.h" |
53 | |
54 #include "gaim.h" | |
5228 | 55 |
56 #include <gdk/gdkkeysyms.h> | |
57 #include <gtk/gtk.h> | |
7620 | 58 #include <gdk/gdk.h> |
59 | |
7662 | 60 #if (GTK_CHECK_VERSION(2,2,0) && !(defined(__APPLE__) && defined(__MACH__))) |
61 #define WANT_DROP_SHADOW | |
62 #endif | |
63 | |
7620 | 64 typedef struct |
65 { | |
66 GaimAccount *account; | |
67 | |
68 GtkWidget *window; | |
69 GtkWidget *combo; | |
70 GtkWidget *entry; | |
71 GtkWidget *entry_for_alias; | |
72 GtkWidget *account_box; | |
73 | |
74 } GaimGtkAddBuddyData; | |
75 | |
76 typedef struct | |
77 { | |
9811 | 78 GaimAccount *account; |
9812 | 79 gchar *default_chat_name; |
9811 | 80 |
81 GtkWidget *window; | |
7620 | 82 GtkWidget *account_menu; |
83 GtkWidget *alias_entry; | |
84 GtkWidget *group_combo; | |
85 GtkWidget *entries_box; | |
86 GtkSizeGroup *sg; | |
87 | |
88 GList *entries; | |
89 | |
90 } GaimGtkAddChatData; | |
91 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
92 typedef struct |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
93 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
94 GaimAccount *account; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
95 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
96 GtkWidget *window; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
97 GtkWidget *account_menu; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
98 GtkWidget *entries_box; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
99 GtkSizeGroup *sg; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
100 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
101 GList *entries; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
102 } GaimGtkJoinChatData; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
103 |
7620 | 104 |
9949 | 105 static GtkWidget *protomenu = NULL; |
106 static GtkWidget *awaymenu = NULL; | |
107 static GtkWidget *pluginmenu = NULL; | |
5228 | 108 |
5422 | 109 GSList *gaim_gtk_blist_sort_methods = NULL; |
110 static struct gaim_gtk_blist_sort_method *current_sort_method = NULL; | |
7620 | 111 static GtkTreeIter sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); |
112 | |
113 /* The functions we use for sorting aren't available in gtk 2.0.x, and | |
114 * segfault in 2.2.0. 2.2.1 is known to work, so I'll require that */ | |
115 #if GTK_CHECK_VERSION(2,2,1) | |
116 static GtkTreeIter sort_method_alphabetical(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); | |
117 static GtkTreeIter sort_method_status(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); | |
118 static GtkTreeIter sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur); | |
119 #endif | |
120 static GaimGtkBuddyList *gtkblist = NULL; | |
5228 | 121 |
122 /* part of the best damn Docklet code this side of Tahiti */ | |
123 static gboolean gaim_gtk_blist_obscured = FALSE; | |
124 | |
125 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data); | |
7620 | 126 static void gaim_gtk_blist_update(GaimBuddyList *list, GaimBlistNode *node); |
5234 | 127 static char *gaim_get_tooltip_text(GaimBlistNode *node); |
5228 | 128 static char *item_factory_translate_func (const char *path, gpointer func_data); |
5273 | 129 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter); |
7620 | 130 static void redo_buddy_list(GaimBuddyList *list, gboolean remove); |
131 static void gaim_gtk_blist_collapse_contact_cb(GtkWidget *w, GaimBlistNode *node); | |
132 | |
133 static void show_rename_group(GtkWidget *unused, GaimGroup *g); | |
5422 | 134 |
10015 | 135 static gboolean xcomposite_is_present(); |
136 | |
5256 | 137 struct _gaim_gtk_blist_node { |
138 GtkTreeRowReference *row; | |
7620 | 139 gboolean contact_expanded; |
5256 | 140 }; |
141 | |
7662 | 142 #ifdef WANT_DROP_SHADOW |
7620 | 143 /**************************** Weird drop shadow stuff *******************/ |
144 /* This is based on a patch for drop shadows in GTK menus available at http://www.xfce.org/gtkmenu-shadow/ */ | |
145 | |
146 enum side { | |
147 EAST_SIDE, | |
148 SOUTH_SIDE | |
149 }; | |
150 | |
151 const double shadow_strip_l[5] = { | |
152 .937, .831, .670, .478, .180 | |
153 }; | |
154 | |
155 const double bottom_left_corner[25] = { | |
156 1.00, .682, .423, .333, .258, | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
157 1.00, .898, .800, .682, .584, |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
158 1.00, .937, .874, .800, .737, |
7620 | 159 1.00, .968, .937, .898, .866, |
160 1.00, .988, .976, .960, .945 | |
161 }; | |
162 | |
163 const double bottom_right_corner[25] = { | |
164 .258, .584, .737, .866, .945, | |
165 .584, .682, .800, .898, .960, | |
166 .737, .800, .874, .937, .976, | |
167 .866, .898, .937, .968, .988, | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
168 .945, .960, .976, .988, .996 |
7620 | 169 }; |
170 | |
171 const double top_right_corner[25] = { | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
172 1.00, 1.00, 1.00, 1.00, 1.00, |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
173 .686, .898, .937, .968, .988, |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
174 .423, .803, .874, .937, .976, |
7620 | 175 .333, .686, .800, .898, .960, |
176 .258, .584, .737, .866, .945 | |
177 }; | |
178 | |
179 const double top_left_corner[25] = { | |
180 .988, .968, .937, .898, .498, | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
181 .976, .937, .874, .803, .423, |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
182 .960, .898, .800, .686, .333, |
7620 | 183 .945, .866, .737, .584, .258, |
184 .941, .847, .698, .521, .215 | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
185 }; |
7620 | 186 |
187 | |
10015 | 188 static gboolean xcomposite_is_present() |
189 { | |
10018
bae1cd16e854
[gaim-migrate @ 10938]
Luke Schierer <lschiere@pidgin.im>
parents:
10017
diff
changeset
|
190 static gboolean result = FALSE; |
bae1cd16e854
[gaim-migrate @ 10938]
Luke Schierer <lschiere@pidgin.im>
parents:
10017
diff
changeset
|
191 #ifndef _WIN32 |
bae1cd16e854
[gaim-migrate @ 10938]
Luke Schierer <lschiere@pidgin.im>
parents:
10017
diff
changeset
|
192 static gboolean known = FALSE; |
10015 | 193 int i, j, k; |
194 | |
195 if (!known) { | |
196 /* I don't actually care about versions/etc. */ | |
197 if (XQueryExtension(GDK_DISPLAY(), "Composite", &i, &j, &k) == True) | |
198 result = TRUE; | |
10017 | 199 known = TRUE; |
10015 | 200 } |
10018
bae1cd16e854
[gaim-migrate @ 10938]
Luke Schierer <lschiere@pidgin.im>
parents:
10017
diff
changeset
|
201 #endif |
10015 | 202 |
203 return result; | |
204 } | |
205 | |
7620 | 206 static GdkPixbuf * |
9811 | 207 get_pixbuf(GtkWidget *menu, int x, int y, int width, int height) |
7620 | 208 { |
9811 | 209 GdkPixbuf *dest, *src; |
210 GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET(menu)); | |
211 GdkWindow *root = gdk_screen_get_root_window (screen); | |
212 gint screen_height = gdk_screen_get_height (screen); | |
213 gint screen_width = gdk_screen_get_width (screen); | |
214 gint original_width = width; | |
215 gint original_height = height; | |
7620 | 216 |
217 #ifdef _WIN32 | |
9822 | 218 #if !GTK_CHECK_VERSION(2,4,8) |
219 /* XXX: Kill this entire block someday. | |
220 * | |
9834 | 221 * 2004-08-22: This bug fix should land in GTK+ version 2.4.8: |
9822 | 222 * http://bugzilla.gnome.org/show_bug.cgi?id=149013 |
223 * | |
224 * In Win32, GDK gets the workarea that isn't occupied by toolbars | |
9811 | 225 * (including the taskbar) and uses that region as the screen size. |
226 * GTK returns positions based on a screen size that ignores these | |
227 * toolbars. Since we want a pixmap with real X,Y coordinates, we | |
228 * need to find out the offset from GTK's screen to GDK's screen, | |
229 * and adjust the pixmaps we grab accordingly. GDK will not deal | |
230 * with toolbar position updates, so we're stuck restarting Gaim | |
9822 | 231 * if that happens. - SimGuy |
9811 | 232 */ |
233 RECT *workarea = g_malloc(sizeof(RECT)); | |
234 SystemParametersInfo(SPI_GETWORKAREA, 0, (void *)workarea, 0); | |
235 x += (workarea->left); | |
236 y += (workarea->top); | |
237 g_free(workarea); | |
7620 | 238 #endif |
9822 | 239 #endif |
7620 | 240 |
9811 | 241 if (x < 0) { |
242 width += x; | |
243 x = 0; | |
244 } | |
245 | |
246 if (y < 0) { | |
247 height += y; | |
248 y = 0; | |
249 } | |
250 | |
251 if (x + width > screen_width) { | |
252 width = screen_width - x; | |
253 } | |
254 | |
255 if (y + height > screen_height) { | |
256 height = screen_height - y; | |
257 } | |
258 | |
259 if (width <= 0 || height <= 0) | |
260 return NULL; | |
261 | |
262 dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, | |
263 original_width, original_height); | |
264 src = gdk_pixbuf_get_from_drawable(NULL, root, NULL, x, y, 0, 0, | |
265 width, height); | |
266 gdk_pixbuf_copy_area (src, 0, 0, width, height, dest, 0, 0); | |
267 | |
268 g_object_unref (G_OBJECT (src)); | |
269 | |
270 return dest; | |
7620 | 271 } |
272 | |
273 static void | |
274 shadow_paint(GaimGtkBuddyList *blist, GdkRectangle *area, enum side shadow) | |
275 { | |
9811 | 276 gint width, height; |
277 GdkGC *gc = gtkblist->tipwindow->style->black_gc; | |
278 | |
279 switch (shadow) { | |
280 case EAST_SIDE: | |
281 if (gtkblist->east != NULL) { | |
282 if (area) | |
283 gdk_gc_set_clip_rectangle (gc, area); | |
284 | |
285 width = gdk_pixbuf_get_width (gtkblist->east); | |
286 height = gdk_pixbuf_get_height (gtkblist->east); | |
287 | |
288 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->east_shadow), gc, | |
289 gtkblist->east, 0, 0, 0, 0, width, height, | |
290 GDK_RGB_DITHER_NONE, 0, 0); | |
291 | |
292 if (area) | |
293 gdk_gc_set_clip_rectangle (gc, NULL); | |
294 } | |
295 break; | |
296 | |
297 case SOUTH_SIDE: | |
298 if (blist->south != NULL) { | |
299 if (area) | |
300 gdk_gc_set_clip_rectangle (gc, area); | |
301 | |
302 width = gdk_pixbuf_get_width (gtkblist->south); | |
303 height = gdk_pixbuf_get_height (gtkblist->south); | |
304 | |
305 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->south_shadow), gc, | |
306 gtkblist->south, 0, 0, 0, 0, width, height, | |
307 GDK_RGB_DITHER_NONE, 0, 0); | |
308 | |
309 if (area) | |
310 gdk_gc_set_clip_rectangle (gc, NULL); | |
311 } | |
312 break; | |
313 } | |
7620 | 314 } |
315 | |
316 static void | |
9811 | 317 pixbuf_add_shadow (GdkPixbuf *pb, enum side shadow) |
7620 | 318 { |
9811 | 319 gint width, rowstride, height; |
320 gint i; | |
321 guchar *pixels, *p; | |
322 | |
323 width = gdk_pixbuf_get_width (pb); | |
324 height = gdk_pixbuf_get_height (pb); | |
325 rowstride = gdk_pixbuf_get_rowstride (pb); | |
326 pixels = gdk_pixbuf_get_pixels (pb); | |
327 | |
328 switch (shadow) { | |
329 case EAST_SIDE: | |
330 if (height > 5) { | |
331 for (i = 0; i < width; i++) { | |
332 gint j, k; | |
333 | |
334 p = pixels + (i * rowstride); | |
335 for (j = 0, k = 0; j < 3 * width; j += 3, k++) { | |
336 p[j] = (guchar) (p[j] * top_right_corner [i * width + k]); | |
337 p[j + 1] = (guchar) (p[j + 1] * top_right_corner [i * width + k]); | |
338 p[j + 2] = (guchar) (p[j + 2] * top_right_corner [i * width + k]); | |
339 } | |
340 } | |
341 | |
342 i = 5; | |
343 } else { | |
344 i = 0; | |
345 } | |
346 | |
347 for (; i < height; i++) { | |
348 gint j, k; | |
349 | |
350 p = pixels + (i * rowstride); | |
351 for (j = 0, k = 0; j < 3 * width; j += 3, k++) { | |
352 p[j] = (guchar) (p[j] * shadow_strip_l[width - 1 - k]); | |
353 p[j + 1] = (guchar) (p[j + 1] * shadow_strip_l[width - 1 - k]); | |
354 p[j + 2] = (guchar) (p[j + 2] * shadow_strip_l[width - 1 - k]); | |
355 } | |
356 } | |
357 break; | |
358 | |
359 case SOUTH_SIDE: | |
360 for (i = 0; i < height; i++) { | |
361 gint j, k; | |
362 | |
363 p = pixels + (i * rowstride); | |
364 for (j = 0, k = 0; j < 3 * height; j += 3, k++) { | |
365 p[j] = (guchar) (p[j] * bottom_left_corner[i * height + k]); | |
366 p[j + 1] = (guchar) (p[j + 1] * bottom_left_corner[i * height + k]); | |
367 p[j + 2] = (guchar) (p[j + 2] * bottom_left_corner[i * height + k]); | |
368 } | |
369 | |
370 p = pixels + (i * rowstride) + 3 * height; | |
371 for (j = 0, k = 0; j < (width * 3) - (6 * height); j += 3, k++) { | |
372 p[j] = (guchar) (p[j] * bottom_right_corner [i * height]); | |
373 p[j + 1] = (guchar) (p[j + 1] * bottom_right_corner [i * height]); | |
374 p[j + 2] = (guchar) (p[j + 2] * bottom_right_corner [i * height]); | |
375 } | |
376 | |
377 p = pixels + (i * rowstride) + ((width * 3) - (3 * height)); | |
378 for (j = 0, k = 0; j < 3 * height; j += 3, k++) { | |
379 p[j] = (guchar) (p[j] * bottom_right_corner[i * height + k]); | |
380 p[j + 1] = (guchar) (p[j + 1] * bottom_right_corner[i * height + k]); | |
381 p[j + 2] = (guchar) (p[j + 2] * bottom_right_corner[i * height + k]); | |
382 } | |
383 } | |
384 break; | |
385 } | |
7620 | 386 } |
387 | |
388 static gboolean | |
389 map_shadow_windows (gpointer data) | |
390 { | |
391 GaimGtkBuddyList *blist = (GaimGtkBuddyList*)data; | |
392 GtkWidget *widget = blist->tipwindow; | |
393 GdkPixbuf *pixbuf; | |
394 int x, y; | |
395 | |
396 gtk_window_get_position(GTK_WINDOW(widget), &x, &y); | |
9811 | 397 pixbuf = get_pixbuf(widget, |
398 x + widget->allocation.width, y, | |
399 5, widget->allocation.height + 5); | |
7620 | 400 if (pixbuf != NULL) |
401 { | |
402 pixbuf_add_shadow (pixbuf, EAST_SIDE); | |
403 if (blist->east != NULL) | |
404 { | |
405 g_object_unref (G_OBJECT (blist->east)); | |
406 } | |
407 blist->east = pixbuf; | |
408 } | |
409 | |
410 pixbuf = get_pixbuf (widget, | |
411 x, y + widget->allocation.height, | |
412 widget->allocation.width + 5, 5); | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
413 if (pixbuf != NULL) |
7620 | 414 { |
415 pixbuf_add_shadow (pixbuf, SOUTH_SIDE); | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
416 if (blist->south != NULL) |
7620 | 417 { |
418 g_object_unref (G_OBJECT (blist->south)); | |
419 } | |
420 blist->south = pixbuf; | |
421 } | |
422 | |
9686 | 423 gdk_window_move_resize (blist->east_shadow, |
424 x + widget->allocation.width, MAX(0,y), | |
425 5, MIN(widget->allocation.height, gdk_screen_height())); | |
426 | |
427 gdk_window_move_resize (blist->south_shadow, | |
428 MAX(0,x), y + widget->allocation.height, | |
429 MIN(widget->allocation.width + 5, gdk_screen_width()), 5); | |
430 | |
431 gdk_window_show (blist->east_shadow); | |
432 gdk_window_show (blist->south_shadow); | |
433 shadow_paint(blist, NULL, EAST_SIDE); | |
434 shadow_paint(blist, NULL, SOUTH_SIDE); | |
435 | |
436 return FALSE; | |
7620 | 437 } |
438 | |
439 /**************** END WEIRD DROP SHADOW STUFF ***********************************/ | |
440 #endif | |
8254 | 441 |
10118 | 442 static char dim_grey_string[8] = ""; |
10144 | 443 static char *dim_grey() |
10118 | 444 { |
445 if (!gtkblist) | |
446 return "dim grey"; | |
447 if (!dim_grey_string[0]) { | |
448 GtkStyle *style = gtk_widget_get_style(gtkblist->treeview); | |
449 snprintf(dim_grey_string, sizeof(dim_grey_string), "#%02x%02x%02x", | |
450 style->text_aa[GTK_STATE_NORMAL].red >> 8, | |
451 style->text_aa[GTK_STATE_NORMAL].green >> 8, | |
452 style->text_aa[GTK_STATE_NORMAL].blue >> 8); | |
453 } | |
454 return dim_grey_string; | |
455 } | |
10144 | 456 |
5228 | 457 /*************************************************** |
458 * Callbacks * | |
459 ***************************************************/ | |
460 | |
461 static gboolean gtk_blist_delete_cb(GtkWidget *w, GdkEventAny *event, gpointer data) | |
462 { | |
463 if (docklet_count) | |
464 gaim_blist_set_visible(FALSE); | |
465 else | |
7620 | 466 gaim_core_quit(); |
5228 | 467 |
468 /* we handle everything, event should not propogate further */ | |
469 return TRUE; | |
470 } | |
471 | |
472 static gboolean gtk_blist_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) | |
473 { | |
474 /* unfortunately GdkEventConfigure ignores the window gravity, but * | |
475 * the only way we have of setting the position doesn't. we have to * | |
7620 | 476 * call get_position because it does pay attention to the gravity. * |
477 * this is inefficient and I agree it sucks, but it's more likely * | |
478 * to work correctly. - Robot101 */ | |
5228 | 479 gint x, y; |
480 | |
481 /* check for visibility because when we aren't visible, this will * | |
482 * give us bogus (0,0) coordinates. - xOr */ | |
7620 | 483 if (GTK_WIDGET_VISIBLE(w)) |
5228 | 484 gtk_window_get_position(GTK_WINDOW(w), &x, &y); |
7620 | 485 else |
486 return FALSE; /* carry on normally */ | |
487 | |
488 /* don't save if nothing changed */ | |
489 if (x == gaim_prefs_get_int("/gaim/gtk/blist/x") && | |
490 y == gaim_prefs_get_int("/gaim/gtk/blist/y") && | |
491 event->width == gaim_prefs_get_int("/gaim/gtk/blist/width") && | |
492 event->height == gaim_prefs_get_int("/gaim/gtk/blist/height")) { | |
493 | |
494 return FALSE; /* carry on normally */ | |
5228 | 495 } |
496 | |
7620 | 497 /* don't save off-screen positioning */ |
498 if (x + event->width < 0 || | |
9811 | 499 y + event->height < 0 || |
500 x > gdk_screen_width() || | |
501 y > gdk_screen_height()) { | |
7620 | 502 |
503 return FALSE; /* carry on normally */ | |
504 } | |
505 | |
506 /* store the position */ | |
507 gaim_prefs_set_int("/gaim/gtk/blist/x", x); | |
508 gaim_prefs_set_int("/gaim/gtk/blist/y", y); | |
509 gaim_prefs_set_int("/gaim/gtk/blist/width", event->width); | |
510 gaim_prefs_set_int("/gaim/gtk/blist/height", event->height); | |
511 | |
5228 | 512 /* continue to handle event normally */ |
513 return FALSE; | |
514 } | |
515 | |
516 static gboolean gtk_blist_visibility_cb(GtkWidget *w, GdkEventVisibility *event, gpointer data) | |
517 { | |
518 if (event->state == GDK_VISIBILITY_FULLY_OBSCURED) | |
519 gaim_gtk_blist_obscured = TRUE; | |
520 else | |
521 gaim_gtk_blist_obscured = FALSE; | |
522 | |
523 /* continue to handle event normally */ | |
524 return FALSE; | |
525 } | |
526 | |
7620 | 527 static void gtk_blist_menu_info_cb(GtkWidget *w, GaimBuddy *b) |
5228 | 528 { |
529 serv_get_info(b->account->gc, b->name); | |
530 } | |
531 | |
7620 | 532 static void gtk_blist_menu_im_cb(GtkWidget *w, GaimBuddy *b) |
5228 | 533 { |
9728 | 534 gaim_gtkdialogs_im_with_user(b->account, b->name); |
5228 | 535 } |
536 | |
9466 | 537 static void gtk_blist_menu_send_file_cb(GtkWidget *w, GaimBuddy *b) |
538 { | |
539 serv_send_file(b->account->gc, b->name, NULL); | |
540 } | |
541 | |
7620 | 542 static void gtk_blist_menu_autojoin_cb(GtkWidget *w, GaimChat *chat) |
543 { | |
7693 | 544 gaim_blist_node_set_bool((GaimBlistNode*)chat, "gtk-autojoin", |
545 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w))); | |
7620 | 546 } |
547 | |
548 static void gtk_blist_menu_join_cb(GtkWidget *w, GaimChat *chat) | |
5228 | 549 { |
5234 | 550 serv_join_chat(chat->account->gc, chat->components); |
551 } | |
552 | |
553 static void gtk_blist_menu_alias_cb(GtkWidget *w, GaimBlistNode *node) | |
554 { | |
555 if(GAIM_BLIST_NODE_IS_BUDDY(node)) | |
9730 | 556 gaim_gtkdialogs_alias_buddy((GaimBuddy*)node); |
7620 | 557 else if(GAIM_BLIST_NODE_IS_CONTACT(node)) |
9730 | 558 gaim_gtkdialogs_alias_contact((GaimContact*)node); |
5234 | 559 else if(GAIM_BLIST_NODE_IS_CHAT(node)) |
9730 | 560 gaim_gtkdialogs_alias_chat((GaimChat*)node); |
5228 | 561 } |
562 | |
7620 | 563 static void gtk_blist_menu_bp_cb(GtkWidget *w, GaimBuddy *b) |
5228 | 564 { |
7620 | 565 gaim_gtkpounce_dialog_show(b->account, b->name, NULL); |
5228 | 566 } |
567 | |
9917 | 568 static void gtk_blist_menu_showlog_cb(GtkWidget *w, GaimBlistNode *node) |
5228 | 569 { |
9917 | 570 GaimLogType type; |
571 GaimAccount *account; | |
572 char *name = NULL; | |
573 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
574 GaimBuddy *b = (GaimBuddy*) node; | |
575 type = GAIM_LOG_IM; | |
576 name = g_strdup(b->name); | |
577 account = b->account; | |
578 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { | |
579 GaimChat *c = (GaimChat*) node; | |
580 GaimPluginProtocolInfo *prpl_info = NULL; | |
581 type = GAIM_LOG_CHAT; | |
582 account = c->account; | |
583 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gaim_find_prpl(gaim_account_get_protocol_id(account))); | |
584 if (prpl_info && prpl_info->get_chat_name) { | |
585 name = prpl_info->get_chat_name(c->components); | |
586 } | |
587 } else | |
588 return; | |
589 | |
590 if (name && account) { | |
591 gaim_gtk_log_show(type, name, account); | |
592 g_free(name); | |
593 } | |
7620 | 594 } |
595 | |
5228 | 596 static void gtk_blist_show_systemlog_cb() |
597 { | |
8573 | 598 gaim_gtk_syslog_show(); |
5228 | 599 } |
600 | |
601 static void gtk_blist_show_onlinehelp_cb() | |
602 { | |
7620 | 603 gaim_notify_uri(NULL, GAIM_WEBSITE "documentation.php"); |
5228 | 604 } |
605 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
606 static void |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
607 do_join_chat(GaimGtkJoinChatData *data) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
608 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
609 if (data) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
610 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
611 GHashTable *components = |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
612 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
613 GList *tmp; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
614 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
615 for (tmp = data->entries; tmp != NULL; tmp = tmp->next) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
616 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
617 if (g_object_get_data(tmp->data, "is_spin")) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
618 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
619 g_hash_table_replace(components, |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
620 g_strdup(g_object_get_data(tmp->data, "identifier")), |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
621 g_strdup_printf("%d", |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
622 gtk_spin_button_get_value_as_int(tmp->data))); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
623 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
624 else |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
625 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
626 g_hash_table_replace(components, |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
627 g_strdup(g_object_get_data(tmp->data, "identifier")), |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
628 g_strdup(gtk_entry_get_text(tmp->data))); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
629 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
630 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
631 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
632 serv_join_chat(gaim_account_get_connection(data->account), components); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
633 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
634 g_hash_table_destroy(components); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
635 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
636 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
637 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
638 static void |
8940 | 639 do_joinchat(GtkWidget *dialog, int id, GaimGtkJoinChatData *info) |
640 { | |
641 switch(id) | |
642 { | |
643 case GTK_RESPONSE_OK: | |
644 do_join_chat(info); | |
645 | |
646 break; | |
647 } | |
648 | |
649 gtk_widget_destroy(GTK_WIDGET(dialog)); | |
650 g_list_free(info->entries); | |
651 g_free(info); | |
652 } | |
653 | |
654 static void | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
655 rebuild_joinchat_entries(GaimGtkJoinChatData *data) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
656 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
657 GaimConnection *gc; |
9959 | 658 GList *list = NULL, *tmp = NULL; |
9770 | 659 GHashTable *defaults = NULL; |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
660 struct proto_chat_entry *pce; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
661 gboolean focus = TRUE; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
662 |
10127 | 663 g_return_if_fail(data->account != NULL); |
664 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
665 gc = gaim_account_get_connection(data->account); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
666 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
667 while (GTK_BOX(data->entries_box)->children) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
668 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
669 gtk_container_remove(GTK_CONTAINER(data->entries_box), |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
670 ((GtkBoxChild *)GTK_BOX(data->entries_box)->children->data)->widget); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
671 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
672 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
673 if (data->entries != NULL) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
674 g_list_free(data->entries); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
675 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
676 data->entries = NULL; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
677 |
9987 | 678 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) |
9959 | 679 list = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
680 |
9770 | 681 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) |
682 defaults = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, NULL); | |
683 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
684 for (tmp = list; tmp; tmp = tmp->next) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
685 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
686 GtkWidget *label; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
687 GtkWidget *rowbox; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
688 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
689 pce = tmp->data; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
690 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
691 rowbox = gtk_hbox_new(FALSE, 12); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
692 gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
693 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
694 label = gtk_label_new_with_mnemonic(pce->label); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
695 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
696 gtk_size_group_add_widget(data->sg, label); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
697 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
698 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
699 if (pce->is_int) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
700 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
701 GtkObject *adjust; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
702 GtkWidget *spin; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
703 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
704 1, 10, 10); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
705 spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
706 g_object_set_data(G_OBJECT(spin), "is_spin", |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
707 GINT_TO_POINTER(TRUE)); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
708 g_object_set_data(G_OBJECT(spin), "identifier", pce->identifier); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
709 data->entries = g_list_append(data->entries, spin); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
710 gtk_widget_set_size_request(spin, 50, -1); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
711 gtk_box_pack_end(GTK_BOX(rowbox), spin, FALSE, FALSE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
712 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(spin)); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
713 gaim_set_accessible_label (spin, label); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
714 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
715 else |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
716 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
717 GtkWidget *entry = gtk_entry_new(); |
9770 | 718 char *value; |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
719 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
720 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
721 g_object_set_data(G_OBJECT(entry), "identifier", pce->identifier); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
722 data->entries = g_list_append(data->entries, entry); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
723 |
9770 | 724 value = g_hash_table_lookup(defaults, pce->identifier); |
725 if (value != NULL) | |
726 gtk_entry_set_text(GTK_ENTRY(entry), value); | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
727 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
728 if (focus) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
729 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
730 gtk_widget_grab_focus(entry); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
731 focus = FALSE; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
732 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
733 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
734 if (pce->secret) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
735 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
736 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
737 gtk_box_pack_end(GTK_BOX(rowbox), entry, TRUE, TRUE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
738 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(entry)); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
739 gaim_set_accessible_label (entry, label); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
740 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
741 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
742 g_free(pce); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
743 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
744 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
745 g_list_free(list); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
746 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
747 gtk_widget_show_all(data->entries_box); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
748 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
749 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
750 static void |
8940 | 751 joinchat_select_account_cb(GObject *w, GaimAccount *account, |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
752 GaimGtkJoinChatData *data) |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
753 { |
9460 | 754 if (strcmp(gaim_account_get_protocol_id(data->account), |
755 gaim_account_get_protocol_id(account)) == 0) | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
756 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
757 data->account = account; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
758 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
759 else |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
760 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
761 data->account = account; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
762 rebuild_joinchat_entries(data); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
763 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
764 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
765 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
766 static gboolean |
9987 | 767 chat_account_filter_func(GaimAccount *account) |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
768 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
769 GaimConnection *gc = gaim_account_get_connection(account); |
8940 | 770 GaimPluginProtocolInfo *prpl_info = NULL; |
771 | |
772 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
773 | |
774 return (prpl_info->chat_info != NULL); | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
775 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
776 |
8940 | 777 gboolean |
778 gaim_gtk_blist_joinchat_is_showable() | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
779 { |
8940 | 780 GList *c; |
781 GaimConnection *gc; | |
782 | |
783 for (c = gaim_connections_get_all(); c != NULL; c = c->next) { | |
784 gc = c->data; | |
785 | |
9987 | 786 if (chat_account_filter_func(gaim_connection_get_account(gc))) |
8940 | 787 return TRUE; |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
788 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
789 |
8940 | 790 return FALSE; |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
791 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
792 |
8305
57bdd25752c1
[gaim-migrate @ 9029]
Christian Hammond <chipx86@chipx86.com>
parents:
8303
diff
changeset
|
793 void |
8940 | 794 gaim_gtk_blist_joinchat_show(void) |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
795 { |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
796 GtkWidget *hbox, *vbox; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
797 GtkWidget *rowbox; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
798 GtkWidget *label; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
799 GaimGtkBuddyList *gtkblist; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
800 GtkWidget *img = NULL; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
801 GaimGtkJoinChatData *data = NULL; |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
802 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
803 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
804 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
805 GTK_ICON_SIZE_DIALOG); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
806 data = g_new0(GaimGtkJoinChatData, 1); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
807 |
8975 | 808 data->window = gtk_dialog_new_with_buttons(_("Join a Chat"), |
809 NULL, GTK_DIALOG_NO_SEPARATOR, | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
810 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
8308 | 811 GAIM_STOCK_CHAT, GTK_RESPONSE_OK, NULL); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
812 gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
813 gtk_container_set_border_width(GTK_CONTAINER(data->window), 6); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
814 gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
815 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), 12); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
816 gtk_container_set_border_width( |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
817 GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), 6); |
8975 | 818 gtk_window_set_role(GTK_WINDOW(data->window), "join_chat"); |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
819 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
820 hbox = gtk_hbox_new(FALSE, 12); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
821 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
822 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
823 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
824 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
825 vbox = gtk_vbox_new(FALSE, 5); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
826 gtk_container_set_border_width(GTK_CONTAINER(vbox), 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
827 gtk_container_add(GTK_CONTAINER(hbox), vbox); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
828 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
829 label = gtk_label_new(_("Please enter the appropriate information " |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
830 "about the chat you would like to join.\n")); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
831 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
832 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
833 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
834 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
835 rowbox = gtk_hbox_new(FALSE, 12); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
836 gtk_box_pack_start(GTK_BOX(vbox), rowbox, TRUE, TRUE, 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
837 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
838 data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
839 |
8940 | 840 label = gtk_label_new_with_mnemonic(_("_Account:")); |
841 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
842 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
843 gtk_size_group_add_widget(data->sg, label); | |
844 | |
845 data->account_menu = gaim_gtk_account_option_menu_new(NULL, FALSE, | |
846 G_CALLBACK(joinchat_select_account_cb), | |
9987 | 847 chat_account_filter_func, data); |
8940 | 848 gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0); |
849 gtk_label_set_mnemonic_widget(GTK_LABEL(label), | |
850 GTK_WIDGET(data->account_menu)); | |
851 gaim_set_accessible_label (data->account_menu, label); | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
852 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
853 data->entries_box = gtk_vbox_new(FALSE, 5); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
854 gtk_container_add(GTK_CONTAINER(vbox), data->entries_box); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
855 gtk_container_set_border_width(GTK_CONTAINER(data->entries_box), 0); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
856 |
8940 | 857 data->account = gaim_gtk_account_option_menu_get_selected(data->account_menu); |
858 | |
8303
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
859 rebuild_joinchat_entries(data); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
860 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
861 g_signal_connect(G_OBJECT(data->window), "response", |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
862 G_CALLBACK(do_joinchat), data); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
863 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
864 g_object_unref(data->sg); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
865 |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
866 gtk_widget_show_all(data->window); |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
867 } |
4eb4b2a6c604
[gaim-migrate @ 9027]
Christian Hammond <chipx86@chipx86.com>
parents:
8302
diff
changeset
|
868 |
5228 | 869 static void gtk_blist_row_expanded_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { |
870 GaimBlistNode *node; | |
871 GValue val = {0,}; | |
872 | |
873 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &val); | |
874 | |
875 node = g_value_get_pointer(&val); | |
876 | |
877 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
7693 | 878 gaim_blist_node_set_bool(node, "collapsed", FALSE); |
5228 | 879 } |
880 } | |
881 | |
882 static void gtk_blist_row_collapsed_cb(GtkTreeView *tv, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { | |
883 GaimBlistNode *node; | |
884 GValue val = {0,}; | |
885 | |
886 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), iter, NODE_COLUMN, &val); | |
887 | |
888 node = g_value_get_pointer(&val); | |
889 | |
890 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
7693 | 891 gaim_blist_node_set_bool(node, "collapsed", TRUE); |
7620 | 892 } else if(GAIM_BLIST_NODE_IS_CONTACT(node)) { |
893 gaim_gtk_blist_collapse_contact_cb(NULL, node); | |
5228 | 894 } |
895 } | |
896 | |
897 static void gtk_blist_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) { | |
898 GaimBlistNode *node; | |
899 GtkTreeIter iter; | |
900 GValue val = { 0, }; | |
901 | |
902 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
903 | |
904 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
905 node = g_value_get_pointer(&val); | |
906 | |
7620 | 907 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node)) { |
908 GaimBuddy *buddy; | |
909 | |
910 if(GAIM_BLIST_NODE_IS_CONTACT(node)) | |
911 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
912 else | |
913 buddy = (GaimBuddy*)node; | |
914 | |
9728 | 915 gaim_gtkdialogs_im_with_user(buddy->account, buddy->name); |
5234 | 916 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { |
7620 | 917 serv_join_chat(((GaimChat *)node)->account->gc, ((GaimChat *)node)->components); |
5228 | 918 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
919 if (gtk_tree_view_row_expanded(tv, path)) | |
920 gtk_tree_view_collapse_row(tv, path); | |
921 else | |
922 gtk_tree_view_expand_row(tv,path,FALSE); | |
923 } | |
924 } | |
925 | |
5234 | 926 static void gaim_gtk_blist_add_chat_cb() |
927 { | |
928 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
929 GtkTreeIter iter; | |
930 GaimBlistNode *node; | |
931 | |
932 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ | |
933 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
7620 | 934 if (GAIM_BLIST_NODE_IS_BUDDY(node)) |
9754 | 935 gaim_blist_request_add_chat(NULL, (GaimGroup*)node->parent->parent, NULL, NULL); |
7620 | 936 if (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_CHAT(node)) |
9754 | 937 gaim_blist_request_add_chat(NULL, (GaimGroup*)node->parent, NULL, NULL); |
5234 | 938 else if (GAIM_BLIST_NODE_IS_GROUP(node)) |
9754 | 939 gaim_blist_request_add_chat(NULL, (GaimGroup*)node, NULL, NULL); |
5234 | 940 } |
941 else { | |
9754 | 942 gaim_blist_request_add_chat(NULL, NULL, NULL, NULL); |
5234 | 943 } |
944 } | |
945 | |
5228 | 946 static void gaim_gtk_blist_add_buddy_cb() |
947 { | |
948 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
949 GtkTreeIter iter; | |
950 GaimBlistNode *node; | |
951 | |
952 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ | |
953 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); | |
7620 | 954 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { |
955 gaim_blist_request_add_buddy(NULL, NULL, ((GaimGroup*)node->parent->parent)->name, | |
956 NULL); | |
957 } else if (GAIM_BLIST_NODE_IS_CONTACT(node) | |
958 || GAIM_BLIST_NODE_IS_CHAT(node)) { | |
959 gaim_blist_request_add_buddy(NULL, NULL, ((GaimGroup*)node->parent)->name, NULL); | |
960 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
961 gaim_blist_request_add_buddy(NULL, NULL, ((GaimGroup*)node)->name, NULL); | |
962 } | |
5228 | 963 } |
964 else { | |
7620 | 965 gaim_blist_request_add_buddy(NULL, NULL, NULL, NULL); |
966 } | |
967 } | |
968 | |
969 static void | |
970 gaim_gtk_blist_remove_cb (GtkWidget *w, GaimBlistNode *node) | |
971 { | |
972 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
9730 | 973 gaim_gtkdialogs_remove_buddy((GaimBuddy*)node); |
7620 | 974 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { |
9730 | 975 gaim_gtkdialogs_remove_chat((GaimChat*)node); |
7620 | 976 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
9730 | 977 gaim_gtkdialogs_remove_group((GaimGroup*)node); |
7620 | 978 } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) { |
9730 | 979 gaim_gtkdialogs_remove_contact((GaimContact*)node); |
5228 | 980 } |
981 } | |
982 | |
983 static void | |
7620 | 984 gaim_gtk_blist_expand_contact_cb(GtkWidget *w, GaimBlistNode *node) |
5228 | 985 { |
7620 | 986 struct _gaim_gtk_blist_node *gtknode; |
9632 | 987 GtkTreeIter iter, parent; |
7620 | 988 GaimBlistNode *bnode; |
9632 | 989 GtkTreePath *path; |
7620 | 990 |
991 if(!GAIM_BLIST_NODE_IS_CONTACT(node)) | |
992 return; | |
993 | |
994 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
995 | |
996 gtknode->contact_expanded = TRUE; | |
997 | |
998 for(bnode = node->child; bnode; bnode = bnode->next) { | |
999 gaim_gtk_blist_update(NULL, bnode); | |
1000 } | |
9632 | 1001 |
1002 /* This ensures that the bottom buddy is visible, i.e. not scrolled off the alignment */ | |
1003 get_iter_from_node(node, &parent); | |
1004 gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(gtkblist->treemodel), &iter, &parent, | |
9811 | 1005 gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &parent) -1); |
9632 | 1006 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); |
1007 /* Let the treeview draw so it knows where to scroll */ | |
1008 while (gtk_events_pending()) | |
1009 gtk_main_iteration(); | |
1010 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(gtkblist->treeview), path, NULL, FALSE, 0, 0); | |
1011 | |
1012 | |
7620 | 1013 gaim_gtk_blist_update(NULL, node); |
9632 | 1014 gtk_tree_path_free(path); |
7620 | 1015 } |
1016 | |
1017 static void | |
1018 gaim_gtk_blist_collapse_contact_cb(GtkWidget *w, GaimBlistNode *node) | |
1019 { | |
1020 GaimBlistNode *bnode; | |
1021 struct _gaim_gtk_blist_node *gtknode; | |
1022 | |
1023 if(!GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1024 return; | |
1025 | |
1026 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
1027 | |
1028 gtknode->contact_expanded = FALSE; | |
1029 | |
1030 for(bnode = node->child; bnode; bnode = bnode->next) { | |
1031 gaim_gtk_blist_update(NULL, bnode); | |
5228 | 1032 } |
1033 } | |
1034 | |
9030 | 1035 |
1036 static void | |
1037 blist_node_menu_cb(GtkMenuItem *item, GaimBlistNode *node) | |
1038 { | |
1039 GaimBlistNodeAction *act; | |
1040 act = (GaimBlistNodeAction *) g_object_get_data(G_OBJECT(item), | |
1041 "gaimcallback"); | |
1042 if(act->callback) | |
1043 act->callback(node, act->data); | |
1044 } | |
1045 | |
1046 | |
1047 static void | |
1048 append_blist_node_action (GtkWidget *menu, GaimBlistNodeAction *act, | |
1049 GaimBlistNode *node, gboolean *dup_separator) | |
5228 | 1050 { |
9030 | 1051 if(act == NULL) { |
1052 if(! *dup_separator) { | |
1053 gaim_separator(menu); | |
1054 *dup_separator = TRUE; | |
1055 } | |
1056 } else { | |
1057 GtkWidget *menuitem; | |
1058 | |
1059 *dup_separator = FALSE; | |
1060 | |
1061 menuitem = gtk_menu_item_new_with_mnemonic(act->label); | |
1062 g_object_set_data(G_OBJECT(menuitem), "gaimcallback", act); | |
1063 g_signal_connect(G_OBJECT(menuitem), "activate", | |
1064 G_CALLBACK(blist_node_menu_cb), node); | |
1065 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
1066 } | |
5228 | 1067 } |
1068 | |
9030 | 1069 |
9051 | 1070 void |
1071 gaim_gtk_append_blist_node_proto_menu (GtkWidget *menu, GaimConnection *gc, GaimBlistNode *node) | |
9030 | 1072 { |
1073 GList *l, *ll; | |
1074 gboolean dup_separator = FALSE; | |
1075 GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
1076 | |
1077 if(!prpl_info || !prpl_info->blist_node_menu) | |
1078 return; | |
1079 | |
1080 for(l = ll = prpl_info->blist_node_menu(node); l; l = l->next) { | |
1081 GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data; | |
1082 append_blist_node_action(menu, act, node, &dup_separator); | |
1083 } | |
1084 g_list_free(ll); | |
1085 } | |
1086 | |
1087 | |
9051 | 1088 void |
1089 gaim_gtk_append_blist_node_extended_menu (GtkWidget *menu, GaimBlistNode *node) | |
9030 | 1090 { |
1091 GList *l, *ll; | |
1092 gboolean dup_separator = FALSE; | |
1093 | |
1094 for(l = ll = gaim_blist_node_get_extended_menu(node); l; l = l->next) { | |
1095 GaimBlistNodeAction *act = (GaimBlistNodeAction *) l->data; | |
1096 append_blist_node_action(menu, act, node, &dup_separator); | |
1097 } | |
1098 g_list_free(ll); | |
1099 } | |
1100 | |
1101 | |
9774 | 1102 void |
1103 gaim_gtk_blist_make_buddy_menu(GtkWidget *menu, GaimBuddy *buddy) { | |
1104 GaimPluginProtocolInfo *prpl_info; | |
1105 | |
1106 g_return_if_fail(menu); | |
1107 g_return_if_fail(buddy); | |
1108 | |
1109 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(buddy->account->gc->prpl); | |
1110 | |
7620 | 1111 if (prpl_info && prpl_info->get_info) { |
8137 | 1112 gaim_new_item_from_stock(menu, _("Get _Info"), GAIM_STOCK_INFO, |
9774 | 1113 G_CALLBACK(gtk_blist_menu_info_cb), buddy, 0, 0, NULL); |
7620 | 1114 } |
8137 | 1115 gaim_new_item_from_stock(menu, _("I_M"), GAIM_STOCK_IM, |
9774 | 1116 G_CALLBACK(gtk_blist_menu_im_cb), buddy, 0, 0, NULL); |
9466 | 1117 if (prpl_info && prpl_info->send_file) { |
9774 | 1118 if (!prpl_info->can_receive_file || |
1119 prpl_info->can_receive_file(buddy->account->gc, buddy->name)) | |
1120 { | |
1121 gaim_new_item_from_stock(menu, _("_Send File"), | |
1122 GAIM_STOCK_FILE_TRANSFER, | |
1123 G_CALLBACK(gtk_blist_menu_send_file_cb), | |
1124 buddy, 0, 0, NULL); | |
9466 | 1125 } |
1126 } | |
7620 | 1127 gaim_new_item_from_stock(menu, _("Add Buddy _Pounce"), NULL, |
9774 | 1128 G_CALLBACK(gtk_blist_menu_bp_cb), buddy, 0, 0, NULL); |
7620 | 1129 gaim_new_item_from_stock(menu, _("View _Log"), NULL, |
9774 | 1130 G_CALLBACK(gtk_blist_menu_showlog_cb), buddy, 0, 0, NULL); |
1131 | |
1132 gaim_gtk_append_blist_node_proto_menu(menu, buddy->account->gc, | |
1133 (GaimBlistNode *)buddy); | |
1134 gaim_gtk_append_blist_node_extended_menu(menu, (GaimBlistNode *)buddy); | |
7620 | 1135 |
1136 gaim_separator(menu); | |
9030 | 1137 |
9925 | 1138 if(((GaimBlistNode*)buddy)->parent->child->next) { |
1139 gaim_new_item_from_stock(menu, _("_Alias Buddy..."), GAIM_STOCK_ALIAS, | |
1140 G_CALLBACK(gtk_blist_menu_alias_cb), buddy, 0, 0, NULL); | |
1141 gaim_new_item_from_stock(menu, _("_Remove Buddy"), GTK_STOCK_REMOVE, | |
1142 G_CALLBACK(gaim_gtk_blist_remove_cb), buddy, 0, 0, NULL); | |
1143 gaim_new_item_from_stock(menu, _("Alias Contact..."), GAIM_STOCK_ALIAS, | |
1144 G_CALLBACK(gtk_blist_menu_alias_cb), | |
1145 gaim_buddy_get_contact(buddy), 0, 0, NULL); | |
1146 gaim_new_item_from_stock(menu, _("Remove Contact"), GTK_STOCK_REMOVE, | |
1147 G_CALLBACK(gaim_gtk_blist_remove_cb), | |
1148 gaim_buddy_get_contact(buddy), 0, 0, NULL); | |
1149 } else { | |
1150 gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, | |
1151 G_CALLBACK(gtk_blist_menu_alias_cb), buddy, 0, 0, NULL); | |
1152 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, | |
1153 G_CALLBACK(gaim_gtk_blist_remove_cb), buddy, | |
1154 0, 0, NULL); | |
1155 } | |
7620 | 1156 } |
1157 | |
9774 | 1158 static gboolean |
1159 gtk_blist_key_press_cb(GtkWidget *tv, GdkEventKey *event, gpointer data) { | |
7620 | 1160 GaimBlistNode *node; |
1161 GValue val = { 0, }; | |
1162 GtkTreeIter iter; | |
1163 GtkTreeSelection *sel; | |
1164 | |
1165 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
1166 if(!gtk_tree_selection_get_selected(sel, NULL, &iter)) | |
1167 return FALSE; | |
1168 | |
1169 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
1170 NODE_COLUMN, &val); | |
1171 node = g_value_get_pointer(&val); | |
1172 | |
1173 if(event->state & GDK_CONTROL_MASK && | |
1174 (event->keyval == 'o' || event->keyval == 'O')) { | |
1175 GaimBuddy *buddy; | |
1176 | |
1177 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
1178 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
1179 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1180 buddy = (GaimBuddy*)node; | |
1181 } else { | |
1182 return FALSE; | |
1183 } | |
1184 if(buddy) | |
1185 serv_get_info(buddy->account->gc, buddy->name); | |
1186 } | |
1187 | |
1188 return FALSE; | |
1189 } | |
1190 | |
9013 | 1191 |
8143 | 1192 static GtkWidget * |
8952 | 1193 create_group_menu (GaimBlistNode *node, GaimGroup *g) |
8143 | 1194 { |
1195 GtkWidget *menu; | |
1196 | |
1197 menu = gtk_menu_new(); | |
1198 gaim_new_item_from_stock(menu, _("Add a _Buddy"), GTK_STOCK_ADD, | |
1199 G_CALLBACK(gaim_gtk_blist_add_buddy_cb), node, 0, 0, NULL); | |
1200 gaim_new_item_from_stock(menu, _("Add a C_hat"), GTK_STOCK_ADD, | |
1201 G_CALLBACK(gaim_gtk_blist_add_chat_cb), node, 0, 0, NULL); | |
1202 gaim_new_item_from_stock(menu, _("_Delete Group"), GTK_STOCK_REMOVE, | |
1203 G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
1204 gaim_new_item_from_stock(menu, _("_Rename"), NULL, | |
1205 G_CALLBACK(show_rename_group), node, 0, 0, NULL); | |
8952 | 1206 |
9051 | 1207 gaim_gtk_append_blist_node_extended_menu(menu, node); |
8952 | 1208 |
8143 | 1209 return menu; |
1210 } | |
1211 | |
8586 | 1212 |
8143 | 1213 static GtkWidget * |
9774 | 1214 create_chat_menu(GaimBlistNode *node, GaimChat *c) { |
8143 | 1215 GtkWidget *menu; |
9030 | 1216 gboolean autojoin; |
8143 | 1217 |
1218 menu = gtk_menu_new(); | |
9030 | 1219 autojoin = (gaim_blist_node_get_bool(node, "gtk-autojoin") || |
1220 (gaim_blist_node_get_string(node, "gtk-autojoin") != NULL)); | |
1221 | |
8143 | 1222 gaim_new_item_from_stock(menu, _("_Join"), GAIM_STOCK_CHAT, |
9030 | 1223 G_CALLBACK(gtk_blist_menu_join_cb), node, 0, 0, NULL); |
8143 | 1224 gaim_new_check_item(menu, _("Auto-Join"), |
9030 | 1225 G_CALLBACK(gtk_blist_menu_autojoin_cb), node, autojoin); |
9917 | 1226 gaim_new_item_from_stock(menu, _("View _Log"), NULL, |
1227 G_CALLBACK(gtk_blist_menu_showlog_cb), node, 0, 0, NULL); | |
9030 | 1228 |
9051 | 1229 gaim_gtk_append_blist_node_proto_menu(menu, c->account->gc, node); |
1230 gaim_gtk_append_blist_node_extended_menu(menu, node); | |
8586 | 1231 |
1232 gaim_separator(menu); | |
9030 | 1233 |
8302
462ead6fc1a0
[gaim-migrate @ 9026]
Christian Hammond <chipx86@chipx86.com>
parents:
8259
diff
changeset
|
1234 gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, |
8143 | 1235 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); |
1236 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, | |
1237 G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
8586 | 1238 |
8143 | 1239 return menu; |
1240 } | |
1241 | |
1242 static GtkWidget * | |
1243 create_contact_menu (GaimBlistNode *node) | |
1244 { | |
1245 GtkWidget *menu; | |
1246 | |
1247 menu = gtk_menu_new(); | |
8302
462ead6fc1a0
[gaim-migrate @ 9026]
Christian Hammond <chipx86@chipx86.com>
parents:
8259
diff
changeset
|
1248 gaim_new_item_from_stock(menu, _("_Alias..."), GAIM_STOCK_ALIAS, |
8143 | 1249 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); |
1250 gaim_new_item_from_stock(menu, _("_Collapse"), GTK_STOCK_ZOOM_OUT, | |
1251 G_CALLBACK(gaim_gtk_blist_collapse_contact_cb), | |
1252 node, 0, 0, NULL); | |
1253 gaim_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, | |
1254 G_CALLBACK(gaim_gtk_blist_remove_cb), node, 0, 0, NULL); | |
9051 | 1255 |
1256 gaim_gtk_append_blist_node_extended_menu(menu, node); | |
1257 | |
8143 | 1258 return menu; |
1259 } | |
1260 | |
1261 static GtkWidget * | |
9774 | 1262 create_buddy_menu(GaimBlistNode *node, GaimBuddy *b) { |
8143 | 1263 struct _gaim_gtk_blist_node *gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; |
1264 GtkWidget *menu; | |
1265 GtkWidget *menuitem; | |
1266 gboolean show_offline = gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies"); | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
1267 |
8143 | 1268 menu = gtk_menu_new(); |
9774 | 1269 gaim_gtk_blist_make_buddy_menu(menu, b); |
8143 | 1270 |
1271 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
1272 gaim_separator(menu); | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
1273 |
8143 | 1274 if(gtknode->contact_expanded) { |
1275 gaim_new_item_from_stock(menu, _("_Collapse"), | |
1276 GTK_STOCK_ZOOM_OUT, | |
1277 G_CALLBACK(gaim_gtk_blist_collapse_contact_cb), | |
1278 node, 0, 0, NULL); | |
1279 } else { | |
1280 gaim_new_item_from_stock(menu, _("_Expand"), | |
1281 GTK_STOCK_ZOOM_IN, | |
1282 G_CALLBACK(gaim_gtk_blist_expand_contact_cb), node, | |
1283 0, 0, NULL); | |
1284 } | |
1285 if(node->child->next) { | |
1286 GaimBlistNode *bnode; | |
1287 | |
1288 for(bnode = node->child; bnode; bnode = bnode->next) { | |
1289 GaimBuddy *buddy = (GaimBuddy*)bnode; | |
9340 | 1290 GdkPixbuf *buf; |
8143 | 1291 GtkWidget *submenu; |
1292 GtkWidget *image; | |
1293 | |
1294 if(buddy == b) | |
1295 continue; | |
1296 if(!buddy->account->gc) | |
1297 continue; | |
1298 if(!show_offline && !GAIM_BUDDY_IS_ONLINE(buddy)) | |
1299 continue; | |
1300 | |
1301 menuitem = gtk_image_menu_item_new_with_label(buddy->name); | |
9340 | 1302 buf = gaim_gtk_blist_get_status_icon(bnode, |
1303 GAIM_STATUS_ICON_SMALL); | |
1304 image = gtk_image_new_from_pixbuf(buf); | |
1305 g_object_unref(G_OBJECT(buf)); | |
8143 | 1306 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), |
9811 | 1307 image); |
8143 | 1308 gtk_widget_show(image); |
1309 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
1310 gtk_widget_show(menuitem); | |
1311 | |
1312 submenu = gtk_menu_new(); | |
1313 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
1314 gtk_widget_show(submenu); | |
1315 | |
9774 | 1316 gaim_gtk_blist_make_buddy_menu(submenu, buddy); |
8143 | 1317 } |
1318 } | |
1319 } | |
1320 return menu; | |
1321 } | |
1322 | |
1323 static gboolean | |
1324 gaim_gtk_blist_show_context_menu(GaimBlistNode *node, | |
1325 GtkMenuPositionFunc func, | |
1326 GtkWidget *tv, | |
1327 guint button, | |
1328 guint32 time) | |
1329 { | |
1330 struct _gaim_gtk_blist_node *gtknode; | |
1331 GtkWidget *menu = NULL; | |
1332 gboolean handled = FALSE; | |
1333 | |
1334 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
1335 | |
1336 /* Create a menu based on the thing we right-clicked on */ | |
1337 if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
8952 | 1338 GaimGroup *g = (GaimGroup *)node; |
9774 | 1339 |
8952 | 1340 menu = create_group_menu(node, g); |
8143 | 1341 } else if (GAIM_BLIST_NODE_IS_CHAT(node)) { |
8586 | 1342 GaimChat *c = (GaimChat *)node; |
9774 | 1343 |
1344 menu = create_chat_menu(node, c); | |
8143 | 1345 } else if ((GAIM_BLIST_NODE_IS_CONTACT(node)) && (gtknode->contact_expanded)) { |
1346 menu = create_contact_menu(node); | |
1347 } else if (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1348 GaimBuddy *b; | |
1349 | |
1350 if (GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1351 b = gaim_contact_get_priority_buddy((GaimContact*)node); | |
1352 else | |
1353 b = (GaimBuddy *)node; | |
1354 | |
9774 | 1355 menu = create_buddy_menu(node, b); |
8143 | 1356 } |
1357 | |
1358 /* Now display the menu */ | |
1359 if (menu != NULL) { | |
1360 gtk_widget_show_all(menu); | |
1361 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, func, tv, button, time); | |
1362 handled = TRUE; | |
1363 } | |
1364 | |
1365 return handled; | |
1366 } | |
1367 | |
1368 static gboolean gtk_blist_button_press_cb(GtkWidget *tv, GdkEventButton *event, gpointer user_data) | |
5228 | 1369 { |
1370 GtkTreePath *path; | |
1371 GaimBlistNode *node; | |
1372 GValue val = { 0, }; | |
1373 GtkTreeIter iter; | |
1374 GtkTreeSelection *sel; | |
1375 GaimPlugin *prpl = NULL; | |
1376 GaimPluginProtocolInfo *prpl_info = NULL; | |
7620 | 1377 struct _gaim_gtk_blist_node *gtknode; |
1378 gboolean handled = FALSE; | |
5228 | 1379 |
1380 /* Here we figure out which node was clicked */ | |
1381 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL)) | |
1382 return FALSE; | |
1383 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
8143 | 1384 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); |
5228 | 1385 node = g_value_get_pointer(&val); |
7620 | 1386 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; |
1387 | |
8143 | 1388 /* Right click draws a context menu */ |
1389 if ((event->button == 3) && (event->type == GDK_BUTTON_PRESS)) { | |
1390 handled = gaim_gtk_blist_show_context_menu(node, NULL, tv, 3, event->time); | |
1391 | |
1392 /* CTRL+middle click expands or collapse a contact */ | |
1393 } else if ((event->button == 2) && (event->type == GDK_BUTTON_PRESS) && | |
1394 (event->state & GDK_CONTROL_MASK) && (GAIM_BLIST_NODE_IS_CONTACT(node))) { | |
1395 if (gtknode->contact_expanded) | |
7620 | 1396 gaim_gtk_blist_collapse_contact_cb(NULL, node); |
1397 else | |
1398 gaim_gtk_blist_expand_contact_cb(NULL, node); | |
1399 handled = TRUE; | |
8143 | 1400 |
1401 /* Double middle click gets info */ | |
1402 } else if ((event->button == 2) && (event->type == GDK_2BUTTON_PRESS) && | |
1403 ((GAIM_BLIST_NODE_IS_CONTACT(node)) || (GAIM_BLIST_NODE_IS_BUDDY(node)))) { | |
7620 | 1404 GaimBuddy *b; |
1405 if(GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1406 b = gaim_contact_get_priority_buddy((GaimContact*)node); | |
1407 else | |
1408 b = (GaimBuddy *)node; | |
1409 | |
7956 | 1410 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); |
5228 | 1411 if (prpl != NULL) |
1412 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
1413 | |
8143 | 1414 if (prpl && prpl_info->get_info) |
1415 serv_get_info(b->account->gc, b->name); | |
1416 handled = TRUE; | |
5228 | 1417 } |
1418 | |
8143 | 1419 #if (1) |
1420 /* | |
1421 * This code only exists because GTK doesn't work. If we return | |
1422 * FALSE here, as would be normal the event propoagates down and | |
1423 * somehow gets interpreted as the start of a drag event. | |
1424 * | |
1425 * Um, isn't it _normal_ to return TRUE here? Since the event | |
1426 * was handled? --Mark | |
1427 */ | |
7620 | 1428 if(handled) { |
1429 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
1430 gtk_tree_selection_select_path(sel, path); | |
1431 gtk_tree_path_free(path); | |
1432 return TRUE; | |
1433 } | |
5228 | 1434 #endif |
7753 | 1435 gtk_tree_path_free(path); |
8143 | 1436 |
7620 | 1437 return FALSE; |
5228 | 1438 } |
1439 | |
8143 | 1440 static gboolean |
1441 gaim_gtk_blist_popup_menu_cb(GtkWidget *tv, void *user_data) | |
1442 { | |
1443 GaimBlistNode *node; | |
1444 GValue val = { 0, }; | |
1445 GtkTreeIter iter; | |
1446 GtkTreeSelection *sel; | |
1447 gboolean handled = FALSE; | |
1448 | |
1449 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tv)); | |
1450 if (!gtk_tree_selection_get_selected(sel, NULL, &iter)) | |
1451 return FALSE; | |
1452 | |
1453 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), | |
1454 &iter, NODE_COLUMN, &val); | |
1455 node = g_value_get_pointer(&val); | |
1456 | |
1457 /* Shift+F10 draws a context menu */ | |
1458 handled = gaim_gtk_blist_show_context_menu(node, gaim_gtk_treeview_popup_menu_position_func, tv, 0, GDK_CURRENT_TIME); | |
1459 | |
1460 return handled; | |
1461 } | |
1462 | |
5228 | 1463 static void gaim_gtk_blist_show_empty_groups_cb(gpointer data, guint action, GtkWidget *item) |
1464 { | |
7620 | 1465 gaim_prefs_set_bool("/gaim/gtk/blist/show_empty_groups", |
1466 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item))); | |
5228 | 1467 } |
1468 | |
1469 static void gaim_gtk_blist_edit_mode_cb(gpointer callback_data, guint callback_action, | |
1470 GtkWidget *checkitem) { | |
1471 if(gtkblist->window->window) { | |
1472 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH); | |
1473 gdk_window_set_cursor(gtkblist->window->window, cursor); | |
1474 while (gtk_events_pending()) | |
1475 gtk_main_iteration(); | |
1476 gdk_cursor_unref(cursor); | |
1477 } | |
1478 | |
7620 | 1479 gaim_prefs_set_bool("/gaim/gtk/blist/show_offline_buddies", |
1480 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(checkitem))); | |
5228 | 1481 |
1482 if(gtkblist->window->window) { | |
1483 GdkCursor *cursor = gdk_cursor_new(GDK_LEFT_PTR); | |
1484 gdk_window_set_cursor(gtkblist->window->window, cursor); | |
1485 gdk_cursor_unref(cursor); | |
1486 } | |
1487 } | |
1488 | |
10074 | 1489 static void gaim_gtk_blist_mute_sounds_cb(gpointer data, guint action, GtkWidget *item) |
1490 { | |
1491 gaim_prefs_set_bool("/gaim/gtk/sound/mute", GTK_CHECK_MENU_ITEM(item)->active); | |
1492 } | |
1493 | |
1494 static void gaim_gtk_blist_mute_pref_cb(const char *name, GaimPrefType type, gpointer value, gpointer data) | |
1495 { | |
1496 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item(gtkblist->ift, | |
1497 N_("/Tools/Mute Sounds"))), (gboolean)GPOINTER_TO_INT(value)); | |
1498 } | |
1499 | |
1500 static void gaim_gtk_blist_sound_method_pref_cb(const char *name, GaimPrefType type, gpointer value, gpointer data) | |
1501 { | |
1502 gboolean sensitive = TRUE; | |
1503 | |
1504 if(!strcmp(value, "none")) | |
1505 sensitive = FALSE; | |
1506 | |
1507 gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), sensitive); | |
1508 } | |
1509 | |
8089 | 1510 static void |
1511 add_buddies_from_vcard(const char *prpl_id, GaimGroup *group, GList *list, | |
1512 const char *alias) | |
1513 { | |
1514 GList *l; | |
1515 GaimAccount *account = NULL; | |
1516 GaimConnection *gc; | |
1517 | |
1518 if (list == NULL) | |
1519 return; | |
1520 | |
1521 for (l = gaim_connections_get_all(); l != NULL; l = l->next) | |
1522 { | |
1523 gc = (GaimConnection *)l->data; | |
1524 account = gaim_connection_get_account(gc); | |
1525 | |
1526 if (!strcmp(gaim_account_get_protocol_id(account), prpl_id)) | |
1527 break; | |
1528 | |
1529 account = NULL; | |
1530 } | |
1531 | |
1532 if (account != NULL) | |
1533 { | |
1534 for (l = list; l != NULL; l = l->next) | |
1535 { | |
1536 gaim_blist_request_add_buddy(account, l->data, | |
1537 (group ? group->name : NULL), | |
1538 alias); | |
1539 } | |
1540 } | |
1541 | |
1542 g_list_foreach(list, (GFunc)g_free, NULL); | |
1543 g_list_free(list); | |
1544 } | |
1545 | |
1546 static gboolean | |
1547 parse_vcard(const char *vcard, GaimGroup *group) | |
1548 { | |
1549 char *temp_vcard; | |
1550 char *s, *c; | |
1551 char *alias = NULL; | |
1552 GList *aims = NULL; | |
1553 GList *icqs = NULL; | |
1554 GList *yahoos = NULL; | |
1555 GList *msns = NULL; | |
1556 GList *jabbers = NULL; | |
1557 | |
1558 s = temp_vcard = g_strdup(vcard); | |
1559 | |
1560 while (*s != '\0' && strncmp(s, "END:vCard", strlen("END:vCard"))) | |
1561 { | |
1562 char *field, *value; | |
1563 | |
1564 field = s; | |
1565 | |
1566 /* Grab the field */ | |
1567 while (*s != '\r' && *s != '\n' && *s != '\0' && *s != ':') | |
1568 s++; | |
1569 | |
1570 if (*s == '\r') s++; | |
1571 if (*s == '\n') | |
1572 { | |
1573 s++; | |
1574 continue; | |
1575 } | |
1576 | |
1577 if (*s != '\0') *s++ = '\0'; | |
1578 | |
1579 if ((c = strchr(field, ';')) != NULL) | |
1580 *c = '\0'; | |
1581 | |
1582 /* Proceed to the end of the line */ | |
1583 value = s; | |
1584 | |
1585 while (*s != '\r' && *s != '\n' && *s != '\0') | |
1586 s++; | |
1587 | |
1588 if (*s == '\r') *s++ = '\0'; | |
1589 if (*s == '\n') *s++ = '\0'; | |
1590 | |
1591 /* We only want to worry about a few fields here. */ | |
1592 if (!strcmp(field, "FN")) | |
1593 alias = g_strdup(value); | |
1594 else if (!strcmp(field, "X-AIM") || !strcmp(field, "X-ICQ") || | |
1595 !strcmp(field, "X-YAHOO") || !strcmp(field, "X-MSN") || | |
1596 !strcmp(field, "X-JABBER")) | |
1597 { | |
1598 char **values = g_strsplit(value, ":", 0); | |
1599 char **im; | |
1600 | |
1601 for (im = values; *im != NULL; im++) | |
1602 { | |
1603 if (!strcmp(field, "X-AIM")) | |
1604 aims = g_list_append(aims, g_strdup(*im)); | |
1605 else if (!strcmp(field, "X-ICQ")) | |
1606 icqs = g_list_append(icqs, g_strdup(*im)); | |
1607 else if (!strcmp(field, "X-YAHOO")) | |
1608 yahoos = g_list_append(yahoos, g_strdup(*im)); | |
1609 else if (!strcmp(field, "X-MSN")) | |
1610 msns = g_list_append(msns, g_strdup(*im)); | |
1611 else if (!strcmp(field, "X-JABBER")) | |
1612 jabbers = g_list_append(jabbers, g_strdup(*im)); | |
1613 } | |
1614 | |
1615 g_strfreev(values); | |
1616 } | |
1617 } | |
1618 | |
1619 g_free(temp_vcard); | |
1620 | |
1621 if (aims == NULL && icqs == NULL && yahoos == NULL && | |
1622 msns == NULL && jabbers == NULL) | |
1623 { | |
1624 if (alias != NULL) | |
1625 g_free(alias); | |
1626 | |
1627 return FALSE; | |
1628 } | |
1629 | |
1630 add_buddies_from_vcard("prpl-oscar", group, aims, alias); | |
1631 add_buddies_from_vcard("prpl-oscar", group, icqs, alias); | |
1632 add_buddies_from_vcard("prpl-yahoo", group, yahoos, alias); | |
1633 add_buddies_from_vcard("prpl-msn", group, msns, alias); | |
1634 add_buddies_from_vcard("prpl-jabber", group, jabbers, alias); | |
1635 | |
1636 if (alias != NULL) | |
1637 g_free(alias); | |
1638 | |
1639 return TRUE; | |
1640 } | |
1641 | |
9811 | 1642 static void gaim_gtk_blist_drag_data_get_cb(GtkWidget *widget, |
1643 GdkDragContext *dc, | |
1644 GtkSelectionData *data, | |
1645 guint info, | |
1646 guint time, | |
1647 gpointer *null) | |
5228 | 1648 { |
8089 | 1649 if (data->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE)) |
1650 { | |
5228 | 1651 GtkTreeRowReference *ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row"); |
1652 GtkTreePath *sourcerow = gtk_tree_row_reference_get_path(ref); | |
1653 GtkTreeIter iter; | |
1654 GaimBlistNode *node = NULL; | |
1655 GValue val = {0}; | |
5273 | 1656 if(!sourcerow) |
1657 return; | |
5228 | 1658 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, sourcerow); |
1659 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
1660 node = g_value_get_pointer(&val); | |
1661 gtk_selection_data_set (data, | |
1662 gdk_atom_intern ("GAIM_BLIST_NODE", FALSE), | |
1663 8, /* bits */ | |
1664 (void*)&node, | |
1665 sizeof (node)); | |
5273 | 1666 |
5228 | 1667 gtk_tree_path_free(sourcerow); |
1668 } | |
8089 | 1669 else if (data->target == gdk_atom_intern("application/x-im-contact", FALSE)) |
1670 { | |
7706 | 1671 GtkTreeRowReference *ref; |
1672 GtkTreePath *sourcerow; | |
1673 GtkTreeIter iter; | |
1674 GaimBlistNode *node = NULL; | |
1675 GaimBuddy *buddy; | |
1676 GaimConnection *gc; | |
1677 GValue val = {0}; | |
1678 GString *str; | |
1679 const char *protocol; | |
1680 char *mime_str; | |
1681 | |
1682 ref = g_object_get_data(G_OBJECT(dc), "gtk-tree-view-source-row"); | |
1683 sourcerow = gtk_tree_row_reference_get_path(ref); | |
1684 | |
1685 if (!sourcerow) | |
1686 return; | |
1687 | |
1688 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
1689 sourcerow); | |
1690 gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
1691 NODE_COLUMN, &val); | |
1692 | |
1693 node = g_value_get_pointer(&val); | |
1694 | |
1695 if (GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1696 { | |
1697 buddy = gaim_contact_get_priority_buddy((GaimContact *)node); | |
1698 } | |
1699 else if (!GAIM_BLIST_NODE_IS_BUDDY(node)) | |
1700 { | |
1701 gtk_tree_path_free(sourcerow); | |
1702 return; | |
1703 } | |
1704 else | |
1705 { | |
1706 buddy = (GaimBuddy *)node; | |
1707 } | |
1708 | |
1709 gc = gaim_account_get_connection(buddy->account); | |
1710 | |
1711 if (gc == NULL) | |
1712 { | |
1713 gtk_tree_path_free(sourcerow); | |
1714 return; | |
1715 } | |
1716 | |
1717 protocol = | |
1718 GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->list_icon(buddy->account, | |
1719 buddy); | |
1720 | |
1721 str = g_string_new(NULL); | |
1722 g_string_printf(str, | |
1723 "MIME-Version: 1.0\r\n" | |
1724 "Content-Type: application/x-im-contact\r\n" | |
1725 "X-IM-Protocol: %s\r\n" | |
1726 "X-IM-Username: %s\r\n", | |
1727 protocol, | |
1728 buddy->name); | |
1729 | |
1730 if (buddy->alias != NULL) | |
1731 { | |
1732 g_string_append_printf(str, | |
1733 "X-IM-Alias: %s\r\n", | |
1734 buddy->alias); | |
1735 } | |
1736 | |
1737 str = g_string_append(str, "\r\n"); | |
1738 | |
1739 mime_str = g_string_free(str, FALSE); | |
1740 | |
1741 gtk_selection_data_set(data, | |
1742 gdk_atom_intern("application/x-im-contact", FALSE), | |
1743 8, /* bits */ | |
1744 mime_str, | |
1745 strlen(mime_str) + 1); | |
1746 | |
1747 g_free(mime_str); | |
1748 gtk_tree_path_free(sourcerow); | |
1749 } | |
5228 | 1750 } |
1751 | |
1752 static void gaim_gtk_blist_drag_data_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, | |
1753 GtkSelectionData *sd, guint info, guint t) | |
7620 | 1754 { |
5228 | 1755 if (sd->target == gdk_atom_intern("GAIM_BLIST_NODE", FALSE) && sd->data) { |
1756 GaimBlistNode *n = NULL; | |
1757 GtkTreePath *path = NULL; | |
1758 GtkTreeViewDropPosition position; | |
1759 memcpy(&n, sd->data, sizeof(n)); | |
1760 if(gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) { | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
1761 /* if we're here, I think it means the drop is ok */ |
7642 | 1762 GtkTreeIter iter; |
5228 | 1763 GaimBlistNode *node; |
1764 GValue val = {0}; | |
7620 | 1765 struct _gaim_gtk_blist_node *gtknode; |
1766 | |
1767 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), | |
1768 &iter, path); | |
1769 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
1770 &iter, NODE_COLUMN, &val); | |
5228 | 1771 node = g_value_get_pointer(&val); |
7620 | 1772 gtknode = node->ui_data; |
1773 | |
1774 if (GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
1775 GaimContact *c = (GaimContact*)n; | |
1776 if (GAIM_BLIST_NODE_IS_CONTACT(node) && gtknode->contact_expanded) { | |
1777 gaim_blist_merge_contact(c, node); | |
1778 } else if (GAIM_BLIST_NODE_IS_CONTACT(node) || | |
5234 | 1779 GAIM_BLIST_NODE_IS_CHAT(node)) { |
5228 | 1780 switch(position) { |
1781 case GTK_TREE_VIEW_DROP_AFTER: | |
1782 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
7620 | 1783 gaim_blist_add_contact(c, (GaimGroup*)node->parent, |
1784 node); | |
1785 break; | |
1786 case GTK_TREE_VIEW_DROP_BEFORE: | |
1787 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1788 gaim_blist_add_contact(c, (GaimGroup*)node->parent, | |
1789 node->prev); | |
1790 break; | |
1791 } | |
1792 } else if(GAIM_BLIST_NODE_IS_GROUP(node)) { | |
1793 gaim_blist_add_contact(c, (GaimGroup*)node, NULL); | |
1794 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1795 gaim_blist_merge_contact(c, node); | |
1796 } | |
1797 } else if (GAIM_BLIST_NODE_IS_BUDDY(n)) { | |
1798 GaimBuddy *b = (GaimBuddy*)n; | |
1799 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1800 switch(position) { | |
1801 case GTK_TREE_VIEW_DROP_AFTER: | |
1802 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1803 gaim_blist_add_buddy(b, (GaimContact*)node->parent, | |
1804 (GaimGroup*)node->parent->parent, node); | |
5228 | 1805 break; |
1806 case GTK_TREE_VIEW_DROP_BEFORE: | |
1807 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
7620 | 1808 gaim_blist_add_buddy(b, (GaimContact*)node->parent, |
1809 (GaimGroup*)node->parent->parent, | |
1810 node->prev); | |
5228 | 1811 break; |
1812 } | |
7620 | 1813 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { |
1814 gaim_blist_add_buddy(b, NULL, (GaimGroup*)node->parent, | |
1815 NULL); | |
5228 | 1816 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
7620 | 1817 gaim_blist_add_buddy(b, NULL, (GaimGroup*)node, NULL); |
1818 } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
1819 if(gtknode->contact_expanded) { | |
1820 switch(position) { | |
1821 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1822 case GTK_TREE_VIEW_DROP_AFTER: | |
1823 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1824 gaim_blist_add_buddy(b, (GaimContact*)node, | |
1825 (GaimGroup*)node->parent, NULL); | |
1826 break; | |
1827 case GTK_TREE_VIEW_DROP_BEFORE: | |
1828 gaim_blist_add_buddy(b, NULL, | |
1829 (GaimGroup*)node->parent, node->prev); | |
1830 break; | |
1831 } | |
1832 } else { | |
1833 switch(position) { | |
1834 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1835 case GTK_TREE_VIEW_DROP_AFTER: | |
1836 gaim_blist_add_buddy(b, NULL, | |
1837 (GaimGroup*)node->parent, NULL); | |
1838 break; | |
1839 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1840 case GTK_TREE_VIEW_DROP_BEFORE: | |
1841 gaim_blist_add_buddy(b, NULL, | |
1842 (GaimGroup*)node->parent, node->prev); | |
1843 break; | |
1844 } | |
1845 } | |
5228 | 1846 } |
5234 | 1847 } else if (GAIM_BLIST_NODE_IS_CHAT(n)) { |
7620 | 1848 GaimChat *chat = (GaimChat *)n; |
1849 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
1850 switch(position) { | |
1851 case GTK_TREE_VIEW_DROP_AFTER: | |
1852 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1853 gaim_blist_add_chat(chat, | |
1854 (GaimGroup*)node->parent->parent, node); | |
1855 break; | |
1856 case GTK_TREE_VIEW_DROP_BEFORE: | |
1857 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1858 gaim_blist_add_chat(chat, | |
1859 (GaimGroup*)node->parent->parent, | |
1860 node->prev); | |
1861 break; | |
1862 } | |
1863 } else if(GAIM_BLIST_NODE_IS_CONTACT(node) || | |
5234 | 1864 GAIM_BLIST_NODE_IS_CHAT(node)) { |
1865 switch(position) { | |
1866 case GTK_TREE_VIEW_DROP_AFTER: | |
1867 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
7620 | 1868 gaim_blist_add_chat(chat, (GaimGroup*)node->parent, node); |
5234 | 1869 break; |
1870 case GTK_TREE_VIEW_DROP_BEFORE: | |
1871 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
7620 | 1872 gaim_blist_add_chat(chat, (GaimGroup*)node->parent, node->prev); |
5234 | 1873 break; |
1874 } | |
1875 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) { | |
7620 | 1876 gaim_blist_add_chat(chat, (GaimGroup*)node, NULL); |
5234 | 1877 } |
5228 | 1878 } else if (GAIM_BLIST_NODE_IS_GROUP(n)) { |
7620 | 1879 GaimGroup *g = (GaimGroup*)n; |
5228 | 1880 if (GAIM_BLIST_NODE_IS_GROUP(node)) { |
1881 switch (position) { | |
1882 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1883 case GTK_TREE_VIEW_DROP_AFTER: | |
1884 gaim_blist_add_group(g, node); | |
1885 break; | |
1886 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1887 case GTK_TREE_VIEW_DROP_BEFORE: | |
1888 gaim_blist_add_group(g, node->prev); | |
1889 break; | |
1890 } | |
7620 | 1891 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { |
1892 gaim_blist_add_group(g, node->parent->parent); | |
1893 } else if(GAIM_BLIST_NODE_IS_CONTACT(node) || | |
5234 | 1894 GAIM_BLIST_NODE_IS_CHAT(node)) { |
5228 | 1895 gaim_blist_add_group(g, node->parent); |
1896 } | |
1897 } | |
1898 | |
1899 gtk_tree_path_free(path); | |
7620 | 1900 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); |
5228 | 1901 } |
1902 } | |
7706 | 1903 else if (sd->target == gdk_atom_intern("application/x-im-contact", |
1904 FALSE) && sd->data) | |
1905 { | |
1906 GaimGroup *group = NULL; | |
1907 GtkTreePath *path = NULL; | |
1908 GtkTreeViewDropPosition position; | |
7712
2823111061ba
[gaim-migrate @ 8357]
Christian Hammond <chipx86@chipx86.com>
parents:
7706
diff
changeset
|
1909 GaimAccount *account; |
7706 | 1910 char *protocol = NULL; |
1911 char *username = NULL; | |
1912 char *alias = NULL; | |
1913 | |
1914 if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), | |
1915 x, y, &path, &position)) | |
1916 { | |
1917 GtkTreeIter iter; | |
1918 GaimBlistNode *node; | |
1919 GValue val = {0}; | |
1920 | |
1921 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), | |
1922 &iter, path); | |
1923 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
1924 &iter, NODE_COLUMN, &val); | |
1925 node = g_value_get_pointer(&val); | |
1926 | |
1927 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
1928 { | |
1929 group = (GaimGroup *)node->parent->parent; | |
1930 } | |
1931 else if (GAIM_BLIST_NODE_IS_CHAT(node) || | |
1932 GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1933 { | |
1934 group = (GaimGroup *)node->parent; | |
1935 } | |
1936 else if (GAIM_BLIST_NODE_IS_GROUP(node)) | |
1937 { | |
1938 group = (GaimGroup *)node; | |
1939 } | |
1940 } | |
1941 | |
7712
2823111061ba
[gaim-migrate @ 8357]
Christian Hammond <chipx86@chipx86.com>
parents:
7706
diff
changeset
|
1942 if (gaim_gtk_parse_x_im_contact(sd->data, FALSE, &account, |
2823111061ba
[gaim-migrate @ 8357]
Christian Hammond <chipx86@chipx86.com>
parents:
7706
diff
changeset
|
1943 &protocol, &username, &alias)) |
7706 | 1944 { |
1945 if (account == NULL) | |
1946 { | |
1947 gaim_notify_error(NULL, NULL, | |
1948 _("You are not currently signed on with an account that " | |
1949 "can add that buddy."), NULL); | |
1950 } | |
1951 else | |
1952 { | |
1953 gaim_blist_request_add_buddy(account, username, | |
1954 (group ? group->name : NULL), | |
1955 alias); | |
1956 } | |
1957 } | |
1958 | |
1959 if (username != NULL) g_free(username); | |
1960 if (protocol != NULL) g_free(protocol); | |
1961 if (alias != NULL) g_free(alias); | |
1962 | |
1963 if (path != NULL) | |
1964 gtk_tree_path_free(path); | |
1965 | |
1966 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); | |
1967 } | |
8089 | 1968 else if (sd->target == gdk_atom_intern("text/x-vcard", FALSE) && sd->data) |
1969 { | |
1970 gboolean result; | |
1971 GaimGroup *group = NULL; | |
1972 GtkTreePath *path = NULL; | |
1973 GtkTreeViewDropPosition position; | |
1974 | |
1975 if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), | |
1976 x, y, &path, &position)) | |
1977 { | |
1978 GtkTreeIter iter; | |
1979 GaimBlistNode *node; | |
1980 GValue val = {0}; | |
1981 | |
1982 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), | |
1983 &iter, path); | |
1984 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
1985 &iter, NODE_COLUMN, &val); | |
1986 node = g_value_get_pointer(&val); | |
1987 | |
1988 if (GAIM_BLIST_NODE_IS_BUDDY(node)) | |
1989 { | |
1990 group = (GaimGroup *)node->parent->parent; | |
1991 } | |
1992 else if (GAIM_BLIST_NODE_IS_CHAT(node) || | |
1993 GAIM_BLIST_NODE_IS_CONTACT(node)) | |
1994 { | |
1995 group = (GaimGroup *)node->parent; | |
1996 } | |
1997 else if (GAIM_BLIST_NODE_IS_GROUP(node)) | |
1998 { | |
1999 group = (GaimGroup *)node; | |
2000 } | |
2001 } | |
2002 | |
2003 result = parse_vcard(sd->data, group); | |
2004 | |
2005 gtk_drag_finish(dc, result, (dc->action == GDK_ACTION_MOVE), t); | |
9525 | 2006 } else if (sd->target == gdk_atom_intern("text/uri-list", FALSE) && sd->data) { |
9495 | 2007 GtkTreePath *path = NULL; |
2008 GtkTreeViewDropPosition position; | |
2009 | |
2010 if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), | |
9811 | 2011 x, y, &path, &position)) |
9495 | 2012 { |
2013 GtkTreeIter iter; | |
2014 GaimBlistNode *node; | |
2015 GValue val = {0}; | |
2016 | |
2017 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), | |
2018 &iter, path); | |
2019 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), | |
2020 &iter, NODE_COLUMN, &val); | |
2021 node = g_value_get_pointer(&val); | |
2022 | |
2023 if (GAIM_BLIST_NODE_IS_BUDDY(node) || GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
2024 GaimBuddy *b = GAIM_BLIST_NODE_IS_BUDDY(node) ? (GaimBuddy*)node : gaim_contact_get_priority_buddy((GaimContact*)node); | |
9670 | 2025 GList *tmp; |
2026 GList *files = gaim_uri_list_extract_filenames(sd->data); | |
9673 | 2027 for(tmp = files; tmp != NULL ; tmp = g_list_next(tmp)) { |
2028 gchar *filename = tmp->data; | |
9670 | 2029 /* XXX - Make ft API support creating a transfer with more than one file */ |
2030 if (g_file_test(filename, G_FILE_TEST_EXISTS) | |
2031 && !g_file_test(filename, G_FILE_TEST_IS_DIR)) { | |
2032 serv_send_file(gaim_account_get_connection(b->account), b->name, filename); | |
9495 | 2033 } |
9670 | 2034 g_free(filename); |
9673 | 2035 } |
9670 | 2036 g_list_free(files); |
9495 | 2037 } |
2038 } | |
8089 | 2039 } |
5228 | 2040 } |
2041 | |
5234 | 2042 static void gaim_gtk_blist_paint_tip(GtkWidget *widget, GdkEventExpose *event, GaimBlistNode *node) |
5228 | 2043 { |
2044 GtkStyle *style; | |
5234 | 2045 GdkPixbuf *pixbuf = gaim_gtk_blist_get_status_icon(node, GAIM_STATUS_ICON_LARGE); |
5228 | 2046 PangoLayout *layout; |
5234 | 2047 char *tooltiptext = gaim_get_tooltip_text(node); |
5228 | 2048 |
7620 | 2049 if(!tooltiptext) |
2050 return; | |
2051 | |
5228 | 2052 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); |
2053 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); | |
2054 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); | |
2055 pango_layout_set_width(layout, 300000); | |
2056 style = gtkblist->tipwindow->style; | |
2057 | |
9811 | 2058 gtk_paint_flat_box(style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, |
2059 NULL, gtkblist->tipwindow, "tooltip", 0, 0, -1, -1); | |
5228 | 2060 |
2061 #if GTK_CHECK_VERSION(2,2,0) | |
2062 gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, pixbuf, | |
2063 0, 0, 4, 4, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); | |
2064 #else | |
2065 gdk_pixbuf_render_to_drawable(pixbuf, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, 4, 4, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); | |
2066 #endif | |
2067 | |
2068 gtk_paint_layout (style, gtkblist->tipwindow->window, GTK_STATE_NORMAL, TRUE, | |
2069 NULL, gtkblist->tipwindow, "tooltip", 38, 4, layout); | |
2070 | |
2071 g_object_unref (pixbuf); | |
2072 g_object_unref (layout); | |
2073 g_free(tooltiptext); | |
7620 | 2074 |
7662 | 2075 #ifdef WANT_DROP_SHADOW |
10015 | 2076 if (!xcomposite_is_present()) { |
2077 shadow_paint(gtkblist, NULL, EAST_SIDE); | |
2078 shadow_paint(gtkblist, NULL, SOUTH_SIDE); | |
2079 } | |
7620 | 2080 #endif |
2081 | |
5228 | 2082 return; |
2083 } | |
2084 | |
8254 | 2085 static void gaim_gtk_blist_tooltip_destroy() |
2086 { | |
2087 if (gtkblist->tipwindow == NULL) | |
2088 return; | |
2089 | |
2090 gtk_widget_destroy(gtkblist->tipwindow); | |
2091 gtkblist->tipwindow = NULL; | |
2092 #ifdef WANT_DROP_SHADOW | |
10015 | 2093 if (!xcomposite_is_present()) { |
2094 gdk_window_set_user_data (gtkblist->east_shadow, NULL); | |
2095 gdk_window_destroy (gtkblist->east_shadow); | |
2096 gtkblist->east_shadow = NULL; | |
2097 | |
2098 gdk_window_set_user_data (gtkblist->south_shadow, NULL); | |
2099 gdk_window_destroy (gtkblist->south_shadow); | |
2100 gtkblist->south_shadow = NULL; | |
2101 } | |
8254 | 2102 #endif |
2103 } | |
2104 | |
5228 | 2105 static gboolean gaim_gtk_blist_tooltip_timeout(GtkWidget *tv) |
2106 { | |
2107 GtkTreePath *path; | |
2108 GtkTreeIter iter; | |
2109 GaimBlistNode *node; | |
2110 GValue val = {0}; | |
9869 | 2111 int scr_w, scr_h, w, h, x, y; |
2112 #if GTK_CHECK_VERSION(2,2,0) | |
2113 int mon_num; | |
2114 GdkScreen *screen = NULL; | |
2115 #endif | |
5234 | 2116 PangoLayout *layout; |
7636 | 2117 gboolean tooltip_top = FALSE; |
5234 | 2118 char *tooltiptext = NULL; |
7636 | 2119 struct _gaim_gtk_blist_node *gtknode; |
9773 | 2120 GdkRectangle mon_size; |
7662 | 2121 #ifdef WANT_DROP_SHADOW |
7620 | 2122 GdkWindowAttr attr; |
2123 #endif | |
5228 | 2124 |
7636 | 2125 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), gtkblist->tip_rect.x, gtkblist->tip_rect.y, &path, NULL, NULL, NULL)) |
5228 | 2126 return FALSE; |
2127 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); | |
2128 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); | |
2129 node = g_value_get_pointer(&val); | |
7620 | 2130 |
2131 if(!GAIM_BLIST_NODE_IS_CONTACT(node) && !GAIM_BLIST_NODE_IS_BUDDY(node) | |
2132 && !GAIM_BLIST_NODE_IS_CHAT(node)) | |
5234 | 2133 return FALSE; |
5228 | 2134 |
7636 | 2135 gtknode = node->ui_data; |
2136 | |
7731 | 2137 if (node->child && GAIM_BLIST_NODE_IS_CONTACT(node) && |
8960 | 2138 (((GaimContact*)node)->online > 1 || |
2139 (gaim_blist_node_get_bool(node, "show_offline") && | |
2140 ((GaimContact*)node)->currentsize > 1)) && | |
2141 !gtknode->contact_expanded && | |
7731 | 2142 gaim_prefs_get_bool("/gaim/gtk/blist/auto_expand_contacts")) { |
7719 | 2143 GtkTreeIter i; |
7636 | 2144 gaim_gtk_blist_expand_contact_cb(NULL, node); |
8083 | 2145 tooltip_top = TRUE; /* When the person expands, the new screennames will be below. |
2146 We'll draw the tip above the cursor so that the user can see | |
2147 the included buddies */ | |
2148 | |
7636 | 2149 while (gtk_events_pending()) |
2150 gtk_main_iteration(); | |
2151 | |
8083 | 2152 /* we check to see if we're still supposed to be moving, now that gtk events have |
2153 * happened, and the mouse might not still be in the buddy list */ | |
2154 if(!gtkblist->timeout) { | |
2155 gaim_gtk_blist_collapse_contact_cb(NULL, node); | |
2156 return FALSE; | |
2157 } | |
2158 | |
7636 | 2159 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->contact_rect); |
7720 | 2160 gdk_drawable_get_size(GDK_DRAWABLE(tv->window), &(gtkblist->contact_rect.width), NULL); |
7636 | 2161 gtkblist->mouseover_contact = node; |
2162 gtk_tree_path_down (path); | |
7719 | 2163 while (gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &i, path)) { |
7636 | 2164 GdkRectangle rect; |
2165 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, &rect); | |
2166 gtkblist->contact_rect.height += rect.height; | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2167 gtk_tree_path_next(path); |
7636 | 2168 } |
2169 } | |
2170 | |
2171 gtk_tree_path_free(path); | |
2172 | |
5234 | 2173 tooltiptext = gaim_get_tooltip_text(node); |
7620 | 2174 |
2175 if(!tooltiptext) | |
2176 return FALSE; | |
2177 | |
7837 | 2178 if(gtkblist->tipwindow) |
2179 gtk_widget_destroy(gtkblist->tipwindow); | |
5234 | 2180 gtkblist->tipwindow = gtk_window_new(GTK_WINDOW_POPUP); |
2181 gtk_widget_set_app_paintable(gtkblist->tipwindow, TRUE); | |
2182 gtk_window_set_resizable(GTK_WINDOW(gtkblist->tipwindow), FALSE); | |
2183 gtk_widget_set_name(gtkblist->tipwindow, "gtk-tooltips"); | |
2184 g_signal_connect(G_OBJECT(gtkblist->tipwindow), "expose_event", | |
2185 G_CALLBACK(gaim_gtk_blist_paint_tip), node); | |
2186 gtk_widget_ensure_style (gtkblist->tipwindow); | |
7837 | 2187 |
7662 | 2188 #ifdef WANT_DROP_SHADOW |
10015 | 2189 if (!xcomposite_is_present()) { |
2190 attr.window_type = GDK_WINDOW_TEMP; | |
2191 attr.override_redirect = TRUE; | |
2192 attr.x = gtkblist->tipwindow->allocation.x; | |
2193 attr.y = gtkblist->tipwindow->allocation.y; | |
2194 attr.width = gtkblist->tipwindow->allocation.width; | |
2195 attr.height = gtkblist->tipwindow->allocation.height; | |
2196 attr.wclass = GDK_INPUT_OUTPUT; | |
2197 attr.visual = gtk_widget_get_visual (gtkblist->window); | |
2198 attr.colormap = gtk_widget_get_colormap (gtkblist->window); | |
2199 | |
2200 attr.event_mask = gtk_widget_get_events (gtkblist->tipwindow); | |
2201 | |
2202 attr.event_mask |= (GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK | | |
2203 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK ); | |
2204 if(gtkblist->east_shadow) { | |
2205 gdk_window_set_user_data (gtkblist->east_shadow, NULL); | |
2206 gdk_window_destroy (gtkblist->east_shadow); | |
2207 } | |
2208 gtkblist->east_shadow = gdk_window_new(gtk_widget_get_root_window(gtkblist->tipwindow), &attr, | |
2209 GDK_WA_NOREDIR | GDK_WA_VISUAL | GDK_WA_COLORMAP); | |
2210 gdk_window_set_user_data (gtkblist->east_shadow, gtkblist->tipwindow); | |
2211 gdk_window_set_back_pixmap (gtkblist->east_shadow, NULL, FALSE); | |
2212 | |
2213 if(gtkblist->south_shadow) { | |
2214 gdk_window_set_user_data (gtkblist->south_shadow, NULL); | |
2215 gdk_window_destroy (gtkblist->south_shadow); | |
2216 } | |
2217 gtkblist->south_shadow = gdk_window_new(gtk_widget_get_root_window(gtkblist->tipwindow), &attr, | |
2218 GDK_WA_NOREDIR | GDK_WA_VISUAL | GDK_WA_COLORMAP); | |
2219 gdk_window_set_user_data (gtkblist->south_shadow, gtkblist->tipwindow); | |
2220 gdk_window_set_back_pixmap (gtkblist->south_shadow, NULL, FALSE); | |
7897 | 2221 } |
7620 | 2222 #endif |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2223 |
5234 | 2224 layout = gtk_widget_create_pango_layout (gtkblist->tipwindow, NULL); |
2225 pango_layout_set_wrap(layout, PANGO_WRAP_WORD); | |
2226 pango_layout_set_width(layout, 300000); | |
2227 pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext)); | |
2228 pango_layout_get_size (layout, &w, &h); | |
9773 | 2229 |
9869 | 2230 #if GTK_CHECK_VERSION(2,2,0) |
9773 | 2231 gdk_display_get_pointer(gdk_display_get_default(), &screen, &x, &y, NULL); |
2232 mon_num = gdk_screen_get_monitor_at_point(screen, x, y); | |
2233 gdk_screen_get_monitor_geometry(screen, mon_num, &mon_size); | |
2234 | |
2235 scr_w = mon_size.width + mon_size.x; | |
2236 scr_h = mon_size.height + mon_size.y; | |
9869 | 2237 #else |
2238 scr_w = gdk_screen_width(); | |
2239 scr_h = gdk_screen_height(); | |
2240 gdk_window_get_pointer(NULL, &x, &y, NULL); | |
2241 mon_size.x = 0; | |
2242 mon_size.y = 0; | |
2243 #endif | |
9773 | 2244 |
5234 | 2245 w = PANGO_PIXELS(w) + 8; |
2246 h = PANGO_PIXELS(h) + 8; | |
5228 | 2247 |
5234 | 2248 /* 38 is the size of a large status icon plus 4 pixels padding on each side. |
2249 * I should #define this or something */ | |
2250 w = w + 38; | |
2251 h = MAX(h, 38); | |
2252 | |
9869 | 2253 #if GTK_CHECK_VERSION(2,2,0) |
10046 | 2254 if (w > mon_size.width) |
9773 | 2255 w = mon_size.width - 10; |
2256 | |
10046 | 2257 if (h > mon_size.height) |
9773 | 2258 h = mon_size.height - 10; |
9869 | 2259 #endif |
9773 | 2260 |
5234 | 2261 if (GTK_WIDGET_NO_WINDOW(gtkblist->window)) |
2262 y+=gtkblist->window->allocation.y; | |
2263 | |
2264 x -= ((w >> 1) + 4); | |
5228 | 2265 |
7636 | 2266 if ((y + h + 4) > scr_h || tooltip_top) |
7620 | 2267 y = y - h - 5; |
5234 | 2268 else |
2269 y = y + 6; | |
7620 | 2270 |
9773 | 2271 if (y < mon_size.y) |
2272 y = mon_size.y; | |
2273 | |
2274 if (y != mon_size.y) { | |
7719 | 2275 if ((x + w) > scr_w) |
2276 x -= (x + w + 5) - scr_w; | |
9773 | 2277 else if (x < mon_size.x) |
2278 x = mon_size.x; | |
7719 | 2279 } else { |
2280 x -= (w / 2 + 10); | |
9773 | 2281 if (x < mon_size.x) |
2282 x = mon_size.x; | |
7719 | 2283 } |
2284 | |
5234 | 2285 g_object_unref (layout); |
2286 g_free(tooltiptext); | |
2287 gtk_widget_set_size_request(gtkblist->tipwindow, w, h); | |
2288 gtk_window_move(GTK_WINDOW(gtkblist->tipwindow), x, y); | |
2289 gtk_widget_show(gtkblist->tipwindow); | |
5228 | 2290 |
7662 | 2291 #ifdef WANT_DROP_SHADOW |
10015 | 2292 if (!xcomposite_is_present()) { |
2293 map_shadow_windows(gtkblist); | |
2294 } | |
7620 | 2295 #endif |
2296 | |
5228 | 2297 return FALSE; |
2298 } | |
2299 | |
2300 static gboolean gaim_gtk_blist_motion_cb (GtkWidget *tv, GdkEventMotion *event, gpointer null) | |
2301 { | |
2302 GtkTreePath *path; | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2303 int delay; |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2304 |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2305 delay = gaim_prefs_get_int("/gaim/gtk/blist/tooltip_delay"); |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2306 |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2307 if (delay == 0) |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2308 return FALSE; |
8083 | 2309 |
5228 | 2310 if (gtkblist->timeout) { |
7636 | 2311 if ((event->y > gtkblist->tip_rect.y) && ((event->y - gtkblist->tip_rect.height) < gtkblist->tip_rect.y)) |
5228 | 2312 return FALSE; |
2313 /* We've left the cell. Remove the timeout and create a new one below */ | |
8254 | 2314 gaim_gtk_blist_tooltip_destroy(); |
5228 | 2315 g_source_remove(gtkblist->timeout); |
2316 } | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2317 |
5228 | 2318 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL); |
7636 | 2319 gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, >kblist->tip_rect); |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2320 |
5228 | 2321 if (path) |
2322 gtk_tree_path_free(path); | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2323 gtkblist->timeout = g_timeout_add(delay, (GSourceFunc)gaim_gtk_blist_tooltip_timeout, tv); |
7636 | 2324 |
2325 if (gtkblist->mouseover_contact) { | |
2326 if ((event->y < gtkblist->contact_rect.y) || ((event->y - gtkblist->contact_rect.height) > gtkblist->contact_rect.y)) { | |
2327 gaim_gtk_blist_collapse_contact_cb(NULL, gtkblist->mouseover_contact); | |
2328 gtkblist->mouseover_contact = NULL; | |
2329 } | |
2330 } | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2331 |
5228 | 2332 return FALSE; |
2333 } | |
2334 | |
2335 static void gaim_gtk_blist_leave_cb (GtkWidget *w, GdkEventCrossing *e, gpointer n) | |
2336 { | |
8083 | 2337 |
5228 | 2338 if (gtkblist->timeout) { |
2339 g_source_remove(gtkblist->timeout); | |
2340 gtkblist->timeout = 0; | |
2341 } | |
8254 | 2342 gaim_gtk_blist_tooltip_destroy(); |
7720 | 2343 |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2344 if (gtkblist->mouseover_contact && |
9811 | 2345 !((e->x > gtkblist->contact_rect.x) && (e->x < (gtkblist->contact_rect.x + gtkblist->contact_rect.width)) && |
2346 (e->y > gtkblist->contact_rect.y) && (e->y < (gtkblist->contact_rect.y + gtkblist->contact_rect.height)))) { | |
2347 gaim_gtk_blist_collapse_contact_cb(NULL, gtkblist->mouseover_contact); | |
7636 | 2348 gtkblist->mouseover_contact = NULL; |
2349 } | |
5228 | 2350 } |
2351 | |
2352 static void | |
2353 toggle_debug(void) | |
2354 { | |
7620 | 2355 gaim_prefs_set_bool("/gaim/gtk/debug/enabled", |
2356 !gaim_prefs_get_bool("/gaim/gtk/debug/enabled")); | |
5228 | 2357 } |
2358 | |
2359 | |
2360 /*************************************************** | |
2361 * Crap * | |
2362 ***************************************************/ | |
2363 static GtkItemFactoryEntry blist_menu[] = | |
2364 { | |
2365 /* Buddies menu */ | |
2366 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>" }, | |
9714 | 2367 { N_("/Buddies/New Instant _Message..."), "<CTL>M", gaim_gtkdialogs_im, 0, "<StockItem>", GAIM_STOCK_IM }, |
8940 | 2368 { N_("/Buddies/Join a _Chat..."), "<CTL>C", gaim_gtk_blist_joinchat_show, 0, "<StockItem>", GAIM_STOCK_CHAT }, |
9714 | 2369 { N_("/Buddies/Get User _Info..."), "<CTL>I", gaim_gtkdialogs_info, 0, "<StockItem>", GAIM_STOCK_INFO }, |
2370 { N_("/Buddies/View User _Log..."), "<CTL>L", gaim_gtkdialogs_log, 0, NULL }, | |
5228 | 2371 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>" }, |
10019
8cc6f0bfa215
[gaim-migrate @ 10943]
Luke Schierer <lschiere@pidgin.im>
parents:
10018
diff
changeset
|
2372 { N_("/Buddies/Show _Offline Buddies"), "<CTL>O", gaim_gtk_blist_edit_mode_cb, 1, "<CheckItem>"}, |
8cc6f0bfa215
[gaim-migrate @ 10943]
Luke Schierer <lschiere@pidgin.im>
parents:
10018
diff
changeset
|
2373 { N_("/Buddies/Show _Empty Groups"), "<CTL>E", gaim_gtk_blist_show_empty_groups_cb, 1, "<CheckItem>"}, |
7853 | 2374 { N_("/Buddies/_Add Buddy..."), "<CTL>B", gaim_gtk_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD }, |
2375 { N_("/Buddies/Add C_hat..."), NULL, gaim_gtk_blist_add_chat_cb, 0, "<StockItem>", GTK_STOCK_ADD }, | |
2376 { N_("/Buddies/Add _Group..."), NULL, gaim_blist_request_add_group, 0, "<StockItem>", GTK_STOCK_ADD }, | |
5228 | 2377 { "/Buddies/sep2", NULL, NULL, 0, "<Separator>" }, |
7620 | 2378 { N_("/Buddies/_Signoff"), "<CTL>D", gaim_connections_disconnect_all, 0, "<StockItem>", GAIM_STOCK_SIGN_OFF }, |
2379 { N_("/Buddies/_Quit"), "<CTL>Q", gaim_core_quit, 0, "<StockItem>", GTK_STOCK_QUIT }, | |
5228 | 2380 |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
2381 /* Tools */ |
5228 | 2382 { N_("/_Tools"), NULL, NULL, 0, "<Branch>" }, |
2383 { N_("/Tools/_Away"), NULL, NULL, 0, "<Branch>" }, | |
2384 { N_("/Tools/Buddy _Pounce"), NULL, NULL, 0, "<Branch>" }, | |
8845 | 2385 { N_("/Tools/Account Ac_tions"), NULL, NULL, 0, "<Branch>" }, |
8986 | 2386 { N_("/Tools/Pl_ugin Actions"), NULL, NULL, 0, "<Branch>" }, |
5228 | 2387 { "/Tools/sep1", NULL, NULL, 0, "<Separator>" }, |
7620 | 2388 { N_("/Tools/A_ccounts"), "<CTL>A", gaim_gtk_accounts_window_show, 0, "<StockItem>", GAIM_STOCK_ACCOUNTS }, |
10019
8cc6f0bfa215
[gaim-migrate @ 10943]
Luke Schierer <lschiere@pidgin.im>
parents:
10018
diff
changeset
|
2389 { N_("/Tools/_File Transfers"), "<CTL>T", gaim_show_xfer_dialog, 0, "<StockItem>", GAIM_STOCK_FILE_TRANSFER }, |
8113 | 2390 { N_("/Tools/R_oom List"), NULL, gaim_gtk_roomlist_dialog_show, 0, NULL }, |
7870 | 2391 { N_("/Tools/Pr_eferences"), "<CTL>P", gaim_gtk_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES }, |
7856 | 2392 { N_("/Tools/Pr_ivacy"), NULL, gaim_gtk_privacy_dialog_show, 0, NULL }, |
10074 | 2393 { N_("/Tools/Mute _Sounds"), "<CTL>S", gaim_gtk_blist_mute_sounds_cb, 0, "<CheckItem>"}, |
5228 | 2394 { "/Tools/sep2", NULL, NULL, 0, "<Separator>" }, |
7620 | 2395 { N_("/Tools/View System _Log"), NULL, gtk_blist_show_systemlog_cb, 0, NULL }, |
5228 | 2396 |
2397 /* Help */ | |
2398 { N_("/_Help"), NULL, NULL, 0, "<Branch>" }, | |
2399 { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, "<StockItem>", GTK_STOCK_HELP }, | |
7620 | 2400 { N_("/Help/_Debug Window"), NULL, toggle_debug, 0, NULL }, |
9753 | 2401 { N_("/Help/_About"), NULL, gaim_gtkdialogs_about, 0, "<StockItem>", GAIM_STOCK_ABOUT }, |
5228 | 2402 }; |
2403 | |
2404 /********************************************************* | |
2405 * Private Utility functions * | |
2406 *********************************************************/ | |
7620 | 2407 static void |
2408 rename_group_cb(GaimGroup *g, const char *new_name) | |
2409 { | |
2410 gaim_blist_rename_group(g, new_name); | |
2411 } | |
2412 | |
9285 | 2413 /* |
2414 * Should disallow empty group names. | |
2415 */ | |
7620 | 2416 static void |
2417 show_rename_group(GtkWidget *unused, GaimGroup *g) | |
2418 { | |
2419 gaim_request_input(NULL, _("Rename Group"), _("New group name"), | |
2420 _("Please enter a new name for the selected group."), | |
8697 | 2421 g->name, FALSE, FALSE, NULL, |
7620 | 2422 _("OK"), G_CALLBACK(rename_group_cb), |
2423 _("Cancel"), NULL, g); | |
2424 } | |
5228 | 2425 |
5234 | 2426 static char *gaim_get_tooltip_text(GaimBlistNode *node) |
5228 | 2427 { |
5237 | 2428 GaimPlugin *prpl; |
2429 GaimPluginProtocolInfo *prpl_info = NULL; | |
5228 | 2430 char *text = NULL; |
7956 | 2431 |
5234 | 2432 if(GAIM_BLIST_NODE_IS_CHAT(node)) { |
7620 | 2433 GaimChat *chat = (GaimChat *)node; |
5237 | 2434 char *name = NULL; |
5274 | 2435 struct proto_chat_entry *pce; |
9959 | 2436 GList *parts = NULL, *tmp = NULL; |
5274 | 2437 GString *parts_text = g_string_new(""); |
2438 | |
7956 | 2439 prpl = gaim_find_prpl(gaim_account_get_protocol_id(chat->account)); |
5274 | 2440 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
2441 | |
9959 | 2442 if (prpl_info->chat_info != NULL) |
2443 parts = prpl_info->chat_info(chat->account->gc); | |
5237 | 2444 |
7620 | 2445 name = g_markup_escape_text(gaim_chat_get_name(chat), -1); |
2446 | |
2447 if(g_list_length(gaim_connections_get_all()) > 1) { | |
5274 | 2448 char *account = g_markup_escape_text(chat->account->username, -1); |
2449 g_string_append_printf(parts_text, _("\n<b>Account:</b> %s"), | |
2450 account); | |
2451 g_free(account); | |
5237 | 2452 } |
5274 | 2453 for(tmp = parts; tmp; tmp = tmp->next) { |
7889 | 2454 char *label, *tmp2, *value; |
5274 | 2455 pce = tmp->data; |
5237 | 2456 |
8020 | 2457 if(!pce->secret) { |
2458 | |
2459 tmp2 = g_markup_escape_text(pce->label, -1); | |
2460 label = gaim_text_strip_mnemonic(tmp2); | |
2461 g_free(tmp2); | |
2462 | |
2463 value = g_markup_escape_text(g_hash_table_lookup(chat->components, | |
2464 pce->identifier), -1); | |
2465 | |
2466 g_string_append_printf(parts_text, "\n<b>%s</b> %s", label, value); | |
2467 g_free(label); | |
2468 g_free(value); | |
2469 } | |
5274 | 2470 g_free(pce); |
2471 } | |
2472 g_list_free(parts); | |
2473 | |
2474 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>%s", | |
2475 name, parts_text->str); | |
2476 g_string_free(parts_text, TRUE); | |
5237 | 2477 g_free(name); |
7620 | 2478 } else if(GAIM_BLIST_NODE_IS_CONTACT(node) || |
2479 GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
2480 GaimBuddy *b; | |
9944 | 2481 GaimPresence *presence; |
2482 gboolean idle; | |
2483 time_t idle_secs; | |
2484 unsigned int warning_level; | |
5234 | 2485 char *statustext = NULL; |
7620 | 2486 char *contactaliastext = NULL; |
5234 | 2487 char *aliastext = NULL, *nicktext = NULL; |
7950 | 2488 char *loggedin = NULL, *idletime = NULL; |
2489 char *warning = NULL; | |
5274 | 2490 char *accounttext = NULL; |
5228 | 2491 |
7620 | 2492 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { |
2493 GaimContact *contact = (GaimContact*)node; | |
2494 b = gaim_contact_get_priority_buddy(contact); | |
2495 if(contact->alias) | |
2496 contactaliastext = g_markup_escape_text(contact->alias, -1); | |
2497 } else { | |
2498 b = (GaimBuddy *)node; | |
2499 } | |
2500 | |
7956 | 2501 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); |
5234 | 2502 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
2503 | |
7620 | 2504 if (prpl_info && prpl_info->tooltip_text) { |
5234 | 2505 const char *end; |
2506 statustext = prpl_info->tooltip_text(b); | |
5228 | 2507 |
5234 | 2508 if(statustext && !g_utf8_validate(statustext, -1, &end)) { |
2509 char *new = g_strndup(statustext, | |
2510 g_utf8_pointer_to_offset(statustext, end)); | |
2511 g_free(statustext); | |
2512 statustext = new; | |
2513 } | |
2514 } | |
2515 | |
9949 | 2516 presence = gaim_buddy_get_presence(b); |
2517 | |
2518 idle = gaim_presence_is_idle(presence); | |
2519 idle_secs = gaim_presence_get_idle_time(presence); | |
2520 warning_level = gaim_presence_get_warning_level(presence); | |
2521 | |
5234 | 2522 if (!statustext && !GAIM_BUDDY_IS_ONLINE(b)) |
8861 | 2523 statustext = g_strdup(_("\n<b>Status:</b> Offline")); |
5228 | 2524 |
7950 | 2525 if (b->signon > 0) |
2526 loggedin = gaim_str_seconds_to_string(time(NULL) - b->signon); | |
2527 | |
9949 | 2528 if (idle && idle_secs > 0) |
2529 idletime = gaim_str_seconds_to_string(time(NULL) - idle_secs); | |
5228 | 2530 |
5234 | 2531 if(b->alias && b->alias[0]) |
2532 aliastext = g_markup_escape_text(b->alias, -1); | |
5228 | 2533 |
5234 | 2534 if(b->server_alias) |
2535 nicktext = g_markup_escape_text(b->server_alias, -1); | |
5228 | 2536 |
9944 | 2537 if (warning_level > 0) |
2538 warning = g_strdup_printf(_("%d%%"), warning_level); | |
5228 | 2539 |
7620 | 2540 if(g_list_length(gaim_connections_get_all()) > 1) |
5274 | 2541 accounttext = g_markup_escape_text(b->account->username, -1); |
2542 | |
5234 | 2543 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>" |
9811 | 2544 "%s %s" /* Account */ |
2545 "%s %s" /* Contact Alias */ | |
2546 "%s %s" /* Alias */ | |
2547 "%s %s" /* Nickname */ | |
2548 "%s %s" /* Logged In */ | |
2549 "%s %s" /* Idle */ | |
2550 "%s %s" /* Warning */ | |
2551 "%s" /* Status */ | |
2552 "%s", | |
2553 b->name, | |
2554 accounttext ? _("\n<b>Account:</b>") : "", accounttext ? accounttext : "", | |
2555 contactaliastext ? _("\n<b>Contact Alias:</b>") : "", contactaliastext ? contactaliastext : "", | |
2556 aliastext ? _("\n<b>Alias:</b>") : "", aliastext ? aliastext : "", | |
2557 nicktext ? _("\n<b>Nickname:</b>") : "", nicktext ? nicktext : "", | |
2558 loggedin ? _("\n<b>Logged In:</b>") : "", loggedin ? loggedin : "", | |
9949 | 2559 idle ? (idle_secs > 0 ? _("\n<b>Idle:</b>") : _("\n<b>Idle</b>")) : "", |
2560 idletime ? idletime : "", | |
2561 warning_level ? _("\n<b>Warned:</b>") : "", warning_level ? warning : "", | |
9811 | 2562 statustext ? statustext : "", |
2563 !g_ascii_strcasecmp(b->name, "robflynn") ? _("\n<b>Description:</b> Spooky") : | |
2564 !g_ascii_strcasecmp(b->name, "seanegn") ? _("\n<b>Status</b>: Awesome") : | |
2565 !g_ascii_strcasecmp(b->name, "chipx86") ? _("\n<b>Status</b>: Rockin'") : ""); | |
5234 | 2566 |
2567 if(warning) | |
2568 g_free(warning); | |
7950 | 2569 if(loggedin) |
2570 g_free(loggedin); | |
5234 | 2571 if(idletime) |
2572 g_free(idletime); | |
2573 if(statustext) | |
2574 g_free(statustext); | |
2575 if(nicktext) | |
2576 g_free(nicktext); | |
2577 if(aliastext) | |
2578 g_free(aliastext); | |
5274 | 2579 if(accounttext) |
2580 g_free(accounttext); | |
5234 | 2581 } |
8824 | 2582 gaim_signal_emit(gaim_gtk_blist_get_handle(), |
8817 | 2583 "drawing-tooltip", node, &text); |
5228 | 2584 return text; |
2585 } | |
2586 | |
7620 | 2587 struct _emblem_data { |
9954 | 2588 const char *filename; |
7620 | 2589 int x; |
2590 int y; | |
2591 }; | |
2592 | |
9944 | 2593 GdkPixbuf * |
2594 gaim_gtk_blist_get_status_icon(GaimBlistNode *node, GaimStatusIconSize size) | |
5228 | 2595 { |
7620 | 2596 GdkPixbuf *scale, *status = NULL; |
2597 int i, scalesize = 30; | |
2598 char *filename; | |
5228 | 2599 const char *protoname = NULL; |
7620 | 2600 struct _gaim_gtk_blist_node *gtknode = node->ui_data; |
2601 struct _emblem_data emblems[4] = {{NULL, 15, 15}, {NULL, 0, 15}, | |
2602 {NULL, 0, 0}, {NULL, 15, 0}}; | |
9944 | 2603 GaimPresence *presence = NULL; |
7620 | 2604 GaimBuddy *buddy = NULL; |
2605 GaimChat *chat = NULL; | |
2606 | |
2607 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
2608 if(!gtknode->contact_expanded) | |
2609 buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
2610 } else if(GAIM_BLIST_NODE_IS_BUDDY(node)) { | |
2611 buddy = (GaimBuddy*)node; | |
2612 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { | |
2613 chat = (GaimChat*)node; | |
2614 } else { | |
5228 | 2615 return NULL; |
5234 | 2616 } |
2617 | |
7620 | 2618 if(buddy || chat) { |
2619 GaimAccount *account; | |
2620 GaimPlugin *prpl; | |
2621 GaimPluginProtocolInfo *prpl_info; | |
2622 | |
2623 if(buddy) | |
2624 account = buddy->account; | |
2625 else | |
2626 account = chat->account; | |
2627 | |
7956 | 2628 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
7620 | 2629 if(!prpl) |
2630 return NULL; | |
2631 | |
2632 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
2633 | |
2634 if(prpl_info && prpl_info->list_icon) { | |
2635 protoname = prpl_info->list_icon(account, buddy); | |
2636 } | |
2637 if(prpl_info && prpl_info->list_emblems && buddy) { | |
2638 if(buddy->present != GAIM_BUDDY_SIGNING_OFF) | |
2639 prpl_info->list_emblems(buddy, &emblems[0].filename, | |
2640 &emblems[1].filename, &emblems[2].filename, | |
2641 &emblems[3].filename); | |
2642 } | |
5234 | 2643 } |
5228 | 2644 |
7620 | 2645 if(size == GAIM_STATUS_ICON_SMALL) { |
5228 | 2646 scalesize = 15; |
7620 | 2647 /* So that only the se icon will composite */ |
2648 emblems[1].filename = emblems[2].filename = emblems[3].filename = NULL; | |
5228 | 2649 } |
2650 | |
7620 | 2651 if(buddy && buddy->present == GAIM_BUDDY_SIGNING_ON) { |
2652 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); | |
2653 } else if(buddy && buddy->present == GAIM_BUDDY_SIGNING_OFF) { | |
2654 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "logout.png", NULL); | |
2655 } else if(buddy || chat) { | |
5228 | 2656 char *image = g_strdup_printf("%s.png", protoname); |
2657 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
2658 g_free(image); | |
7620 | 2659 } else { |
2660 /* gaim dude */ | |
2661 filename = g_build_filename(DATADIR, "pixmaps", "gaim.png", NULL); | |
5228 | 2662 } |
7620 | 2663 |
2664 status = gdk_pixbuf_new_from_file(filename, NULL); | |
2665 g_free(filename); | |
2666 | |
2667 if(!status) | |
2668 return NULL; | |
2669 | |
2670 scale = gdk_pixbuf_scale_simple(status, scalesize, scalesize, | |
2671 GDK_INTERP_BILINEAR); | |
2672 g_object_unref(status); | |
2673 | |
2674 for(i=0; i<4; i++) { | |
2675 if(emblems[i].filename) { | |
2676 GdkPixbuf *emblem; | |
2677 char *image = g_strdup_printf("%s.png", emblems[i].filename); | |
2678 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", image, NULL); | |
2679 g_free(image); | |
2680 emblem = gdk_pixbuf_new_from_file(filename, NULL); | |
2681 g_free(filename); | |
2682 if(emblem) { | |
2683 if(i == 0 && size == GAIM_STATUS_ICON_SMALL) { | |
2684 gdk_pixbuf_composite(emblem, | |
2685 scale, 5, 5, | |
2686 10, 10, | |
2687 5, 5, | |
2688 .6, .6, | |
2689 GDK_INTERP_BILINEAR, | |
2690 255); | |
2691 } else { | |
2692 gdk_pixbuf_composite(emblem, | |
2693 scale, emblems[i].x, emblems[i].y, | |
2694 15, 15, | |
2695 emblems[i].x, emblems[i].y, | |
2696 1, 1, | |
2697 GDK_INTERP_BILINEAR, | |
2698 255); | |
2699 } | |
2700 g_object_unref(emblem); | |
2701 } | |
5228 | 2702 } |
2703 } | |
7620 | 2704 |
2705 if(buddy) { | |
9944 | 2706 presence = gaim_buddy_get_presence(buddy); |
2707 | |
2708 if (!GAIM_BUDDY_IS_ONLINE(buddy)) | |
7620 | 2709 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE); |
10118 | 2710 else if (gaim_presence_is_idle(presence)) |
9944 | 2711 { |
7620 | 2712 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.25, FALSE); |
9944 | 2713 } |
5228 | 2714 } |
7620 | 2715 |
5228 | 2716 return scale; |
2717 } | |
2718 | |
7620 | 2719 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(GaimBuddy *b) |
5228 | 2720 { |
2721 GdkPixbuf *buf, *ret; | |
9324 | 2722 GdkPixbufLoader *loader; |
2723 GaimBuddyIcon *icon; | |
2724 const char *data; | |
2725 size_t len; | |
5228 | 2726 |
7620 | 2727 if (!gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) |
5228 | 2728 return NULL; |
2729 | |
9396 | 2730 if (!(icon = gaim_buddy_get_icon(b))) |
2731 if (!(icon = gaim_buddy_icons_find(b->account, b->name))) /* Not sure I like this...*/ | |
9324 | 2732 return NULL; |
2733 | |
2734 | |
2735 loader = gdk_pixbuf_loader_new(); | |
2736 data = gaim_buddy_icon_get_data(icon, &len); | |
2737 gdk_pixbuf_loader_write(loader, data, len, NULL); | |
2738 buf = gdk_pixbuf_loader_get_pixbuf(loader); | |
9337 | 2739 if (buf) |
2740 g_object_ref(G_OBJECT(buf)); | |
9324 | 2741 gdk_pixbuf_loader_close(loader, NULL); |
9337 | 2742 g_object_unref(G_OBJECT(loader)); |
5228 | 2743 |
9944 | 2744 if (buf) |
2745 { | |
2746 GaimPresence *presence = gaim_buddy_get_presence(b); | |
2747 | |
5228 | 2748 if (!GAIM_BUDDY_IS_ONLINE(b)) |
2749 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.0, FALSE); | |
9944 | 2750 |
10118 | 2751 if (gaim_presence_is_idle(presence)) |
9944 | 2752 { |
5228 | 2753 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.25, FALSE); |
9944 | 2754 } |
5228 | 2755 |
2756 ret = gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR); | |
2757 g_object_unref(G_OBJECT(buf)); | |
2758 return ret; | |
2759 } | |
2760 return NULL; | |
2761 } | |
2762 | |
7620 | 2763 static gchar *gaim_gtk_blist_get_name_markup(GaimBuddy *b, gboolean selected) |
5228 | 2764 { |
7620 | 2765 const char *name; |
2766 char *esc, *text = NULL; | |
5228 | 2767 GaimPlugin *prpl; |
2768 GaimPluginProtocolInfo *prpl_info = NULL; | |
7620 | 2769 GaimContact *contact; |
9944 | 2770 GaimPresence *presence; |
7620 | 2771 struct _gaim_gtk_blist_node *gtkcontactnode = NULL; |
5228 | 2772 char *idletime = NULL, *warning = NULL, *statustext = NULL; |
9944 | 2773 unsigned int warning_level; |
5228 | 2774 time_t t; |
7620 | 2775 /* XXX Clean up this crap */ |
2776 | |
2777 contact = (GaimContact*)((GaimBlistNode*)b)->parent; | |
2778 if(contact) | |
2779 gtkcontactnode = ((GaimBlistNode*)contact)->ui_data; | |
2780 | |
2781 if(gtkcontactnode && !gtkcontactnode->contact_expanded && contact->alias) | |
2782 name = contact->alias; | |
2783 else | |
9620 | 2784 name = gaim_buddy_get_alias(b); |
7620 | 2785 esc = g_markup_escape_text(name, strlen(name)); |
2786 | |
7956 | 2787 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); |
5228 | 2788 |
2789 if (prpl != NULL) | |
2790 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
2791 | |
9944 | 2792 presence = gaim_buddy_get_presence(b); |
2793 | |
7620 | 2794 if (!gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) { |
9944 | 2795 |
10118 | 2796 if ((gaim_presence_is_idle(presence) || !GAIM_BUDDY_IS_ONLINE(b)) && !selected) |
9944 | 2797 { |
10118 | 2798 text = g_strdup_printf("<span color='%s'>%s</span>", |
2799 dim_grey(), esc); | |
5228 | 2800 g_free(esc); |
2801 return text; | |
7620 | 2802 } |
9944 | 2803 else |
5228 | 2804 return esc; |
2805 } | |
2806 | |
8122
36674144c510
[gaim-migrate @ 8826]
Christian Hammond <chipx86@chipx86.com>
parents:
8113
diff
changeset
|
2807 if (prpl_info && prpl_info->status_text && b->account->gc) { |
5228 | 2808 char *tmp = prpl_info->status_text(b); |
2809 const char *end; | |
2810 | |
2811 if(tmp && !g_utf8_validate(tmp, -1, &end)) { | |
2812 char *new = g_strndup(tmp, | |
2813 g_utf8_pointer_to_offset(tmp, end)); | |
2814 g_free(tmp); | |
2815 tmp = new; | |
2816 } | |
2817 | |
2818 if(tmp) { | |
2819 char buf[32]; | |
2820 char *c = tmp; | |
2821 int length = 0, vis=0; | |
2822 gboolean inside = FALSE; | |
2823 g_strdelimit(tmp, "\n", ' '); | |
7620 | 2824 gaim_str_strip_cr(tmp); |
5228 | 2825 |
2826 while(*c && vis < 20) { | |
2827 if(*c == '&') | |
2828 inside = TRUE; | |
2829 else if(*c == ';') | |
2830 inside = FALSE; | |
2831 if(!inside) | |
2832 vis++; | |
7620 | 2833 c = g_utf8_next_char(c); /* this is fun */ |
5228 | 2834 } |
2835 | |
7620 | 2836 length = c - tmp; |
2837 | |
5228 | 2838 if(vis == 20) |
2839 g_snprintf(buf, sizeof(buf), "%%.%ds...", length); | |
2840 else | |
2841 g_snprintf(buf, sizeof(buf), "%%s "); | |
2842 | |
2843 statustext = g_strdup_printf(buf, tmp); | |
2844 | |
2845 g_free(tmp); | |
2846 } | |
2847 } | |
2848 | |
9944 | 2849 if (gaim_presence_is_idle(presence) && |
2850 gaim_prefs_get_bool("/gaim/gtk/blist/show_idle_time")) | |
2851 { | |
2852 time_t idle_secs = gaim_presence_get_idle_time(presence); | |
2853 | |
2854 if (idle_secs > 0) | |
2855 { | |
2856 int ihrs, imin; | |
2857 | |
2858 time(&t); | |
2859 ihrs = (t - idle_secs) / 3600; | |
2860 imin = ((t - idle_secs) / 60) % 60; | |
2861 | |
2862 if (ihrs) | |
2863 idletime = g_strdup_printf(_("Idle (%dh%02dm) "), ihrs, imin); | |
2864 else | |
2865 idletime = g_strdup_printf(_("Idle (%dm) "), imin); | |
2866 } | |
5228 | 2867 else |
9944 | 2868 idletime = g_strdup(_("Idle ")); |
5228 | 2869 } |
2870 | |
9944 | 2871 warning_level = gaim_presence_get_warning_level(presence); |
2872 | |
2873 if (warning_level > 0 && | |
2874 gaim_prefs_get_bool("/gaim/gtk/blist/show_warning_level")) | |
2875 { | |
2876 warning = g_strdup_printf(_("Warned (%d%%) "), warning_level); | |
2877 } | |
5228 | 2878 |
2879 if(!GAIM_BUDDY_IS_ONLINE(b) && !statustext) | |
7620 | 2880 statustext = g_strdup(_("Offline ")); |
2881 | |
10118 | 2882 if (gaim_presence_is_idle(presence) && !selected) { |
2883 text = g_strdup_printf("<span color='%s'>%s</span>\n" | |
2884 "<span color='%s' size='smaller'>%s%s%s</span>", | |
2885 dim_grey(), esc, dim_grey(), | |
5228 | 2886 statustext != NULL ? statustext : "", |
2887 idletime != NULL ? idletime : "", | |
2888 warning != NULL ? warning : ""); | |
7620 | 2889 } else if (statustext == NULL && idletime == NULL && warning == NULL && |
2890 GAIM_BUDDY_IS_ONLINE(b)) { | |
5228 | 2891 text = g_strdup(esc); |
2892 } else { | |
10118 | 2893 if (selected) |
2894 text = g_strdup_printf("%s\n" | |
2895 "<span size='smaller'>%s%s%s</span>", esc, | |
2896 statustext != NULL ? statustext : "", | |
2897 idletime != NULL ? idletime : "", | |
2898 warning != NULL ? warning : ""); | |
2899 else | |
2900 text = g_strdup_printf("%s\n" | |
2901 "<span color='%s' size='smaller'>%s%s%s</span>", esc, | |
10144 | 2902 dim_grey(), |
10118 | 2903 statustext != NULL ? statustext : "", |
2904 idletime != NULL ? idletime : "", | |
2905 warning != NULL ? warning : ""); | |
5228 | 2906 } |
2907 if (idletime) | |
2908 g_free(idletime); | |
2909 if (warning) | |
2910 g_free(warning); | |
2911 if (statustext) | |
2912 g_free(statustext); | |
2913 if (esc) | |
2914 g_free(esc); | |
2915 | |
2916 return text; | |
2917 } | |
2918 | |
2919 static void gaim_gtk_blist_restore_position() | |
2920 { | |
7620 | 2921 int blist_x, blist_y, blist_width, blist_height; |
2922 | |
2923 blist_width = gaim_prefs_get_int("/gaim/gtk/blist/width"); | |
2924 | |
2925 /* if the window exists, is hidden, we're saving positions, and the | |
2926 * position is sane... */ | |
2927 if (gtkblist && gtkblist->window && | |
2928 !GTK_WIDGET_VISIBLE(gtkblist->window) && blist_width != 0) { | |
2929 | |
2930 blist_x = gaim_prefs_get_int("/gaim/gtk/blist/x"); | |
2931 blist_y = gaim_prefs_get_int("/gaim/gtk/blist/y"); | |
2932 blist_height = gaim_prefs_get_int("/gaim/gtk/blist/height"); | |
2933 | |
5228 | 2934 /* ...check position is on screen... */ |
7620 | 2935 if (blist_x >= gdk_screen_width()) |
2936 blist_x = gdk_screen_width() - 100; | |
2937 else if (blist_x + blist_width < 0) | |
2938 blist_x = 100; | |
2939 | |
2940 if (blist_y >= gdk_screen_height()) | |
2941 blist_y = gdk_screen_height() - 100; | |
2942 else if (blist_y + blist_height < 0) | |
2943 blist_y = 100; | |
2944 | |
5228 | 2945 /* ...and move it back. */ |
7620 | 2946 gtk_window_move(GTK_WINDOW(gtkblist->window), blist_x, blist_y); |
2947 gtk_window_resize(GTK_WINDOW(gtkblist->window), blist_width, blist_height); | |
5228 | 2948 } |
2949 } | |
2950 | |
7620 | 2951 static gboolean gaim_gtk_blist_refresh_timer(GaimBuddyList *list) |
5228 | 2952 { |
7620 | 2953 GaimBlistNode *gnode, *cnode; |
2954 | |
2955 for(gnode = list->root; gnode; gnode = gnode->next) { | |
2956 if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
5234 | 2957 continue; |
7620 | 2958 for(cnode = gnode->child; cnode; cnode = cnode->next) { |
2959 if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { | |
9944 | 2960 GaimBuddy *buddy; |
2961 | |
2962 buddy = gaim_contact_get_priority_buddy((GaimContact*)cnode); | |
10012 | 2963 |
2964 if (buddy && | |
2965 gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) | |
9944 | 2966 gaim_gtk_blist_update(list, cnode); |
7620 | 2967 } |
5228 | 2968 } |
2969 } | |
2970 | |
2971 /* keep on going */ | |
2972 return TRUE; | |
2973 } | |
2974 | |
7620 | 2975 static void gaim_gtk_blist_hide_node(GaimBuddyList *list, GaimBlistNode *node) |
5260 | 2976 { |
2977 struct _gaim_gtk_blist_node *gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
2978 GtkTreeIter iter; | |
2979 | |
2980 if (!gtknode || !gtknode->row || !gtkblist) | |
2981 return; | |
2982 | |
2983 if(gtkblist->selected_node == node) | |
2984 gtkblist->selected_node = NULL; | |
2985 | |
2986 if (get_iter_from_node(node, &iter)) { | |
2987 gtk_tree_store_remove(gtkblist->treemodel, &iter); | |
7620 | 2988 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node) |
2989 || GAIM_BLIST_NODE_IS_CHAT(node)) { | |
5260 | 2990 gaim_gtk_blist_update(list, node->parent); |
2991 } | |
2992 } | |
2993 gtk_tree_row_reference_free(gtknode->row); | |
2994 gtknode->row = NULL; | |
2995 } | |
2996 | |
7620 | 2997 static void |
8937 | 2998 sign_on_off_cb(GaimConnection *gc, GaimBuddyList *blist) |
7620 | 2999 { |
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3000 GaimGtkBuddyList *gtkblist = GAIM_GTK_BLIST(blist); |
8937 | 3001 GtkWidget *widget; |
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3002 |
7620 | 3003 gaim_gtk_blist_update_protocol_actions(); |
8235 | 3004 gaim_gtkpounce_menu_build(gtkblist->bpmenu); |
8937 | 3005 |
8940 | 3006 /* Make menu items sensitive/insensitive where appropriate */ |
3007 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Buddies/Join a Chat...")); | |
3008 gtk_widget_set_sensitive(widget, gaim_gtk_blist_joinchat_is_showable()); | |
3009 | |
8937 | 3010 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Room List")); |
8939 | 3011 gtk_widget_set_sensitive(widget, gaim_gtk_roomlist_is_showable()); |
8938 | 3012 |
3013 widget = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Privacy")); | |
3014 gtk_widget_set_sensitive(widget, gaim_gtk_privacy_is_showable()); | |
7620 | 3015 } |
3016 | |
8986 | 3017 |
3018 static void | |
3019 plugin_changed_cb(GaimPlugin *p, gpointer *data) | |
3020 { | |
3021 gaim_gtk_blist_update_plugin_actions(); | |
3022 } | |
3023 | |
5228 | 3024 /********************************************************************************** |
3025 * Public API Functions * | |
3026 **********************************************************************************/ | |
9774 | 3027 |
7620 | 3028 static void gaim_gtk_blist_new_list(GaimBuddyList *blist) |
5228 | 3029 { |
7620 | 3030 GaimGtkBuddyList *gtkblist; |
3031 | |
3032 gtkblist = g_new0(GaimGtkBuddyList, 1); | |
3033 blist->ui_data = gtkblist; | |
5228 | 3034 } |
3035 | |
5256 | 3036 static void gaim_gtk_blist_new_node(GaimBlistNode *node) |
3037 { | |
3038 node->ui_data = g_new0(struct _gaim_gtk_blist_node, 1); | |
3039 } | |
3040 | |
5228 | 3041 void gaim_gtk_blist_update_columns() |
3042 { | |
3043 if(!gtkblist) | |
3044 return; | |
3045 | |
7620 | 3046 if (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) { |
5228 | 3047 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, TRUE); |
3048 gtk_tree_view_column_set_visible(gtkblist->idle_column, FALSE); | |
3049 gtk_tree_view_column_set_visible(gtkblist->warning_column, FALSE); | |
3050 } else { | |
7620 | 3051 gtk_tree_view_column_set_visible(gtkblist->idle_column, |
3052 gaim_prefs_get_bool("/gaim/gtk/blist/show_idle_time")); | |
3053 gtk_tree_view_column_set_visible(gtkblist->warning_column, | |
3054 gaim_prefs_get_bool("/gaim/gtk/blist/show_warning_level")); | |
5228 | 3055 gtk_tree_view_column_set_visible(gtkblist->buddy_icon_column, FALSE); |
3056 } | |
3057 } | |
3058 | |
9525 | 3059 enum {DRAG_BUDDY, DRAG_ROW, DRAG_VCARD, DRAG_TEXT, DRAG_URI,NUM_TARGETS}; |
5228 | 3060 |
3061 static char * | |
3062 item_factory_translate_func (const char *path, gpointer func_data) | |
3063 { | |
7620 | 3064 return _((char *)path); |
5228 | 3065 } |
3066 | |
5422 | 3067 void gaim_gtk_blist_setup_sort_methods() |
3068 { | |
7620 | 3069 gaim_gtk_blist_sort_method_reg("none", _("None"), sort_method_none); |
3070 #if GTK_CHECK_VERSION(2,2,1) | |
3071 gaim_gtk_blist_sort_method_reg("alphabetical", _("Alphabetical"), sort_method_alphabetical); | |
3072 gaim_gtk_blist_sort_method_reg("status", _("By status"), sort_method_status); | |
3073 gaim_gtk_blist_sort_method_reg("log_size", _("By log size"), sort_method_log); | |
3074 #endif | |
3075 gaim_gtk_blist_sort_method_set(gaim_prefs_get_string("/gaim/gtk/blist/sort_type")); | |
3076 } | |
3077 | |
3078 static void _prefs_change_redo_list() { | |
3079 redo_buddy_list(gaim_get_blist(), TRUE); | |
3080 } | |
3081 | |
3082 static void _prefs_change_sort_method(const char *pref_name, GaimPrefType type, | |
3083 gpointer val, gpointer data) { | |
3084 if(!strcmp(pref_name, "/gaim/gtk/blist/sort_type")) | |
3085 gaim_gtk_blist_sort_method_set(val); | |
3086 } | |
3087 | |
3088 static void gaim_gtk_blist_show(GaimBuddyList *list) | |
5228 | 3089 { |
10087 | 3090 void *handle; |
5228 | 3091 GtkCellRenderer *rend; |
3092 GtkTreeViewColumn *column; | |
3093 GtkWidget *sw; | |
3094 GtkAccelGroup *accel_group; | |
3095 GtkTreeSelection *selection; | |
9556 | 3096 GtkTargetEntry dte[] = {{"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW}, |
8089 | 3097 {"application/x-im-contact", 0, DRAG_BUDDY}, |
9495 | 3098 {"text/x-vcard", 0, DRAG_VCARD }, |
9525 | 3099 {"text/uri-list", 0, DRAG_URI}, |
3100 {"text/plain", 0, DRAG_TEXT}}; | |
9556 | 3101 GtkTargetEntry ste[] = {{"GAIM_BLIST_NODE", GTK_TARGET_SAME_APP, DRAG_ROW}, |
3102 {"application/x-im-contact", 0, DRAG_BUDDY}, | |
3103 {"text/x-vcard", 0, DRAG_VCARD }}; | |
5228 | 3104 if (gtkblist && gtkblist->window) { |
3105 gtk_widget_show(gtkblist->window); | |
3106 return; | |
3107 } | |
3108 | |
3109 gtkblist = GAIM_GTK_BLIST(list); | |
3110 | |
3111 gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
3112 gtk_window_set_role(GTK_WINDOW(gtkblist->window), "buddy_list"); | |
9746 | 3113 gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List")); |
5228 | 3114 |
3115 gtkblist->vbox = gtk_vbox_new(FALSE, 0); | |
3116 gtk_container_add(GTK_CONTAINER(gtkblist->window), gtkblist->vbox); | |
3117 | |
3118 g_signal_connect(G_OBJECT(gtkblist->window), "delete_event", G_CALLBACK(gtk_blist_delete_cb), NULL); | |
3119 g_signal_connect(G_OBJECT(gtkblist->window), "configure_event", G_CALLBACK(gtk_blist_configure_cb), NULL); | |
3120 g_signal_connect(G_OBJECT(gtkblist->window), "visibility_notify_event", G_CALLBACK(gtk_blist_visibility_cb), NULL); | |
3121 gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK); | |
3122 | |
3123 /******************************* Menu bar *************************************/ | |
3124 accel_group = gtk_accel_group_new(); | |
3125 gtk_window_add_accel_group(GTK_WINDOW (gtkblist->window), accel_group); | |
3126 g_object_unref(accel_group); | |
5427 | 3127 gtkblist->ift = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<GaimMain>", accel_group); |
9811 | 3128 gtk_item_factory_set_translate_func(gtkblist->ift, |
3129 item_factory_translate_func, | |
3130 NULL, NULL); | |
5427 | 3131 gtk_item_factory_create_items(gtkblist->ift, sizeof(blist_menu) / sizeof(*blist_menu), |
9811 | 3132 blist_menu, NULL); |
7620 | 3133 gaim_gtk_load_accels(); |
3134 g_signal_connect(G_OBJECT(accel_group), "accel-changed", | |
3135 G_CALLBACK(gaim_gtk_save_accels_cb), NULL); | |
5427 | 3136 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtk_item_factory_get_widget(gtkblist->ift, "<GaimMain>"), FALSE, FALSE, 0); |
5228 | 3137 |
5427 | 3138 awaymenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Away")); |
9944 | 3139 |
3140 /* FIXME: Status */ | |
3141 #if 0 | |
5228 | 3142 do_away_menu(); |
9944 | 3143 #endif |
5228 | 3144 |
5427 | 3145 gtkblist->bpmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Buddy Pounce")); |
5228 | 3146 gaim_gtkpounce_menu_build(gtkblist->bpmenu); |
3147 | |
8844 | 3148 protomenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Account Actions")); |
7620 | 3149 gaim_gtk_blist_update_protocol_actions(); |
8986 | 3150 |
3151 pluginmenu = gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Plugin Actions")); | |
3152 gaim_gtk_blist_update_plugin_actions(); | |
5228 | 3153 /****************************** GtkTreeView **********************************/ |
3154 sw = gtk_scrolled_window_new(NULL,NULL); | |
3155 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); | |
3156 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
3157 | |
7620 | 3158 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, |
3159 GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, G_TYPE_STRING, | |
3160 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER); | |
5228 | 3161 |
3162 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel)); | |
9176 | 3163 gtk_widget_set_name(gtkblist->treeview, "gaim_gtkblist_treeview"); |
5228 | 3164 |
3165 /* Set up selection stuff */ | |
3166 | |
3167 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); | |
3168 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(gaim_gtk_blist_selection_changed), NULL); | |
3169 | |
3170 | |
3171 /* Set up dnd */ | |
7650 | 3172 gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(gtkblist->treeview), |
9811 | 3173 GDK_BUTTON1_MASK, ste, 3, |
3174 GDK_ACTION_COPY); | |
7650 | 3175 gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(gtkblist->treeview), |
9811 | 3176 dte, 5, |
3177 GDK_ACTION_COPY | GDK_ACTION_MOVE); | |
7636 | 3178 |
10087 | 3179 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-received", G_CALLBACK(gaim_gtk_blist_drag_data_rcv_cb), NULL); |
5228 | 3180 g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-get", G_CALLBACK(gaim_gtk_blist_drag_data_get_cb), NULL); |
3181 | |
3182 /* Tooltips */ | |
3183 g_signal_connect(G_OBJECT(gtkblist->treeview), "motion-notify-event", G_CALLBACK(gaim_gtk_blist_motion_cb), NULL); | |
3184 g_signal_connect(G_OBJECT(gtkblist->treeview), "leave-notify-event", G_CALLBACK(gaim_gtk_blist_leave_cb), NULL); | |
3185 | |
3186 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gtkblist->treeview), FALSE); | |
3187 | |
3188 column = gtk_tree_view_column_new (); | |
3189 | |
3190 rend = gtk_cell_renderer_pixbuf_new(); | |
9811 | 3191 gtk_tree_view_column_pack_start(column, rend, FALSE); |
3192 gtk_tree_view_column_set_attributes(column, rend, | |
3193 "pixbuf", STATUS_ICON_COLUMN, | |
3194 "visible", STATUS_ICON_VISIBLE_COLUMN, | |
3195 NULL); | |
5228 | 3196 g_object_set(rend, "xalign", 0.0, "ypad", 0, NULL); |
3197 | |
3198 rend = gtk_cell_renderer_text_new(); | |
3199 gtk_tree_view_column_pack_start (column, rend, TRUE); | |
9811 | 3200 gtk_tree_view_column_set_attributes(column, rend, |
3201 "markup", NAME_COLUMN, | |
3202 NULL); | |
5228 | 3203 g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL); |
3204 | |
3205 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), column); | |
3206 | |
3207 rend = gtk_cell_renderer_text_new(); | |
3208 gtkblist->warning_column = gtk_tree_view_column_new_with_attributes("Warning", rend, "markup", WARNING_COLUMN, NULL); | |
3209 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->warning_column); | |
3210 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); | |
3211 | |
3212 rend = gtk_cell_renderer_text_new(); | |
3213 gtkblist->idle_column = gtk_tree_view_column_new_with_attributes("Idle", rend, "markup", IDLE_COLUMN, NULL); | |
3214 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->idle_column); | |
3215 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); | |
3216 | |
3217 rend = gtk_cell_renderer_pixbuf_new(); | |
3218 gtkblist->buddy_icon_column = gtk_tree_view_column_new_with_attributes("Buddy Icon", rend, "pixbuf", BUDDY_ICON_COLUMN, NULL); | |
3219 g_object_set(rend, "xalign", 1.0, "ypad", 0, NULL); | |
3220 gtk_tree_view_append_column(GTK_TREE_VIEW(gtkblist->treeview), gtkblist->buddy_icon_column); | |
3221 | |
3222 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-activated", G_CALLBACK(gtk_blist_row_activated_cb), NULL); | |
3223 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-expanded", G_CALLBACK(gtk_blist_row_expanded_cb), NULL); | |
3224 g_signal_connect(G_OBJECT(gtkblist->treeview), "row-collapsed", G_CALLBACK(gtk_blist_row_collapsed_cb), NULL); | |
3225 g_signal_connect(G_OBJECT(gtkblist->treeview), "button-press-event", G_CALLBACK(gtk_blist_button_press_cb), NULL); | |
7620 | 3226 g_signal_connect(G_OBJECT(gtkblist->treeview), "key-press-event", G_CALLBACK(gtk_blist_key_press_cb), NULL); |
8143 | 3227 g_signal_connect(G_OBJECT(gtkblist->treeview), "popup-menu", G_CALLBACK(gaim_gtk_blist_popup_menu_cb), NULL); |
5228 | 3228 |
5419 | 3229 /* Enable CTRL+F searching */ |
3230 gtk_tree_view_set_search_column(GTK_TREE_VIEW(gtkblist->treeview), NAME_COLUMN); | |
3231 | |
5228 | 3232 gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sw, TRUE, TRUE, 0); |
3233 gtk_container_add(GTK_CONTAINER(sw), gtkblist->treeview); | |
3234 gaim_gtk_blist_update_columns(); | |
3235 | |
3236 /* set the Show Offline Buddies option. must be done | |
3237 * after the treeview or faceprint gets mad. -Robot101 | |
3238 */ | |
5427 | 3239 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show Offline Buddies"))), |
7620 | 3240 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")); |
5427 | 3241 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show Empty Groups"))), |
7620 | 3242 gaim_prefs_get_bool("/gaim/gtk/blist/show_empty_groups")); |
10074 | 3243 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds"))), |
3244 gaim_prefs_get_bool("/gaim/gtk/sound/mute")); | |
3245 if(!strcmp(gaim_prefs_get_string("/gaim/gtk/sound/method"), "none")) | |
3246 gtk_widget_set_sensitive(gtk_item_factory_get_widget(gtkblist->ift, N_("/Tools/Mute Sounds")), FALSE); | |
5228 | 3247 |
3248 /* OK... let's show this bad boy. */ | |
3249 gaim_gtk_blist_refresh(list); | |
3250 gaim_gtk_blist_restore_position(); | |
3251 gtk_widget_show_all(gtkblist->window); | |
3252 | |
3253 /* start the refresh timer */ | |
7620 | 3254 if (gaim_prefs_get_bool("/gaim/gtk/blist/show_idle_time") || |
3255 gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) { | |
3256 | |
3257 gtkblist->refresh_timer = g_timeout_add(30000, | |
3258 (GSourceFunc)gaim_gtk_blist_refresh_timer, list); | |
3259 } | |
3260 | |
10087 | 3261 handle = gaim_gtk_blist_get_handle(); |
3262 | |
7620 | 3263 /* things that affect how buddies are displayed */ |
10087 | 3264 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_buddy_icons", |
3265 _prefs_change_redo_list, NULL); | |
3266 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_warning_level", | |
3267 _prefs_change_redo_list, NULL); | |
3268 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_idle_time", | |
3269 _prefs_change_redo_list, NULL); | |
3270 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_empty_groups", | |
3271 _prefs_change_redo_list, NULL); | |
3272 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_offline_buddies", | |
3273 _prefs_change_redo_list, NULL); | |
7620 | 3274 |
3275 /* sorting */ | |
10087 | 3276 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/sort_type", |
3277 _prefs_change_sort_method, NULL); | |
7620 | 3278 |
3279 /* things that affect what columns are displayed */ | |
10087 | 3280 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_buddy_icons", |
3281 gaim_gtk_blist_update_columns, NULL); | |
3282 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_idle_time", | |
3283 gaim_gtk_blist_update_columns, NULL); | |
3284 gaim_prefs_connect_callback(handle, "/gaim/gtk/blist/show_warning_level", | |
3285 gaim_gtk_blist_update_columns, NULL); | |
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3286 |
10074 | 3287 /* menus */ |
10087 | 3288 gaim_prefs_connect_callback(handle, "/gaim/gtk/sound/mute", |
3289 gaim_gtk_blist_mute_pref_cb, NULL); | |
3290 gaim_prefs_connect_callback(handle, "/gaim/gtk/sound/method", | |
3291 gaim_gtk_blist_sound_method_pref_cb, NULL); | |
10074 | 3292 |
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3293 /* Setup some gaim signal handlers. */ |
8937 | 3294 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", |
3295 gtkblist, GAIM_CALLBACK(sign_on_off_cb), list); | |
3296 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", | |
3297 gtkblist, GAIM_CALLBACK(sign_on_off_cb), list); | |
8815 | 3298 |
8986 | 3299 gaim_signal_connect(gaim_plugins_get_handle(), "plugin-load", |
3300 gtkblist, GAIM_CALLBACK(plugin_changed_cb), NULL); | |
3301 gaim_signal_connect(gaim_plugins_get_handle(), "plugin-unload", | |
3302 gtkblist, GAIM_CALLBACK(plugin_changed_cb), NULL); | |
3303 | |
8815 | 3304 /* emit our created signal */ |
10087 | 3305 gaim_signal_emit(handle, "gtkblist-created", list); |
5228 | 3306 } |
3307 | |
7620 | 3308 /* XXX: does this need fixing? */ |
3309 static void redo_buddy_list(GaimBuddyList *list, gboolean remove) | |
5228 | 3310 { |
7620 | 3311 GaimBlistNode *gnode, *cnode, *bnode; |
3312 | |
3313 for(gnode = list->root; gnode; gnode = gnode->next) { | |
3314 if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
5234 | 3315 continue; |
7620 | 3316 for(cnode = gnode->child; cnode; cnode = cnode->next) { |
3317 if(GAIM_BLIST_NODE_IS_CONTACT(cnode)) { | |
3318 if(remove) | |
3319 gaim_gtk_blist_hide_node(list, cnode); | |
3320 | |
3321 for(bnode = cnode->child; bnode; bnode = bnode->next) { | |
3322 if(!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
3323 continue; | |
3324 if(remove) | |
3325 gaim_gtk_blist_hide_node(list, bnode); | |
3326 gaim_gtk_blist_update(list, bnode); | |
3327 } | |
3328 | |
3329 gaim_gtk_blist_update(list, cnode); | |
3330 } else if(GAIM_BLIST_NODE_IS_CHAT(cnode)) { | |
3331 if(remove) | |
3332 gaim_gtk_blist_hide_node(list, cnode); | |
3333 | |
3334 gaim_gtk_blist_update(list, cnode); | |
3335 } | |
5228 | 3336 } |
7620 | 3337 gaim_gtk_blist_update(list, gnode); |
5228 | 3338 } |
3339 } | |
3340 | |
7620 | 3341 void gaim_gtk_blist_refresh(GaimBuddyList *list) |
5422 | 3342 { |
3343 redo_buddy_list(list, FALSE); | |
3344 } | |
3345 | |
5297 | 3346 void |
3347 gaim_gtk_blist_update_refresh_timeout() | |
3348 { | |
7620 | 3349 GaimBuddyList *blist; |
3350 GaimGtkBuddyList *gtkblist; | |
5297 | 3351 |
3352 blist = gaim_get_blist(); | |
3353 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); | |
3354 | |
7620 | 3355 if (gaim_prefs_get_bool("/gaim/gtk/blist/show_idle_time") || |
3356 gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) { | |
3357 | |
3358 gtkblist->refresh_timer = g_timeout_add(30000, | |
3359 (GSourceFunc)gaim_gtk_blist_refresh_timer, blist); | |
5297 | 3360 } else { |
3361 g_source_remove(gtkblist->refresh_timer); | |
3362 gtkblist->refresh_timer = 0; | |
3363 } | |
3364 } | |
3365 | |
5256 | 3366 static gboolean get_iter_from_node(GaimBlistNode *node, GtkTreeIter *iter) { |
3367 struct _gaim_gtk_blist_node *gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
3368 GtkTreePath *path; | |
5228 | 3369 |
7620 | 3370 /* XXX: why do we assume we have a buddy here? */ |
5263 | 3371 if (!gtknode) { |
7620 | 3372 #if 0 |
10006 | 3373 gaim_debug_error("gtkblist", "buddy %s has no ui_data\n", ((GaimBuddy *)node)->name); |
7620 | 3374 #endif |
5263 | 3375 return FALSE; |
3376 } | |
3377 | |
3378 if (!gtkblist) { | |
10006 | 3379 gaim_debug_error("gtkblist", "get_iter_from_node was called, but we don't seem to have a blist\n"); |
5263 | 3380 return FALSE; |
3381 } | |
3382 | |
3383 if (!gtknode->row) | |
5228 | 3384 return FALSE; |
3385 | |
5256 | 3386 if ((path = gtk_tree_row_reference_get_path(gtknode->row)) == NULL) |
5228 | 3387 return FALSE; |
5256 | 3388 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), iter, path)) { |
3389 gtk_tree_path_free(path); | |
3390 return FALSE; | |
3391 } | |
3392 gtk_tree_path_free(path); | |
3393 return TRUE; | |
5228 | 3394 } |
3395 | |
7620 | 3396 static void gaim_gtk_blist_remove(GaimBuddyList *list, GaimBlistNode *node) |
5228 | 3397 { |
5260 | 3398 gaim_gtk_blist_hide_node(list, node); |
5228 | 3399 |
7620 | 3400 if(node->parent) |
3401 gaim_gtk_blist_update(list, node->parent); | |
3402 | |
5263 | 3403 /* There's something I don't understand here */ |
3404 /* g_free(node->ui_data); | |
3405 node->ui_data = NULL; */ | |
5228 | 3406 } |
3407 | |
3408 static gboolean do_selection_changed(GaimBlistNode *new_selection) | |
3409 { | |
5254 | 3410 GaimBlistNode *old_selection = NULL; |
5228 | 3411 |
5254 | 3412 /* test for gtkblist because crazy timeout means we can be called after the blist is gone */ |
3413 if (gtkblist && new_selection != gtkblist->selected_node) { | |
3414 old_selection = gtkblist->selected_node; | |
5228 | 3415 gtkblist->selected_node = new_selection; |
3416 if(new_selection) | |
3417 gaim_gtk_blist_update(NULL, new_selection); | |
3418 if(old_selection) | |
3419 gaim_gtk_blist_update(NULL, old_selection); | |
3420 } | |
3421 | |
3422 return FALSE; | |
3423 } | |
3424 | |
3425 static void gaim_gtk_blist_selection_changed(GtkTreeSelection *selection, gpointer data) | |
3426 { | |
3427 GaimBlistNode *new_selection = NULL; | |
3428 GtkTreeIter iter; | |
3429 | |
3430 if(gtk_tree_selection_get_selected(selection, NULL, &iter)){ | |
3431 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, | |
3432 NODE_COLUMN, &new_selection, -1); | |
3433 } | |
5254 | 3434 |
5228 | 3435 /* we set this up as a timeout, otherwise the blist flickers */ |
3436 g_timeout_add(0, (GSourceFunc)do_selection_changed, new_selection); | |
3437 } | |
3438 | |
8252 | 3439 static gboolean insert_node(GaimBuddyList *list, GaimBlistNode *node, GtkTreeIter *iter) |
7620 | 3440 { |
3441 GtkTreeIter parent_iter, cur, *curptr = NULL; | |
3442 struct _gaim_gtk_blist_node *gtknode = node->ui_data; | |
5256 | 3443 GtkTreePath *newpath; |
7620 | 3444 |
3445 if(!gtknode || !iter) | |
8252 | 3446 return FALSE; |
7620 | 3447 |
3448 if(node->parent && !get_iter_from_node(node->parent, &parent_iter)) | |
8252 | 3449 return FALSE; |
7620 | 3450 |
3451 if(get_iter_from_node(node, &cur)) | |
3452 curptr = &cur; | |
3453 | |
3454 if(GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_CHAT(node)) { | |
3455 *iter = current_sort_method->func(node, list, parent_iter, curptr); | |
3456 } else { | |
3457 *iter = sort_method_none(node, list, parent_iter, curptr); | |
5228 | 3458 } |
3459 | |
7620 | 3460 gtk_tree_row_reference_free(gtknode->row); |
3461 newpath = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), | |
3462 iter); | |
3463 gtknode->row = | |
3464 gtk_tree_row_reference_new(GTK_TREE_MODEL(gtkblist->treemodel), | |
3465 newpath); | |
5256 | 3466 gtk_tree_path_free(newpath); |
3467 | |
5228 | 3468 gtk_tree_store_set(gtkblist->treemodel, iter, |
3469 NODE_COLUMN, node, | |
3470 -1); | |
7620 | 3471 |
3472 if(node->parent) { | |
3473 GtkTreePath *expand = NULL; | |
3474 struct _gaim_gtk_blist_node *gtkparentnode = node->parent->ui_data; | |
3475 | |
3476 if(GAIM_BLIST_NODE_IS_GROUP(node->parent)) { | |
7693 | 3477 if(!gaim_blist_node_get_bool(node->parent, "collapsed")) |
7620 | 3478 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &parent_iter); |
3479 } else if(GAIM_BLIST_NODE_IS_CONTACT(node->parent) && | |
3480 gtkparentnode->contact_expanded) { | |
3481 expand = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &parent_iter); | |
3482 } | |
3483 if(expand) { | |
7693 | 3484 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), expand, FALSE); |
7620 | 3485 gtk_tree_path_free(expand); |
3486 } | |
3487 } | |
3488 | |
8252 | 3489 return TRUE; |
5228 | 3490 } |
3491 | |
7620 | 3492 static void gaim_gtk_blist_update_group(GaimBuddyList *list, GaimBlistNode *node) |
3493 { | |
3494 GaimGroup *group; | |
8203 | 3495 int count; |
7620 | 3496 |
3497 g_return_if_fail(GAIM_BLIST_NODE_IS_GROUP(node)); | |
3498 | |
3499 group = (GaimGroup*)node; | |
3500 | |
8203 | 3501 if(gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) |
3502 count = gaim_blist_get_group_size(group, FALSE); | |
3503 else | |
3504 count = gaim_blist_get_group_online_count(group); | |
3505 if(gaim_prefs_get_bool("/gaim/gtk/blist/show_empty_groups") || count > 0) { | |
7620 | 3506 char *mark, *esc; |
3507 GtkTreeIter iter; | |
3508 | |
8252 | 3509 if(!insert_node(list, node, &iter)) |
3510 return; | |
7620 | 3511 |
3512 esc = g_markup_escape_text(group->name, -1); | |
8945 | 3513 mark = g_strdup_printf("<span weight='bold'>%s</span> (%d/%d)", |
3514 esc, gaim_blist_get_group_online_count(group), | |
3515 gaim_blist_get_group_size(group, FALSE)); | |
7620 | 3516 g_free(esc); |
3517 | |
3518 gtk_tree_store_set(gtkblist->treemodel, &iter, | |
3519 STATUS_ICON_COLUMN, NULL, | |
3520 STATUS_ICON_VISIBLE_COLUMN, FALSE, | |
3521 NAME_COLUMN, mark, | |
3522 NODE_COLUMN, node, | |
3523 -1); | |
3524 g_free(mark); | |
3525 } else { | |
3526 gaim_gtk_blist_hide_node(list, node); | |
3527 } | |
3528 } | |
3529 | |
3530 static void buddy_node(GaimBuddy *buddy, GtkTreeIter *iter, GaimBlistNode *node) | |
5228 | 3531 { |
9944 | 3532 GaimPresence *presence; |
7620 | 3533 GdkPixbuf *status, *avatar; |
3534 char *mark; | |
3535 char *warning = NULL, *idle = NULL; | |
9944 | 3536 unsigned int warning_level; |
7620 | 3537 gboolean selected = (gtkblist->selected_node == node); |
3538 | |
9944 | 3539 presence = gaim_buddy_get_presence(buddy); |
3540 | |
7620 | 3541 status = gaim_gtk_blist_get_status_icon((GaimBlistNode*)buddy, |
3542 (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons") | |
3543 ? GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL)); | |
3544 | |
3545 avatar = gaim_gtk_blist_get_buddy_icon(buddy); | |
3546 mark = gaim_gtk_blist_get_name_markup(buddy, selected); | |
3547 | |
9944 | 3548 if (gaim_presence_is_idle(presence)) |
3549 { | |
3550 time_t idle_secs = gaim_presence_get_idle_time(presence); | |
3551 | |
3552 if (idle_secs > 0) | |
3553 { | |
3554 time_t t; | |
3555 int ihrs, imin; | |
3556 time(&t); | |
3557 ihrs = (t - idle_secs) / 3600; | |
3558 imin = ((t - idle_secs) / 60) % 60; | |
3559 | |
3560 if (ihrs > 0) | |
3561 idle = g_strdup_printf("(%d:%02d)", ihrs, imin); | |
3562 else | |
3563 idle = g_strdup_printf("(%d)", imin); | |
3564 } | |
7620 | 3565 } |
3566 | |
9944 | 3567 warning_level = gaim_presence_get_warning_level(presence); |
3568 | |
3569 if (warning_level > 0) | |
3570 warning = g_strdup_printf("%d%%", warning_level); | |
7620 | 3571 |
10118 | 3572 if (gaim_presence_is_idle(presence)) |
9944 | 3573 { |
3574 if (warning && !selected) { | |
10118 | 3575 char *w2 = g_strdup_printf("<span color='%s'>%s</span>", |
3576 dim_grey(), warning); | |
7620 | 3577 g_free(warning); |
3578 warning = w2; | |
3579 } | |
3580 | |
9944 | 3581 if (idle && !selected) { |
10118 | 3582 char *i2 = g_strdup_printf("<span color='%s'>%s</span>", |
3583 dim_grey(), idle); | |
7620 | 3584 g_free(idle); |
3585 idle = i2; | |
5228 | 3586 } |
7620 | 3587 } |
3588 | |
3589 gtk_tree_store_set(gtkblist->treemodel, iter, | |
3590 STATUS_ICON_COLUMN, status, | |
3591 STATUS_ICON_VISIBLE_COLUMN, TRUE, | |
3592 NAME_COLUMN, mark, | |
3593 WARNING_COLUMN, warning, | |
3594 IDLE_COLUMN, idle, | |
3595 BUDDY_ICON_COLUMN, avatar, | |
3596 -1); | |
3597 | |
3598 g_free(mark); | |
3599 if(idle) | |
3600 g_free(idle); | |
3601 if(warning) | |
3602 g_free(warning); | |
3603 if(status) | |
3604 g_object_unref(status); | |
3605 if(avatar) | |
3606 g_object_unref(avatar); | |
3607 } | |
3608 | |
3609 static void gaim_gtk_blist_update_contact(GaimBuddyList *list, GaimBlistNode *node) | |
3610 { | |
3611 GaimContact *contact; | |
3612 GaimBuddy *buddy; | |
3613 struct _gaim_gtk_blist_node *gtknode; | |
3614 | |
3615 g_return_if_fail(GAIM_BLIST_NODE_IS_CONTACT(node)); | |
3616 | |
3617 /* First things first, update the group */ | |
3618 gaim_gtk_blist_update_group(list, node->parent); | |
3619 | |
3620 gtknode = (struct _gaim_gtk_blist_node *)node->ui_data; | |
3621 contact = (GaimContact*)node; | |
3622 buddy = gaim_contact_get_priority_buddy(contact); | |
3623 | |
10006 | 3624 if (buddy && (gaim_presence_is_online(buddy->presence) || |
3625 (gaim_account_is_connected(buddy->account) && | |
3626 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) || | |
3627 gaim_blist_node_get_bool(node, "show_offline"))) | |
3628 { | |
7620 | 3629 GtkTreeIter iter; |
3630 | |
8252 | 3631 if(!insert_node(list, node, &iter)) |
3632 return; | |
7620 | 3633 |
3634 if(gtknode->contact_expanded) { | |
3635 GdkPixbuf *status; | |
5228 | 3636 char *mark; |
3637 | |
7620 | 3638 status = gaim_gtk_blist_get_status_icon(node, |
3639 (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons") ? | |
3640 GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL)); | |
3641 | |
3642 mark = g_markup_escape_text(gaim_contact_get_alias(contact), -1); | |
3643 | |
5228 | 3644 gtk_tree_store_set(gtkblist->treemodel, &iter, |
7620 | 3645 STATUS_ICON_COLUMN, status, |
3646 STATUS_ICON_VISIBLE_COLUMN, TRUE, | |
5228 | 3647 NAME_COLUMN, mark, |
7620 | 3648 WARNING_COLUMN, NULL, |
3649 IDLE_COLUMN, NULL, | |
3650 BUDDY_ICON_COLUMN, NULL, | |
5228 | 3651 -1); |
3652 g_free(mark); | |
7620 | 3653 if(status) |
3654 g_object_unref(status); | |
3655 } else { | |
3656 buddy_node(buddy, &iter, node); | |
5228 | 3657 } |
7620 | 3658 } else { |
3659 gaim_gtk_blist_hide_node(list, node); | |
5228 | 3660 } |
7620 | 3661 } |
3662 | |
3663 static void gaim_gtk_blist_update_buddy(GaimBuddyList *list, GaimBlistNode *node) | |
3664 { | |
3665 GaimContact *contact; | |
3666 GaimBuddy *buddy; | |
3667 struct _gaim_gtk_blist_node *gtkparentnode; | |
3668 | |
3669 g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); | |
3670 | |
3671 buddy = (GaimBuddy*)node; | |
3672 contact = (GaimContact*)node->parent; | |
3673 gtkparentnode = (struct _gaim_gtk_blist_node *)node->parent->ui_data; | |
3674 | |
3675 /* First things first, update the contact */ | |
3676 gaim_gtk_blist_update_contact(list, node->parent); | |
3677 | |
10006 | 3678 if (gtkparentnode->contact_expanded && |
3679 (gaim_presence_is_online(buddy->presence) || | |
7620 | 3680 (gaim_account_is_connected(buddy->account) && |
10006 | 3681 gaim_prefs_get_bool("/gaim/gtk/blist/show_offline_buddies")) || |
3682 gaim_blist_node_get_bool(node->parent, "show_offline"))) | |
3683 { | |
7620 | 3684 GtkTreeIter iter; |
3685 | |
10006 | 3686 if (!insert_node(list, node, &iter)) |
8252 | 3687 return; |
3688 | |
7620 | 3689 buddy_node(buddy, &iter, node); |
3690 | |
3691 } else { | |
3692 gaim_gtk_blist_hide_node(list, node); | |
3693 } | |
3694 | |
3695 } | |
3696 | |
3697 static void gaim_gtk_blist_update_chat(GaimBuddyList *list, GaimBlistNode *node) | |
3698 { | |
3699 GaimChat *chat; | |
3700 | |
3701 g_return_if_fail(GAIM_BLIST_NODE_IS_CHAT(node)); | |
3702 | |
3703 /* First things first, update the group */ | |
3704 gaim_gtk_blist_update_group(list, node->parent); | |
3705 | |
3706 chat = (GaimChat*)node; | |
3707 | |
3708 if(gaim_account_is_connected(chat->account)) { | |
3709 GtkTreeIter iter; | |
5234 | 3710 GdkPixbuf *status; |
7620 | 3711 char *mark; |
3712 | |
8252 | 3713 if(!insert_node(list, node, &iter)) |
3714 return; | |
5234 | 3715 |
3716 status = gaim_gtk_blist_get_status_icon(node, | |
7620 | 3717 (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons") ? |
3718 GAIM_STATUS_ICON_LARGE : GAIM_STATUS_ICON_SMALL)); | |
3719 | |
3720 mark = g_markup_escape_text(gaim_chat_get_name(chat), -1); | |
5234 | 3721 |
3722 gtk_tree_store_set(gtkblist->treemodel, &iter, | |
7620 | 3723 STATUS_ICON_COLUMN, status, |
3724 STATUS_ICON_VISIBLE_COLUMN, TRUE, | |
3725 NAME_COLUMN, mark, | |
3726 -1); | |
5228 | 3727 |
3728 g_free(mark); | |
7620 | 3729 if(status) |
5228 | 3730 g_object_unref(status); |
7620 | 3731 } else { |
5260 | 3732 gaim_gtk_blist_hide_node(list, node); |
5228 | 3733 } |
7620 | 3734 } |
3735 | |
3736 static void gaim_gtk_blist_update(GaimBuddyList *list, GaimBlistNode *node) | |
3737 { | |
3738 if(!gtkblist) | |
3739 return; | |
3740 | |
3741 switch(node->type) { | |
3742 case GAIM_BLIST_GROUP_NODE: | |
3743 gaim_gtk_blist_update_group(list, node); | |
3744 break; | |
3745 case GAIM_BLIST_CONTACT_NODE: | |
3746 gaim_gtk_blist_update_contact(list, node); | |
3747 break; | |
3748 case GAIM_BLIST_BUDDY_NODE: | |
3749 gaim_gtk_blist_update_buddy(list, node); | |
3750 break; | |
3751 case GAIM_BLIST_CHAT_NODE: | |
3752 gaim_gtk_blist_update_chat(list, node); | |
3753 break; | |
3754 case GAIM_BLIST_OTHER_NODE: | |
3755 return; | |
3756 } | |
5234 | 3757 |
5228 | 3758 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview)); |
3759 } | |
3760 | |
7620 | 3761 |
3762 static void gaim_gtk_blist_destroy(GaimBuddyList *list) | |
5228 | 3763 { |
3764 if (!gtkblist) | |
3765 return; | |
3766 | |
8937 | 3767 gaim_signal_disconnect(gaim_connections_get_handle(), "signed-on", |
3768 gtkblist, GAIM_CALLBACK(sign_on_off_cb)); | |
3769 gaim_signal_disconnect(gaim_connections_get_handle(), "signed-off", | |
3770 gtkblist, GAIM_CALLBACK(sign_on_off_cb)); | |
8259
4f9f68ab8770
[gaim-migrate @ 8982]
Christian Hammond <chipx86@chipx86.com>
parents:
8254
diff
changeset
|
3771 |
5228 | 3772 gtk_widget_destroy(gtkblist->window); |
7620 | 3773 |
8254 | 3774 gaim_gtk_blist_tooltip_destroy(); |
7620 | 3775 |
5228 | 3776 if (gtkblist->refresh_timer) |
3777 g_source_remove(gtkblist->refresh_timer); | |
3778 if (gtkblist->timeout) | |
3779 g_source_remove(gtkblist->timeout); | |
3780 | |
3781 gtkblist->refresh_timer = 0; | |
3782 gtkblist->timeout = 0; | |
3783 gtkblist->window = gtkblist->vbox = gtkblist->treeview = NULL; | |
3784 gtkblist->treemodel = NULL; | |
3785 gtkblist->idle_column = NULL; | |
3786 gtkblist->warning_column = gtkblist->buddy_icon_column = NULL; | |
5427 | 3787 g_object_unref(G_OBJECT(gtkblist->ift)); |
5228 | 3788 protomenu = NULL; |
8986 | 3789 pluginmenu = NULL; |
5228 | 3790 awaymenu = NULL; |
3791 gtkblist = NULL; | |
7620 | 3792 |
10087 | 3793 gaim_prefs_disconnect_by_handle(gaim_gtk_blist_get_handle()); |
5228 | 3794 } |
3795 | |
7620 | 3796 static void gaim_gtk_blist_set_visible(GaimBuddyList *list, gboolean show) |
5228 | 3797 { |
3798 if (!(gtkblist && gtkblist->window)) | |
3799 return; | |
3800 | |
3801 if (show) { | |
3802 gaim_gtk_blist_restore_position(); | |
3803 gtk_window_present(GTK_WINDOW(gtkblist->window)); | |
3804 } else { | |
7620 | 3805 if (!gaim_connections_get_all() || docklet_count) { |
5228 | 3806 #ifdef _WIN32 |
3807 wgaim_systray_minimize(gtkblist->window); | |
3808 #endif | |
3809 gtk_widget_hide(gtkblist->window); | |
3810 } else { | |
3811 gtk_window_iconify(GTK_WINDOW(gtkblist->window)); | |
3812 } | |
3813 } | |
3814 } | |
3815 | |
7620 | 3816 static GList * |
3817 groups_tree(void) | |
3818 { | |
3819 GList *tmp = NULL; | |
3820 char *tmp2; | |
3821 GaimGroup *g; | |
3822 GaimBlistNode *gnode; | |
3823 | |
3824 if (gaim_get_blist()->root == NULL) | |
3825 { | |
3826 tmp2 = g_strdup(_("Buddies")); | |
3827 tmp = g_list_append(tmp, tmp2); | |
3828 } | |
3829 else | |
3830 { | |
3831 for (gnode = gaim_get_blist()->root; | |
3832 gnode != NULL; | |
3833 gnode = gnode->next) | |
3834 { | |
3835 if (GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
3836 { | |
3837 g = (GaimGroup *)gnode; | |
3838 tmp2 = g->name; | |
3839 tmp = g_list_append(tmp, tmp2); | |
3840 } | |
3841 } | |
3842 } | |
3843 | |
3844 return tmp; | |
3845 } | |
3846 | |
3847 static void | |
3848 add_buddy_select_account_cb(GObject *w, GaimAccount *account, | |
3849 GaimGtkAddBuddyData *data) | |
3850 { | |
3851 /* Save our account */ | |
3852 data->account = account; | |
3853 } | |
3854 | |
3855 static void | |
3856 destroy_add_buddy_dialog_cb(GtkWidget *win, GaimGtkAddBuddyData *data) | |
3857 { | |
3858 g_free(data); | |
3859 } | |
3860 | |
3861 static void | |
3862 add_buddy_cb(GtkWidget *w, int resp, GaimGtkAddBuddyData *data) | |
3863 { | |
3864 const char *grp, *who, *whoalias; | |
3865 GaimConversation *c; | |
3866 GaimBuddy *b; | |
3867 GaimGroup *g; | |
3868 | |
3869 if (resp == GTK_RESPONSE_OK) | |
3870 { | |
3871 who = gtk_entry_get_text(GTK_ENTRY(data->entry)); | |
3872 grp = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(data->combo)->entry)); | |
3873 whoalias = gtk_entry_get_text(GTK_ENTRY(data->entry_for_alias)); | |
9658 | 3874 if (*whoalias == '\0') |
3875 whoalias = NULL; | |
7620 | 3876 |
3877 c = gaim_find_conversation_with_account(who, data->account); | |
3878 | |
3879 if ((g = gaim_find_group(grp)) == NULL) | |
3880 { | |
3881 g = gaim_group_new(grp); | |
3882 gaim_blist_add_group(g, NULL); | |
3883 } | |
3884 | |
3885 b = gaim_buddy_new(data->account, who, whoalias); | |
3886 gaim_blist_add_buddy(b, NULL, g, NULL); | |
9285 | 3887 serv_add_buddy(gaim_account_get_connection(data->account), b); |
7620 | 3888 |
7887 | 3889 /* |
9285 | 3890 * XXX |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
3891 * It really seems like it would be better if the call to serv_add_buddy() |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
3892 * and gaim_conversation_update() were done in blist.c, possibly in the |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
3893 * gaim_blist_add_buddy() function. Maybe serv_add_buddy() should be |
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
3894 * renamed to gaim_blist_add_new_buddy() or something, and have it call |
7887 | 3895 * gaim_blist_add_buddy() after it creates it. --Mark |
9285 | 3896 * |
3897 * No that's not good. blist.c should only deal with adding nodes to the | |
3898 * local list. We need a new, non-gtk file that calls both serv_add_buddy | |
3899 * and gaim_blist_add_buddy(). Or something. --Mark | |
7887 | 3900 */ |
3901 | |
7620 | 3902 if (c != NULL) { |
3903 gaim_buddy_icon_update(gaim_conv_im_get_icon(GAIM_CONV_IM(c))); | |
3904 gaim_conversation_update(c, GAIM_CONV_UPDATE_ADD); | |
3905 } | |
3906 } | |
3907 | |
3908 gtk_widget_destroy(data->window); | |
3909 } | |
3910 | |
3911 static void | |
3912 gaim_gtk_blist_request_add_buddy(GaimAccount *account, const char *username, | |
3913 const char *group, const char *alias) | |
3914 { | |
3915 GtkWidget *table; | |
3916 GtkWidget *label; | |
3917 GtkWidget *hbox; | |
3918 GtkWidget *vbox; | |
3919 GtkWidget *img; | |
3920 GaimGtkBuddyList *gtkblist; | |
3921 GaimGtkAddBuddyData *data = g_new0(GaimGtkAddBuddyData, 1); | |
3922 | |
3923 data->account = | |
3924 (account != NULL | |
3925 ? account | |
3926 : gaim_connection_get_account(gaim_connections_get_all()->data)); | |
3927 | |
3928 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, | |
3929 GTK_ICON_SIZE_DIALOG); | |
3930 | |
3931 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); | |
3932 | |
3933 data->window = gtk_dialog_new_with_buttons(_("Add Buddy"), | |
8975 | 3934 NULL, GTK_DIALOG_NO_SEPARATOR, |
7620 | 3935 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
3936 GTK_STOCK_ADD, GTK_RESPONSE_OK, | |
3937 NULL); | |
3938 | |
3939 gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); | |
3940 gtk_container_set_border_width(GTK_CONTAINER(data->window), 6); | |
3941 gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); | |
3942 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), 12); | |
3943 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), 6); | |
3944 gtk_window_set_role(GTK_WINDOW(data->window), "add_buddy"); | |
8975 | 3945 gtk_window_set_type_hint(GTK_WINDOW(data->window), |
9811 | 3946 GDK_WINDOW_TYPE_HINT_DIALOG); |
7620 | 3947 |
3948 hbox = gtk_hbox_new(FALSE, 12); | |
3949 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); | |
3950 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
3951 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
3952 | |
3953 vbox = gtk_vbox_new(FALSE, 0); | |
3954 gtk_container_add(GTK_CONTAINER(hbox), vbox); | |
3955 | |
3956 label = gtk_label_new( | |
3957 _("Please enter the screen name of the person you would like " | |
3958 "to add to your buddy list. You may optionally enter an alias, " | |
3959 "or nickname, for the buddy. The alias will be displayed in " | |
3960 "place of the screen name whenever possible.\n")); | |
3961 | |
3962 gtk_widget_set_size_request(GTK_WIDGET(label), 400, -1); | |
3963 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
3964 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
3965 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
3966 | |
3967 hbox = gtk_hbox_new(FALSE, 6); | |
3968 gtk_container_add(GTK_CONTAINER(vbox), hbox); | |
3969 | |
3970 g_signal_connect(G_OBJECT(data->window), "destroy", | |
3971 G_CALLBACK(destroy_add_buddy_dialog_cb), data); | |
3972 | |
3973 table = gtk_table_new(4, 2, FALSE); | |
3974 gtk_table_set_row_spacings(GTK_TABLE(table), 5); | |
3975 gtk_table_set_col_spacings(GTK_TABLE(table), 5); | |
3976 gtk_container_set_border_width(GTK_CONTAINER(table), 0); | |
3977 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); | |
3978 | |
3979 label = gtk_label_new(_("Screen Name:")); | |
3980 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
3981 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); | |
3982 | |
3983 data->entry = gtk_entry_new(); | |
3984 gtk_table_attach_defaults(GTK_TABLE(table), data->entry, 1, 2, 0, 1); | |
3985 gtk_widget_grab_focus(data->entry); | |
3986 | |
3987 if (username != NULL) | |
3988 gtk_entry_set_text(GTK_ENTRY(data->entry), username); | |
3989 | |
3990 gtk_entry_set_activates_default (GTK_ENTRY(data->entry), TRUE); | |
8137 | 3991 gaim_set_accessible_label (data->entry, label); |
7620 | 3992 |
3993 label = gtk_label_new(_("Alias:")); | |
3994 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
3995 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); | |
3996 | |
3997 data->entry_for_alias = gtk_entry_new(); | |
3998 gtk_table_attach_defaults(GTK_TABLE(table), | |
3999 data->entry_for_alias, 1, 2, 1, 2); | |
4000 | |
4001 if (alias != NULL) | |
4002 gtk_entry_set_text(GTK_ENTRY(data->entry_for_alias), alias); | |
4003 | |
4004 gtk_entry_set_activates_default (GTK_ENTRY(data->entry_for_alias), TRUE); | |
8137 | 4005 gaim_set_accessible_label (data->entry_for_alias, label); |
7620 | 4006 |
4007 label = gtk_label_new(_("Group:")); | |
4008 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
4009 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); | |
4010 | |
4011 data->combo = gtk_combo_new(); | |
4012 gtk_combo_set_popdown_strings(GTK_COMBO(data->combo), groups_tree()); | |
4013 gtk_table_attach_defaults(GTK_TABLE(table), data->combo, 1, 2, 2, 3); | |
8137 | 4014 gaim_set_accessible_label (data->combo, label); |
7620 | 4015 |
4016 /* Set up stuff for the account box */ | |
4017 label = gtk_label_new(_("Account:")); | |
4018 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
4019 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); | |
4020 | |
4021 data->account_box = gaim_gtk_account_option_menu_new(account, FALSE, | |
4022 G_CALLBACK(add_buddy_select_account_cb), NULL, data); | |
4023 | |
4024 gtk_table_attach_defaults(GTK_TABLE(table), data->account_box, 1, 2, 3, 4); | |
8137 | 4025 gaim_set_accessible_label (data->account_box, label); |
7620 | 4026 |
4027 /* End of account box */ | |
4028 | |
4029 g_signal_connect(G_OBJECT(data->window), "response", | |
4030 G_CALLBACK(add_buddy_cb), data); | |
4031 | |
4032 gtk_widget_show_all(data->window); | |
4033 | |
4034 if (group != NULL) | |
4035 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(data->combo)->entry), group); | |
4036 } | |
4037 | |
4038 static void | |
4039 add_chat_cb(GtkWidget *w, GaimGtkAddChatData *data) | |
4040 { | |
4041 GHashTable *components; | |
4042 GList *tmp; | |
4043 GaimChat *chat; | |
4044 GaimGroup *group; | |
4045 const char *group_name; | |
9918 | 4046 char *chat_name = NULL; |
4047 GaimConversation *conv = NULL; | |
7620 | 4048 |
4049 components = g_hash_table_new_full(g_str_hash, g_str_equal, | |
4050 g_free, g_free); | |
4051 | |
4052 for (tmp = data->entries; tmp; tmp = tmp->next) | |
4053 { | |
4054 if (g_object_get_data(tmp->data, "is_spin")) | |
4055 { | |
4056 g_hash_table_replace(components, | |
4057 g_strdup(g_object_get_data(tmp->data, "identifier")), | |
4058 g_strdup_printf("%d", | |
4059 gtk_spin_button_get_value_as_int(tmp->data))); | |
4060 } | |
4061 else | |
4062 { | |
4063 g_hash_table_replace(components, | |
4064 g_strdup(g_object_get_data(tmp->data, "identifier")), | |
4065 g_strdup(gtk_entry_get_text(tmp->data))); | |
4066 } | |
4067 } | |
4068 | |
4069 chat = gaim_chat_new(data->account, | |
4070 gtk_entry_get_text(GTK_ENTRY(data->alias_entry)), | |
4071 components); | |
4072 | |
4073 group_name = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(data->group_combo)->entry)); | |
4074 | |
4075 if ((group = gaim_find_group(group_name)) == NULL) | |
4076 { | |
4077 group = gaim_group_new(group_name); | |
4078 gaim_blist_add_group(group, NULL); | |
4079 } | |
4080 | |
4081 if (chat != NULL) | |
4082 { | |
4083 gaim_blist_add_chat(chat, group, NULL); | |
9918 | 4084 |
4085 if (GAIM_PLUGIN_PROTOCOL_INFO(data->account->gc->prpl)->get_chat_name != NULL) | |
4086 chat_name = GAIM_PLUGIN_PROTOCOL_INFO( | |
4087 data->account->gc->prpl)->get_chat_name(chat->components); | |
4088 | |
4089 if (chat_name != NULL) { | |
4090 conv = gaim_find_conversation_with_account(chat_name, data->account); | |
4091 g_free(chat_name); | |
4092 } | |
4093 | |
4094 if (conv != NULL) | |
4095 gaim_conversation_update(conv, GAIM_CONV_UPDATE_ADD); | |
7620 | 4096 } |
4097 | |
4098 gtk_widget_destroy(data->window); | |
9812 | 4099 g_free(data->default_chat_name); |
7620 | 4100 g_list_free(data->entries); |
4101 g_free(data); | |
4102 } | |
4103 | |
4104 static void | |
4105 add_chat_resp_cb(GtkWidget *w, int resp, GaimGtkAddChatData *data) | |
4106 { | |
4107 if (resp == GTK_RESPONSE_OK) | |
4108 { | |
4109 add_chat_cb(NULL, data); | |
4110 } | |
4111 else | |
4112 { | |
4113 gtk_widget_destroy(data->window); | |
9812 | 4114 g_free(data->default_chat_name); |
7620 | 4115 g_list_free(data->entries); |
4116 g_free(data); | |
4117 } | |
4118 } | |
4119 | |
4120 static void | |
4121 rebuild_addchat_entries(GaimGtkAddChatData *data) | |
4122 { | |
4123 GaimConnection *gc; | |
9959 | 4124 GList *list = NULL, *tmp = NULL; |
9754 | 4125 GHashTable *defaults = NULL; |
7620 | 4126 struct proto_chat_entry *pce; |
4127 gboolean focus = TRUE; | |
4128 | |
10127 | 4129 g_return_if_fail(data->account != NULL); |
4130 | |
7620 | 4131 gc = gaim_account_get_connection(data->account); |
4132 | |
4133 while (GTK_BOX(data->entries_box)->children) | |
4134 { | |
4135 gtk_container_remove(GTK_CONTAINER(data->entries_box), | |
4136 ((GtkBoxChild *)GTK_BOX(data->entries_box)->children->data)->widget); | |
4137 } | |
4138 | |
4139 if (data->entries != NULL) | |
4140 g_list_free(data->entries); | |
4141 | |
4142 data->entries = NULL; | |
4143 | |
9959 | 4144 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) |
4145 list = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc); | |
7620 | 4146 |
9754 | 4147 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) |
4148 defaults = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, | |
4149 data->default_chat_name); | |
4150 | |
7620 | 4151 for (tmp = list; tmp; tmp = tmp->next) |
4152 { | |
4153 GtkWidget *label; | |
4154 GtkWidget *rowbox; | |
4155 | |
4156 pce = tmp->data; | |
4157 | |
4158 rowbox = gtk_hbox_new(FALSE, 5); | |
4159 gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0); | |
4160 | |
7889 | 4161 label = gtk_label_new_with_mnemonic(pce->label); |
7620 | 4162 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); |
4163 gtk_size_group_add_widget(data->sg, label); | |
4164 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
4165 | |
4166 if (pce->is_int) | |
4167 { | |
4168 GtkObject *adjust; | |
4169 GtkWidget *spin; | |
4170 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, | |
4171 1, 10, 10); | |
4172 spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); | |
4173 g_object_set_data(G_OBJECT(spin), "is_spin", GINT_TO_POINTER(TRUE)); | |
4174 g_object_set_data(G_OBJECT(spin), "identifier", pce->identifier); | |
4175 data->entries = g_list_append(data->entries, spin); | |
4176 gtk_widget_set_size_request(spin, 50, -1); | |
4177 gtk_box_pack_end(GTK_BOX(rowbox), spin, FALSE, FALSE, 0); | |
7891 | 4178 gtk_label_set_mnemonic_widget(GTK_LABEL(label), spin); |
8137 | 4179 gaim_set_accessible_label (spin, label); |
7620 | 4180 } |
4181 else | |
4182 { | |
4183 GtkWidget *entry = gtk_entry_new(); | |
9754 | 4184 char *value; |
7620 | 4185 |
4186 g_object_set_data(G_OBJECT(entry), "identifier", pce->identifier); | |
4187 data->entries = g_list_append(data->entries, entry); | |
4188 | |
9754 | 4189 value = g_hash_table_lookup(defaults, pce->identifier); |
4190 if (value != NULL) | |
4191 gtk_entry_set_text(GTK_ENTRY(entry), value); | |
7620 | 4192 |
4193 if (focus) | |
4194 { | |
4195 gtk_widget_grab_focus(entry); | |
4196 focus = FALSE; | |
4197 } | |
4198 | |
4199 if (pce->secret) | |
4200 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); | |
4201 | |
4202 gtk_box_pack_end(GTK_BOX(rowbox), entry, TRUE, TRUE, 0); | |
4203 | |
4204 g_signal_connect(G_OBJECT(entry), "activate", | |
4205 G_CALLBACK(add_chat_cb), data); | |
7891 | 4206 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); |
8137 | 4207 gaim_set_accessible_label (entry, label); |
7620 | 4208 } |
4209 | |
4210 g_free(pce); | |
4211 } | |
4212 | |
4213 g_list_free(list); | |
9754 | 4214 g_hash_table_destroy(defaults); |
7620 | 4215 |
4216 gtk_widget_show_all(data->entries_box); | |
4217 } | |
4218 | |
4219 static void | |
4220 add_chat_select_account_cb(GObject *w, GaimAccount *account, | |
4221 GaimGtkAddChatData *data) | |
4222 { | |
9460 | 4223 if (strcmp(gaim_account_get_protocol_id(data->account), |
4224 gaim_account_get_protocol_id(account)) == 0) | |
7620 | 4225 { |
4226 data->account = account; | |
4227 } | |
4228 else | |
4229 { | |
4230 data->account = account; | |
4231 rebuild_addchat_entries(data); | |
4232 } | |
4233 } | |
4234 | |
4235 void | |
7859 | 4236 gaim_gtk_blist_request_add_chat(GaimAccount *account, GaimGroup *group, |
9754 | 4237 const char *alias, const char *name) |
7620 | 4238 { |
4239 GaimGtkAddChatData *data; | |
8975 | 4240 GaimGtkBuddyList *gtkblist; |
4241 GList *l; | |
4242 GaimConnection *gc; | |
7620 | 4243 GtkWidget *label; |
4244 GtkWidget *rowbox; | |
4245 GtkWidget *hbox; | |
4246 GtkWidget *vbox; | |
4247 GtkWidget *img; | |
4248 | |
9812 | 4249 if (account != NULL) { |
4250 gc = gaim_account_get_connection(account); | |
4251 | |
4252 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat == NULL) { | |
4253 gaim_notify_error(gc, NULL, _("This protocol does not support chat rooms."), NULL); | |
4254 return; | |
4255 } | |
4256 } else { | |
4257 /* Find an account with chat capabilities */ | |
4258 for (l = gaim_connections_get_all(); l != NULL; l = l->next) { | |
4259 gc = (GaimConnection *)l->data; | |
4260 | |
4261 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat != NULL) { | |
4262 account = gaim_connection_get_account(gc); | |
4263 break; | |
4264 } | |
4265 } | |
4266 | |
4267 if (account == NULL) { | |
4268 gaim_notify_error(NULL, NULL, | |
4269 _("You are not currently signed on with any " | |
4270 "protocols that have the ability to chat."), NULL); | |
4271 return; | |
4272 } | |
4273 } | |
4274 | |
7620 | 4275 data = g_new0(GaimGtkAddChatData, 1); |
9812 | 4276 data->account = account; |
4277 data->default_chat_name = g_strdup(name); | |
7620 | 4278 |
4279 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, | |
4280 GTK_ICON_SIZE_DIALOG); | |
4281 | |
8975 | 4282 gtkblist = GAIM_GTK_BLIST(gaim_get_blist()); |
4283 | |
7620 | 4284 data->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
4285 | |
8975 | 4286 data->window = gtk_dialog_new_with_buttons(_("Add Chat"), |
4287 NULL, GTK_DIALOG_NO_SEPARATOR, | |
4288 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
4289 GTK_STOCK_ADD, GTK_RESPONSE_OK, | |
4290 NULL); | |
4291 | |
4292 gtk_dialog_set_default_response(GTK_DIALOG(data->window), GTK_RESPONSE_OK); | |
4293 gtk_container_set_border_width(GTK_CONTAINER(data->window), 6); | |
4294 gtk_window_set_resizable(GTK_WINDOW(data->window), FALSE); | |
4295 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(data->window)->vbox), 12); | |
4296 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), 6); | |
7620 | 4297 gtk_window_set_role(GTK_WINDOW(data->window), "add_chat"); |
8975 | 4298 gtk_window_set_type_hint(GTK_WINDOW(data->window), |
9811 | 4299 GDK_WINDOW_TYPE_HINT_DIALOG); |
7620 | 4300 |
4301 hbox = gtk_hbox_new(FALSE, 12); | |
4302 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(data->window)->vbox), hbox); | |
4303 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
4304 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
4305 | |
4306 vbox = gtk_vbox_new(FALSE, 5); | |
4307 gtk_container_add(GTK_CONTAINER(hbox), vbox); | |
4308 | |
4309 label = gtk_label_new( | |
4310 _("Please enter an alias, and the appropriate information " | |
4311 "about the chat you would like to add to your buddy list.\n")); | |
4312 gtk_widget_set_size_request(label, 400, -1); | |
4313 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
4314 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
4315 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | |
4316 | |
4317 rowbox = gtk_hbox_new(FALSE, 5); | |
4318 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
4319 | |
4320 label = gtk_label_new(_("Account:")); | |
4321 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
4322 gtk_size_group_add_widget(data->sg, label); | |
4323 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
4324 | |
4325 data->account_menu = gaim_gtk_account_option_menu_new(account, FALSE, | |
4326 G_CALLBACK(add_chat_select_account_cb), | |
9987 | 4327 chat_account_filter_func, data); |
7620 | 4328 gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0); |
8137 | 4329 gaim_set_accessible_label (data->account_menu, label); |
7620 | 4330 |
4331 data->entries_box = gtk_vbox_new(FALSE, 5); | |
9811 | 4332 gtk_container_set_border_width(GTK_CONTAINER(data->entries_box), 0); |
7620 | 4333 gtk_box_pack_start(GTK_BOX(vbox), data->entries_box, TRUE, TRUE, 0); |
4334 | |
4335 rebuild_addchat_entries(data); | |
4336 | |
4337 rowbox = gtk_hbox_new(FALSE, 5); | |
4338 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
4339 | |
4340 label = gtk_label_new(_("Alias:")); | |
4341 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
4342 gtk_size_group_add_widget(data->sg, label); | |
4343 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
4344 | |
4345 data->alias_entry = gtk_entry_new(); | |
7859 | 4346 if (alias != NULL) |
4347 gtk_entry_set_text(GTK_ENTRY(data->alias_entry), alias); | |
7620 | 4348 gtk_box_pack_end(GTK_BOX(rowbox), data->alias_entry, TRUE, TRUE, 0); |
8137 | 4349 gaim_set_accessible_label (data->alias_entry, label); |
7620 | 4350 |
4351 rowbox = gtk_hbox_new(FALSE, 5); | |
4352 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
4353 | |
9811 | 4354 label = gtk_label_new(_("Group:")); |
7620 | 4355 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); |
4356 gtk_size_group_add_widget(data->sg, label); | |
4357 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); | |
4358 | |
9811 | 4359 data->group_combo = gtk_combo_new(); |
4360 gtk_combo_set_popdown_strings(GTK_COMBO(data->group_combo), groups_tree()); | |
7620 | 4361 gtk_box_pack_end(GTK_BOX(rowbox), data->group_combo, TRUE, TRUE, 0); |
4362 | |
4363 if (group) | |
4364 { | |
4365 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(data->group_combo)->entry), | |
4366 group->name); | |
4367 } | |
8137 | 4368 gaim_set_accessible_label (data->group_combo, label); |
7620 | 4369 |
4370 g_signal_connect(G_OBJECT(data->window), "response", | |
4371 G_CALLBACK(add_chat_resp_cb), data); | |
4372 | |
4373 gtk_widget_show_all(data->window); | |
4374 } | |
4375 | |
4376 static void | |
4377 add_group_cb(GaimConnection *gc, const char *group_name) | |
4378 { | |
9285 | 4379 GaimGroup *group; |
4380 | |
4381 group = gaim_group_new(group_name); | |
4382 gaim_blist_add_group(group, NULL); | |
7620 | 4383 } |
4384 | |
4385 void | |
4386 gaim_gtk_blist_request_add_group(void) | |
4387 { | |
7853 | 4388 gaim_request_input(NULL, _("Add Group"), NULL, |
7620 | 4389 _("Please enter the name of the group to be added."), |
8697 | 4390 NULL, FALSE, FALSE, NULL, |
7620 | 4391 _("Add"), G_CALLBACK(add_group_cb), |
4392 _("Cancel"), NULL, NULL); | |
4393 } | |
4394 | |
5228 | 4395 void gaim_gtk_blist_docklet_toggle() { |
4396 /* Useful for the docklet plugin and also for the win32 tray icon*/ | |
8470
9949b752d1ab
[gaim-migrate @ 9203]
Christian Hammond <chipx86@chipx86.com>
parents:
8444
diff
changeset
|
4397 /* This is called when one of those is clicked--it will show/hide the |
5228 | 4398 buddy list/login window--depending on which is active */ |
7620 | 4399 if (gaim_connections_get_all()) { |
5228 | 4400 if (gtkblist && gtkblist->window) { |
4401 if (GTK_WIDGET_VISIBLE(gtkblist->window)) { | |
4402 gaim_blist_set_visible(GAIM_WINDOW_ICONIFIED(gtkblist->window) || gaim_gtk_blist_obscured); | |
4403 } else { | |
4404 #if _WIN32 | |
4405 wgaim_systray_maximize(gtkblist->window); | |
4406 #endif | |
4407 gaim_blist_set_visible(TRUE); | |
4408 } | |
4409 } else { | |
4410 /* we're logging in or something... do nothing */ | |
4411 /* or should I make the blist? */ | |
10006 | 4412 gaim_debug_warning("gtkblist", |
7620 | 4413 "docklet_toggle called with gaim_connections_get_all() " |
5228 | 4414 "but no blist!\n"); |
4415 } | |
4416 } else if (mainwindow) { | |
4417 if (GTK_WIDGET_VISIBLE(mainwindow)) { | |
4418 if (GAIM_WINDOW_ICONIFIED(mainwindow)) { | |
4419 gtk_window_present(GTK_WINDOW(mainwindow)); | |
4420 } else { | |
4421 #if _WIN32 | |
4422 wgaim_systray_minimize(mainwindow); | |
4423 #endif | |
4424 gtk_widget_hide(mainwindow); | |
4425 } | |
4426 } else { | |
4427 #if _WIN32 | |
4428 wgaim_systray_maximize(mainwindow); | |
4429 #endif | |
4430 show_login(); | |
4431 } | |
4432 } else { | |
4433 show_login(); | |
4434 } | |
4435 } | |
4436 | |
4437 void gaim_gtk_blist_docklet_add() | |
4438 { | |
4439 docklet_count++; | |
4440 } | |
4441 | |
4442 void gaim_gtk_blist_docklet_remove() | |
4443 { | |
4444 docklet_count--; | |
4445 if (!docklet_count) { | |
7620 | 4446 if (gaim_connections_get_all()) |
5228 | 4447 gaim_blist_set_visible(TRUE); |
4448 else if (mainwindow) | |
4449 gtk_window_present(GTK_WINDOW(mainwindow)); | |
4450 else | |
4451 show_login(); | |
4452 } | |
4453 } | |
4454 | |
7620 | 4455 static GaimBlistUiOps blist_ui_ops = |
5228 | 4456 { |
4457 gaim_gtk_blist_new_list, | |
5256 | 4458 gaim_gtk_blist_new_node, |
5228 | 4459 gaim_gtk_blist_show, |
4460 gaim_gtk_blist_update, | |
4461 gaim_gtk_blist_remove, | |
4462 gaim_gtk_blist_destroy, | |
7620 | 4463 gaim_gtk_blist_set_visible, |
4464 gaim_gtk_blist_request_add_buddy, | |
4465 gaim_gtk_blist_request_add_chat, | |
10012 | 4466 gaim_gtk_blist_request_add_group |
5228 | 4467 }; |
4468 | |
4469 | |
7620 | 4470 GaimBlistUiOps * |
4471 gaim_gtk_blist_get_ui_ops(void) | |
5228 | 4472 { |
4473 return &blist_ui_ops; | |
4474 } | |
4475 | |
7620 | 4476 static void account_signon_cb(GaimConnection *gc, gpointer z) |
4477 { | |
4478 GaimAccount *account = gaim_connection_get_account(gc); | |
4479 GaimBlistNode *gnode, *cnode; | |
4480 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) | |
4481 { | |
4482 if(!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
4483 continue; | |
4484 for(cnode = gnode->child; cnode; cnode = cnode->next) | |
4485 { | |
4486 GaimChat *chat; | |
4487 | |
4488 if(!GAIM_BLIST_NODE_IS_CHAT(cnode)) | |
4489 continue; | |
4490 | |
4491 chat = (GaimChat *)cnode; | |
4492 | |
4493 if(chat->account != account) | |
4494 continue; | |
4495 | |
8197 | 4496 if(gaim_blist_node_get_bool((GaimBlistNode*)chat, "gtk-autojoin") || |
8198 | 4497 (gaim_blist_node_get_string((GaimBlistNode*)chat, |
4498 "gtk-autojoin") != NULL)) | |
7620 | 4499 serv_join_chat(gc, chat->components); |
4500 } | |
4501 } | |
4502 } | |
4503 | |
8815 | 4504 void * |
4505 gaim_gtk_blist_get_handle() { | |
4506 static int handle; | |
4507 | |
4508 return &handle; | |
4509 } | |
4510 | |
7620 | 4511 void gaim_gtk_blist_init(void) |
4512 { | |
8815 | 4513 void *gtk_blist_handle = gaim_gtk_blist_get_handle(); |
7620 | 4514 |
4515 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", | |
8815 | 4516 gtk_blist_handle, GAIM_CALLBACK(account_signon_cb), |
7620 | 4517 NULL); |
7731 | 4518 |
4519 /* Initialize prefs */ | |
8819 | 4520 gaim_prefs_add_none("/gaim/gtk/blist"); |
7731 | 4521 gaim_prefs_add_bool("/gaim/gtk/blist/auto_expand_contacts", TRUE); |
8819 | 4522 gaim_prefs_add_bool("/gaim/gtk/blist/show_buddy_icons", TRUE); |
4523 gaim_prefs_add_bool("/gaim/gtk/blist/show_empty_groups", FALSE); | |
4524 gaim_prefs_add_bool("/gaim/gtk/blist/show_idle_time", TRUE); | |
4525 gaim_prefs_add_bool("/gaim/gtk/blist/show_offline_buddies", FALSE); | |
4526 gaim_prefs_add_bool("/gaim/gtk/blist/show_warning_level", TRUE); | |
9711 | 4527 gaim_prefs_add_string("/gaim/gtk/blist/sort_type", "alphabetical"); |
8819 | 4528 gaim_prefs_add_int("/gaim/gtk/blist/x", 0); |
4529 gaim_prefs_add_int("/gaim/gtk/blist/y", 0); | |
9778 | 4530 gaim_prefs_add_int("/gaim/gtk/blist/width", 309); /* Golden ratio, baby */ |
4531 gaim_prefs_add_int("/gaim/gtk/blist/height", 500); /* Golden ratio, baby */ | |
8819 | 4532 gaim_prefs_add_int("/gaim/gtk/blist/tooltip_delay", 500); |
7731 | 4533 |
8815 | 4534 /* Register our signals */ |
4535 gaim_signal_register(gtk_blist_handle, "gtkblist-created", | |
9811 | 4536 gaim_marshal_VOID__POINTER, NULL, 1, |
4537 gaim_value_new(GAIM_TYPE_SUBTYPE, | |
4538 GAIM_SUBTYPE_BLIST)); | |
8819 | 4539 |
4540 gaim_signal_register(gtk_blist_handle, "drawing-tooltip", | |
9811 | 4541 gaim_marshal_VOID__POINTER_POINTER, NULL, 2, |
4542 gaim_value_new(GAIM_TYPE_SUBTYPE, GAIM_SUBTYPE_BLIST_NODE), | |
4543 gaim_value_new_outgoing(GAIM_TYPE_STRING)); | |
7620 | 4544 } |
4545 | |
8815 | 4546 void |
4547 gaim_gtk_blist_uninit(void) { | |
4548 gaim_signals_unregister_by_instance(gaim_gtk_blist_get_handle()); | |
4549 } | |
5228 | 4550 |
4551 /********************************************************************* | |
4552 * Public utility functions * | |
4553 *********************************************************************/ | |
4554 | |
4555 GdkPixbuf * | |
7620 | 4556 create_prpl_icon(GaimAccount *account) |
5228 | 4557 { |
4558 GaimPlugin *prpl; | |
4559 GaimPluginProtocolInfo *prpl_info = NULL; | |
4560 GdkPixbuf *status = NULL; | |
4561 char *filename = NULL; | |
4562 const char *protoname = NULL; | |
4563 char buf[256]; | |
4564 | |
10046 | 4565 g_return_val_if_fail(account != NULL, NULL); |
4566 | |
7956 | 4567 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
5228 | 4568 |
4569 if (prpl != NULL) { | |
4570 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
4571 | |
4572 if (prpl_info->list_icon != NULL) | |
4573 protoname = prpl_info->list_icon(account, NULL); | |
4574 } | |
4575 | |
4576 if (protoname == NULL) | |
4577 return NULL; | |
4578 | |
4579 /* | |
4580 * Status icons will be themeable too, and then it will look up | |
4581 * protoname from the theme | |
4582 */ | |
4583 g_snprintf(buf, sizeof(buf), "%s.png", protoname); | |
4584 | |
4585 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", | |
4586 "default", buf, NULL); | |
4587 status = gdk_pixbuf_new_from_file(filename, NULL); | |
4588 g_free(filename); | |
4589 | |
4590 return status; | |
4591 } | |
4592 | |
5422 | 4593 |
4594 /********************************************************************* | |
9811 | 4595 * Buddy List sorting functions * |
5422 | 4596 *********************************************************************/ |
4597 | |
7620 | 4598 void gaim_gtk_blist_sort_method_reg(const char *id, const char *name, gaim_gtk_blist_sort_function func) |
5422 | 4599 { |
4600 struct gaim_gtk_blist_sort_method *method = g_new0(struct gaim_gtk_blist_sort_method, 1); | |
7620 | 4601 method->id = g_strdup(id); |
5422 | 4602 method->name = g_strdup(name); |
9775 | 4603 method->func = func; |
5422 | 4604 gaim_gtk_blist_sort_methods = g_slist_append(gaim_gtk_blist_sort_methods, method); |
4605 } | |
4606 | |
7620 | 4607 void gaim_gtk_blist_sort_method_unreg(const char *id){ |
4608 GSList *l = gaim_gtk_blist_sort_methods; | |
4609 | |
4610 while(l) { | |
4611 struct gaim_gtk_blist_sort_method *method = l->data; | |
4612 if(!strcmp(method->id, id)) { | |
4613 gaim_gtk_blist_sort_methods = g_slist_remove(gaim_gtk_blist_sort_methods, method); | |
4614 g_free(method->id); | |
4615 g_free(method->name); | |
4616 g_free(method); | |
4617 break; | |
4618 } | |
4619 } | |
5422 | 4620 } |
4621 | |
7620 | 4622 void gaim_gtk_blist_sort_method_set(const char *id){ |
5422 | 4623 GSList *l = gaim_gtk_blist_sort_methods; |
7620 | 4624 |
4625 if(!id) | |
4626 id = "none"; | |
4627 | |
4628 while (l && strcmp(((struct gaim_gtk_blist_sort_method*)l->data)->id, id)) | |
5422 | 4629 l = l->next; |
7620 | 4630 |
5422 | 4631 if (l) { |
4632 current_sort_method = l->data; | |
4633 } else if (!current_sort_method) { | |
7620 | 4634 gaim_gtk_blist_sort_method_set("none"); |
5422 | 4635 return; |
4636 } | |
4637 redo_buddy_list(gaim_get_blist(), TRUE); | |
4638 | |
4639 } | |
4640 | |
4641 /****************************************** | |
4642 ** Sort Methods | |
4643 ******************************************/ | |
4644 | |
7620 | 4645 static GtkTreeIter sort_method_none(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter parent_iter, GtkTreeIter *cur) |
5422 | 4646 { |
7620 | 4647 GtkTreeIter iter; |
4648 GaimBlistNode *sibling = node->prev; | |
4649 GtkTreeIter sibling_iter; | |
4650 | |
4651 if(cur) | |
5422 | 4652 return *cur; |
7620 | 4653 |
4654 while (sibling && !get_iter_from_node(sibling, &sibling_iter)) { | |
4655 sibling = sibling->prev; | |
5422 | 4656 } |
7620 | 4657 |
4658 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, | |
4659 node->parent ? &parent_iter : NULL, | |
4660 sibling ? &sibling_iter : NULL); | |
4661 | |
5422 | 4662 return iter; |
4663 } | |
4664 | |
7620 | 4665 #if GTK_CHECK_VERSION(2,2,1) |
4666 | |
4667 static GtkTreeIter sort_method_alphabetical(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) | |
5422 | 4668 { |
4669 GtkTreeIter more_z, iter; | |
4670 GaimBlistNode *n; | |
4671 GValue val = {0,}; | |
7620 | 4672 |
4673 const char *my_name; | |
4674 | |
4675 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
4676 my_name = gaim_contact_get_alias((GaimContact*)node); | |
4677 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { | |
4678 my_name = gaim_chat_get_name((GaimChat*)node); | |
4679 } else { | |
4680 return sort_method_none(node, blist, groupiter, cur); | |
4681 } | |
4682 | |
5422 | 4683 |
4684 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { | |
4685 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); | |
7620 | 4686 return iter; |
4687 } | |
4688 | |
4689 do { | |
4690 const char *this_name; | |
4691 int cmp; | |
4692 | |
4693 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); | |
4694 n = g_value_get_pointer(&val); | |
4695 | |
4696 if(GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
4697 this_name = gaim_contact_get_alias((GaimContact*)n); | |
4698 } else if(GAIM_BLIST_NODE_IS_CHAT(n)) { | |
4699 this_name = gaim_chat_get_name((GaimChat*)n); | |
4700 } else { | |
4701 this_name = NULL; | |
4702 } | |
4703 | |
4704 cmp = gaim_utf8_strcasecmp(my_name, this_name); | |
4705 | |
4706 if(this_name && (cmp < 0 || (cmp == 0 && node < n))) { | |
4707 if(cur) { | |
4708 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); | |
4709 return *cur; | |
4710 } else { | |
4711 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, | |
4712 &groupiter, &more_z); | |
4713 return iter; | |
4714 } | |
4715 } | |
4716 g_value_unset(&val); | |
4717 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z)); | |
4718 | |
4719 if(cur) { | |
4720 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); | |
4721 return *cur; | |
4722 } else { | |
4723 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
4724 return iter; | |
4725 } | |
4726 } | |
4727 | |
4728 static GtkTreeIter sort_method_status(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) | |
4729 { | |
4730 GtkTreeIter more_z, iter; | |
4731 GaimBlistNode *n; | |
4732 GValue val = {0,}; | |
4733 | |
4734 GaimBuddy *my_buddy, *this_buddy; | |
4735 | |
4736 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
4737 my_buddy = gaim_contact_get_priority_buddy((GaimContact*)node); | |
4738 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { | |
4739 if(cur) | |
4740 return *cur; | |
4741 | |
4742 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
4743 return iter; | |
4744 } else { | |
4745 return sort_method_none(node, blist, groupiter, cur); | |
4746 } | |
4747 | |
4748 | |
4749 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { | |
4750 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); | |
5422 | 4751 return iter; |
4752 } | |
4753 | |
4754 do { | |
9944 | 4755 gint name_cmp; |
4756 gint presence_cmp; | |
7620 | 4757 |
5422 | 4758 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); |
4759 n = g_value_get_pointer(&val); | |
7620 | 4760 |
4761 if(GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
4762 this_buddy = gaim_contact_get_priority_buddy((GaimContact*)n); | |
4763 } else { | |
4764 this_buddy = NULL; | |
4765 } | |
4766 | |
9944 | 4767 name_cmp = gaim_utf8_strcasecmp( |
4768 (my_buddy | |
4769 ? gaim_contact_get_alias(gaim_buddy_get_contact(my_buddy)) | |
4770 : NULL), | |
4771 (this_buddy | |
4772 ? gaim_contact_get_alias(gaim_buddy_get_contact(this_buddy)) | |
4773 : NULL)); | |
4774 | |
4775 presence_cmp = gaim_presence_compare( | |
4776 gaim_buddy_get_presence(my_buddy), | |
4777 gaim_buddy_get_presence(this_buddy)); | |
4778 | |
4779 if (this_buddy == NULL || | |
4780 (presence_cmp > 0 || | |
4781 (presence_cmp == 0 && | |
4782 (name_cmp < 0 || (name_cmp == 0 && node < n))))) | |
4783 { | |
4784 if (cur != NULL) | |
4785 { | |
7620 | 4786 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); |
4787 return *cur; | |
9944 | 4788 } |
4789 else | |
4790 { | |
7620 | 4791 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, |
9944 | 4792 &groupiter, &more_z); |
7620 | 4793 return iter; |
4794 } | |
5422 | 4795 } |
9944 | 4796 |
5422 | 4797 g_value_unset(&val); |
9944 | 4798 } |
4799 while (gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), | |
4800 &more_z)); | |
7620 | 4801 |
4802 if(cur) { | |
4803 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); | |
4804 return *cur; | |
4805 } else { | |
4806 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
4807 return iter; | |
4808 } | |
5422 | 4809 } |
4810 | |
7620 | 4811 static GtkTreeIter sort_method_log(GaimBlistNode *node, GaimBuddyList *blist, GtkTreeIter groupiter, GtkTreeIter *cur) |
5422 | 4812 { |
4813 GtkTreeIter more_z, iter; | |
7620 | 4814 GaimBlistNode *n = NULL, *n2; |
5422 | 4815 GValue val = {0,}; |
7620 | 4816 |
4817 int log_size = 0, this_log_size = 0; | |
4818 const char *buddy_name, *this_buddy_name; | |
4819 | |
4820 if(cur && (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(gtkblist->treemodel), &groupiter) == 1)) | |
4821 return *cur; | |
4822 | |
4823 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { | |
4824 for (n = node->child; n; n = n->next) | |
8898 | 4825 log_size += gaim_log_get_total_size(GAIM_LOG_IM, ((GaimBuddy*)(n))->name, ((GaimBuddy*)(n))->account); |
7620 | 4826 buddy_name = gaim_contact_get_alias((GaimContact*)node); |
4827 } else if(GAIM_BLIST_NODE_IS_CHAT(node)) { | |
4828 /* we don't have a reliable way of getting the log filename | |
4829 * from the chat info in the blist, yet */ | |
4830 if(cur) | |
4831 return *cur; | |
4832 | |
4833 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
4834 return iter; | |
4835 } else { | |
4836 return sort_method_none(node, blist, groupiter, cur); | |
4837 } | |
4838 | |
4839 | |
5422 | 4840 if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &more_z, &groupiter)) { |
4841 gtk_tree_store_insert(gtkblist->treemodel, &iter, &groupiter, 0); | |
4842 return iter; | |
4843 } | |
4844 | |
4845 do { | |
7620 | 4846 int cmp; |
4847 | |
5422 | 4848 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &more_z, NODE_COLUMN, &val); |
4849 n = g_value_get_pointer(&val); | |
7620 | 4850 this_log_size = 0; |
4851 | |
4852 if(GAIM_BLIST_NODE_IS_CONTACT(n)) { | |
4853 for (n2 = n->child; n2; n2 = n2->next) | |
8898 | 4854 this_log_size += gaim_log_get_total_size(GAIM_LOG_IM, ((GaimBuddy*)(n2))->name, ((GaimBuddy*)(n2))->account); |
7620 | 4855 this_buddy_name = gaim_contact_get_alias((GaimContact*)n); |
4856 } else { | |
4857 this_buddy_name = NULL; | |
5422 | 4858 } |
7620 | 4859 |
4860 cmp = gaim_utf8_strcasecmp(buddy_name, this_buddy_name); | |
4861 | |
4862 if (!GAIM_BLIST_NODE_IS_CONTACT(n) || log_size > this_log_size || | |
4863 ((log_size == this_log_size) && | |
4864 (cmp < 0 || (cmp == 0 && node < n)))) { | |
4865 if(cur) { | |
4866 gtk_tree_store_move_before(gtkblist->treemodel, cur, &more_z); | |
4867 return *cur; | |
4868 } else { | |
4869 gtk_tree_store_insert_before(gtkblist->treemodel, &iter, | |
4870 &groupiter, &more_z); | |
4871 return iter; | |
4872 } | |
5422 | 4873 } |
4874 g_value_unset(&val); | |
4875 } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(gtkblist->treemodel), &more_z)); | |
7620 | 4876 |
4877 if(cur) { | |
4878 gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL); | |
4879 return *cur; | |
4880 } else { | |
4881 gtk_tree_store_append(gtkblist->treemodel, &iter, &groupiter); | |
4882 return iter; | |
4883 } | |
4884 } | |
4885 | |
4886 #endif | |
4887 | |
9015 | 4888 |
7620 | 4889 static void |
9015 | 4890 plugin_act(GtkObject *obk, GaimPluginAction *pam) |
7620 | 4891 { |
9015 | 4892 if (pam->callback) pam->callback(pam); |
5422 | 4893 } |
7620 | 4894 |
8986 | 4895 |
9015 | 4896 |
8986 | 4897 static void |
9015 | 4898 build_plugin_actions(GtkWidget *menu, GaimPlugin *plugin, gpointer context) |
8986 | 4899 { |
9015 | 4900 GtkWidget *menuitem = NULL; |
4901 GaimPluginAction *action = NULL; | |
4902 GList *l, *ll; | |
4903 | |
4904 for (l = ll = GAIM_PLUGIN_ACTIONS(plugin, context); l; l = l->next) { | |
4905 if (l->data) { | |
4906 action = (GaimPluginAction *) l->data; | |
4907 action->plugin = plugin; | |
4908 action->context = context; | |
4909 | |
4910 menuitem = gtk_menu_item_new_with_label(action->label); | |
4911 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
4912 g_signal_connect(G_OBJECT(menuitem), "activate", | |
4913 G_CALLBACK(plugin_act), action); | |
4914 g_object_set_data(G_OBJECT(menuitem), "plugin_action", action); | |
4915 gtk_widget_show(menuitem); | |
4916 } | |
4917 else | |
4918 gaim_separator(menu); | |
4919 } | |
4920 | |
4921 g_list_free(ll); | |
8986 | 4922 } |
4923 | |
4924 | |
7620 | 4925 void |
4926 gaim_gtk_blist_update_protocol_actions(void) | |
4927 { | |
9015 | 4928 GtkWidget *menuitem, *submenu; |
7620 | 4929 GList *l; |
4930 GaimConnection *gc = NULL; | |
9015 | 4931 GaimPlugin *plugin = NULL; |
7620 | 4932 int count = 0; |
9015 | 4933 |
9019 | 4934 if (protomenu == NULL) |
7620 | 4935 return; |
4936 | |
9019 | 4937 /* Clear the old Account Actions menu */ |
9015 | 4938 for (l = gtk_container_get_children(GTK_CONTAINER(protomenu)); l; l = l->next) { |
4939 GaimPluginAction *action; | |
9987 | 4940 |
7620 | 4941 menuitem = l->data; |
9015 | 4942 action = (GaimPluginAction *) g_object_get_data(G_OBJECT(menuitem), |
4943 "plugin_action"); | |
4944 g_free(action); | |
7620 | 4945 |
4946 gtk_container_remove(GTK_CONTAINER(protomenu), GTK_WIDGET(menuitem)); | |
4947 } | |
4948 | |
9019 | 4949 /* Count the number of accounts with actions */ |
9015 | 4950 for (l = gaim_connections_get_all(); l; l = l->next) { |
4951 gc = l->data; | |
4952 plugin = gc->prpl; | |
4953 | |
9019 | 4954 if (GAIM_CONNECTION_IS_CONNECTED(gc) && GAIM_PLUGIN_HAS_ACTIONS(plugin)) |
4955 count++; | |
4956 | |
9015 | 4957 /* no need to count past 2, so don't */ |
9019 | 4958 if (count > 1) |
9015 | 4959 break; |
7620 | 4960 } |
4961 | |
9015 | 4962 if (count == 0) { |
4963 menuitem = gtk_menu_item_new_with_label(_("No actions available")); | |
7620 | 4964 gtk_menu_shell_append(GTK_MENU_SHELL(protomenu), menuitem); |
9015 | 4965 gtk_widget_set_sensitive(menuitem, FALSE); |
7620 | 4966 gtk_widget_show(menuitem); |
4967 } | |
9019 | 4968 |
4969 else if (count == 1) { | |
4970 /* Find the one account that has actions */ | |
4971 for (l = gaim_connections_get_all(); l; l = l->next) { | |
4972 gc = l->data; | |
4973 plugin = gc->prpl; | |
4974 | |
4975 if (GAIM_CONNECTION_IS_CONNECTED(gc) && GAIM_PLUGIN_HAS_ACTIONS(plugin)) | |
4976 break; | |
4977 } | |
4978 | |
9015 | 4979 build_plugin_actions(protomenu, plugin, gc); |
7620 | 4980 } |
9019 | 4981 |
7620 | 4982 else { |
9015 | 4983 for (l = gaim_connections_get_all(); l; l = l->next) { |
7620 | 4984 GaimAccount *account; |
4985 GdkPixbuf *pixbuf, *scale; | |
4986 GtkWidget *image; | |
9015 | 4987 char *buf; |
4988 | |
4989 gc = l->data; | |
4990 plugin = gc->prpl; | |
4991 | |
9019 | 4992 if (!GAIM_CONNECTION_IS_CONNECTED(gc) || !GAIM_PLUGIN_HAS_ACTIONS(plugin)) |
7620 | 4993 continue; |
4994 | |
4995 account = gaim_connection_get_account(gc); | |
9015 | 4996 buf = g_strconcat(gaim_account_get_username(account), " (", |
4997 plugin->info->name, ")", NULL); | |
7620 | 4998 menuitem = gtk_image_menu_item_new_with_label(buf); |
9015 | 4999 g_free(buf); |
5000 | |
5001 pixbuf = create_prpl_icon(account); | |
9019 | 5002 if (pixbuf) { |
7620 | 5003 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, |
5004 GDK_INTERP_BILINEAR); | |
5005 image = gtk_image_new_from_pixbuf(scale); | |
5006 g_object_unref(G_OBJECT(pixbuf)); | |
5007 g_object_unref(G_OBJECT(scale)); | |
5008 gtk_widget_show(image); | |
9015 | 5009 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); |
7620 | 5010 } |
5011 | |
5012 gtk_menu_shell_append(GTK_MENU_SHELL(protomenu), menuitem); | |
5013 gtk_widget_show(menuitem); | |
5014 | |
5015 submenu = gtk_menu_new(); | |
5016 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
5017 gtk_widget_show(submenu); | |
5018 | |
9015 | 5019 build_plugin_actions(submenu, plugin, gc); |
7620 | 5020 } |
5021 } | |
5022 } | |
8986 | 5023 |
5024 | |
5025 void | |
5026 gaim_gtk_blist_update_plugin_actions(void) | |
5027 { | |
9015 | 5028 GtkWidget *menuitem, *submenu; |
5029 GaimPlugin *plugin = NULL; | |
8986 | 5030 GList *l; |
5031 int count = 0; | |
5032 | |
9019 | 5033 if (pluginmenu == NULL) |
8986 | 5034 return; |
5035 | |
9019 | 5036 /* Clear the old Account Actions menu */ |
9015 | 5037 for (l = gtk_container_get_children(GTK_CONTAINER(pluginmenu)); l; l = l->next) { |
5038 GaimPluginAction *action; | |
8986 | 5039 |
5040 menuitem = l->data; | |
9015 | 5041 action = g_object_get_data(G_OBJECT(menuitem), "plugin_action"); |
5042 g_free(action); | |
8986 | 5043 |
5044 gtk_container_remove(GTK_CONTAINER(pluginmenu), GTK_WIDGET(menuitem)); | |
5045 } | |
5046 | |
9019 | 5047 /* Count the number of plugins with actions */ |
9015 | 5048 for (l = gaim_plugins_get_loaded(); l; l = l->next) { |
5049 plugin = (GaimPlugin *) l->data; | |
5050 | |
9019 | 5051 if (!GAIM_IS_PROTOCOL_PLUGIN(plugin) && GAIM_PLUGIN_HAS_ACTIONS(plugin)) |
5052 count++; | |
5053 | |
5054 /* no need to count past 2, so don't */ | |
5055 if (count > 1) | |
9015 | 5056 break; |
8986 | 5057 } |
5058 | |
5059 if (count == 0) { | |
5060 menuitem = gtk_menu_item_new_with_label(_("No actions available")); | |
5061 gtk_menu_shell_append(GTK_MENU_SHELL(pluginmenu), menuitem); | |
9015 | 5062 gtk_widget_set_sensitive(menuitem, FALSE); |
8986 | 5063 gtk_widget_show(menuitem); |
5064 } | |
9019 | 5065 |
5066 else if (count == 1) { | |
5067 /* Find the one plugin that has actions */ | |
5068 for (l = gaim_plugins_get_loaded(); l; l = l->next) { | |
5069 plugin = (GaimPlugin *) l->data; | |
5070 | |
5071 if (!GAIM_IS_PROTOCOL_PLUGIN(plugin) && GAIM_PLUGIN_HAS_ACTIONS(plugin)) | |
5072 break; | |
5073 } | |
5074 | |
9015 | 5075 build_plugin_actions(pluginmenu, plugin, NULL); |
8986 | 5076 } |
9019 | 5077 |
8986 | 5078 else { |
9015 | 5079 for (l = gaim_plugins_get_loaded(); l; l = l->next) { |
5080 plugin = (GaimPlugin *) l->data; | |
5081 | |
5082 if (GAIM_IS_PROTOCOL_PLUGIN(plugin)) | |
8986 | 5083 continue; |
5084 | |
9019 | 5085 if (!GAIM_PLUGIN_HAS_ACTIONS(plugin)) |
9015 | 5086 continue; |
5087 | |
5088 menuitem = gtk_image_menu_item_new_with_label(plugin->info->name); | |
8986 | 5089 gtk_menu_shell_append(GTK_MENU_SHELL(pluginmenu), menuitem); |
5090 gtk_widget_show(menuitem); | |
5091 | |
5092 submenu = gtk_menu_new(); | |
5093 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
5094 gtk_widget_show(submenu); | |
5095 | |
9015 | 5096 build_plugin_actions(submenu, plugin, NULL); |
8986 | 5097 } |
5098 } | |
5099 } | |
9811 | 5100 |