Mercurial > pidgin.yaz
annotate gtk/gtkdocklet.c @ 14739:63d5b71d0c68
[gaim-migrate @ 17495]
This should fix the statusbox issues that were keeping us from releasing beta
4 (and which were just really annoying). Thakn sadrul for most of this, I just
added the if (index == -1) bit. Anyway, the way this works now is that for
saved/popular statuses the primitive underlying that status is where the
dropdown for the statusbox starts. If we don't like that we can change it but
I'm not sure we'll find something better.
Also, this might plug a couple leaks, I'm not really sure but it certainly
looks right.
Up next, the patch to make the docklet use the per-protocol statuses in the
top section.
committer: Tailor Script <tailor@pidgin.im>
author | Etan Reisner <pidgin@unreliablesource.net> |
---|---|
date | Tue, 17 Oct 2006 08:13:41 +0000 |
parents | a8c2af13b96d |
children | 510da3975938 |
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 const char *im = gaim_prefs_get_string("/plugins/gtk/docklet/blink_im"); | |
93 const char *chat = gaim_prefs_get_string("/plugins/gtk/docklet/blink_chat"); | |
94 GList *l_im = NULL; | |
95 GList *l_chat = NULL; | |
96 | |
97 if (im != NULL && strcmp(im, "always") == 0) { | |
98 l_im = gaim_gtk_conversations_find_unseen_list(GAIM_CONV_TYPE_IM, | |
99 GAIM_UNSEEN_TEXT, | |
100 FALSE, max); | |
101 } else if (im != NULL && strcmp(im, "hidden") == 0) { | |
102 l_im = gaim_gtk_conversations_find_unseen_list(GAIM_CONV_TYPE_IM, | |
103 GAIM_UNSEEN_TEXT, | |
104 TRUE, max); | |
105 } | |
106 | |
107 if (chat != NULL && strcmp(chat, "always") == 0) { | |
108 l_chat = gaim_gtk_conversations_find_unseen_list(GAIM_CONV_TYPE_CHAT, | |
109 GAIM_UNSEEN_TEXT, | |
110 FALSE, max); | |
111 } else if (chat != NULL && strcmp(chat, "nick") == 0) { | |
112 l_chat = gaim_gtk_conversations_find_unseen_list(GAIM_CONV_TYPE_CHAT, | |
113 GAIM_UNSEEN_NICK, | |
114 FALSE, max); | |
115 } | |
116 | |
117 if (l_im != NULL && l_chat != NULL) | |
118 return g_list_concat(l_im, l_chat); | |
119 else if (l_im != NULL) | |
120 return l_im; | |
121 else | |
122 return l_chat; | |
123 } | |
124 | |
125 static gboolean | |
126 docklet_update_status() | |
127 { | |
128 GList *convs; | |
129 GList *l; | |
130 int count; | |
131 DockletStatus newstatus = DOCKLET_STATUS_OFFLINE; | |
132 gboolean pending = FALSE; | |
133 | |
134 /* determine if any ims have unseen messages */ | |
135 convs = get_pending_list(DOCKLET_TOOLTIP_LINE_LIMIT); | |
136 | |
137 if (convs != NULL) { | |
138 pending = TRUE; | |
139 | |
140 /* set tooltip if messages are pending */ | |
141 if (ui_ops->set_tooltip) { | |
142 GString *tooltip_text = g_string_new(""); | |
143 for (l = convs, count = 0 ; l != NULL ; l = l->next, count++) { | |
144 if (GAIM_IS_GTK_CONVERSATION(l->data)) { | |
145 GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION((GaimConversation *)l->data); | |
146 if (count == DOCKLET_TOOLTIP_LINE_LIMIT - 1) | |
147 g_string_append(tooltip_text, _("Right-click for more unread messages...\n")); | |
148 else | |
149 g_string_append_printf(tooltip_text, | |
150 ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count), | |
151 gtkconv->unseen_count, | |
152 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); | |
153 } | |
154 } | |
155 | |
156 /* get rid of the last newline */ | |
157 if (tooltip_text->len > 0) | |
158 tooltip_text = g_string_truncate(tooltip_text, tooltip_text->len - 1); | |
159 | |
160 ui_ops->set_tooltip(tooltip_text->str); | |
161 | |
162 g_string_free(tooltip_text, TRUE); | |
163 } | |
164 | |
165 g_list_free(convs); | |
166 | |
167 } else if (ui_ops->set_tooltip) { | |
168 ui_ops->set_tooltip(NULL); | |
169 } | |
170 | |
171 /* iterate through all accounts and determine which | |
172 * status to show in the tray icon based on the following | |
173 * ranks (highest encountered rank will be used): | |
174 * | |
175 * 1) OFFLINE | |
176 * 2) ONLINE | |
177 * 3) ONLINE_PENDING | |
178 * 4) AWAY | |
179 * 5) AWAY_PENDING | |
180 * 6) CONNECTING | |
181 */ | |
182 for(l = gaim_accounts_get_all(); l != NULL; l = l->next) { | |
183 DockletStatus tmpstatus = DOCKLET_STATUS_OFFLINE; | |
184 | |
185 GaimAccount *account = (GaimAccount*)l->data; | |
186 GaimStatus *account_status; | |
187 | |
188 if (!gaim_account_get_enabled(account, GAIM_GTK_UI)) | |
189 continue; | |
190 | |
191 if (gaim_account_is_disconnected(account)) | |
192 continue; | |
193 | |
194 account_status = gaim_account_get_active_status(account); | |
195 | |
196 if (gaim_account_is_connecting(account)) { | |
197 tmpstatus = DOCKLET_STATUS_CONNECTING; | |
198 } else if (gaim_status_is_online(account_status)) { | |
199 if (!gaim_status_is_available(account_status)) { | |
200 if (pending) | |
201 tmpstatus = DOCKLET_STATUS_AWAY_PENDING; | |
202 else | |
203 tmpstatus = DOCKLET_STATUS_AWAY; | |
204 } | |
205 else { | |
206 if (pending) | |
207 tmpstatus = DOCKLET_STATUS_ONLINE_PENDING; | |
208 else | |
209 tmpstatus = DOCKLET_STATUS_ONLINE; | |
210 } | |
211 } | |
212 | |
213 if (tmpstatus > newstatus) | |
214 newstatus = tmpstatus; | |
215 } | |
216 | |
217 /* update the icon if we changed status */ | |
218 if (status != newstatus) { | |
219 status = newstatus; | |
220 | |
221 if (ui_ops && ui_ops->update_icon) | |
222 ui_ops->update_icon(status); | |
223 | |
224 /* and schedule the blinker function if messages are pending */ | |
225 if ((status == DOCKLET_STATUS_ONLINE_PENDING | |
226 || status == DOCKLET_STATUS_AWAY_PENDING) | |
227 && docklet_blinking_timer == 0) { | |
228 docklet_blinking_timer = g_timeout_add(500, docklet_blink_icon, NULL); | |
229 } | |
230 } | |
231 | |
232 return FALSE; /* for when we're called by the glib idle handler */ | |
233 } | |
234 | |
235 static gboolean | |
236 online_account_supports_chat() | |
237 { | |
238 GList *c = NULL; | |
239 c = gaim_connections_get_all(); | |
240 | |
241 while(c != NULL) { | |
242 GaimConnection *gc = c->data; | |
243 GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
244 if (prpl_info != NULL && prpl_info->chat_info != NULL) | |
245 return TRUE; | |
246 c = c->next; | |
247 } | |
248 | |
249 return FALSE; | |
250 } | |
251 | |
252 /************************************************************************** | |
253 * callbacks and signal handlers | |
254 **************************************************************************/ | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
255 #if 0 |
14681 | 256 static void |
257 gaim_quit_cb() | |
258 { | |
259 /* TODO: confirm quit while pending */ | |
260 } | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
261 #endif |
14681 | 262 |
263 static void | |
264 docklet_update_status_cb(void *data) | |
265 { | |
266 docklet_update_status(); | |
267 } | |
268 | |
269 static void | |
270 docklet_conv_updated_cb(GaimConversation *conv, GaimConvUpdateType type) | |
271 { | |
272 if (type == GAIM_CONV_UPDATE_UNSEEN) | |
273 docklet_update_status(); | |
274 } | |
275 | |
276 static void | |
277 docklet_signed_on_cb(GaimConnection *gc) | |
278 { | |
279 if (!enable_join_chat) { | |
280 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) | |
281 enable_join_chat = TRUE; | |
282 } | |
283 docklet_update_status(); | |
284 } | |
285 | |
286 static void | |
287 docklet_signed_off_cb(GaimConnection *gc) | |
288 { | |
289 if (enable_join_chat) { | |
290 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) | |
291 enable_join_chat = online_account_supports_chat(); | |
292 } | |
293 docklet_update_status(); | |
294 } | |
295 | |
296 /************************************************************************** | |
297 * docklet pop-up menu | |
298 **************************************************************************/ | |
299 static void | |
300 docklet_toggle_mute(GtkWidget *toggle, void *data) | |
301 { | |
302 gaim_prefs_set_bool("/gaim/gtk/sound/mute", GTK_CHECK_MENU_ITEM(toggle)->active); | |
303 } | |
304 | |
305 static void | |
306 docklet_toggle_blist(GtkWidget *toggle, void *data) | |
307 { | |
308 gaim_blist_set_visible(GTK_CHECK_MENU_ITEM(toggle)->active); | |
309 } | |
310 | |
311 #ifdef _WIN32 | |
312 /* This is a workaround for a bug in windows GTK+. Clicking outside of the | |
313 menu does not get rid of it, so instead we get rid of it as soon as the | |
314 pointer leaves the menu. */ | |
315 static gboolean | |
316 hide_docklet_menu(gpointer data) | |
317 { | |
318 if (data != NULL) { | |
319 gtk_menu_popdown(GTK_MENU(data)); | |
320 } | |
321 return FALSE; | |
322 } | |
323 | |
324 static gboolean | |
325 docklet_menu_leave_enter(GtkWidget *menu, GdkEventCrossing *event, void *data) | |
326 { | |
327 static guint hide_docklet_timer = 0; | |
328 if (event->type == GDK_LEAVE_NOTIFY && event->detail == GDK_NOTIFY_ANCESTOR) { | |
329 gaim_debug(GAIM_DEBUG_INFO, "docklet", "menu leave-notify-event\n"); | |
330 /* Add some slop so that the menu doesn't annoyingly disappear when mousing around */ | |
331 if (hide_docklet_timer == 0) { | |
332 hide_docklet_timer = gaim_timeout_add(500, | |
333 hide_docklet_menu, menu); | |
334 } | |
335 } else if (event->type == GDK_ENTER_NOTIFY && event->detail == GDK_NOTIFY_ANCESTOR) { | |
336 gaim_debug(GAIM_DEBUG_INFO, "docklet", "menu enter-notify-event\n"); | |
337 if (hide_docklet_timer != 0) { | |
338 /* Cancel the hiding if we reenter */ | |
339 | |
340 gaim_timeout_remove(hide_docklet_timer); | |
341 hide_docklet_timer = 0; | |
342 } | |
343 } | |
344 return FALSE; | |
345 } | |
346 #endif | |
347 | |
348 static void | |
349 show_custom_status_editor_cb(GtkMenuItem *menuitem, gpointer user_data) | |
350 { | |
351 GaimSavedStatus *saved_status; | |
352 saved_status = gaim_savedstatus_get_current(); | |
353 gaim_gtk_status_editor_show(FALSE, | |
354 gaim_savedstatus_is_transient(saved_status) ? saved_status : NULL); | |
355 } | |
356 | |
357 static void | |
358 activate_status_primitive_cb(GtkMenuItem *menuitem, gpointer user_data) | |
359 { | |
360 GaimStatusPrimitive primitive; | |
361 GaimSavedStatus *saved_status; | |
362 | |
363 primitive = GPOINTER_TO_INT(user_data); | |
364 | |
365 /* Try to lookup an already existing transient saved status */ | |
366 saved_status = gaim_savedstatus_find_transient_by_type_and_message(primitive, NULL); | |
367 | |
368 /* Create a new transient saved status if we weren't able to find one */ | |
369 if (saved_status == NULL) | |
370 saved_status = gaim_savedstatus_new(NULL, primitive); | |
371 | |
372 /* Set the status for each account */ | |
373 gaim_savedstatus_activate(saved_status); | |
374 } | |
375 | |
376 static void | |
377 activate_saved_status_cb(GtkMenuItem *menuitem, gpointer user_data) | |
378 { | |
379 time_t creation_time; | |
380 GaimSavedStatus *saved_status; | |
381 | |
382 creation_time = GPOINTER_TO_INT(user_data); | |
383 saved_status = gaim_savedstatus_find_by_creation_time(creation_time); | |
384 if (saved_status != NULL) | |
385 gaim_savedstatus_activate(saved_status); | |
386 } | |
387 | |
388 static GtkWidget * | |
389 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) | |
390 { | |
391 GtkWidget *menuitem; | |
392 GdkPixbuf *pixbuf; | |
393 GtkWidget *image; | |
394 | |
395 menuitem = gtk_image_menu_item_new_with_mnemonic(str); | |
396 | |
397 if (menu) | |
398 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
399 | |
400 if (sf) | |
401 g_signal_connect(G_OBJECT(menuitem), "activate", sf, data); | |
402 | |
403 pixbuf = gaim_gtk_create_gaim_icon_with_status(primitive, 0.5); | |
404 image = gtk_image_new_from_pixbuf(pixbuf); | |
405 g_object_unref(pixbuf); | |
406 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); | |
407 | |
408 gtk_widget_show_all(menuitem); | |
409 | |
410 return menuitem; | |
411 } | |
412 | |
413 static GtkWidget * | |
414 docklet_status_submenu() | |
415 { | |
416 GtkWidget *submenu, *menuitem; | |
417 GList *popular_statuses, *cur; | |
418 | |
419 submenu = gtk_menu_new(); | |
420 menuitem = gtk_menu_item_new_with_label(_("Change Status")); | |
421 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
422 | |
423 new_menu_item_with_gaim_icon(submenu, _("Available"), | |
424 GAIM_STATUS_AVAILABLE, G_CALLBACK(activate_status_primitive_cb), | |
425 GINT_TO_POINTER(GAIM_STATUS_AVAILABLE), 0, 0, NULL); | |
426 | |
427 new_menu_item_with_gaim_icon(submenu, _("Away"), | |
428 GAIM_STATUS_AWAY, G_CALLBACK(activate_status_primitive_cb), | |
429 GINT_TO_POINTER(GAIM_STATUS_AWAY), 0, 0, NULL); | |
430 | |
431 new_menu_item_with_gaim_icon(submenu, _("Invisible"), | |
432 GAIM_STATUS_INVISIBLE, G_CALLBACK(activate_status_primitive_cb), | |
433 GINT_TO_POINTER(GAIM_STATUS_INVISIBLE), 0, 0, NULL); | |
434 | |
435 new_menu_item_with_gaim_icon(submenu, _("Offline"), | |
436 GAIM_STATUS_OFFLINE, G_CALLBACK(activate_status_primitive_cb), | |
437 GINT_TO_POINTER(GAIM_STATUS_OFFLINE), 0, 0, NULL); | |
438 | |
439 popular_statuses = gaim_savedstatuses_get_popular(6); | |
440 if (popular_statuses != NULL) | |
441 gaim_separator(submenu); | |
442 for (cur = popular_statuses; cur != NULL; cur = cur->next) | |
443 { | |
444 GaimSavedStatus *saved_status = cur->data; | |
445 time_t creation_time = gaim_savedstatus_get_creation_time(saved_status); | |
446 new_menu_item_with_gaim_icon(submenu, | |
447 gaim_savedstatus_get_title(saved_status), | |
448 gaim_savedstatus_get_type(saved_status), G_CALLBACK(activate_saved_status_cb), | |
449 GINT_TO_POINTER(creation_time), 0, 0, NULL); | |
450 } | |
451 g_list_free(popular_statuses); | |
452 | |
453 gaim_separator(submenu); | |
454 | |
455 new_menu_item_with_gaim_icon(submenu, _("New..."), GAIM_STATUS_AVAILABLE, G_CALLBACK(show_custom_status_editor_cb), NULL, 0, 0, NULL); | |
456 new_menu_item_with_gaim_icon(submenu, _("Saved..."), GAIM_STATUS_AVAILABLE, G_CALLBACK(gaim_gtk_status_window_show), NULL, 0, 0, NULL); | |
457 | |
458 return menuitem; | |
459 } | |
460 | |
461 static void | |
462 docklet_menu() { | |
463 static GtkWidget *menu = NULL; | |
464 GtkWidget *menuitem; | |
465 | |
466 if (menu) { | |
467 gtk_widget_destroy(menu); | |
468 } | |
469 | |
470 menu = gtk_menu_new(); | |
471 | |
472 menuitem = gtk_check_menu_item_new_with_label(_("Show Buddy List")); | |
473 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), gaim_prefs_get_bool("/gaim/gtk/blist/list_visible")); | |
474 g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_blist), NULL); | |
475 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
476 | |
477 menuitem = gtk_menu_item_new_with_label(_("Unread Messages")); | |
478 | |
479 if (status == DOCKLET_STATUS_ONLINE_PENDING || status == DOCKLET_STATUS_AWAY_PENDING) { | |
480 GtkWidget *submenu = gtk_menu_new(); | |
481 GList *l = get_pending_list(0); | |
482 if (l == NULL) { | |
483 gtk_widget_set_sensitive(menuitem, FALSE); | |
484 gaim_debug_warning("docklet", | |
485 "status indicates messages pending, but no conversations with unseen messages were found."); | |
486 } else { | |
487 gaim_gtk_conversations_fill_menu(submenu, l); | |
488 g_list_free(l); | |
489 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); | |
490 } | |
491 } else { | |
492 gtk_widget_set_sensitive(menuitem, FALSE); | |
493 } | |
494 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
495 | |
496 gaim_separator(menu); | |
497 | |
498 menuitem = gaim_new_item_from_stock(menu, _("New Message..."), GAIM_STOCK_IM, G_CALLBACK(gaim_gtkdialogs_im), NULL, 0, 0, NULL); | |
499 if (status == DOCKLET_STATUS_OFFLINE) | |
500 gtk_widget_set_sensitive(menuitem, FALSE); | |
501 | |
502 menuitem = docklet_status_submenu(); | |
503 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
504 | |
505 gaim_separator(menu); | |
506 | |
507 gaim_new_item_from_stock(menu, _("Accounts"), GAIM_STOCK_ACCOUNTS, G_CALLBACK(gaim_gtk_accounts_window_show), NULL, 0, 0, NULL); | |
508 gaim_new_item_from_stock(menu, _("Plugins"), GAIM_STOCK_PLUGIN, G_CALLBACK(gaim_gtk_plugin_dialog_show), NULL, 0, 0, NULL); | |
509 gaim_new_item_from_stock(menu, _("Preferences"), GTK_STOCK_PREFERENCES, G_CALLBACK(gaim_gtk_prefs_show), NULL, 0, 0, NULL); | |
510 | |
511 gaim_separator(menu); | |
512 | |
513 menuitem = gtk_check_menu_item_new_with_label(_("Mute Sounds")); | |
514 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), gaim_prefs_get_bool("/gaim/gtk/sound/mute")); | |
515 if (!strcmp(gaim_prefs_get_string("/gaim/gtk/sound/method"), "none")) | |
516 gtk_widget_set_sensitive(GTK_WIDGET(menuitem), FALSE); | |
517 g_signal_connect(G_OBJECT(menuitem), "toggled", G_CALLBACK(docklet_toggle_mute), NULL); | |
518 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | |
519 | |
520 gaim_separator(menu); | |
521 | |
522 /* TODO: need a submenu to change status, this needs to "link" | |
523 * to the status in the buddy list gtkstatusbox | |
524 */ | |
525 | |
526 gaim_new_item_from_stock(menu, _("Quit"), GTK_STOCK_QUIT, G_CALLBACK(gaim_core_quit), NULL, 0, 0, NULL); | |
527 | |
528 #ifdef _WIN32 | |
529 g_signal_connect(menu, "leave-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL); | |
530 g_signal_connect(menu, "enter-notify-event", G_CALLBACK(docklet_menu_leave_enter), NULL); | |
531 #endif | |
532 gtk_widget_show_all(menu); | |
533 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, | |
534 ui_ops->position_menu, | |
535 NULL, 0, gtk_get_current_event_time()); | |
536 } | |
537 | |
538 /************************************************************************** | |
539 * public api for ui_ops | |
540 **************************************************************************/ | |
541 void | |
542 gaim_gtk_docklet_clicked(int button_type) | |
543 { | |
544 switch (button_type) { | |
545 case 1: | |
546 if (status == DOCKLET_STATUS_ONLINE_PENDING || status == DOCKLET_STATUS_AWAY_PENDING) { | |
547 GList *l = get_pending_list(1); | |
548 if (l != NULL) { | |
549 gaim_gtkconv_present_conversation((GaimConversation *)l->data); | |
550 g_list_free(l); | |
551 } | |
552 } else { | |
553 gaim_gtk_blist_toggle_visibility(); | |
554 } | |
555 break; | |
556 case 3: | |
557 docklet_menu(); | |
558 break; | |
559 } | |
560 } | |
561 | |
562 void | |
563 gaim_gtk_docklet_embedded() | |
564 { | |
565 if (!visibility_manager) { | |
566 gaim_gtk_blist_visibility_manager_add(); | |
567 visibility_manager = TRUE; | |
568 } | |
569 docklet_update_status(); | |
570 if (ui_ops && ui_ops->update_icon) | |
571 ui_ops->update_icon(status); | |
572 } | |
573 | |
574 void | |
575 gaim_gtk_docklet_remove() | |
576 { | |
577 if (visibility_manager) { | |
578 gaim_gtk_blist_visibility_manager_remove(); | |
579 visibility_manager = FALSE; | |
580 } | |
581 } | |
582 | |
583 void | |
584 gaim_gtk_docklet_set_ui_ops(struct docklet_ui_ops *ops) | |
585 { | |
586 ui_ops = ops; | |
587 } | |
588 | |
589 void* | |
590 gaim_gtk_docklet_get_handle() | |
591 { | |
592 static int i; | |
593 return &i; | |
594 } | |
595 | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
596 void |
14681 | 597 gaim_gtk_docklet_init() |
598 { | |
599 void *conn_handle = gaim_connections_get_handle(); | |
600 void *conv_handle = gaim_conversations_get_handle(); | |
601 void *accounts_handle = gaim_accounts_get_handle(); | |
602 void *docklet_handle = gaim_gtk_docklet_get_handle(); | |
603 | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
604 gaim_prefs_add_none("/plugins/gtk/docklet"); |
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
605 gaim_prefs_add_string("/plugins/gtk/docklet/blink_im", "hidden"); |
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
606 gaim_prefs_add_string("/plugins/gtk/docklet/blink_chat", "never"); |
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
607 |
14681 | 608 docklet_ui_init(); |
609 if (ui_ops && ui_ops->create) | |
610 ui_ops->create(); | |
611 gaim_signal_connect(conn_handle, "signed-on", | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
612 docklet_handle, GAIM_CALLBACK(docklet_signed_on_cb), NULL); |
14681 | 613 gaim_signal_connect(conn_handle, "signed-off", |
614 docklet_handle, GAIM_CALLBACK(docklet_signed_off_cb), NULL); | |
615 gaim_signal_connect(accounts_handle, "account-status-changed", | |
616 docklet_handle, GAIM_CALLBACK(docklet_update_status_cb), NULL); | |
617 gaim_signal_connect(conv_handle, "received-im-msg", | |
618 docklet_handle, GAIM_CALLBACK(docklet_update_status_cb), NULL); | |
619 gaim_signal_connect(conv_handle, "conversation-created", | |
620 docklet_handle, GAIM_CALLBACK(docklet_update_status_cb), NULL); | |
621 gaim_signal_connect(conv_handle, "deleting-conversation", | |
622 docklet_handle, GAIM_CALLBACK(docklet_update_status_cb), NULL); | |
623 gaim_signal_connect(conv_handle, "conversation-updated", | |
624 docklet_handle, GAIM_CALLBACK(docklet_conv_updated_cb), NULL); | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
625 #if 0 |
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
626 gaim_signal_connect(gaim_get_core(), "quitting", |
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
627 docklet_handle, GAIM_CALLBACK(gaim_quit_cb), NULL); |
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
628 #endif |
14681 | 629 |
630 /* gaim_prefs_connect_callback(plugin, "/plugins/gtk/docklet/blink_im", | |
631 docklet_prefs_cb, NULL); | |
632 gaim_prefs_connect_callback(plugin, "/plugins/gtk/docklet/blink_chat", | |
633 docklet_prefs_cb, NULL); | |
634 */ | |
635 enable_join_chat = online_account_supports_chat(); | |
636 } | |
637 | |
638 void | |
639 gaim_gtk_docklet_uninit() | |
640 { | |
641 if (ui_ops && ui_ops->destroy) | |
642 ui_ops->destroy(); | |
643 } | |
644 | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
645 #if 0 |
14681 | 646 static GtkWidget * |
647 plugin_config_frame(GaimPlugin *plugin) | |
648 { | |
649 GtkWidget *frame; | |
650 GtkWidget *vbox; | |
651 GtkSizeGroup *sg; | |
652 GtkWidget *dd; | |
653 | |
654 frame = gtk_vbox_new(FALSE, 18); | |
655 gtk_container_set_border_width(GTK_CONTAINER(frame), 12); | |
656 | |
657 vbox = gaim_gtk_make_frame(frame, _("Blink tray icon for unread...")); | |
658 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
659 | |
660 dd = gaim_gtk_prefs_dropdown(vbox, _("_Instant Messages:"), | |
661 GAIM_PREF_STRING, "/plugins/gtk/docklet/blink_im", | |
662 _("Never"), "never", | |
663 _("In hidden conversations"), "hidden", | |
664 _("Always"), "always", | |
665 NULL); | |
666 gtk_size_group_add_widget(sg, dd); | |
667 | |
668 dd = gaim_gtk_prefs_dropdown(vbox, _("C_hat Messages:"), | |
669 GAIM_PREF_STRING, "/plugins/gtk/docklet/blink_chat", | |
670 _("Never"), "never", | |
671 _("When my nick is said"), "nick", | |
672 _("Always"), "always", | |
673 NULL); | |
674 gtk_size_group_add_widget(sg, dd); | |
675 | |
676 gtk_widget_show_all(frame); | |
677 return frame; | |
678 } | |
14683
a8c2af13b96d
[gaim-migrate @ 17435]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
14681
diff
changeset
|
679 #endif |
14681 | 680 |