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