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