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