]> git.0d.be Git - empathy.git/blob - libempathy/gossip-presence.c
[darcs-to-svn @ Fix copyright in GPL header]
[empathy.git] / libempathy / gossip-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 "gossip-presence.h"
30 #include "gossip-time.h"
31
32 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_PRESENCE, GossipPresencePriv))
33
34 typedef struct _GossipPresencePriv GossipPresencePriv;
35
36 struct _GossipPresencePriv {
37         GossipPresenceState  state;
38         gchar               *status;
39         GossipTime           timestamp;
40 };
41
42 static void         presence_finalize           (GObject             *object);
43 static void         presence_get_property       (GObject             *object,
44                                                  guint                param_id,
45                                                  GValue              *value,
46                                                  GParamSpec          *pspec);
47 static void         presence_set_property       (GObject             *object,
48                                                  guint                param_id,
49                                                  const GValue        *value,
50                                                  GParamSpec          *pspec);
51
52 enum {
53         PROP_0,
54         PROP_STATE,
55         PROP_STATUS
56 };
57
58 G_DEFINE_TYPE (GossipPresence, gossip_presence, G_TYPE_OBJECT);
59
60 static void
61 gossip_presence_class_init (GossipPresenceClass *class)
62 {
63         GObjectClass *object_class;
64
65         object_class = G_OBJECT_CLASS (class);
66
67         object_class->finalize     = presence_finalize;
68         object_class->get_property = presence_get_property;
69         object_class->set_property = presence_set_property;
70
71         g_object_class_install_property (object_class,
72                                          PROP_STATE,
73                                          g_param_spec_int ("state",
74                                                            "Presence State",
75                                                            "The current state of the presence",
76                                                            GOSSIP_PRESENCE_STATE_AVAILABLE,
77                                                            GOSSIP_PRESENCE_STATE_EXT_AWAY,
78                                                            GOSSIP_PRESENCE_STATE_AVAILABLE,
79                                                            G_PARAM_READWRITE));
80         g_object_class_install_property (object_class,
81                                          PROP_STATUS,
82                                          g_param_spec_string ("status",
83                                                               "Presence Status",
84                                                               "Status string set on presence",
85                                                               NULL,
86                                                               G_PARAM_READWRITE));
87
88         g_type_class_add_private (object_class, sizeof (GossipPresencePriv));
89 }
90
91 static void
92 gossip_presence_init (GossipPresence *presence)
93 {
94         GossipPresencePriv *priv;
95
96         priv = GET_PRIV (presence);
97
98         priv->state = GOSSIP_PRESENCE_STATE_AVAILABLE;
99         priv->status = NULL;
100         priv->timestamp = gossip_time_get_current ();
101 }
102
103 static void
104 presence_finalize (GObject *object)
105 {
106         GossipPresencePriv *priv;
107
108         priv = GET_PRIV (object);
109
110         g_free (priv->status);
111
112         (G_OBJECT_CLASS (gossip_presence_parent_class)->finalize) (object);
113 }
114
115 static void
116 presence_get_property (GObject    *object,
117                        guint       param_id,
118                        GValue     *value,
119                        GParamSpec *pspec)
120 {
121         GossipPresencePriv *priv;
122
123         priv = GET_PRIV (object);
124
125         switch (param_id) {
126         case PROP_STATE:
127                 g_value_set_int (value, priv->state);
128                 break;
129         case PROP_STATUS:
130                 g_value_set_string (value,
131                                     gossip_presence_get_status (GOSSIP_PRESENCE (object)));
132                 break;
133         default:
134                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
135                 break;
136         }
137 }
138 static void
139 presence_set_property (GObject      *object,
140                        guint         param_id,
141                        const GValue *value,
142                        GParamSpec   *pspec)
143 {
144         GossipPresencePriv *priv;
145
146         priv = GET_PRIV (object);
147
148         switch (param_id) {
149         case PROP_STATE:
150                 priv->state = g_value_get_int (value);
151                 break;
152         case PROP_STATUS:
153                 gossip_presence_set_status (GOSSIP_PRESENCE (object),
154                                             g_value_get_string (value));
155                 break;
156         default:
157                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
158                 break;
159         }
160 }
161
162 GossipPresence *
163 gossip_presence_new (void)
164 {
165         return g_object_new (GOSSIP_TYPE_PRESENCE, NULL);
166 }
167
168 GossipPresence *
169 gossip_presence_new_full (GossipPresenceState  state,
170                           const gchar         *status)
171 {
172         return g_object_new (GOSSIP_TYPE_PRESENCE,
173                              "state", state,
174                              "status", status,
175                              NULL);
176 }
177
178 const gchar *
179 gossip_presence_get_status (GossipPresence *presence)
180 {
181         GossipPresencePriv *priv;
182
183         g_return_val_if_fail (GOSSIP_IS_PRESENCE (presence),
184                               _("Offline"));
185
186         priv = GET_PRIV (presence);
187
188         return priv->status;
189 }
190
191 GossipPresenceState
192 gossip_presence_get_state (GossipPresence *presence)
193 {
194         GossipPresencePriv *priv;
195
196         g_return_val_if_fail (GOSSIP_IS_PRESENCE (presence),
197                               GOSSIP_PRESENCE_STATE_AVAILABLE);
198
199         priv = GET_PRIV (presence);
200
201         return priv->state;
202 }
203
204 void
205 gossip_presence_set_state (GossipPresence      *presence,
206                            GossipPresenceState  state)
207 {
208         GossipPresencePriv *priv;
209
210         g_return_if_fail (GOSSIP_IS_PRESENCE (presence));
211
212         priv = GET_PRIV (presence);
213
214         priv->state = state;
215
216         g_object_notify (G_OBJECT (presence), "state");
217 }
218
219 void
220 gossip_presence_set_status (GossipPresence *presence,
221                             const gchar    *status)
222 {
223         GossipPresencePriv *priv;
224
225         priv = GET_PRIV (presence);
226         g_return_if_fail (GOSSIP_IS_PRESENCE (presence));
227
228         g_free (priv->status);
229
230         if (status) {
231                 priv->status = g_strdup (status);
232         } else {
233                 priv->status = NULL;
234         }
235
236         g_object_notify (G_OBJECT (presence), "status");
237 }
238
239 gint
240 gossip_presence_sort_func (gconstpointer a,
241                            gconstpointer b)
242 {
243         GossipPresencePriv *priv_a;
244         GossipPresencePriv *priv_b;
245         gint                diff;
246
247         g_return_val_if_fail (GOSSIP_IS_PRESENCE (a), 0);
248         g_return_val_if_fail (GOSSIP_IS_PRESENCE (b), 0);
249          
250         priv_a = GET_PRIV (a);
251         priv_b = GET_PRIV (b);
252
253         /* 1. State */
254         diff = priv_a->state - priv_b->state;
255         if (diff != 0) {
256                 return diff < 1 ? -1 : +1;
257         }
258
259         /* 3. Time (newest first) */
260         diff = priv_b->timestamp - priv_a->timestamp;
261         if (diff != 0) {
262                 return diff < 1 ? -1 : +1;
263         }
264                 
265         /* No real difference */
266         return 0;
267 }
268
269 const gchar *
270 gossip_presence_state_get_default_status (GossipPresenceState state)
271 {
272         switch (state) {
273         case GOSSIP_PRESENCE_STATE_AVAILABLE:
274                 return _("Available");
275                 break;
276
277         case GOSSIP_PRESENCE_STATE_BUSY:
278                 return _("Busy");
279                 break;
280
281         case GOSSIP_PRESENCE_STATE_AWAY:
282         case GOSSIP_PRESENCE_STATE_EXT_AWAY:
283                 return _("Away");
284                 break;
285
286         case GOSSIP_PRESENCE_STATE_HIDDEN:
287         case GOSSIP_PRESENCE_STATE_UNAVAILABLE:
288                 return _("Unavailable");
289         }
290
291         return _("Available");
292 }