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