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