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