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