[darcs-to-svn @ Set Collabora copyright for files I created/modified]
[empathy.git] / libempathy / gossip-message.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2004-2007 Imendio AB
4  * Copyright (C) 2007 Collabora Ltd.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  * Authors: Mikael Hallendal <micke@imendio.com>
22  *          Xavier Claessens <xclaesse@gmail.com>
23  */
24
25 #include "config.h"
26
27 #include "gossip-message.h"
28
29 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_MESSAGE, GossipMessagePriv))
30
31 typedef struct _GossipMessagePriv GossipMessagePriv;
32
33 struct _GossipMessagePriv {
34         GossipMessageType     type;
35         GossipContact        *sender;
36         gchar                *body;
37         GossipTime            timestamp;
38
39 };
40
41 static void gossip_message_class_init (GossipMessageClass *class);
42 static void gossip_message_init       (GossipMessage      *message);
43 static void gossip_message_finalize   (GObject            *object);
44 static void message_get_property      (GObject            *object,
45                                        guint               param_id,
46                                        GValue             *value,
47                                        GParamSpec         *pspec);
48 static void message_set_property      (GObject            *object,
49                                        guint               param_id,
50                                        const GValue       *value,
51                                        GParamSpec         *pspec);
52
53 enum {
54         PROP_0,
55         PROP_TYPE,
56         PROP_SENDER,
57         PROP_BODY,
58         PROP_TIMESTAMP,
59 };
60
61 static gpointer parent_class = NULL;
62
63 GType
64 gossip_message_get_gtype (void)
65 {
66         static GType type = 0;
67
68         if (!type) {
69                 static const GTypeInfo info = {
70                         sizeof (GossipMessageClass),
71                         NULL, /* base_init */
72                         NULL, /* base_finalize */
73                         (GClassInitFunc) gossip_message_class_init,
74                         NULL, /* class_finalize */
75                         NULL, /* class_data */
76                         sizeof (GossipMessage),
77                         0,    /* n_preallocs */
78                         (GInstanceInitFunc) gossip_message_init
79                 };
80
81                 type = g_type_register_static (G_TYPE_OBJECT,
82                                                "GossipMessage",
83                                                &info, 0);
84         }
85
86         return type;
87 }
88
89 static void
90 gossip_message_class_init (GossipMessageClass *class)
91 {
92         GObjectClass *object_class;
93
94         object_class = G_OBJECT_CLASS (class);
95         parent_class = g_type_class_peek_parent (class);
96
97         object_class->finalize     = gossip_message_finalize;
98         object_class->get_property = message_get_property;
99         object_class->set_property = message_set_property;
100
101         g_object_class_install_property (object_class,
102                                          PROP_TYPE,
103                                          g_param_spec_int ("type",
104                                                            "Message Type",
105                                                            "The type of message",
106                                                            GOSSIP_MESSAGE_TYPE_NORMAL,
107                                                            GOSSIP_MESSAGE_TYPE_LAST,
108                                                            GOSSIP_MESSAGE_TYPE_NORMAL,
109                                                            G_PARAM_READWRITE));
110         g_object_class_install_property (object_class,
111                                          PROP_SENDER,
112                                          g_param_spec_object ("sender",
113                                                               "Message Sender",
114                                                               "The sender of the message",
115                                                               GOSSIP_TYPE_CONTACT,
116                                                               G_PARAM_READWRITE));
117
118         g_object_class_install_property (object_class,
119                                          PROP_BODY,
120                                          g_param_spec_string ("body",
121                                                               "Message Body",
122                                                               "The content of the message",
123                                                               NULL,
124                                                               G_PARAM_READWRITE));
125         g_object_class_install_property (object_class,
126                                          PROP_TIMESTAMP,
127                                          g_param_spec_long ("timestamp",
128                                                             "timestamp",
129                                                             "timestamp",
130                                                             -1,
131                                                             G_MAXLONG,
132                                                             -1,
133                                                             G_PARAM_READWRITE));
134
135
136         g_type_class_add_private (object_class, sizeof (GossipMessagePriv));
137
138 }
139
140 static void
141 gossip_message_init (GossipMessage *message)
142 {
143         GossipMessagePriv *priv;
144
145         priv = GET_PRIV (message);
146
147         priv->type = GOSSIP_MESSAGE_TYPE_NORMAL;
148         priv->sender = NULL;
149         priv->body = NULL;
150         priv->timestamp = gossip_time_get_current ();
151 }
152
153 static void
154 gossip_message_finalize (GObject *object)
155 {
156         GossipMessagePriv *priv;
157
158         priv = GET_PRIV (object);
159
160         if (priv->sender) {
161                 g_object_unref (priv->sender);
162         }
163
164         g_free (priv->body);
165
166         (G_OBJECT_CLASS (parent_class)->finalize) (object);
167 }
168
169 static void
170 message_get_property (GObject    *object,
171                       guint       param_id,
172                       GValue     *value,
173                       GParamSpec *pspec)
174 {
175         GossipMessagePriv *priv;
176
177         priv = GET_PRIV (object);
178
179         switch (param_id) {
180         case PROP_TYPE:
181                 g_value_set_int (value, priv->type);
182                 break;
183         case PROP_SENDER:
184                 g_value_set_object (value, priv->sender);
185                 break;
186         case PROP_BODY:
187                 g_value_set_string (value, priv->body);
188                 break;
189         default:
190                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
191                 break;
192         };
193 }
194
195 static void
196 message_set_property (GObject      *object,
197                       guint         param_id,
198                       const GValue *value,
199                       GParamSpec   *pspec)
200 {
201         GossipMessagePriv *priv;
202
203         priv = GET_PRIV (object);
204
205         switch (param_id) {
206         case PROP_TYPE:
207                 gossip_message_set_type (GOSSIP_MESSAGE (object),
208                                          g_value_get_int (value));
209                 break;
210         case PROP_SENDER:
211                 gossip_message_set_sender (GOSSIP_MESSAGE (object),
212                                            GOSSIP_CONTACT (g_value_get_object (value)));
213                 break;
214         case PROP_BODY:
215                 gossip_message_set_body (GOSSIP_MESSAGE (object),
216                                          g_value_get_string (value));
217                 break;
218         default:
219                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
220                 break;
221         };
222 }
223
224 GossipMessage *
225 gossip_message_new (const gchar *body)
226 {
227         return g_object_new (GOSSIP_TYPE_MESSAGE,
228                              "body", body,
229                              NULL);
230 }
231
232 GossipMessageType
233 gossip_message_get_type (GossipMessage *message)
234 {
235         GossipMessagePriv *priv;
236
237         g_return_val_if_fail (GOSSIP_IS_MESSAGE (message),
238                               GOSSIP_MESSAGE_TYPE_NORMAL);
239
240         priv = GET_PRIV (message);
241
242         return priv->type;
243 }
244
245 void
246 gossip_message_set_type (GossipMessage     *message,
247                          GossipMessageType  type)
248 {
249         GossipMessagePriv *priv;
250
251         g_return_if_fail (GOSSIP_IS_MESSAGE (message));
252
253         priv = GET_PRIV (message);
254
255         priv->type = type;
256
257         g_object_notify (G_OBJECT (message), "type");
258 }
259
260 GossipContact *
261 gossip_message_get_sender (GossipMessage *message)
262 {
263         GossipMessagePriv *priv;
264
265         g_return_val_if_fail (GOSSIP_IS_MESSAGE (message), NULL);
266
267         priv = GET_PRIV (message);
268
269         return priv->sender;
270 }
271
272 void
273 gossip_message_set_sender (GossipMessage *message, GossipContact *contact)
274 {
275         GossipMessagePriv *priv;
276         GossipContact     *old_sender;
277
278         g_return_if_fail (GOSSIP_IS_MESSAGE (message));
279         g_return_if_fail (GOSSIP_IS_CONTACT (contact));
280
281         priv = GET_PRIV (message);
282
283         old_sender = priv->sender;
284         priv->sender = g_object_ref (contact);
285
286         if (old_sender) {
287                 g_object_unref (old_sender);
288         }
289
290         g_object_notify (G_OBJECT (message), "sender");
291 }
292
293 const gchar *
294 gossip_message_get_body (GossipMessage *message)
295 {
296         GossipMessagePriv *priv;
297
298         g_return_val_if_fail (GOSSIP_IS_MESSAGE (message), NULL);
299
300         priv = GET_PRIV (message);
301
302         return priv->body;
303 }
304
305 void
306 gossip_message_set_body (GossipMessage *message,
307                          const gchar   *body)
308 {
309         GossipMessagePriv *priv;
310         GossipMessageType  type;
311
312         g_return_if_fail (GOSSIP_IS_MESSAGE (message));
313
314         priv = GET_PRIV (message);
315
316         g_free (priv->body);
317         priv->body = NULL;
318
319         type = GOSSIP_MESSAGE_TYPE_NORMAL;
320         if (g_str_has_prefix (body, "/me")) {
321                 type = GOSSIP_MESSAGE_TYPE_ACTION;
322                 body += 4;
323         }
324
325         if (body) {
326                 priv->body = g_strdup (body);
327         }
328
329         if (type != priv->type) {
330                 gossip_message_set_type (message, type);
331         }
332
333         g_object_notify (G_OBJECT (message), "body");
334 }
335
336 GossipTime
337 gossip_message_get_timestamp (GossipMessage *message)
338 {
339         GossipMessagePriv *priv;
340
341         g_return_val_if_fail (GOSSIP_IS_MESSAGE (message), -1);
342
343         priv = GET_PRIV (message);
344
345         return priv->timestamp;
346 }
347
348 void
349 gossip_message_set_timestamp (GossipMessage *message,
350                               GossipTime     timestamp)
351 {
352         GossipMessagePriv *priv;
353
354         g_return_if_fail (GOSSIP_IS_MESSAGE (message));
355         g_return_if_fail (timestamp >= -1);
356
357         priv = GET_PRIV (message);
358
359         if (timestamp <= 0) {
360                 priv->timestamp = gossip_time_get_current ();
361         } else {
362                 priv->timestamp = timestamp;
363         }
364
365         g_object_notify (G_OBJECT (message), "timestamp");
366 }
367