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