Mercurial > pidgin.yaz
annotate gtk/gtkdocklet.c @ 14837:118fd0dc5b6e
[gaim-migrate @ 17606]
Add a "handle" parameter to gaim_proxy_connect(). It seemed like
people thought this was a good idea. You can still cancel
each gaim_proxy_connect() individually, if needed. I passed in
NULL for the handle in most places. It might be better to pass
in the gc in more places, but these changes do no harm, and they
should help some Yahoo! things, and I wanted to get the API change in.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sat, 28 Oct 2006 20:04:03 +0000 |
parents | dd000ac4d148 |
children | 3a23706f9f4b |
rev | line source |
---|---|
14681 | 1 /* |
2 * System tray icon (aka docklet) plugin for Gaim | |
3 * | |
4 * Copyright (C) 2002-3 Robert McQueen <robot101@debian.org> | |
5 * Copyright (C) 2003 Herman Bloggs <hermanator12002@yahoo.com> | |
6 * Inspired by a similar plugin by: | |
7 * John (J5) Palmieri <johnp@martianrock.com> | |
8 * | |
9 * This program is free software; you can redistribute it and/or | |
10 * modify it under the terms of the GNU General Public License as | |
11 * published by the Free Software Foundation; either version 2 of the | |
12 * License, or (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, but | |
15 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
22 * 02111-1307, USA. | |
23 */ | |
24 #include "internal.h" | |
25 #include "gtkgaim.h" | |
26 | |
27 #include "core.h" | |
28 #include "conversation.h" | |
29 #include "debug.h" | |
30 #include "prefs.h" | |
31 #include "signals.h" | |
32 #include "sound.h" | |
33 | |
34 #include "gtkaccount.h" | |
35 #include "gtkblist.h" | |
36 #include "gtkconv.h" | |
37 #include "gtkplugin.h" | |
38 #include "gtkprefs.h" | |
39 #include "gtksavedstatuses.h" | |
40 #include "gtksound.h" | |
41 #include "gtkutils.h" | |
42 #include "gaimstock.h" | |
43 #include "gtkdocklet.h" | |
44 #include "gtkdialogs.h" | |
45 | |
46 #ifndef DOCKLET_TOOLTIP_LINE_LIMIT | |
47 #define DOCKLET_TOOLTIP_LINE_LIMIT 5 | |
48 #endif | |
49 | |
50 /* globals */ | |
51 static struct docklet_ui_ops *ui_ops = NULL; | |
52 static DockletStatus status = DOCKLET_STATUS_OFFLINE; | |
53 static gboolean enable_join_chat = FALSE; | |
54 static guint docklet_blinking_timer = 0; | |
55 static gboolean visibility_manager = FALSE; | |
56 | |
57 /************************************************************************** | |
58 * docklet status and utility functions | |
59 **************************************************************************/ | |
60 static gboolean | |
61 docklet_blink_icon() | |
62 { | |
63 static gboolean blinked = FALSE; | |
64 gboolean ret = FALSE; /* by default, don't keep blinking */ | |
65 | |
66 blinked = !blinked; | |
67 | |
68 switch (status) { | |
69 case DOCKLET_STATUS_ONLINE_PENDING: | |
70 case DOCKLET_STATUS_AWAY_PENDING: | |
71 if (blinked) { | |
72 if (ui_ops && ui_ops->blank_icon) | |
73 ui_ops->blank_icon(); | |
74 } else { | |
75 if (ui_ops && ui_ops->update_icon) | |
76 ui_ops->update_icon(status); | |
77 } | |
78 ret = TRUE; /* keep blinking */ | |
79 break; | |
80 default: | |
81 docklet_blinking_timer = 0; | |
82 blinked = FALSE; | |
83 break; | |
84 } | |
85 | |
86 return ret; | |
87 } | |
88 | |
89 static GList * | |
90 get_pending_list(guint max) | |
91 { | |
92 GList *l_im = NULL; | |
93 GList *l_chat = NULL; | |
94 | |
14751 | 95 l_im = gaim_gtk_conversations_find_unseen_list(GAIM_CONV_TYPE_IM, |
96 GAIM_UNSEEN_TEXT, | |
97 FALSE, max); | |
14681 | 98 |
14751 | 99 l_chat = gaim_gtk_conversations_find_unseen_list(GAIM_CONV_TYPE_CHAT, |
100 GAIM_UNSEEN_NICK, | |
101 FALSE, max); | |
14681 | 102 |
103 if (l_im != NULL && l_chat != NULL) | |
104 return g_list_concat(l_im, l_chat); | |
105 else if (l_im != NULL) | |
106 return l_im; | |
107 else | |
108 return l_chat; | |
109 } | |
110 | |
111 static gboolean | |
112 docklet_update_status() | |
113 { | |
14813 | 114 GList *convs = NULL; |
14681 | 115 GList *l; |
116 int count; | |
117 DockletStatus newstatus = DOCKLET_STATUS_OFFLINE; | |
118 gboolean pending = FALSE; | |
119 | |
120 /* determine if any ims have unseen messages */ | |
121 convs = get_pending_list(DOCKLET_TOOLTIP_LINE_LIMIT); | |
122 | |
123 if (convs != NULL) { | |
124 pending = TRUE; | |
125 | |
126 /* set tooltip if messages are pending */ | |
127 if (ui_ops->set_tooltip) { | |
128 GString *tooltip_text = g_string_new(""); | |
129 for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) { | |
130 if (GAIM_IS_GTK_CONVERSATION(l->data)) { | |
131 GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION((GaimConversation *)l->data); | |
132 if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) | |
133 g_string_append(tooltip_text, _("Right-click for more unread messages...\n")); | |
134 else | |
135 g_string_append_printf(tooltip_text, | |
136 ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count), | |
137 gtkconv->unseen_count, | |
138 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); | |
139 } | |
140 } | |
141 | |
142 /* get rid of the last newline */ | |
143 if (tooltip_text->len > 0) | |
144 tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len - 1); | |
145 | |
146 ui_ops->set_tooltip(tooltip_text->str); | |
147 | |
148 g_string_free(tooltip_text, TRUE); | |
149 } | |
150 | |
151 g_list_free(convs); | |
152 | |
153 } else if (ui_ops->set_tooltip) { | |
154 ui_ops->set_tooltip(NULL); | |
155 } | |
156 | |
157 /* iterate through all accounts and determine which | |
158 * status to show in the tray icon based on the following | |
159 * ranks (highest encountered rank will be used): | |
160 * | |
161 * 1) OFFLINE | |
162 * 2) ONLINE | |
163 * 3) ONLINE_PENDING | |
164 * 4) AWAY | |
165 * 5) AWAY_PENDING | |
166 * 6) CONNECTING | |
167 */ | |
168 for(l = gaim_accounts_get_all(); l != NULL; l = l->next) { | |
169 DockletStatus tmpstatus = DOCKLET_STATUS_OFFLINE; | |
170 | |
171 GaimAccount *account = (GaimAccount*)l->data; | |
172 GaimStatus *account_status; | |
173 | |
174 if (!gaim_account_get_enabled(account, GAIM_GTK_UI)) | |
175 continue; | |
176 | |
177 if (gaim_account_is_disconnected(account)) | |
178 continue; | |
179 | |
180 account_status = gaim_account_get_active_status(account); | |
181 | |
182 if (gaim_account_is_connecting(account)) { | |
183 tmpstatus = DOCKLET_STATUS_CONNECTING; | |
184 } else if (gaim_status_is_online(account_status)) { | |
185 if (!gaim_status_is_available(account_status)) { | |
186 if (pending) | |
187 tmpstatus = DOCKLET_STATUS_AWAY_PENDING; | |
188 else | |
189 tmpstatus = DOCKLET_STATUS_AWAY; | |
190 } | |
191 else { | |
192 if (pending) | |
193 tmpstatus = DOCKLET_STATUS_ONLINE_PENDING; | |
194 else | |
195 tmpstatus = DOCKLET_STATUS_ONLINE; | |
196 } | |
197 } | |
198 | |
199 if (tmpstatus > newstatus) | |
200 newstatus = tmpstatus; | |
201 } | |
202 | |
203 /* update the icon if we changed status */ | |
204 if (status != newstatus) { | |
205 status = newstatus; | |
206 | |
207 if (ui_ops && ui_ops->update_icon) | |
208 ui_ops->update_icon(status); | |
209 | |
210 /* and schedule the blinker function if messages are pending */ | |
14813 | 211 if (gaim_prefs_get_bool("/gaim/gtk/docklet/blink") && |
212 (status == DOCKLET_STATUS_ONLINE_PENDING | |
213 || status == DOCKLET_STATUS_AWAY_PENDING) | |
214 && docklet_blinking_timer == 0) { | |
14681 | 215 docklet_blinking_timer = g_timeout_add(500, docklet_blink_icon, NULL); |
216 } | |
217 } | |
218 | |
219 return FALSE; /* for when we're called by the glib idle handler */ | |
220 } | |
221 | |
222 static gboolean | |
223 online_account_supports_chat() | |
224 { | |
225 GList *c = NULL; | |
226 c = gaim_connections_get_all(); | |
227 | |
228 while(c != NULL) { | |
229 GaimConnection *gc = c->data; | |
230 GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
231 if (prpl_info != NULL && prpl_info->chat_info != NULL) | |
232 return TRUE; | |
233 c = c->next; | |
234 } | |
235 | |
236 return FALSE; | |
237 } | |
238 | |
239 /************************************************************************** | |
240 * callbacks and signal handlers | |
241 **************************************************************************/ | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
242 #if 0 |
14681 | 243 static void |
244 gaim_quit_cb() | |
245 { | |
246 /* TODO: confirm quit while pending */ | |
247 } | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
248 #endif |
14681 | 249 |
250 static void | |
251 docklet_update_status_cb(void *data) | |
252 { | |
253 docklet_update_status(); | |
254 } | |
255 | |
256 static void | |
257 docklet_conv_updated_cb(GaimConversation *conv, GaimConvUpdateType type) | |
258 { | |
259 if (type == GAIM_CONV_UPDATE_UNSEEN) | |
260 docklet_update_status(); | |
261 } | |
262 | |
263 static void | |
264 docklet_signed_on_cb(GaimConnection *gc) | |
265 { | |
266 if (!enable_join_chat) { | |
267 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) | |
268 enable_join_chat = TRUE; | |
269 } | |
270 docklet_update_status(); | |
271 } | |
272 | |
273 static void | |
274 docklet_signed_off_cb(GaimConnection *gc) | |
275 { | |
276 if (enable_join_chat) { | |
277 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) | |
278 enable_join_chat = online_account_supports_chat(); | |
279 } | |
280 docklet_update_status(); | |
281 } | |
282 | |
283 /************************************************************************** | |
284 * docklet pop-up menu | |
285 **************************************************************************/ | |
286 static void | |
287 docklet_toggle_mute(GtkWidget *toggle, void *data) | |
288 { | |
289 gaim_prefs_set_bool("/gaim/gtk/sound/mute", GTK_CHECK_MENU_ITEM(toggle)->active); | |
290 } | |
291 | |
292 static void | |
14813 | 293 docklet_toggle_blink(GtkWidget *toggle, void *data) |
294 { | |
295 gaim_prefs_set_bool("/gaim/gtk/docklet/blink", GTK_CHECK_MENU_ITEM(toggle)->active); | |
296 } | |
297 | |
298 static void | |
14681 | 299 docklet_toggle_blist(GtkWidget *toggle, void *data) |
300 { | |
301 gaim_blist_set_visible(GTK_CHECK_MENU_ITEM(toggle)->active); | |
302 } | |
303 | |
304 #ifdef _WIN32 | |
305 /* This is a workaround for a bug in windows GTK+. Clicking outside of the | |
306 menu does not get rid of it, so instead we get rid of it as soon as the | |
307 pointer leaves the menu. */ | |
308 static gboolean | |
309 hide_docklet_menu(gpointer data) | |
310 { | |
311 if (data != NULL) { | |
312 gtk_menu_popdown(GTK_MENU(data)); | |
313 } | |
314 return FALSE; | |
315 } | |
316 | |
317 static gboolean | |
318 docklet_menu_leave_enter(GtkWidget *menu, GdkEventCrossing *event, void *data) | |
319 { | |
320 static guint hide_docklet_timer = 0; | |
321 if (event->type == GDK_LEAVE_NOTIFY && event->detail == GDK_NOTIFY_ANCESTOR) { | |
322 gaim_debug(GAIM_DEBUG_INFO, "docklet", "menu leave-notify-event\n"); | |
323 /* Add some slop so that the menu doesn't annoyingly disappear when mousing around */ | |
324 if (hide_docklet_timer == 0) { | |
325 hide_docklet_timer = gaim_timeout_add(500, | |
326 hide_docklet_menu, menu); | |
327 } | |
328 } else if (event->type == GDK_ENTER_NOTIFY && event->detail == GDK_NOTIFY_ANCESTOR) { | |
329 gaim_debug(GAIM_DEBUG_INFO, "docklet", "menu enter-notify-event\n"); | |
330 if (hide_docklet_timer != 0) { | |
331 /* Cancel the hiding if we reenter */ | |
332 | |
333 gaim_timeout_remove(hide_docklet_timer); | |
334 hide_docklet_timer = 0; | |
335 } | |
336 } | |
337 return FALSE; | |
338 } | |
339 #endif | |
340 | |
341 static void | |
342 show_custom_status_editor_cb(GtkMenuItem *menuitem, gpointer user_data) | |
343 { | |
344 GaimSavedStatus *saved_status; | |
345 saved_status = gaim_savedstatus_get_current(); | |
346 gaim_gtk_status_editor_show(FALSE, | |
347 gaim_savedstatus_is_transient(saved_status) ? saved_status : NULL); | |
348 } | |
349 | |
350 static void | |
351 activate_status_primitive_cb(GtkMenuItem *menuitem, gpointer user_data) | |
352 { | |
353 GaimStatusPrimitive primitive; | |
354 GaimSavedStatus *saved_status; | |
355 | |
356 primitive = GPOINTER_TO_INT(user_data); | |
357 | |
358 /* Try to lookup an already existing transient saved status */ | |
359 saved_status = gaim_savedstatus_find_transient_by_type_and_message(primitive, NULL); | |
360 | |
361 /* Create a new transient saved status if we weren't able to find one */ | |
362 if (saved_status == NULL) | |
363 saved_status = gaim_savedstatus_new(NULL, primitive); | |
364 | |
365 /* Set the status for each account */ | |
366 gaim_savedstatus_activate(saved_status); | |
367 } | |
368 | |
369 static void | |
370 activate_saved_status_cb(GtkMenuItem *menuitem, gpointer user_data) | |
371 { | |
372 time_t creation_time; | |
373 GaimSavedStatus *saved_status; | |
374 | |
375 creation_time = GPOINTER_TO_INT(user_data); | |
376 saved_status = gaim_savedstatus_find_by_creation_time(creation_time); | |
377 if (saved_status != NULL) | |
378 gaim_savedstatus_activate(saved_status); | |
379 } | |
380 | |
381 static GtkWidget * | |
382 new_menu_item_with_gaim_icon(GtkWidget *menu, const char *str, GaimStatusPrimitive primitive, GtkSignalFunc sf, gpointer data, guint accel_key, guint accel_mods, char *mod) | |
383 { | |
384 GtkWidget *menuitem; | |
385 GdkPixbuf *pixbuf; | |
386 GtkWidget *image; | |
387 | |
388 menuitem = gtk_image_menu_item_new_with_mnemonic(str); | |
389 | |
390 if (menu) | |
391 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
392 | |
393 if (sf) | |
394 g_signal_connect(G_OBJECT(menuitem), "activate", sf, data); | |
395 | |
396 pixbuf = gaim_gtk_create_gaim_icon_with_status(primitive, 0.5); | |
397 image = gtk_image_new_from_pixbuf(pixbuf); | |
398 g_object_unref(pixbuf); | |
399 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); | |
400 | |
401 gtk_widget_show_all(menuitem); | |
402 | |
403 return menuitem; | |
404 } | |
405 | |
406 static GtkWidget * | |
407 docklet_status_submenu() | |
408 { | |
409 GtkWidget *submenu, *menuitem; | |
410 GList *popular_statuses, *cur; | |
411 | |
412 submenu = gtk_menu_new(); | |
413 menuitem = gtk_menu_item_new_with_label(_("Change Status")); | |
414 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
415 | |
416 new_menu_item_with_gaim_icon(submenu, _("Available"), | |
417 GAIM_STATUS_AVAILABLE, G_CALLBACK(activate_status_primitive_cb), | |
418 GINT_TO_POINTER(GAIM_STATUS_AVAILABLE), 0, 0, NULL); | |
419 | |
420 new_menu_item_with_gaim_icon(submenu, _("Away"), | |
421 GAIM_STATUS_AWAY, G_CALLBACK(activate_status_primitive_cb), | |
422 GINT_TO_POINTER(GAIM_STATUS_AWAY), 0, 0, NULL); | |
423 | |
424 new_menu_item_with_gaim_icon(submenu, _("Invisible"), | |
425 GAIM_STATUS_INVISIBLE, G_CALLBACK(activate_status_primitive_cb), | |
426 GINT_TO_POINTER(GAIM_STATUS_INVISIBLE), 0, 0, NULL); | |
427 | |
428 new_menu_item_with_gaim_icon(submenu, _("Offline"), | |
429 GAIM_STATUS_OFFLINE, G_CALLBACK(activate_status_primitive_cb), | |
430 GINT_TO_POINTER(GAIM_STATUS_OFFLINE), 0, 0, NULL); | |
431 | |
432 popular_statuses = gaim_savedstatuses_get_popular(6); | |
433 if (popular_statuses != NULL) | |
434 gaim_separator(submenu); | |
435 for (cur = popular_statuses; cur != NULL; cur = cur->next) | |
436 { | |
437 GaimSavedStatus *saved_status = cur->data; | |
438 time_t creation_time = gaim_savedstatus_get_creation_time(saved_status); | |
439 new_menu_item_with_gaim_icon(submenu, | |
440 gaim_savedstatus_get_title(saved_status), | |
441 gaim_savedstatus_get_type(saved_status), G_CALLBACK(activate_saved_status_cb), | |
442 GINT_TO_POINTER(creation_time), 0, 0, NULL); | |
443 } | |
444 g_list_free(popular_statuses); | |
445 | |
446 gaim_separator(submenu); | |
447 | |
448 new_menu_item_with_gaim_icon(submenu, _("New..."), GAIM_STATUS_AVAILABLE, G_CALLBACK(show_custom_status_editor_cb), NULL, 0, 0, NULL); | |
449 new_menu_item_with_gaim_icon(submenu, _("Saved..."), GAIM_STATUS_AVAILABLE, G_CALLBACK(gaim_gtk_status_window_show), NULL, 0, 0, NULL); | |
450 | |
451 return menuitem; | |
452 } | |
453 | |
454 static void | |
455 docklet_menu() { | |
456 static GtkWidget *menu = NULL; | |
457 GtkWidget *menuitem; | |
458 | |
459 if (menu) { | |
460 gtk_widget_destroy(menu); | |
461 } | |
462 | |
463 menu = gtk_menu_new(); | |
464 | |
465 menuitem = gtk_check_menu_item_new_with_label(_("Show Buddy List")); | |
466 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")); | |
467 g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_blist), NULL); | |
468 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
469 | |
470 menuitem = gtk_menu_item_new_with_label(_("Unread Messages")); | |
471 | |
472 if (status == DOCKLET_STATUS_ONLINE_PENDING || status == DOCKLET_STATUS_AWAY_PENDING) { | |
473 GtkWidget *submenu = gtk_menu_new(); | |
474 GList *l = get_pending_list(0); | |
475 if (l == NULL) { | |
476 gtk_widget_set_sensitive(menuitem, FALSE); | |
477 gaim_debug_warning("docklet", | |
478 "status indicates messages pending, but no conversations with unseen messages were found."); | |
479 } else { | |
480 gaim_gtk_conversations_fill_menu(submenu, l); | |
481 g_list_free(l); | |
482 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
483 } | |
484 } else { | |
485 gtk_widget_set_sensitive(menuitem, FALSE); | |
486 } | |
487 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
488 | |
489 gaim_separator(menu); | |
490 | |
491 menuitem = gaim_new_item_from_stock(menu, _("New Message..."), GAIM_STOCK_IM, G_CALLBACK(gaim_gtkdialogs_im), NULL, 0, 0, NULL); | |
492 if (status == DOCKLET_STATUS_OFFLINE) | |
493 gtk_widget_set_sensitive(menuitem, FALSE); | |
494 | |
495 menuitem = docklet_status_submenu(); | |
496 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
497 | |
498 gaim_separator(menu); | |
499 | |
500 gaim_new_item_from_stock(menu, _("Accounts"), GAIM_STOCK_ACCOUNTS, G_CALLBACK(gaim_gtk_accounts_window_show), NULL, 0, 0, NULL); | |
501 gaim_new_item_from_stock(menu, _("Plugins"), GAIM_STOCK_PLUGIN, G_CALLBACK(gaim_gtk_plugin_dialog_show), NULL, 0, 0, NULL); | |
502 gaim_new_item_from_stock(menu, _("Preferences"), GTK_STOCK_PREFERENCES, G_CALLBACK(gaim_gtk_prefs_show), NULL, 0, 0, NULL); | |
503 | |
504 gaim_separator(menu); | |
505 | |
506 menuitem = gtk_check_menu_item_new_with_label(_("Mute Sounds")); | |
507 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), gaim_prefs_get_bool("/gaim/gtk/sound/mute")); | |
508 if (!strcmp(gaim_prefs_get_string("/gaim/gtk/sound/method"), "none")) | |
509 gtk_widget_set_sensitive(GTK_WIDGET(menuitem), FALSE); | |
510 g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_mute), NULL); | |
511 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
14813 | 512 |
513 menuitem = gtk_check_menu_item_new_with_label(_("Blink on new message")); | |
514 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), gaim_prefs_get_bool("/gaim/gtk/docklet/blink")); | |
515 g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_blink), NULL); | |
516 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
14681 | 517 |
518 gaim_separator(menu); | |
519 | |
520 /* TODO: need a submenu to change status, this needs to "link" | |
521 * to the status in the buddy list gtkstatusbox | |
522 */ | |
523 | |
524 gaim_new_item_from_stock(menu, _("Quit"), GTK_STOCK_QUIT, G_CALLBACK(gaim_core_quit), NULL, 0, 0, NULL); | |
525 | |
526 #ifdef _WIN32 | |
527 g_signal_connect(menu, "leave-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL); | |
528 g_signal_connect(menu, "enter-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL); | |
529 #endif | |
530 gtk_widget_show_all(menu); | |
531 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, | |
532 ui_ops->position_menu, | |
533 NULL, 0, gtk_get_current_event_time()); | |
534 } | |
535 | |
536 /************************************************************************** | |
537 * public api for ui_ops | |
538 **************************************************************************/ | |
539 void | |
540 gaim_gtk_docklet_clicked(int button_type) | |
541 { | |
542 switch (button_type) { | |
543 case 1: | |
544 if (status == DOCKLET_STATUS_ONLINE_PENDING || status == DOCKLET_STATUS_AWAY_PENDING) { | |
545 GList *l = get_pending_list(1); | |
546 if (l != NULL) { | |
547 gaim_gtkconv_present_conversation((GaimConversation *)l->data); | |
548 g_list_free(l); | |
549 } | |
550 } else { | |
551 gaim_gtk_blist_toggle_visibility(); | |
552 } | |
553 break; | |
554 case 3: | |
555 docklet_menu(); | |
556 break; | |
557 } | |
558 } | |
559 | |
560 void | |
561 gaim_gtk_docklet_embedded() | |
562 { | |
563 if (!visibility_manager) { | |
564 gaim_gtk_blist_visibility_manager_add(); | |
565 visibility_manager = TRUE; | |
566 } | |
567 docklet_update_status(); | |
568 if (ui_ops && ui_ops->update_icon) | |
569 ui_ops->update_icon(status); | |
570 } | |
571 | |
572 void | |
573 gaim_gtk_docklet_remove() | |
574 { | |
575 if (visibility_manager) { | |
576 gaim_gtk_blist_visibility_manager_remove(); | |
577 visibility_manager = FALSE; | |
578 } | |
579 } | |
580 | |
581 void | |
582 gaim_gtk_docklet_set_ui_ops(struct docklet_ui_ops *ops) | |
583 { | |
584 ui_ops = ops; | |
585 } | |
586 | |
587 void* | |
588 gaim_gtk_docklet_get_handle() | |
589 { | |
590 static int i; | |
591 return &i; | |
592 } | |
593 | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
594 void |
14681 | 595 gaim_gtk_docklet_init() |
596 { | |
597 void *conn_handle = gaim_connections_get_handle(); | |
598 void *conv_handle = gaim_conversations_get_handle(); | |
599 void *accounts_handle = gaim_accounts_get_handle(); | |
600 void *docklet_handle = gaim_gtk_docklet_get_handle(); | |
14813 | 601 |
602 gaim_prefs_add_none("/gaim/gtk/docklet"); | |
603 gaim_prefs_add_bool("/gaim/gtk/docklet/blink", FALSE); | |
604 gaim_prefs_add_string("/gaim/gtk/docklet/show", "always"); | |
14681 | 605 |
606 docklet_ui_init(); | |
607 if (ui_ops && ui_ops->create) | |
608 ui_ops->create(); | |
609 gaim_signal_connect(conn_handle, "signed-on", | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
610 docklet_handle, GAIM_CALLBACK(docklet_signed_on_cb), NULL); |
14681 | 611 gaim_signal_connect(conn_handle, "signed-off", |
612 docklet_handle, GAIM_CALLBACK(docklet_signed_off_cb), NULL); | |
613 gaim_signal_connect(accounts_handle, "account-status-changed", | |
614 docklet_handle, GAIM_CALLBACK(docklet_update_status_cb), NULL); | |
615 gaim_signal_connect(conv_handle, "received-im-msg", | |
616 docklet_handle, GAIM_CALLBACK(docklet_update_status_cb), NULL); | |
617 gaim_signal_connect(conv_handle, "conversation-created", | |
618 docklet_handle, GAIM_CALLBACK(docklet_update_status_cb), NULL); | |
619 gaim_signal_connect(conv_handle, "deleting-conversation", | |
620 docklet_handle, GAIM_CALLBACK(docklet_update_status_cb), NULL); | |
621 gaim_signal_connect(conv_handle, "conversation-updated", | |
622 docklet_handle, GAIM_CALLBACK(docklet_conv_updated_cb), NULL); | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
623 #if 0 |
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
624 gaim_signal_connect(gaim_get_core(), "quitting", |
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
625 docklet_handle, GAIM_CALLBACK(gaim_quit_cb), NULL); |
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
626 #endif |
14681 | 627 |
628 enable_join_chat = online_account_supports_chat(); | |
629 } | |
630 | |
631 void | |
632 gaim_gtk_docklet_uninit() | |
633 { | |
634 if (ui_ops && ui_ops->destroy) | |
635 ui_ops->destroy(); | |
636 } |