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