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