pidgin/pidginapplication.c

changeset 40600
46d10c72c137
parent 40555
0bf5825aab0a
child 40607
807f0b114d36
equal deleted inserted replaced
40599:13b1e211d865 40600:46d10c72c137
33 33
34 #include "pidginapplication.h" 34 #include "pidginapplication.h"
35 35
36 #include "gtkaccount.h" 36 #include "gtkaccount.h"
37 #include "gtkblist.h" 37 #include "gtkblist.h"
38 #include "gtkdialogs.h"
39 #include "gtkpounce.h"
40 #include "gtkprefs.h"
41 #include "gtkprivacy.h"
42 #include "gtkroomlist.h"
43 #include "gtksmiley-manager.h"
44 #include "gtkxfer.h"
45 #include "pidginabout.h"
38 #include "pidgincore.h" 46 #include "pidgincore.h"
39 #include "pidgindebug.h" 47 #include "pidgindebug.h"
48 #include "pidginlog.h"
49 #include "pidginmooddialog.h"
50 #include "pidgin/pidginpluginsdialog.h"
40 51
41 struct _PidginApplication { 52 struct _PidginApplication {
42 GtkApplication parent; 53 GtkApplication parent;
43 }; 54 };
44 55
65 }; 76 };
66 77
67 G_DEFINE_TYPE(PidginApplication, pidgin_application, GTK_TYPE_APPLICATION) 78 G_DEFINE_TYPE(PidginApplication, pidgin_application, GTK_TYPE_APPLICATION)
68 79
69 /****************************************************************************** 80 /******************************************************************************
81 * Actions
82 *****************************************************************************/
83 /**< private >
84 * pidgin_application_online_actions:
85 *
86 * This list keeps track of which actions should only be enabled while online.
87 */
88 static const gchar *pidgin_application_online_actions[] = {
89 "add-buddy",
90 "add-group",
91 "get-user-info",
92 "new-message",
93 "privacy",
94 "set-mood",
95 };
96
97 /**< private >
98 * pidgin_application_chat_actions:
99 *
100 * This list keeps track of which actions should only be enabled if a protocol
101 * supporting groups chats is connected.
102 */
103 static const gchar *pidgin_application_chat_actions[] = {
104 "add-chat",
105 "join-chat",
106 };
107
108 /**< private >
109 * pidgin_application_room_list_actions:
110 *
111 * This list keeps track of which actions should only be enabled if an online
112 * account supports room lists.
113 */
114 static const gchar *pidgin_application_room_list_actions[] = {
115 "room-list",
116 };
117
118 /*< private >
119 * pidgin_action_group_actions_set_enable:
120 * @group: The #PidginActionGroup instance.
121 * @actions: The action names.
122 * @n_actions: The number of @actions.
123 * @enabled: Whether or not to enable the actions.
124 *
125 * Sets the enabled property of the named actions to @enabled.
126 */
127 static void
128 pidgin_application_actions_set_enabled(PidginApplication *application,
129 const gchar *const *actions,
130 gint n_actions,
131 gboolean enabled)
132 {
133 gint i = 0;
134
135 for(i = 0; i < n_actions; i++) {
136 GAction *action = NULL;
137 const gchar *name = actions[i];
138
139 action = g_action_map_lookup_action(G_ACTION_MAP(application), name);
140
141 if(action != NULL) {
142 g_simple_action_set_enabled(G_SIMPLE_ACTION(action), enabled);
143 } else {
144 g_warning("Failed to find action named %s", name);
145 }
146 }
147 }
148
149 static void
150 pidgin_application_about(GSimpleAction *simple, GVariant *parameter,
151 gpointer data)
152 {
153 GtkWidget *about = pidgin_about_dialog_new();
154
155 /* fix me? */
156 #if 0
157 gtk_window_set_transient_for(GTK_WINDOW(about), GTK_WINDOW(window));
158 #endif
159
160 gtk_widget_show_all(about);
161 }
162
163 static void
164 pidgin_application_accounts(GSimpleAction *simple, GVariant *parameter,
165 gpointer data)
166 {
167 pidgin_accounts_window_show();
168 }
169
170 static void
171 pidgin_application_add_buddy(GSimpleAction *simple, GVariant *parameter,
172 gpointer data)
173 {
174 purple_blist_request_add_buddy(NULL, NULL, NULL, NULL);
175 }
176
177 static void
178 pidgin_application_add_chat(GSimpleAction *simple, GVariant *parameter,
179 gpointer data)
180 {
181 purple_blist_request_add_chat(NULL, NULL, NULL, NULL);
182 }
183
184 static void
185 pidgin_application_add_group(GSimpleAction *simple, GVariant *parameter,
186 gpointer data)
187 {
188 purple_blist_request_add_group();
189 }
190
191 static void
192 pidgin_application_buddy_pounces(GSimpleAction *simple, GVariant *parameter,
193 gpointer data)
194 {
195 pidgin_pounces_manager_show();
196 }
197
198 static void
199 pidgin_application_custom_smiley(GSimpleAction *simple, GVariant *parameter,
200 gpointer data)
201 {
202 pidgin_smiley_manager_show();
203 }
204
205 static void
206 pidgin_application_debug(GSimpleAction *simple, GVariant *parameter,
207 gpointer data)
208 {
209 gboolean old = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/enabled");
210 purple_prefs_set_bool(PIDGIN_PREFS_ROOT "/debug/enabled", !old);
211 }
212
213 static void
214 pidgin_application_file_transfers(GSimpleAction *simple, GVariant *parameter,
215 gpointer data)
216 {
217 pidgin_xfer_dialog_show(NULL);
218 }
219
220 static void
221 pidgin_application_get_user_info(GSimpleAction *simple, GVariant *parameter,
222 gpointer data)
223 {
224 pidgin_dialogs_info();
225 }
226
227 static void
228 pidgin_application_join_chat(GSimpleAction *simple, GVariant *parameter,
229 gpointer data)
230 {
231 pidgin_blist_joinchat_show();
232 }
233
234 static void
235 pidgin_application_new_message(GSimpleAction *simple, GVariant *parameter,
236 gpointer data)
237 {
238 pidgin_dialogs_im();
239 }
240
241 static void
242 pidgin_application_online_help(GSimpleAction *simple, GVariant *parameter,
243 gpointer data)
244 {
245 purple_notify_uri(NULL, PURPLE_WEBSITE "help");
246 }
247
248 static void
249 pidgin_application_plugins(GSimpleAction *simple, GVariant *parameter,
250 gpointer data)
251 {
252 GtkWidget *dialog = pidgin_plugins_dialog_new();
253
254 /* fixme? */
255 #if 0
256 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window));
257 #endif
258
259 gtk_widget_show_all(dialog);
260 }
261
262 static void
263 pidgin_application_preferences(GSimpleAction *simple, GVariant *parameter,
264 gpointer data)
265 {
266 pidgin_prefs_show();
267 }
268
269 static void
270 pidgin_application_privacy(GSimpleAction *simple, GVariant *parameter,
271 gpointer data)
272 {
273 pidgin_privacy_dialog_show();
274 }
275
276 static void
277 pidgin_application_quit(GSimpleAction *simple, GVariant *parameter,
278 gpointer data)
279 {
280 purple_core_quit();
281 }
282
283 static void
284 pidgin_application_room_list(GSimpleAction *simple, GVariant *parameter,
285 gpointer data)
286 {
287 pidgin_roomlist_dialog_show();
288 }
289
290 static void
291 pidgin_application_set_mood(GSimpleAction *simple, GVariant *parameter,
292 gpointer data)
293 {
294 pidgin_mood_dialog_show(NULL);
295 }
296
297 static void
298 pidgin_application_system_log(GSimpleAction *simple, GVariant *parameter,
299 gpointer data)
300 {
301 pidgin_syslog_show();
302 }
303
304 static void
305 pidgin_application_view_user_log(GSimpleAction *simple, GVariant *parameter,
306 gpointer data)
307 {
308 pidgin_dialogs_log();
309 }
310
311 static GActionEntry app_entries[] = {
312 {
313 .name = "about",
314 .activate = pidgin_application_about,
315 }, {
316 .name = "add-buddy",
317 .activate = pidgin_application_add_buddy,
318 }, {
319 .name = "add-chat",
320 .activate = pidgin_application_add_chat,
321 }, {
322 .name = "add-group",
323 .activate = pidgin_application_add_group,
324 }, {
325 .name = "buddy-pounces",
326 .activate = pidgin_application_buddy_pounces,
327 }, {
328 .name = "custom-smiley",
329 .activate = pidgin_application_custom_smiley,
330 }, {
331 .name = "debug",
332 .activate = pidgin_application_debug,
333 }, {
334 .name = "file-transfers",
335 .activate = pidgin_application_file_transfers,
336 }, {
337 .name = "get-user-info",
338 .activate = pidgin_application_get_user_info,
339 }, {
340 .name = "join-chat",
341 .activate = pidgin_application_join_chat,
342 }, {
343 .name = "manage-accounts",
344 .activate = pidgin_application_accounts,
345 }, {
346 .name = "manage-plugins",
347 .activate = pidgin_application_plugins,
348 }, {
349 .name = "new-message",
350 .activate = pidgin_application_new_message,
351 }, {
352 .name = "online-help",
353 .activate = pidgin_application_online_help,
354 }, {
355 .name = "preferences",
356 .activate = pidgin_application_preferences,
357 }, {
358 .name = "privacy",
359 .activate = pidgin_application_privacy,
360 }, {
361 .name = "quit",
362 .activate = pidgin_application_quit,
363 }, {
364 .name = "room-list",
365 .activate = pidgin_application_room_list,
366 }, {
367 .name = "set-mood",
368 .activate = pidgin_application_set_mood,
369 }, {
370 .name = "system-log",
371 .activate = pidgin_application_system_log,
372 }, {
373 .name = "view-user-log",
374 .activate = pidgin_application_view_user_log,
375 }
376 };
377
378 /******************************************************************************
379 * Purple Signal Callbacks
380 *****************************************************************************/
381 static void
382 pidgin_application_online_cb(gpointer data) {
383 gint n_actions = G_N_ELEMENTS(pidgin_application_online_actions);
384
385 pidgin_application_actions_set_enabled(PIDGIN_APPLICATION(data),
386 pidgin_application_online_actions,
387 n_actions,
388 TRUE);
389 }
390
391 static void
392 pidgin_application_offline_cb(gpointer data) {
393 gint n_actions = G_N_ELEMENTS(pidgin_application_online_actions);
394
395 pidgin_application_actions_set_enabled(PIDGIN_APPLICATION(data),
396 pidgin_application_online_actions,
397 n_actions,
398 FALSE);
399 }
400
401 static void
402 pidgin_application_signed_on_cb(PurpleAccount *account, gpointer data) {
403 PidginApplication *application = PIDGIN_APPLICATION(data);
404 PurpleProtocol *protocol = NULL;
405 const gchar *protocol_id = NULL;
406 gboolean should_enable_chat = FALSE, should_enable_room_list = FALSE;
407 gint n_actions = 0;
408
409 protocol_id = purple_account_get_protocol_id(account);
410 protocol = purple_protocols_find(protocol_id);
411
412 /* We assume that the current state is correct, so we don't bother changing
413 * state unless the newly connected account implements the chat interface,
414 * which would cause a state change.
415 */
416 should_enable_chat = PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, info);
417 if(should_enable_chat) {
418 n_actions = G_N_ELEMENTS(pidgin_application_chat_actions);
419 pidgin_application_actions_set_enabled(application,
420 pidgin_application_chat_actions,
421 n_actions,
422 TRUE);
423 }
424
425 /* likewise, for the room list, we only care about enabling in this
426 * handler.
427 */
428 should_enable_room_list = PURPLE_PROTOCOL_IMPLEMENTS(protocol, ROOMLIST,
429 get_list);
430 if(should_enable_room_list) {
431 n_actions = G_N_ELEMENTS(pidgin_application_room_list_actions);
432 pidgin_application_actions_set_enabled(application,
433 pidgin_application_room_list_actions,
434 n_actions,
435 TRUE);
436 }
437 }
438
439 static void
440 pidgin_application_signed_off_cb(PurpleAccount *account, gpointer data) {
441 PidginApplication *application = PIDGIN_APPLICATION(data);
442 gboolean should_disable_chat = TRUE, should_disable_room_list = TRUE;
443 GList *connections = NULL, *l = NULL;
444 gint n_actions = 0;
445
446 /* walk through all the connections, looking for online ones that implement
447 * the chat interface. We don't bother checking the account that this
448 * signal was emitted for, because it's already offline and will be
449 * filtered out by the online check.
450 */
451 connections = purple_connections_get_all();
452 for(l = connections; l != NULL; l = l->next) {
453 PurpleConnection *connection = PURPLE_CONNECTION(l->data);
454 PurpleProtocol *protocol = NULL;
455
456 /* if the connection isn't online, we don't care about it */
457 if(!PURPLE_CONNECTION_IS_CONNECTED(connection)) {
458 continue;
459 }
460
461 protocol = purple_connection_get_protocol(connection);
462
463 /* check if the protocol implements the chat interface */
464 if(PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, info)) {
465 should_disable_chat = FALSE;
466 }
467
468 /* check if the protocol implements the room list interface */
469 if(PURPLE_PROTOCOL_IMPLEMENTS(protocol, ROOMLIST, get_list)) {
470 should_disable_room_list = FALSE;
471 }
472
473 /* if we can't disable both, we can bail out of the loop */
474 if(!should_disable_chat && !should_disable_room_list) {
475 break;
476 }
477 }
478
479 if(should_disable_chat) {
480 n_actions = G_N_ELEMENTS(pidgin_application_chat_actions);
481 pidgin_application_actions_set_enabled(application,
482 pidgin_application_chat_actions,
483 n_actions,
484 FALSE);
485 }
486
487 if(should_disable_room_list) {
488 n_actions = G_N_ELEMENTS(pidgin_application_room_list_actions);
489 pidgin_application_actions_set_enabled(application,
490 pidgin_application_room_list_actions,
491 n_actions,
492 FALSE);
493 }
494 }
495
496 /******************************************************************************
70 * GApplication Implementation 497 * GApplication Implementation
71 *****************************************************************************/ 498 *****************************************************************************/
72 static void 499 static void
73 pidgin_application_startup(GApplication *application) { 500 pidgin_application_startup(GApplication *application) {
74 GtkCssProvider *provider = NULL; 501 GtkCssProvider *provider = NULL;
75 GError *error = NULL; 502 GError *error = NULL;
76 GList *active_accounts = NULL; 503 GList *active_accounts = NULL;
77 gchar *search_path = NULL; 504 gchar *search_path = NULL;
505 gpointer handle = NULL;
78 506
79 G_APPLICATION_CLASS(pidgin_application_parent_class)->startup(application); 507 G_APPLICATION_CLASS(pidgin_application_parent_class)->startup(application);
80 508
81 /* set a user-specified config directory */ 509 /* set a user-specified config directory */
82 if (opt_config_dir_arg != NULL) { 510 if (opt_config_dir_arg != NULL) {
199 */ 627 */
200 gdk_notify_startup_complete(); 628 gdk_notify_startup_complete();
201 629
202 /* TODO: Use GtkApplicationWindow or add a window instead */ 630 /* TODO: Use GtkApplicationWindow or add a window instead */
203 g_application_hold(application); 631 g_application_hold(application);
632
633 /* connect to the online and offline signals in purple connections. This
634 * is used to toggle states of actions that require being online.
635 */
636 handle = purple_connections_get_handle();
637 purple_signal_connect(handle, "online", application,
638 PURPLE_CALLBACK(pidgin_application_online_cb),
639 application);
640 purple_signal_connect(handle, "offline", application,
641 PURPLE_CALLBACK(pidgin_application_offline_cb),
642 application);
643
644 /* connect to account-signed-on and account-signed-off to toggle actions
645 * that depend on specific interfaces in accounts.
646 */
647 handle = purple_accounts_get_handle();
648 purple_signal_connect(handle, "account-signed-on", application,
649 PURPLE_CALLBACK(pidgin_application_signed_on_cb),
650 application);
651 purple_signal_connect(handle, "account-signed-off", application,
652 PURPLE_CALLBACK(pidgin_application_signed_off_cb),
653 application);
654
204 } 655 }
205 656
206 static void 657 static void
207 pidgin_application_activate(GApplication *application) { 658 pidgin_application_activate(GApplication *application) {
208 PidginBuddyList *blist = pidgin_blist_get_default_gtk_blist(); 659 PidginBuddyList *blist = pidgin_blist_get_default_gtk_blist();
254 * GObject Implementation 705 * GObject Implementation
255 *****************************************************************************/ 706 *****************************************************************************/
256 static void 707 static void
257 pidgin_application_init(PidginApplication *application) { 708 pidgin_application_init(PidginApplication *application) {
258 GApplication *gapp = G_APPLICATION(application); 709 GApplication *gapp = G_APPLICATION(application);
710 gboolean online = FALSE;
711 gint n_actions = 0;
259 712
260 g_application_add_main_option_entries(gapp, option_entries); 713 g_application_add_main_option_entries(gapp, option_entries);
261 g_application_add_option_group(gapp, purple_get_option_group()); 714 g_application_add_option_group(gapp, purple_get_option_group());
262 g_application_add_option_group(gapp, gplugin_get_option_group()); 715 g_application_add_option_group(gapp, gplugin_get_option_group());
716
717 g_action_map_add_action_entries(G_ACTION_MAP(application), app_entries,
718 G_N_ELEMENTS(app_entries), application);
719
720 /* Set the default state for our actions to match our online state. */
721 online = purple_connections_is_online();
722
723 n_actions = G_N_ELEMENTS(pidgin_application_online_actions);
724 pidgin_application_actions_set_enabled(application,
725 pidgin_application_online_actions,
726 n_actions,
727 online);
728
729 n_actions = G_N_ELEMENTS(pidgin_application_chat_actions);
730 pidgin_application_actions_set_enabled(application,
731 pidgin_application_chat_actions,
732 n_actions,
733 online);
734
735 n_actions = G_N_ELEMENTS(pidgin_application_room_list_actions);
736 pidgin_application_actions_set_enabled(application,
737 pidgin_application_room_list_actions,
738 n_actions,
739 online);
263 } 740 }
264 741
265 static void 742 static void
266 pidgin_application_class_init(PidginApplicationClass *klass) { 743 pidgin_application_class_init(PidginApplicationClass *klass) {
267 GApplicationClass *app_class = G_APPLICATION_CLASS(klass); 744 GApplicationClass *app_class = G_APPLICATION_CLASS(klass);

mercurial