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