Mercurial > pidgin
comparison plugins/docklet/docklet.c @ 3517:6b0cb60162f4
[gaim-migrate @ 3590]
Rob McQueen added a mute feature to his nice little docklet. I added a
queuing feature. Configure the docklet in the plugins dialog to queue
unread messages, and when you receive a message the docklet will eat it up
and show a little message pending icon. Click on it, and read your message.
ICQ people will like it.
I also made plugin_event use a va_list.
I bet this breaks perl.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Mon, 16 Sep 2002 08:35:24 +0000 |
parents | b1ebeecfd2aa |
children | ff62b03bee6d |
comparison
equal
deleted
inserted
replaced
3516:db00eb77997d | 3517:6b0cb60162f4 |
---|---|
21 | 21 |
22 /* todo (in order of importance): | 22 /* todo (in order of importance): |
23 - don't crash when the plugin gets unloaded (it seems to crash after | 23 - don't crash when the plugin gets unloaded (it seems to crash after |
24 the plugin has gone, when gtk updates the button in the plugins | 24 the plugin has gone, when gtk updates the button in the plugins |
25 dialog. backtrace is always useless. weird) | 25 dialog. backtrace is always useless. weird) |
26 - have a toggle on the menu to mute all Gaim sounds | |
27 - handle and update tooltips to show your current accounts | 26 - handle and update tooltips to show your current accounts |
28 - connecting status support (needs more fruxing with the core) | |
29 - dernyi's account status menu in the right click | 27 - dernyi's account status menu in the right click |
30 - store icons in gtk2 stock icon thing (needs doing for the whole prog) | 28 - store icons in gtk2 stock icon thing (needs doing for the whole prog) |
31 - pop up notices when GNOME2's system-tray-applet supports it, with a | 29 - pop up notices when GNOME2's system-tray-applet supports it, with a |
32 prefs dialog to choose what to alert for */ | 30 prefs dialog to choose what to alert for */ |
33 | 31 |
34 /* includes */ | 32 /* includes */ |
35 #define GAIM_PLUGINS | 33 #define GAIM_PLUGINS |
36 #include <gtk/gtk.h> | 34 #include <gtk/gtk.h> |
35 #include <fcntl.h> | |
37 #include "gaim.h" | 36 #include "gaim.h" |
38 #include "eggtrayicon.h" | 37 #include "eggtrayicon.h" |
39 | |
40 /* macros */ | |
41 #define DOCKLET_WINDOW_ICONIFIED(x) (gdk_window_get_state(GTK_WIDGET(x)->window) & GDK_WINDOW_STATE_ICONIFIED) | |
42 | 38 |
43 /* types */ | 39 /* types */ |
44 enum docklet_status { | 40 enum docklet_status { |
45 online, | 41 online, |
46 away, | 42 away, |
47 away_pending, | 43 away_pending, |
44 unread_pending, | |
48 connecting, | 45 connecting, |
49 offline | 46 offline |
50 }; | 47 }; |
51 | 48 |
52 /* functions */ | 49 /* functions */ |
54 | 51 |
55 /* globals */ | 52 /* globals */ |
56 static EggTrayIcon *docklet = NULL; | 53 static EggTrayIcon *docklet = NULL; |
57 static GtkWidget *icon; | 54 static GtkWidget *icon; |
58 static enum docklet_status status; | 55 static enum docklet_status status; |
56 static GtkWidget *configwin = NULL; | |
59 | 57 |
60 static void docklet_embedded(GtkWidget *widget, void *data) { | 58 static void docklet_embedded(GtkWidget *widget, void *data) { |
61 debug_printf("Docklet: embedded\n"); | 59 debug_printf("Docklet: embedded\n"); |
62 docklet_add(); | 60 docklet_add(); |
63 } | 61 } |
66 debug_printf("Docklet: destroyed\n"); | 64 debug_printf("Docklet: destroyed\n"); |
67 docklet_remove(); | 65 docklet_remove(); |
68 docklet_create(); | 66 docklet_create(); |
69 } | 67 } |
70 | 68 |
71 static void docklet_toggle() { | 69 |
72 /* this looks bad, but we need to use (un)hide_buddy_list to allow buddy.c to | 70 static void docklet_mute(GtkWidget *toggle, void *data) { |
73 correctly hide/iconify depending on the docklet refcount, and to reposition | 71 mute_sounds = GTK_CHECK_MENU_ITEM(toggle)->active; |
74 the blist for us when we unhide. no such constraint for the login window | 72 if (mute_sounds) { |
75 because nothing else needs a unified way to hide/iconify it. otherwise I'd | 73 debug_printf("Docklet: sounds muted\n"); |
76 make a function and use it for both. */ | 74 } else { |
77 if (connections) { | 75 debug_printf("Docklet: sounds unmuted\n"); |
78 if (GTK_WIDGET_VISIBLE(blist)) { | 76 } |
79 if (DOCKLET_WINDOW_ICONIFIED(blist)) { | 77 } |
80 unhide_buddy_list(); | 78 |
81 } else { | |
82 hide_buddy_list(); | |
83 } | |
84 } else { | |
85 unhide_buddy_list(); | |
86 } | |
87 } else { | |
88 if (GTK_WIDGET_VISIBLE(mainwindow)) { | |
89 if (DOCKLET_WINDOW_ICONIFIED(mainwindow)) { | |
90 gtk_window_present(GTK_WINDOW(mainwindow)); | |
91 } else { | |
92 gtk_widget_hide(mainwindow); | |
93 } | |
94 } else { | |
95 gtk_window_present(GTK_WINDOW(mainwindow)); | |
96 } | |
97 } | |
98 } | |
99 | 79 |
100 static void docklet_menu(GdkEventButton *event) { | 80 static void docklet_menu(GdkEventButton *event) { |
101 static GtkWidget *menu = NULL; | 81 static GtkWidget *menu = NULL; |
102 GtkWidget *entry; | 82 GtkWidget *entry; |
103 | 83 |
152 } | 132 } |
153 | 133 |
154 entry = gtk_separator_menu_item_new(); | 134 entry = gtk_separator_menu_item_new(); |
155 gtk_menu_append(GTK_MENU(menu), entry); | 135 gtk_menu_append(GTK_MENU(menu), entry); |
156 | 136 |
137 entry = gtk_check_menu_item_new_with_label(_("Mute Sounds")); | |
138 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(entry), mute_sounds); | |
139 g_signal_connect(GTK_WIDGET(entry), "toggled", G_CALLBACK(docklet_mute), NULL); | |
140 gtk_menu_append(GTK_MENU(menu), entry); | |
141 | |
157 entry = gtk_menu_item_new_with_label(_("Accounts")); | 142 entry = gtk_menu_item_new_with_label(_("Accounts")); |
158 g_signal_connect(GTK_WIDGET(entry), "activate", G_CALLBACK(account_editor), NULL); | 143 g_signal_connect(GTK_WIDGET(entry), "activate", G_CALLBACK(account_editor), NULL); |
159 gtk_menu_append(GTK_MENU(menu), entry); | 144 gtk_menu_append(GTK_MENU(menu), entry); |
160 | 145 |
161 entry = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL); | 146 entry = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL); |
182 } | 167 } |
183 | 168 |
184 static void docklet_clicked(GtkWidget *button, GdkEventButton *event, void *data) { | 169 static void docklet_clicked(GtkWidget *button, GdkEventButton *event, void *data) { |
185 switch (event->button) { | 170 switch (event->button) { |
186 case 1: | 171 case 1: |
187 docklet_toggle(); | 172 if (unread_message_queue) { |
173 purge_away_queue(unread_message_queue); | |
174 unread_message_queue=NULL; | |
175 docklet_update_status(); | |
176 } | |
177 else | |
178 docklet_toggle(); | |
188 break; | 179 break; |
189 case 2: | 180 case 2: |
190 break; | 181 break; |
191 case 3: | 182 case 3: |
192 docklet_menu(event); | 183 docklet_menu(event); |
206 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "away.png", NULL); | 197 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "away.png", NULL); |
207 break; | 198 break; |
208 case away_pending: | 199 case away_pending: |
209 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "msgpend.png", NULL); | 200 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "msgpend.png", NULL); |
210 break; | 201 break; |
202 case unread_pending: | |
203 /* XXX MAKE ME BLINK! */ | |
204 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "msgunread.png", NULL); | |
205 break; | |
211 case connecting: | 206 case connecting: |
212 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "connecting.png", NULL); | 207 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "connect.png", NULL); |
213 break; | 208 break; |
214 case offline: | 209 case offline: |
215 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "offline.png", NULL); | 210 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "offline.png", NULL); |
216 } | 211 } |
217 | 212 |
237 enum docklet_status oldstatus; | 232 enum docklet_status oldstatus; |
238 | 233 |
239 oldstatus = status; | 234 oldstatus = status; |
240 | 235 |
241 if (connections) { | 236 if (connections) { |
242 if (awaymessage) { | 237 if (unread_message_queue) { |
238 status = unread_pending; | |
239 } else if (awaymessage) { | |
243 if (message_queue) { | 240 if (message_queue) { |
244 status = away_pending; | 241 status = away_pending; |
245 } else { | 242 } else { |
246 status = away; | 243 status = away; |
247 } | 244 } |
248 } else { | 245 } else { |
249 status = online; | 246 status = online; |
250 } | 247 } |
251 } else { | 248 } else { |
252 status = offline; | 249 if (connecting_count) { |
250 status = connecting; | |
251 } else { | |
252 status = offline; | |
253 } | |
253 } | 254 } |
254 | 255 |
255 if (status != oldstatus) { | 256 if (status != oldstatus) { |
256 docklet_update_icon(); | 257 docklet_update_icon(); |
257 } | 258 } |
338 gaim_signal_connect(handle, event_new_conversation, gaim_new_conversation, NULL); | 339 gaim_signal_connect(handle, event_new_conversation, gaim_new_conversation, NULL); |
339 | 340 |
340 return NULL; | 341 return NULL; |
341 } | 342 } |
342 | 343 |
344 static void toggle_queue (GtkWidget *w, void *null) { | |
345 away_options ^= OPT_AWAY_QUEUE_UNREAD; | |
346 save_prefs(); | |
347 } | |
348 | |
349 void gaim_plugin_config() { | |
350 /* This is the sorriest dialog ever written ever */ | |
351 /* It's a good thing I plan on rewriting it later tonight */ | |
352 GtkWidget *button; | |
353 GtkWidget *vbox; | |
354 | |
355 if (configwin) return; | |
356 GAIM_DIALOG(configwin); | |
357 | |
358 vbox = gtk_vbox_new(0, 6); | |
359 gtk_container_add(GTK_CONTAINER(configwin), vbox); | |
360 gtk_window_set_title(GTK_WINDOW(configwin), "Docklet Configuration"); | |
361 | |
362 button = gtk_check_button_new_with_mnemonic("_Hide new messages until docklet is clicked"); | |
363 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), away_options & OPT_AWAY_QUEUE_UNREAD); | |
364 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(toggle_queue), NULL); | |
365 gtk_box_pack_end(GTK_BOX(vbox), button, 0, 0, 0); | |
366 | |
367 gtk_widget_show_all(configwin); | |
368 } | |
369 | |
370 | |
343 void gaim_plugin_remove() { | 371 void gaim_plugin_remove() { |
344 if (GTK_WIDGET_VISIBLE(docklet)) { | 372 if (GTK_WIDGET_VISIBLE(docklet)) { |
345 docklet_remove(); | 373 docklet_remove(); |
346 } | 374 } |
347 | 375 |