]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-notify-manager.c
Merge remote-tracking branch 'origin/gnome-3-8'
[empathy.git] / libempathy-gtk / empathy-notify-manager.c
1 /* * Copyright (C) 2009 Collabora Ltd.
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2.1 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16  *
17  * Authors: Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
18  */
19
20 #include "config.h"
21 #include "empathy-notify-manager.h"
22
23 #include <libnotify/notify.h>
24
25 #include "empathy-gsettings.h"
26 #include "empathy-ui-utils.h"
27 #include "empathy-utils.h"
28
29 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
30 #include "empathy-debug.h"
31
32 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyNotifyManager)
33
34 typedef struct
35 {
36   /* owned (gchar *) => TRUE */
37   GHashTable *capabilities;
38   TpAccountManager *account_manager;
39   GSettings *gsettings_notif;
40 } EmpathyNotifyManagerPriv;
41
42 G_DEFINE_TYPE (EmpathyNotifyManager, empathy_notify_manager, G_TYPE_OBJECT);
43
44 static EmpathyNotifyManager *notify_manager = NULL;
45
46 static GObject *
47 notify_manager_constructor (GType type,
48     guint n_construct_params,
49     GObjectConstructParam *construct_params)
50 {
51   GObject *retval;
52
53   if (notify_manager != NULL)
54     return g_object_ref (notify_manager);
55
56   retval = G_OBJECT_CLASS (empathy_notify_manager_parent_class)->constructor
57     (type, n_construct_params, construct_params);
58
59   notify_manager = EMPATHY_NOTIFY_MANAGER (retval);
60   g_object_add_weak_pointer (retval, (gpointer) &notify_manager);
61
62   return retval;
63 }
64
65 static void
66 notify_manager_dispose (GObject *object)
67 {
68   EmpathyNotifyManagerPriv *priv = GET_PRIV (object);
69
70   if (priv->account_manager != NULL)
71     {
72       g_object_unref (priv->account_manager);
73       priv->account_manager = NULL;
74     }
75
76   tp_clear_object (&priv->gsettings_notif);
77
78   G_OBJECT_CLASS (empathy_notify_manager_parent_class)->dispose (object);
79 }
80
81 static void
82 notify_manager_finalize (GObject *object)
83 {
84   EmpathyNotifyManagerPriv *priv = GET_PRIV (object);
85
86   g_hash_table_unref (priv->capabilities);
87
88   G_OBJECT_CLASS (empathy_notify_manager_parent_class)->finalize (object);
89 }
90
91 static void
92 empathy_notify_manager_class_init (EmpathyNotifyManagerClass *klass)
93 {
94   GObjectClass *object_class = G_OBJECT_CLASS (klass);
95
96   object_class->dispose = notify_manager_dispose;
97   object_class->finalize = notify_manager_finalize;
98   object_class->constructor = notify_manager_constructor;
99
100   g_type_class_add_private (object_class, sizeof (EmpathyNotifyManagerPriv));
101 }
102
103 static void
104 account_manager_prepared_cb (GObject *source_object,
105     GAsyncResult *result,
106     gpointer user_data)
107 {
108   TpAccountManager *account_manager = TP_ACCOUNT_MANAGER (source_object);
109   GError *error = NULL;
110
111   if (!tp_proxy_prepare_finish (account_manager, result, &error))
112     {
113       DEBUG ("Failed to prepare account manager: %s", error->message);
114       g_error_free (error);
115       return;
116     }
117 }
118
119 static void
120 empathy_notify_manager_init (EmpathyNotifyManager *self)
121 {
122   EmpathyNotifyManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
123     EMPATHY_TYPE_NOTIFY_MANAGER, EmpathyNotifyManagerPriv);
124   GList *list, *l;
125
126   self->priv = priv;
127
128   priv->gsettings_notif = g_settings_new (EMPATHY_PREFS_NOTIFICATIONS_SCHEMA);
129
130   priv->capabilities = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
131       NULL);
132
133   /* fetch capabilities */
134   list = notify_get_server_caps ();
135   for (l = list; l != NULL; l = g_list_next (l))
136     {
137       gchar *cap = l->data;
138
139       DEBUG ("add capability: %s", cap);
140       /* owernship of the string is transfered to the hash table */
141       g_hash_table_insert (priv->capabilities, cap, GUINT_TO_POINTER (TRUE));
142     }
143   g_list_free (list);
144
145   priv->account_manager = tp_account_manager_dup ();
146
147   tp_proxy_prepare_async (priv->account_manager, NULL,
148       account_manager_prepared_cb, self);
149 }
150
151 EmpathyNotifyManager *
152 empathy_notify_manager_dup_singleton (void)
153 {
154   return g_object_new (EMPATHY_TYPE_NOTIFY_MANAGER, NULL);
155 }
156
157 gboolean
158 empathy_notify_manager_has_capability (EmpathyNotifyManager *self,
159     const gchar *cap)
160 {
161   EmpathyNotifyManagerPriv *priv = GET_PRIV (self);
162
163   return g_hash_table_lookup (priv->capabilities, cap) != NULL;
164 }
165
166 GdkPixbuf *
167 empathy_notify_manager_get_pixbuf_for_notification (EmpathyNotifyManager *self,
168     EmpathyContact *contact,
169     const char *icon_name)
170 {
171   GdkPixbuf *pixbuf = NULL;
172
173   if (contact != NULL)
174     pixbuf = empathy_pixbuf_avatar_from_contact_scaled (contact, 48, 48);
175
176   if (pixbuf == NULL)
177     pixbuf = empathy_pixbuf_from_icon_name_sized (icon_name, 48);
178
179   return pixbuf;
180 }
181
182 gboolean
183 empathy_notify_manager_notification_is_enabled  (EmpathyNotifyManager *self)
184 {
185   EmpathyNotifyManagerPriv *priv = GET_PRIV (self);
186   TpConnectionPresenceType presence;
187
188   if (!g_settings_get_boolean (priv->gsettings_notif,
189         EMPATHY_PREFS_NOTIFICATIONS_ENABLED))
190     return FALSE;
191
192   if (!tp_account_manager_is_prepared (priv->account_manager,
193         TP_ACCOUNT_MANAGER_FEATURE_CORE))
194     {
195       DEBUG ("account manager is not ready yet; display the notification");
196       return TRUE;
197     }
198
199   presence = tp_account_manager_get_most_available_presence (
200       priv->account_manager,
201       NULL, NULL);
202
203   if (presence != TP_CONNECTION_PRESENCE_TYPE_AVAILABLE &&
204       presence != TP_CONNECTION_PRESENCE_TYPE_UNSET)
205     {
206       if (g_settings_get_boolean (priv->gsettings_notif,
207             EMPATHY_PREFS_NOTIFICATIONS_DISABLED_AWAY))
208         return FALSE;
209     }
210
211   return TRUE;
212 }
213
214 NotifyNotification *
215 empathy_notify_manager_create_notification (const gchar *summary,
216     const char *body,
217     const gchar *icon)
218 {
219   NotifyNotification *notification;
220
221   notification = notify_notification_new (summary, body, icon);
222
223   notify_notification_set_hint (notification,
224       EMPATHY_NOTIFY_MANAGER_CAP_DESKTOP_ENTRY,
225       g_variant_new_string ("empathy"));
226
227   return notification;
228 }