]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-main-window.c
7f86932788599fb0b32154f3c64e5c0a5a61f1a0
[empathy.git] / libempathy-gtk / empathy-main-window.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2007 Collabora Ltd.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  * 
20  * Authors: Xavier Claessens <xclaesse@gmail.com>
21  */
22
23 #include <config.h>
24
25 #include <sys/stat.h>
26 #include <gtk/gtk.h>
27 #include <glade/glade.h>
28 #include <glib/gi18n.h>
29
30 #include <libempathy/gossip-conf.h>
31 #include <libempathy/gossip-contact.h>
32 #include <libempathy/gossip-debug.h>
33 #include <libempathy/gossip-utils.h>
34 #include <libempathy/gossip-chatroom-manager.h>
35 #include <libempathy/gossip-chatroom.h>
36 #include <libempathy/empathy-contact-list.h>
37 #include <libempathy/empathy-contact-manager.h>
38
39 #include "empathy-main-window.h"
40 #include "empathy-contact-dialogs.h"
41 #include "ephy-spinner.h"
42 #include "gossip-contact-list-store.h"
43 #include "gossip-contact-list-view.h"
44 #include "gossip-presence-chooser.h"
45 #include "gossip-ui-utils.h"
46 #include "gossip-status-presets.h"
47 #include "gossip-geometry.h"
48 #include "gossip-preferences.h"
49 #include "gossip-accounts-dialog.h"
50 #include "gossip-about-dialog.h"
51 #include "gossip-new-chatroom-dialog.h"
52 #include "gossip-chatrooms-window.h"
53
54 #define DEBUG_DOMAIN "MainWindow"
55
56 /* Minimum width of roster window if something goes wrong. */
57 #define MIN_WIDTH 50
58
59 /* Accels (menu shortcuts) can be configured and saved */
60 #define ACCELS_FILENAME "accels.txt"
61
62 /* Name in the geometry file */
63 #define GEOMETRY_NAME "main-window"
64
65 typedef struct {
66         GossipContactListView  *list_view;
67         GossipContactListStore *list_store;
68         MissionControl         *mc;
69         GossipChatroomManager  *chatroom_manager;
70
71         /* Main widgets */
72         GtkWidget              *window;
73         GtkWidget              *main_vbox;
74
75         /* Tooltips for all widgets */
76         GtkTooltips            *tooltips;
77
78         /* Menu widgets */
79         GtkWidget              *room;
80         GtkWidget              *room_menu;
81         GtkWidget              *room_sep;
82         GtkWidget              *room_join_favorites;
83         GtkWidget              *edit_context;
84         GtkWidget              *edit_context_separator;
85
86         /* Throbber */
87         GtkWidget              *throbber;
88
89         /* Widgets that are enabled when there is... */
90         GList                  *widgets_connected;      /* ... connected accounts */
91         GList                  *widgets_disconnected;   /* ... disconnected accounts */
92
93         /* Status popup */
94         GtkWidget              *presence_toolbar;
95         GtkWidget              *presence_chooser;
96
97         /* Misc */
98         guint                   size_timeout_id;
99 } EmpathyMainWindow;
100
101 static void     main_window_destroy_cb                         (GtkWidget                       *widget,
102                                                                 EmpathyMainWindow               *window);
103 static void     main_window_favorite_chatroom_menu_setup       (EmpathyMainWindow               *window);
104 static void     main_window_favorite_chatroom_menu_added_cb    (GossipChatroomManager           *manager,
105                                                                 GossipChatroom                  *chatroom,
106                                                                 EmpathyMainWindow               *window);
107 static void     main_window_favorite_chatroom_menu_removed_cb  (GossipChatroomManager           *manager,
108                                                                 GossipChatroom                  *chatroom,
109                                                                 EmpathyMainWindow               *window);
110 static void     main_window_favorite_chatroom_menu_activate_cb (GtkMenuItem                     *menu_item,
111                                                                 GossipChatroom                  *chatroom);
112 static void     main_window_favorite_chatroom_menu_update      (EmpathyMainWindow               *window);
113 static void     main_window_favorite_chatroom_menu_add         (EmpathyMainWindow               *window,
114                                                                 GossipChatroom                  *chatroom);
115 static void     main_window_favorite_chatroom_join             (GossipChatroom                  *chatroom);
116 static void     main_window_chat_quit_cb                       (GtkWidget                       *widget,
117                                                                 EmpathyMainWindow               *window);
118 static void     main_window_chat_new_message_cb                (GtkWidget                       *widget,
119                                                                 EmpathyMainWindow               *window);
120 static void     main_window_chat_history_cb                    (GtkWidget                       *widget,
121                                                                 EmpathyMainWindow               *window);
122 static void     main_window_room_join_new_cb                   (GtkWidget                       *widget,
123                                                                 EmpathyMainWindow               *window);
124 static void     main_window_room_join_favorites_cb             (GtkWidget                       *widget,
125                                                                 EmpathyMainWindow               *window);
126 static void     main_window_room_manage_favorites_cb           (GtkWidget                       *widget,
127                                                                 EmpathyMainWindow               *window);
128 static void     main_window_chat_add_contact_cb                (GtkWidget                       *widget,
129                                                                 EmpathyMainWindow               *window);
130 static void     main_window_chat_show_offline_cb               (GtkCheckMenuItem                *item,
131                                                                 EmpathyMainWindow               *window);
132 static gboolean main_window_edit_button_press_event_cb         (GtkWidget                       *widget,
133                                                                 GdkEventButton                  *event,
134                                                                 EmpathyMainWindow               *window);
135 static void     main_window_edit_accounts_cb                   (GtkWidget                       *widget,
136                                                                 EmpathyMainWindow               *window);
137 static void     main_window_edit_personal_information_cb       (GtkWidget                       *widget,
138                                                                 EmpathyMainWindow               *window);
139 static void     main_window_edit_preferences_cb                (GtkWidget                       *widget,
140                                                                 EmpathyMainWindow               *window);
141 static void     main_window_help_about_cb                      (GtkWidget                       *widget,
142                                                                 EmpathyMainWindow               *window);
143 static void     main_window_help_contents_cb                   (GtkWidget                       *widget,
144                                                                 EmpathyMainWindow               *window);
145 static gboolean main_window_throbber_button_press_event_cb     (GtkWidget                       *throbber_ebox,
146                                                                 GdkEventButton                  *event,
147                                                                 EmpathyMainWindow               *window);
148 static void     main_window_status_changed_cb                  (MissionControl                  *mc,
149                                                                 TelepathyConnectionStatus        status,
150                                                                 McPresence                       presence,
151                                                                 TelepathyConnectionStatusReason  reason,
152                                                                 const gchar                     *unique_name,
153                                                                 EmpathyMainWindow               *window);
154 static void     main_window_update_status                      (EmpathyMainWindow               *window);
155 static void     main_window_accels_load                        (void);
156 static void     main_window_accels_save                        (void);
157 static void     main_window_connection_items_setup             (EmpathyMainWindow               *window,
158                                                                 GladeXML                        *glade);
159 static gboolean main_window_configure_event_timeout_cb         (EmpathyMainWindow               *window);
160 static gboolean main_window_configure_event_cb                 (GtkWidget                       *widget,
161                                                                 GdkEventConfigure               *event,
162                                                                 EmpathyMainWindow               *window);
163 static void     main_window_notify_show_offline_cb             (GossipConf                      *conf,
164                                                                 const gchar                     *key,
165                                                                 gpointer                         check_menu_item);
166 static void     main_window_notify_show_avatars_cb             (GossipConf                      *conf,
167                                                                 const gchar                     *key,
168                                                                 EmpathyMainWindow               *window);
169 static void     main_window_notify_compact_contact_list_cb     (GossipConf                      *conf,
170                                                                 const gchar                     *key,
171                                                                 EmpathyMainWindow               *window);
172 static void     main_window_notify_sort_criterium_cb           (GossipConf                      *conf,
173                                                                 const gchar                     *key,
174                                                                 EmpathyMainWindow               *window);
175
176 GtkWidget *
177 empathy_main_window_show (void)
178 {
179         static EmpathyMainWindow *window = NULL;
180         EmpathyContactList       *list_iface;
181         GladeXML                 *glade;
182         GossipConf               *conf;
183         GtkWidget                *sw;
184         GtkWidget                *show_offline_widget;
185         GtkWidget                *ebox;
186         GtkToolItem              *item;
187         gchar                    *str;
188         gboolean                  show_offline;
189         gboolean                  show_avatars;
190         gboolean                  compact_contact_list;
191         gint                      x, y, w, h;
192
193         if (window) {
194                 gtk_window_present (GTK_WINDOW (window->window));
195                 return window->window;
196         }
197
198         window = g_new0 (EmpathyMainWindow, 1);
199
200         /* Set up interface */
201         glade = gossip_glade_get_file ("empathy-main-window.glade",
202                                        "main_window",
203                                        NULL,
204                                        "main_window", &window->window,
205                                        "main_vbox", &window->main_vbox,
206                                        "chat_show_offline", &show_offline_widget,
207                                        "room", &window->room,
208                                        "room_sep", &window->room_sep,
209                                        "room_join_favorites", &window->room_join_favorites,
210                                        "edit_context", &window->edit_context,
211                                        "edit_context_separator", &window->edit_context_separator,
212                                        "presence_toolbar", &window->presence_toolbar,
213                                        "roster_scrolledwindow", &sw,
214                                        NULL);
215
216         gossip_glade_connect (glade,
217                               window,
218                               "main_window", "destroy", main_window_destroy_cb,
219                               "main_window", "configure_event", main_window_configure_event_cb,
220                               "chat_quit", "activate", main_window_chat_quit_cb,
221                               "chat_new_message", "activate", main_window_chat_new_message_cb,
222                               "chat_history", "activate", main_window_chat_history_cb,
223                               "room_join_new", "activate", main_window_room_join_new_cb,
224                               "room_join_favorites", "activate", main_window_room_join_favorites_cb,
225                               "room_manage_favorites", "activate", main_window_room_manage_favorites_cb,
226                               "chat_add_contact", "activate", main_window_chat_add_contact_cb,
227                               "chat_show_offline", "toggled", main_window_chat_show_offline_cb,
228                               "edit", "button-press-event", main_window_edit_button_press_event_cb,
229                               "edit_accounts", "activate", main_window_edit_accounts_cb,
230                               "edit_personal_information", "activate", main_window_edit_personal_information_cb,
231                               "edit_preferences", "activate", main_window_edit_preferences_cb,
232                               "help_about", "activate", main_window_help_about_cb,
233                               "help_contents", "activate", main_window_help_contents_cb,
234                               NULL);
235
236         /* Set up connection related widgets. */
237         main_window_connection_items_setup (window, glade);
238         g_object_unref (glade);
239
240         window->tooltips = g_object_ref_sink (gtk_tooltips_new ());
241         window->mc = gossip_mission_control_new ();
242         dbus_g_proxy_connect_signal (DBUS_G_PROXY (window->mc), "AccountStatusChanged",
243                                      G_CALLBACK (main_window_status_changed_cb),
244                                      window, NULL);
245
246         /* Set up menu */
247         main_window_favorite_chatroom_menu_setup (window);
248
249         gtk_widget_hide (window->edit_context);
250         gtk_widget_hide (window->edit_context_separator);
251
252         /* Set up presence chooser */
253         window->presence_chooser = gossip_presence_chooser_new ();
254         gtk_widget_show (window->presence_chooser);
255         item = gtk_tool_item_new ();
256         gtk_widget_show (GTK_WIDGET (item));
257         gtk_container_add (GTK_CONTAINER (item), window->presence_chooser);
258         gtk_tool_item_set_is_important (item, TRUE);
259         gtk_tool_item_set_expand (item, TRUE);
260         gtk_toolbar_insert (GTK_TOOLBAR (window->presence_toolbar), item, -1);
261
262         /* Set up the throbber */
263         ebox = gtk_event_box_new ();
264         gtk_event_box_set_visible_window (GTK_EVENT_BOX (ebox), FALSE);
265
266         window->throbber = ephy_spinner_new ();
267         ephy_spinner_set_size (EPHY_SPINNER (window->throbber), GTK_ICON_SIZE_LARGE_TOOLBAR);
268         gtk_container_add (GTK_CONTAINER (ebox), window->throbber);
269
270         item = gtk_tool_item_new ();
271         gtk_container_add (GTK_CONTAINER (item), ebox);
272         gtk_widget_show_all (GTK_WIDGET (item));
273
274         gtk_toolbar_insert (GTK_TOOLBAR (window->presence_toolbar), item, -1);
275
276         str = _("Show and edit accounts");
277         gtk_tooltips_set_tip (GTK_TOOLTIPS (window->tooltips),
278                               ebox, str, str);
279
280         g_signal_connect (ebox,
281                           "button-press-event",
282                           G_CALLBACK (main_window_throbber_button_press_event_cb),
283                           window);
284
285         /* Set up contact list. */
286         gossip_status_presets_get_all ();
287
288         list_iface = EMPATHY_CONTACT_LIST (empathy_contact_manager_new ());
289         empathy_contact_list_setup (list_iface);
290         window->list_store = gossip_contact_list_store_new (list_iface);
291         window->list_view = gossip_contact_list_view_new (window->list_store);
292         g_object_unref (list_iface);
293
294         gtk_widget_show (GTK_WIDGET (window->list_view));
295         gtk_container_add (GTK_CONTAINER (sw),
296                            GTK_WIDGET (window->list_view));
297
298         /* Load user-defined accelerators. */
299         main_window_accels_load ();
300
301         /* Set window size. */
302         gossip_geometry_load (GEOMETRY_NAME, &x, &y, &w, &h);
303
304         if (w >= 1 && h >= 1) {
305                 /* Use the defaults from the glade file if we
306                  * don't have good w, h geometry.
307                  */
308                 gossip_debug (DEBUG_DOMAIN, "Configuring window default size w:%d, h:%d", w, h);
309                 gtk_window_set_default_size (GTK_WINDOW (window->window), w, h);
310         }
311
312         if (x >= 0 && y >= 0) {
313                 /* Let the window manager position it if we
314                  * don't have good x, y coordinates.
315                  */
316                 gossip_debug (DEBUG_DOMAIN, "Configuring window default position x:%d, y:%d", x, y);
317                 gtk_window_move (GTK_WINDOW (window->window), x, y);
318         }
319
320         conf = gossip_conf_get ();
321         
322         /* Show offline ? */
323         gossip_conf_get_bool (conf,
324                               GOSSIP_PREFS_CONTACTS_SHOW_OFFLINE,
325                               &show_offline);
326         gossip_conf_notify_add (conf,
327                                 GOSSIP_PREFS_CONTACTS_SHOW_OFFLINE,
328                                 main_window_notify_show_offline_cb,
329                                 show_offline_widget);
330
331         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (show_offline_widget),
332                                         show_offline);
333
334         /* Show avatars ? */
335         gossip_conf_get_bool (conf,
336                               GOSSIP_PREFS_UI_SHOW_AVATARS,
337                               &show_avatars);
338         gossip_conf_notify_add (conf,
339                                 GOSSIP_PREFS_UI_SHOW_AVATARS,
340                                 (GossipConfNotifyFunc) main_window_notify_show_avatars_cb,
341                                 window);
342         gossip_contact_list_store_set_show_avatars (window->list_store, show_avatars);
343
344         /* Is compact ? */
345         gossip_conf_get_bool (conf,
346                               GOSSIP_PREFS_UI_COMPACT_CONTACT_LIST,
347                               &compact_contact_list);
348         gossip_conf_notify_add (conf,
349                                 GOSSIP_PREFS_UI_COMPACT_CONTACT_LIST,
350                                 (GossipConfNotifyFunc) main_window_notify_compact_contact_list_cb,
351                                 window);
352         gossip_contact_list_store_set_is_compact (window->list_store, compact_contact_list);
353
354         /* Sort criterium */
355         gossip_conf_notify_add (conf,
356                                 GOSSIP_PREFS_CONTACTS_SORT_CRITERIUM,
357                                 (GossipConfNotifyFunc) main_window_notify_sort_criterium_cb,
358                                 window);
359         main_window_notify_sort_criterium_cb (conf,
360                                               GOSSIP_PREFS_CONTACTS_SORT_CRITERIUM,
361                                               window);
362
363         main_window_update_status (window);
364
365         return window->window;
366 }
367
368 static void
369 main_window_destroy_cb (GtkWidget         *widget,
370                         EmpathyMainWindow *window)
371 {
372         /* Save user-defined accelerators. */
373         main_window_accels_save ();
374
375         dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (window->mc), "AccountStatusChanged",
376                                         G_CALLBACK (main_window_status_changed_cb),
377                                         window);
378
379         if (window->size_timeout_id) {
380                 g_source_remove (window->size_timeout_id);
381         }
382
383         g_list_free (window->widgets_connected);
384         g_list_free (window->widgets_disconnected);
385
386         g_object_unref (window->tooltips);
387         g_object_unref (window->mc);
388         g_object_unref (window->list_store);
389
390         g_free (window);
391 }
392
393 static void
394 main_window_favorite_chatroom_menu_setup (EmpathyMainWindow *window)
395 {
396         GList *chatrooms, *l;
397
398         window->chatroom_manager = gossip_chatroom_manager_new ();
399         chatrooms = gossip_chatroom_manager_get_chatrooms (window->chatroom_manager, NULL);
400         window->room_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (window->room));
401
402         for (l = chatrooms; l; l = l->next) {
403                 main_window_favorite_chatroom_menu_add (window, l->data);
404         }
405
406         if (!chatrooms) {
407                 gtk_widget_hide (window->room_sep);
408         }
409
410         gtk_widget_set_sensitive (window->room_join_favorites, chatrooms != NULL);
411
412         g_signal_connect (window->chatroom_manager, "chatroom-added",
413                           G_CALLBACK (main_window_favorite_chatroom_menu_added_cb),
414                           window);
415         g_signal_connect (window->chatroom_manager, "chatroom-removed",
416                           G_CALLBACK (main_window_favorite_chatroom_menu_removed_cb),
417                           window);
418
419         g_list_free (chatrooms);
420 }
421
422 static void
423 main_window_favorite_chatroom_menu_added_cb (GossipChatroomManager *manager,
424                                              GossipChatroom        *chatroom,
425                                              EmpathyMainWindow     *window)
426 {
427         main_window_favorite_chatroom_menu_add (window, chatroom);
428         gtk_widget_show (window->room_sep);
429         gtk_widget_set_sensitive (window->room_join_favorites, TRUE);
430 }
431
432 static void
433 main_window_favorite_chatroom_menu_removed_cb (GossipChatroomManager *manager,
434                                                GossipChatroom        *chatroom,
435                                                EmpathyMainWindow     *window)
436 {
437         GtkWidget *menu_item;
438
439         menu_item = g_object_get_data (G_OBJECT (chatroom), "menu_item");
440
441         g_object_set_data (G_OBJECT (chatroom), "menu_item", NULL);
442         gtk_widget_destroy (menu_item);
443
444         main_window_favorite_chatroom_menu_update (window);
445 }
446
447 static void
448 main_window_favorite_chatroom_menu_activate_cb (GtkMenuItem    *menu_item,
449                                                 GossipChatroom *chatroom)
450 {
451         main_window_favorite_chatroom_join (chatroom);
452 }
453
454 static void
455 main_window_favorite_chatroom_menu_update (EmpathyMainWindow *window)
456 {
457         GList *chatrooms;
458
459         chatrooms = gossip_chatroom_manager_get_chatrooms (window->chatroom_manager, NULL);
460
461         if (chatrooms) {
462                 gtk_widget_show (window->room_sep);
463         } else {
464                 gtk_widget_hide (window->room_sep);
465         }
466
467         gtk_widget_set_sensitive (window->room_join_favorites, chatrooms != NULL);
468         g_list_free (chatrooms);
469 }
470
471 static void
472 main_window_favorite_chatroom_menu_add (EmpathyMainWindow *window,
473                                         GossipChatroom    *chatroom)
474 {
475         GtkWidget   *menu_item;
476         const gchar *name;
477
478         if (g_object_get_data (G_OBJECT (chatroom), "menu_item")) {
479                 return;
480         }
481
482         name = gossip_chatroom_get_name (chatroom);
483         menu_item = gtk_menu_item_new_with_label (name);
484
485         g_object_set_data (G_OBJECT (chatroom), "menu_item", menu_item);
486         g_signal_connect (menu_item, "activate",
487                           G_CALLBACK (main_window_favorite_chatroom_menu_activate_cb),
488                           chatroom);
489
490         gtk_menu_shell_insert (GTK_MENU_SHELL (window->room_menu),
491                                menu_item, 3);
492
493         gtk_widget_show (menu_item);
494 }
495
496 static void
497 main_window_favorite_chatroom_join (GossipChatroom *chatroom)
498 {
499         MissionControl *mc;
500         McAccount      *account;
501         const gchar    *room;
502
503         mc = gossip_mission_control_new ();
504         account = gossip_chatroom_get_account (chatroom);
505         room = gossip_chatroom_get_room (chatroom);
506
507         gossip_debug (DEBUG_DOMAIN, "Requesting channel for '%s'", room);
508
509         mission_control_request_channel_with_string_handle (mc,
510                                                             account,
511                                                             TP_IFACE_CHANNEL_TYPE_TEXT,
512                                                             room,
513                                                             TP_HANDLE_TYPE_ROOM,
514                                                             NULL, NULL);        
515         g_object_unref (mc);
516 }
517
518 static void
519 main_window_chat_quit_cb (GtkWidget         *widget,
520                           EmpathyMainWindow *window)
521 {
522         gtk_main_quit ();
523 }
524
525 static void
526 main_window_chat_new_message_cb (GtkWidget         *widget,
527                                  EmpathyMainWindow *window)
528 {
529         //gossip_new_message_dialog_show (GTK_WINDOW (window->window));
530 }
531
532 static void
533 main_window_chat_history_cb (GtkWidget         *widget,
534                              EmpathyMainWindow *window)
535 {
536         //gossip_log_window_show (NULL, NULL);
537 }
538
539 static void
540 main_window_room_join_new_cb (GtkWidget         *widget,
541                               EmpathyMainWindow *window)
542 {
543         gossip_new_chatroom_dialog_show (GTK_WINDOW (window->window));
544 }
545
546 static void
547 main_window_room_join_favorites_cb (GtkWidget         *widget,
548                                     EmpathyMainWindow *window)
549 {
550         GList *chatrooms, *l;
551
552         chatrooms = gossip_chatroom_manager_get_chatrooms (window->chatroom_manager, NULL);
553         for (l = chatrooms; l; l = l->next) {
554                 main_window_favorite_chatroom_join (l->data);
555         }
556         g_list_free (chatrooms);
557 }
558
559 static void
560 main_window_room_manage_favorites_cb (GtkWidget         *widget,
561                                       EmpathyMainWindow *window)
562 {
563         gossip_chatrooms_window_show (GTK_WINDOW (window->window));
564 }
565
566 static void
567 main_window_chat_add_contact_cb (GtkWidget         *widget,
568                                  EmpathyMainWindow *window)
569 {
570         empathy_new_contact_dialog_show (GTK_WINDOW (window->window));
571 }
572
573 static void
574 main_window_chat_show_offline_cb (GtkCheckMenuItem  *item,
575                                   EmpathyMainWindow *window)
576 {
577         gboolean current;
578
579         current = gtk_check_menu_item_get_active (item);
580
581         gossip_conf_set_bool (gossip_conf_get (),
582                               GOSSIP_PREFS_CONTACTS_SHOW_OFFLINE,
583                               current);
584
585         /* Turn off sound just while we alter the contact list. */
586         // FIXME: gossip_sound_set_enabled (FALSE);
587         gossip_contact_list_store_set_show_offline (window->list_store, current);
588         //gossip_sound_set_enabled (TRUE);
589 }
590
591 static gboolean
592 main_window_edit_button_press_event_cb (GtkWidget         *widget,
593                                         GdkEventButton    *event,
594                                         EmpathyMainWindow *window)
595 {
596         GossipContact *contact;
597         gchar         *group;
598
599         if (!event->button == 1) {
600                 return FALSE;
601         }
602
603         group = gossip_contact_list_view_get_selected_group (window->list_view);
604         if (group) {
605                 GtkMenuItem *item;
606                 GtkWidget   *label;
607                 GtkWidget   *submenu;
608
609                 item = GTK_MENU_ITEM (window->edit_context);
610                 label = gtk_bin_get_child (GTK_BIN (item));
611                 gtk_label_set_text (GTK_LABEL (label), _("Group"));
612
613                 gtk_widget_show (window->edit_context);
614                 gtk_widget_show (window->edit_context_separator);
615
616                 submenu = gossip_contact_list_view_get_group_menu (window->list_view);
617                 gtk_menu_item_set_submenu (item, submenu);
618
619                 g_free (group);
620
621                 return FALSE;
622         }
623
624         contact = gossip_contact_list_view_get_selected (window->list_view);
625         if (contact) {
626                 GtkMenuItem *item;
627                 GtkWidget   *label;
628                 GtkWidget   *submenu;
629
630                 item = GTK_MENU_ITEM (window->edit_context);
631                 label = gtk_bin_get_child (GTK_BIN (item));
632                 gtk_label_set_text (GTK_LABEL (label), _("Contact"));
633
634                 gtk_widget_show (window->edit_context);
635                 gtk_widget_show (window->edit_context_separator);
636
637                 submenu = gossip_contact_list_view_get_contact_menu (window->list_view,
638                                                                      contact);
639                 gtk_menu_item_set_submenu (item, submenu);
640
641                 g_object_unref (contact);
642
643                 return FALSE;
644         }
645
646         gtk_widget_hide (window->edit_context);
647         gtk_widget_hide (window->edit_context_separator);
648
649         return FALSE;
650 }
651
652 static void
653 main_window_edit_accounts_cb (GtkWidget         *widget,
654                               EmpathyMainWindow *window)
655 {
656         gossip_accounts_dialog_show (GTK_WINDOW (window->window));
657 }
658
659 static void
660 main_window_edit_personal_information_cb (GtkWidget         *widget,
661                                           EmpathyMainWindow *window)
662 {
663         //gossip_vcard_dialog_show (GTK_WINDOW (window->window));
664 }
665
666 static void
667 main_window_edit_preferences_cb (GtkWidget         *widget,
668                                  EmpathyMainWindow *window)
669 {
670         gossip_preferences_show (GTK_WINDOW (window->window));
671 }
672
673 static void
674 main_window_help_about_cb (GtkWidget         *widget,
675                            EmpathyMainWindow *window)
676 {
677         gossip_about_dialog_new (GTK_WINDOW (window->window));
678 }
679
680 static void
681 main_window_help_contents_cb (GtkWidget         *widget,
682                               EmpathyMainWindow *window)
683 {
684         //gossip_help_show ();
685 }
686
687 static gboolean
688 main_window_throbber_button_press_event_cb (GtkWidget         *throbber_ebox,
689                                             GdkEventButton    *event,
690                                             EmpathyMainWindow *window)
691 {
692         if (event->type != GDK_BUTTON_PRESS ||
693             event->button != 1) {
694                 return FALSE;
695         }
696
697         gossip_accounts_dialog_show (GTK_WINDOW (window->window));
698
699         return FALSE;
700 }
701
702 static void
703 main_window_status_changed_cb (MissionControl                  *mc,
704                                TelepathyConnectionStatus        status,
705                                McPresence                       presence,
706                                TelepathyConnectionStatusReason  reason,
707                                const gchar                     *unique_name,
708                                EmpathyMainWindow               *window)
709 {
710         main_window_update_status (window);
711 }
712
713 static void
714 main_window_update_status (EmpathyMainWindow *window)
715 {
716         GList *accounts, *l;
717         guint  connected = 0;
718         guint  connecting = 0;
719         guint  disconnected = 0;
720
721         /* Count number of connected/connecting/disconnected accounts */
722         accounts = mc_accounts_list (); 
723         for (l = accounts; l; l = l->next) {
724                 McAccount *account;
725                 guint      status;
726
727                 account = l->data;
728
729                 status = mission_control_get_connection_status (window->mc,
730                                                                 account,
731                                                                 NULL);
732
733                 if (status == 0) {
734                         connected++;
735                 } else if (status == 1) {
736                         connecting++;
737                 } else if (status == 2) {
738                         disconnected++;
739                 }
740
741                 g_object_unref (account);
742         }
743         g_list_free (accounts);
744
745         /* Update the spinner state */
746         if (connecting > 0) {
747                 ephy_spinner_start (EPHY_SPINNER (window->throbber));
748         } else {
749                 ephy_spinner_stop (EPHY_SPINNER (window->throbber));
750         }
751
752         /* Update widgets sensibility */
753         for (l = window->widgets_connected; l; l = l->next) {
754                 gtk_widget_set_sensitive (l->data, (connected > 0));
755         }
756
757         for (l = window->widgets_disconnected; l; l = l->next) {
758                 gtk_widget_set_sensitive (l->data, (disconnected > 0));
759         }
760 }
761
762 /*
763  * Accels
764  */
765 static void
766 main_window_accels_load (void)
767 {
768         gchar *filename;
769
770         filename = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, ACCELS_FILENAME, NULL);
771         if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
772                 gossip_debug (DEBUG_DOMAIN, "Loading from:'%s'", filename);
773                 gtk_accel_map_load (filename);
774         }
775
776         g_free (filename);
777 }
778
779 static void
780 main_window_accels_save (void)
781 {
782         gchar *dir;
783         gchar *file_with_path;
784
785         dir = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, NULL);
786         g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
787         file_with_path = g_build_filename (dir, ACCELS_FILENAME, NULL);
788         g_free (dir);
789
790         gossip_debug (DEBUG_DOMAIN, "Saving to:'%s'", file_with_path);
791         gtk_accel_map_save (file_with_path);
792
793         g_free (file_with_path);
794 }
795
796 static void
797 main_window_connection_items_setup (EmpathyMainWindow *window,
798                                     GladeXML          *glade)
799 {
800         GList         *list;
801         GtkWidget     *w;
802         gint           i;
803         const gchar *widgets_connected[] = {
804                 "room",
805                 "chat_new_message",
806                 "chat_add_contact",
807                 "edit_personal_information"
808         };
809         const gchar *widgets_disconnected[] = {
810         };
811
812         for (i = 0, list = NULL; i < G_N_ELEMENTS (widgets_connected); i++) {
813                 w = glade_xml_get_widget (glade, widgets_connected[i]);
814                 list = g_list_prepend (list, w);
815         }
816
817         window->widgets_connected = list;
818
819         for (i = 0, list = NULL; i < G_N_ELEMENTS (widgets_disconnected); i++) {
820                 w = glade_xml_get_widget (glade, widgets_disconnected[i]);
821                 list = g_list_prepend (list, w);
822         }
823
824         window->widgets_disconnected = list;
825 }
826
827 static gboolean
828 main_window_configure_event_timeout_cb (EmpathyMainWindow *window)
829 {
830         gint x, y, w, h;
831
832         gtk_window_get_size (GTK_WINDOW (window->window), &w, &h);
833         gtk_window_get_position (GTK_WINDOW (window->window), &x, &y);
834
835         gossip_geometry_save (GEOMETRY_NAME, x, y, w, h);
836
837         window->size_timeout_id = 0;
838
839         return FALSE;
840 }
841
842 static gboolean
843 main_window_configure_event_cb (GtkWidget         *widget,
844                                 GdkEventConfigure *event,
845                                 EmpathyMainWindow *window)
846 {
847         if (window->size_timeout_id) {
848                 g_source_remove (window->size_timeout_id);
849         }
850
851         window->size_timeout_id = g_timeout_add (500,
852                                                (GSourceFunc) main_window_configure_event_timeout_cb,
853                                                window);
854
855         return FALSE;
856 }
857
858 static void
859 main_window_notify_show_offline_cb (GossipConf  *conf,
860                                     const gchar *key,
861                                     gpointer     check_menu_item)
862 {
863         gboolean show_offline;
864
865         if (gossip_conf_get_bool (conf, key, &show_offline)) {
866                 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (check_menu_item),
867                                                 show_offline);
868         }
869 }
870
871 static void
872 main_window_notify_show_avatars_cb (GossipConf        *conf,
873                                     const gchar       *key,
874                                     EmpathyMainWindow *window)
875 {
876         gboolean show_avatars;
877
878         if (gossip_conf_get_bool (conf, key, &show_avatars)) {
879                 gossip_contact_list_store_set_show_avatars (window->list_store,
880                                                             show_avatars);
881         }
882 }
883
884 static void
885 main_window_notify_compact_contact_list_cb (GossipConf        *conf,
886                                             const gchar       *key,
887                                             EmpathyMainWindow *window)
888 {
889         gboolean compact_contact_list;
890
891         if (gossip_conf_get_bool (conf, key, &compact_contact_list)) {
892                 gossip_contact_list_store_set_is_compact (window->list_store,
893                                                           compact_contact_list);
894         }
895 }
896
897 static void
898 main_window_notify_sort_criterium_cb (GossipConf        *conf,
899                                       const gchar       *key,
900                                       EmpathyMainWindow *window)
901 {
902         gchar *str = NULL;
903
904         if (gossip_conf_get_string (conf, key, &str)) {
905                 GType       type;
906                 GEnumClass *enum_class;
907                 GEnumValue *enum_value;
908
909                 type = gossip_contact_list_store_sort_get_type ();
910                 enum_class = G_ENUM_CLASS (g_type_class_peek (type));
911                 enum_value = g_enum_get_value_by_nick (enum_class, str);
912                 g_free (str);
913
914                 if (enum_value) {
915                         gossip_contact_list_store_set_sort_criterium (window->list_store, 
916                                                                       enum_value->value);
917                 }
918         }
919 }
920