]> git.0d.be Git - empathy.git/blob - libempathy/empathy-presence.c
136dce36a862e0a8b42722615a5d3e3972e9684b
[empathy.git] / libempathy / empathy-presence.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2004-2007 Imendio AB
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: Mikael Hallendal <micke@imendio.com>
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include <glib/gi18n.h>
28
29 #include "empathy-presence.h"
30 #include "empathy-time.h"
31
32 /* FIXME mission-control does not install libmissioncontrol/mc-enum-types.h so
33  * we have to define MC_TYPE_PRESENCE here. See sf.net bug #1768235,
34  * https://sf.net/tracker/?func=detail&atid=932444&aid=1768235&group_id=190214 */
35 #ifndef MC_TYPE_PRESENCE
36 GType mc_presence_get_type (void) G_GNUC_CONST;
37 #define MC_TYPE_PRESENCE (mc_presence_get_type())
38 #endif
39
40 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_PRESENCE, EmpathyPresencePriv))
41
42 typedef struct _EmpathyPresencePriv EmpathyPresencePriv;
43
44 struct _EmpathyPresencePriv {
45         McPresence  state;
46         gchar      *status;
47         EmpathyTime  timestamp;
48 };
49
50 static void         presence_finalize     (GObject      *object);
51 static void         presence_get_property (GObject      *object,
52                                            guint         param_id,
53                                            GValue       *value,
54                                            GParamSpec   *pspec);
55 static void         presence_set_property (GObject      *object,
56                                            guint         param_id,
57                                            const GValue *value,
58                                            GParamSpec   *pspec);
59
60 enum {
61         PROP_0,
62         PROP_STATE,
63         PROP_STATUS
64 };
65
66 G_DEFINE_TYPE (EmpathyPresence, empathy_presence, G_TYPE_OBJECT);
67
68 static void
69 empathy_presence_class_init (EmpathyPresenceClass *class)
70 {
71         GObjectClass *object_class;
72
73         object_class = G_OBJECT_CLASS (class);
74
75         object_class->finalize     = presence_finalize;
76         object_class->get_property = presence_get_property;
77         object_class->set_property = presence_set_property;
78
79         g_object_class_install_property (object_class,
80                                          PROP_STATE,
81                                          g_param_spec_enum ("state",
82                                                             "Presence State",
83                                                             "The current state of the presence",
84                                                             MC_TYPE_PRESENCE,
85                                                             MC_PRESENCE_AVAILABLE,
86                                                             G_PARAM_READWRITE));
87         g_object_class_install_property (object_class,
88                                          PROP_STATUS,
89                                          g_param_spec_string ("status",
90                                                               "Presence Status",
91                                                               "Status string set on presence",
92                                                               NULL,
93                                                               G_PARAM_READWRITE));
94
95         g_type_class_add_private (object_class, sizeof (EmpathyPresencePriv));
96 }
97
98 static void
99 empathy_presence_init (EmpathyPresence *presence)
100 {
101         EmpathyPresencePriv *priv;
102
103         priv = GET_PRIV (presence);
104
105         priv->state = MC_PRESENCE_AVAILABLE;
106         priv->status = NULL;
107         priv->timestamp = empathy_time_get_current ();
108 }
109
110 static void
111 presence_finalize (GObject *object)
112 {
113         EmpathyPresencePriv *priv;
114
115         priv = GET_PRIV (object);
116
117         g_free (priv->status);
118
119         (G_OBJECT_CLASS (empathy_presence_parent_class)->finalize) (object);
120 }
121
122 static void
123 presence_get_property (GObject    *object,
124                        guint       param_id,
125                        GValue     *value,
126                        GParamSpec *pspec)
127 {
128         EmpathyPresencePriv *priv;
129
130         priv = GET_PRIV (object);
131
132         switch (param_id) {
133         case PROP_STATE:
134                 g_value_set_enum (value, priv->state);
135                 break;
136         case PROP_STATUS:
137                 g_value_set_string (value,
138                                     empathy_presence_get_status (EMPATHY_PRESENCE (object)));
139                 break;
140         default:
141                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
142                 break;
143         }
144 }
145 static void
146 presence_set_property (GObject      *object,
147                        guint         param_id,
148                        const GValue *value,
149                        GParamSpec   *pspec)
150 {
151         EmpathyPresencePriv *priv;
152
153         priv = GET_PRIV (object);
154
155         switch (param_id) {
156         case PROP_STATE:
157                 priv->state = g_value_get_enum (value);
158                 break;
159         case PROP_STATUS:
160                 empathy_presence_set_status (EMPATHY_PRESENCE (object),
161                                             g_value_get_string (value));
162                 break;
163         default:
164                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
165                 break;
166         }
167 }
168
169 EmpathyPresence *
170 empathy_presence_new (void)
171 {
172         return g_object_new (EMPATHY_TYPE_PRESENCE, NULL);
173 }
174
175 EmpathyPresence *
176 empathy_presence_new_full (McPresence   state,
177                           const gchar *status)
178 {
179         return g_object_new (EMPATHY_TYPE_PRESENCE,
180                              "state", state,
181                              "status", status,
182                              NULL);
183 }
184
185 const gchar *
186 empathy_presence_get_status (EmpathyPresence *presence)
187 {
188         EmpathyPresencePriv *priv;
189
190         g_return_val_if_fail (EMPATHY_IS_PRESENCE (presence),
191                               _("Offline"));
192
193         priv = GET_PRIV (presence);
194
195         return priv->status;
196 }
197
198 McPresence
199 empathy_presence_get_state (EmpathyPresence *presence)
200 {
201         EmpathyPresencePriv *priv;
202
203         g_return_val_if_fail (EMPATHY_IS_PRESENCE (presence),
204                               MC_PRESENCE_AVAILABLE);
205
206         priv = GET_PRIV (presence);
207
208         return priv->state;
209 }
210
211 void
212 empathy_presence_set_state (EmpathyPresence *presence,
213                            McPresence      state)
214 {
215         EmpathyPresencePriv *priv;
216
217         g_return_if_fail (EMPATHY_IS_PRESENCE (presence));
218
219         priv = GET_PRIV (presence);
220
221         priv->state = state;
222
223         g_object_notify (G_OBJECT (presence), "state");
224 }
225
226 void
227 empathy_presence_set_status (EmpathyPresence *presence,
228                             const gchar    *status)
229 {
230         EmpathyPresencePriv *priv;
231
232         priv = GET_PRIV (presence);
233         g_return_if_fail (EMPATHY_IS_PRESENCE (presence));
234
235         g_free (priv->status);
236
237         if (status) {
238                 priv->status = g_strdup (status);
239         } else {
240                 priv->status = NULL;
241         }
242
243         g_object_notify (G_OBJECT (presence), "status");
244 }
245
246 gint
247 empathy_presence_sort_func (gconstpointer a,
248                            gconstpointer b)
249 {
250         EmpathyPresencePriv *priv_a;
251         EmpathyPresencePriv *priv_b;
252         gint                diff;
253
254         g_return_val_if_fail (EMPATHY_IS_PRESENCE (a), 0);
255         g_return_val_if_fail (EMPATHY_IS_PRESENCE (b), 0);
256          
257         priv_a = GET_PRIV (a);
258         priv_b = GET_PRIV (b);
259
260         /* 1. State */
261         diff = priv_a->state - priv_b->state;
262         if (diff != 0) {
263                 return diff < 1 ? -1 : +1;
264         }
265
266         /* 3. Time (newest first) */
267         diff = priv_b->timestamp - priv_a->timestamp;
268         if (diff != 0) {
269                 return diff < 1 ? -1 : +1;
270         }
271                 
272         /* No real difference */
273         return 0;
274 }
275
276 const gchar *
277 empathy_presence_state_get_default_status (McPresence state)
278 {
279         switch (state) {
280         case MC_PRESENCE_AVAILABLE:
281                 return _("Available");
282         case MC_PRESENCE_DO_NOT_DISTURB:
283                 return _("Busy");
284         case MC_PRESENCE_AWAY:
285         case MC_PRESENCE_EXTENDED_AWAY:
286                 return _("Away");
287         case MC_PRESENCE_HIDDEN:
288         case MC_PRESENCE_OFFLINE:
289         case MC_PRESENCE_UNSET:
290                 return _("Offline");
291         default:
292                 g_assert_not_reached ();
293         }
294
295         return NULL;
296 }
297
298 const gchar *
299 empathy_presence_state_to_str (McPresence state)
300 {
301         switch (state) {
302         case MC_PRESENCE_AVAILABLE:
303                 return "available";
304         case MC_PRESENCE_DO_NOT_DISTURB:
305                 return "busy";
306         case MC_PRESENCE_AWAY:
307                 return "away";
308         case MC_PRESENCE_EXTENDED_AWAY:
309                 return "ext_away";
310         case MC_PRESENCE_HIDDEN:
311                 return "hidden";
312         case MC_PRESENCE_OFFLINE:
313                 return "offline";
314         case MC_PRESENCE_UNSET:
315                 return "unset";
316         default:
317                 g_assert_not_reached ();
318         }
319
320         return NULL;
321 }
322
323 McPresence
324 empathy_presence_state_from_str (const gchar *str)
325 {
326         if (strcmp (str, "available") == 0) {
327                 return MC_PRESENCE_AVAILABLE;
328         } else if ((strcmp (str, "dnd") == 0) || (strcmp (str, "busy") == 0)) {
329                 return MC_PRESENCE_DO_NOT_DISTURB;
330         } else if ((strcmp (str, "away") == 0) || (strcmp (str, "brb") == 0)) {
331                 return MC_PRESENCE_AWAY;
332         } else if ((strcmp (str, "xa") == 0) || (strcmp (str, "ext_away") == 0)) {
333                 return MC_PRESENCE_EXTENDED_AWAY;
334         } else if (strcmp (str, "hidden") == 0) {
335                 return MC_PRESENCE_HIDDEN;
336         } else if (strcmp (str, "offline") == 0) {
337                 return MC_PRESENCE_OFFLINE;
338         } else if (strcmp (str, "unset") == 0) {
339                 return MC_PRESENCE_UNSET;
340         }
341
342         return MC_PRESENCE_AVAILABLE;
343 }
344