~bcurtiswx/ubuntu/precise/empathy/3.4.2.1-0ubuntu1

« back to all changes in this revision

Viewing changes to libempathy-gtk/empathy-status-icon.c

  • Committer: Bazaar Package Importer
  • Author(s): Sjoerd Simons
  • Date: 2007-05-20 15:31:42 UTC
  • Revision ID: james.westby@ubuntu.com-20070520153142-r3auwguxdgxhktqb
Tags: upstream-0.4
ImportĀ upstreamĀ versionĀ 0.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <string.h>
 
26
 
 
27
#include <gtk/gtk.h>
 
28
#include <glade/glade.h>
 
29
 
 
30
#include <libmissioncontrol/mission-control.h>
 
31
 
 
32
#include <libempathy/gossip-debug.h>
 
33
#include <libempathy/gossip-utils.h>
 
34
#include <libempathy/gossip-conf.h>
 
35
#include <libempathy/empathy-idle.h>
 
36
 
 
37
#include "empathy-status-icon.h"
 
38
#include "gossip-presence-chooser.h"
 
39
#include "gossip-preferences.h"
 
40
#include "gossip-ui-utils.h"
 
41
#include "gossip-accounts-dialog.h"
 
42
 
 
43
 
 
44
#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
 
45
                       EMPATHY_TYPE_STATUS_ICON, EmpathyStatusIconPriv))
 
46
 
 
47
#define DEBUG_DOMAIN "StatusIcon"
 
48
 
 
49
struct _EmpathyStatusIconPriv {
 
50
        MissionControl *mc;
 
51
        GtkStatusIcon  *icon;
 
52
        EmpathyIdle    *idle;
 
53
 
 
54
        GtkWindow      *window;
 
55
 
 
56
        GtkWidget      *popup_menu;
 
57
        GtkWidget      *show_window_item;
 
58
        GtkWidget      *message_item;
 
59
        GtkWidget      *status_item;
 
60
};
 
61
 
 
62
static void     empathy_status_icon_class_init  (EmpathyStatusIconClass *klass);
 
63
static void     empathy_status_icon_init        (EmpathyStatusIcon      *icon);
 
64
static void     status_icon_finalize            (GObject                *object);
 
65
static void     status_icon_presence_changed_cb (MissionControl         *mc,
 
66
                                                 McPresence              state,
 
67
                                                 EmpathyStatusIcon      *icon);
 
68
static void     status_icon_toggle_visibility   (EmpathyStatusIcon      *icon);
 
69
static void     status_icon_activate_cb         (GtkStatusIcon          *status_icon,
 
70
                                                 EmpathyStatusIcon      *icon);
 
71
static gboolean status_icon_delete_event_cb     (GtkWidget              *widget,
 
72
                                                 GdkEvent               *event,
 
73
                                                 EmpathyStatusIcon      *icon);
 
74
static void     status_icon_popup_menu_cb       (GtkStatusIcon          *status_icon,
 
75
                                                 guint                   button,
 
76
                                                 guint                   activate_time,
 
77
                                                 EmpathyStatusIcon      *icon);
 
78
static void     status_icon_create_menu         (EmpathyStatusIcon      *icon);
 
79
static void     status_icon_new_message_cb      (GtkWidget              *widget,
 
80
                                                 EmpathyStatusIcon      *icon);
 
81
static void     status_icon_quit_cb             (GtkWidget              *window,
 
82
                                                 EmpathyStatusIcon      *icon);
 
83
static void     status_icon_show_hide_window_cb (GtkWidget              *widget,
 
84
                                                 EmpathyStatusIcon      *icon);
 
85
 
 
86
G_DEFINE_TYPE (EmpathyStatusIcon, empathy_status_icon, G_TYPE_OBJECT);
 
87
 
 
88
static void
 
89
empathy_status_icon_class_init (EmpathyStatusIconClass *klass)
 
90
{
 
91
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
92
 
 
93
        object_class->finalize = status_icon_finalize;
 
94
 
 
95
        g_type_class_add_private (object_class, sizeof (EmpathyStatusIconPriv));
 
96
}
 
97
 
 
98
static void
 
99
empathy_status_icon_init (EmpathyStatusIcon *icon)
 
100
{
 
101
        EmpathyStatusIconPriv *priv;
 
102
        McPresence             state;
 
103
 
 
104
        priv = GET_PRIV (icon);
 
105
 
 
106
        priv->icon = gtk_status_icon_new ();
 
107
        priv->mc = gossip_mission_control_new ();
 
108
        priv->idle = empathy_idle_new ();
 
109
 
 
110
        status_icon_create_menu (icon);
 
111
 
 
112
        state = mission_control_get_presence_actual (priv->mc, NULL);
 
113
        status_icon_presence_changed_cb (priv->mc, state, icon);
 
114
        
 
115
        dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc),
 
116
                                     "PresenceStatusActual",
 
117
                                     G_CALLBACK (status_icon_presence_changed_cb),
 
118
                                     icon, NULL);
 
119
        g_signal_connect (priv->icon, "activate",
 
120
                          G_CALLBACK (status_icon_activate_cb),
 
121
                          icon);
 
122
        g_signal_connect (priv->icon, "popup-menu",
 
123
                          G_CALLBACK (status_icon_popup_menu_cb),
 
124
                          icon);
 
125
}
 
126
 
 
127
static void
 
128
status_icon_finalize (GObject *object)
 
129
{
 
130
        EmpathyStatusIconPriv *priv;
 
131
 
 
132
        priv = GET_PRIV (object);
 
133
 
 
134
        dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc),
 
135
                                        "PresenceStatusActual",
 
136
                                        G_CALLBACK (status_icon_presence_changed_cb),
 
137
                                        object);
 
138
 
 
139
        g_object_unref (priv->mc);
 
140
        g_object_unref (priv->icon);
 
141
        g_object_unref (priv->window);
 
142
        g_object_unref (priv->idle);
 
143
}
 
144
 
 
145
EmpathyStatusIcon *
 
146
empathy_status_icon_new (GtkWindow *window)
 
147
{
 
148
        EmpathyStatusIconPriv *priv;
 
149
        EmpathyStatusIcon     *icon;
 
150
        gboolean               should_hide;
 
151
        gboolean               visible;
 
152
 
 
153
        g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
 
154
 
 
155
        icon = g_object_new (EMPATHY_TYPE_STATUS_ICON, NULL);
 
156
        priv = GET_PRIV (icon);
 
157
 
 
158
        priv->window = g_object_ref (window);
 
159
 
 
160
        g_signal_connect (priv->window, "delete-event",
 
161
                          G_CALLBACK (status_icon_delete_event_cb),
 
162
                          icon);
 
163
 
 
164
        gossip_conf_get_bool (gossip_conf_get (),
 
165
                              GOSSIP_PREFS_UI_MAIN_WINDOW_HIDDEN,
 
166
                              &should_hide);
 
167
        visible = gossip_window_get_is_visible (window);
 
168
 
 
169
        if ((!should_hide && !visible) || (should_hide && visible)) {
 
170
                status_icon_toggle_visibility (icon);
 
171
        }
 
172
 
 
173
        return icon;
 
174
}
 
175
 
 
176
static void
 
177
status_icon_presence_changed_cb (MissionControl    *mc,
 
178
                                 McPresence         state,
 
179
                                 EmpathyStatusIcon *icon)
 
180
{
 
181
        EmpathyStatusIconPriv *priv;
 
182
        const gchar           *icon_name;
 
183
        gchar                 *status;
 
184
 
 
185
        priv = GET_PRIV (icon);
 
186
 
 
187
        icon_name = gossip_icon_name_for_presence_state (state);
 
188
        status = mission_control_get_presence_message_actual (priv->mc, NULL);
 
189
        if (G_STR_EMPTY (status)) {
 
190
                g_free (status);
 
191
                status = g_strdup (gossip_presence_state_get_default_status (state));
 
192
        }
 
193
 
 
194
        gtk_status_icon_set_from_icon_name (priv->icon, icon_name);
 
195
        gtk_status_icon_set_tooltip (priv->icon, status);
 
196
 
 
197
        g_free (status);
 
198
 
 
199
        if (state < MC_PRESENCE_AVAILABLE) {
 
200
                gtk_widget_set_sensitive (priv->message_item, FALSE);
 
201
        } else {
 
202
                gtk_widget_set_sensitive (priv->message_item, TRUE);
 
203
        }
 
204
}
 
205
 
 
206
static void
 
207
status_icon_toggle_visibility (EmpathyStatusIcon *icon)
 
208
{
 
209
        EmpathyStatusIconPriv *priv;
 
210
        gboolean               visible;
 
211
 
 
212
        priv = GET_PRIV (icon);
 
213
 
 
214
        visible = gossip_window_get_is_visible (GTK_WINDOW (priv->window));
 
215
 
 
216
        if (visible) {
 
217
                gtk_widget_hide (GTK_WIDGET (priv->window));
 
218
                gossip_conf_set_bool (gossip_conf_get (),
 
219
                                      GOSSIP_PREFS_UI_MAIN_WINDOW_HIDDEN, TRUE);
 
220
        } else {
 
221
                GList *accounts;
 
222
 
 
223
                gossip_window_present (GTK_WINDOW (priv->window), TRUE);
 
224
                gossip_conf_set_bool (gossip_conf_get (),
 
225
                                      GOSSIP_PREFS_UI_MAIN_WINDOW_HIDDEN, FALSE);
 
226
        
 
227
                /* Show the accounts dialog if there is no enabled accounts */
 
228
                accounts = mc_accounts_list_by_enabled (TRUE);
 
229
                if (accounts) {
 
230
                        mc_accounts_list_free (accounts);
 
231
                } else {
 
232
                        gossip_debug (DEBUG_DOMAIN,
 
233
                                      "No enabled account, Showing account dialog");
 
234
                        gossip_accounts_dialog_show ();
 
235
                }
 
236
        }
 
237
}
 
238
 
 
239
static void
 
240
status_icon_activate_cb (GtkStatusIcon     *status_icon,
 
241
                         EmpathyStatusIcon *icon)
 
242
{
 
243
        status_icon_toggle_visibility (icon);
 
244
}
 
245
 
 
246
static gboolean
 
247
status_icon_delete_event_cb (GtkWidget         *widget,
 
248
                             GdkEvent          *event,
 
249
                             EmpathyStatusIcon *icon)
 
250
{
 
251
        status_icon_toggle_visibility (icon);
 
252
 
 
253
        return TRUE;
 
254
}
 
255
 
 
256
static void
 
257
status_icon_popup_menu_cb (GtkStatusIcon     *status_icon,
 
258
                           guint              button,
 
259
                           guint              activate_time,
 
260
                           EmpathyStatusIcon *icon)
 
261
{
 
262
        EmpathyStatusIconPriv *priv;
 
263
        GtkWidget             *submenu;
 
264
        gboolean               show;
 
265
 
 
266
        priv = GET_PRIV (icon);
 
267
 
 
268
        show = gossip_window_get_is_visible (GTK_WINDOW (priv->window));
 
269
 
 
270
        g_signal_handlers_block_by_func (priv->show_window_item,
 
271
                                         status_icon_show_hide_window_cb,
 
272
                                         icon);
 
273
        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (priv->show_window_item),
 
274
                                        show);
 
275
        g_signal_handlers_unblock_by_func (priv->show_window_item,
 
276
                                           status_icon_show_hide_window_cb,
 
277
                                           icon);
 
278
 
 
279
        submenu = gossip_presence_chooser_create_menu ();
 
280
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (priv->status_item),
 
281
                                   submenu);
 
282
 
 
283
        gtk_menu_popup (GTK_MENU (priv->popup_menu),
 
284
                        NULL, NULL,
 
285
                        gtk_status_icon_position_menu,
 
286
                        priv->icon,
 
287
                        button,
 
288
                        activate_time);
 
289
}
 
290
 
 
291
static void
 
292
status_icon_create_menu (EmpathyStatusIcon *icon)
 
293
{
 
294
        EmpathyStatusIconPriv *priv;
 
295
        GladeXML              *glade;
 
296
 
 
297
        priv = GET_PRIV (icon);
 
298
 
 
299
        glade = gossip_glade_get_file ("empathy-status-icon.glade",
 
300
                                       "tray_menu",
 
301
                                       NULL,
 
302
                                       "tray_menu", &priv->popup_menu,
 
303
                                       "tray_show_list", &priv->show_window_item,
 
304
                                       "tray_new_message", &priv->message_item,
 
305
                                       "tray_status", &priv->status_item,
 
306
                                       NULL);
 
307
 
 
308
        gossip_glade_connect (glade,
 
309
                              icon,
 
310
                              "tray_new_message", "activate", status_icon_new_message_cb,
 
311
                              "tray_quit", "activate", status_icon_quit_cb,
 
312
                              NULL);
 
313
 
 
314
        g_signal_connect (priv->show_window_item, "toggled",
 
315
                          G_CALLBACK (status_icon_show_hide_window_cb),
 
316
                          icon);
 
317
 
 
318
        g_object_unref (glade);
 
319
}
 
320
 
 
321
static void
 
322
status_icon_new_message_cb (GtkWidget         *widget,
 
323
                            EmpathyStatusIcon *icon)
 
324
{
 
325
        EmpathyStatusIconPriv *priv;
 
326
 
 
327
        priv = GET_PRIV (icon);
 
328
 
 
329
        //gossip_new_message_dialog_show (GTK_WINDOW (priv->window));
 
330
}
 
331
 
 
332
static void
 
333
status_icon_quit_cb (GtkWidget         *window,
 
334
                     EmpathyStatusIcon *icon)
 
335
{
 
336
        gtk_main_quit ();
 
337
}
 
338
 
 
339
static void
 
340
status_icon_show_hide_window_cb (GtkWidget         *widget,
 
341
                                 EmpathyStatusIcon *icon)
 
342
{
 
343
        status_icon_toggle_visibility (icon);
 
344
}
 
345