[darcs-to-svn @ initial import]
[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  *
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 "gossip-message.h"
26
27 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_MESSAGE, GossipMessagePriv))
28
29 typedef struct _GossipMessagePriv GossipMessagePriv;
30
31 struct _GossipMessagePriv {
32         GossipMessageType     type;
33         GossipContact        *sender;
34         gchar                *body;
35         GossipTime            timestamp;
36
37 };
38
39 static void gossip_message_class_init (GossipMessageClass *class);
40 static void gossip_message_init       (GossipMessage      *message);
41 static void gossip_message_finalize   (GObject            *object);
42 static void message_get_property      (GObject            *object,
43                                        guint               param_id,
44                                        GValue             *value,
45                                        GParamSpec         *pspec);
46 static void message_set_property      (GObject            *object,
47                                        guint               param_id,
48                                        const GValue       *value,
49                                        GParamSpec         *pspec);
50
51 enum {
52         PROP_0,
53         PROP_TYPE,
54         PROP_SENDER,
55         PROP_BODY,
56         PROP_TIMESTAMP,
57 };
58
59 static gpointer parent_class = NULL;
60
61 GType
62 gossip_message_get_gtype (void)
63 {
64         static GType type = 0;
65
66         if (!type) {
67                 static const GTypeInfo info = {
68                         sizeof (GossipMessageClass),
69                         NULL, /* base_init */
70                         NULL, /* base_finalize */
71                         (GClassInitFunc) gossip_message_class_init,
72                         NULL, /* class_finalize */
73                         NULL, /* class_data */
74                         sizeof (GossipMessage),
75                         0,    /* n_preallocs */
76                         (GInstanceInitFunc) gossip_message_init
77                 };
78
79                 type = g_type_register_static (G_TYPE_OBJECT,
80                                                "GossipMessage",
81                                                &info, 0);
82         }
83
84         return type;
85 }
86
87 static void
88 gossip_message_class_init (GossipMessageClass *class)
89 {
90         GObjectClass *object_class;
91
92         object_class = G_OBJECT_CLASS (class);
93         parent_class = g_type_class_peek_parent (class);
94
95         object_class->finalize     = gossip_message_finalize;
96         object_class->get_property = message_get_property;
97         object_class->set_property = message_set_property;
98
99         g_object_class_install_property (object_class,
100                                          PROP_TYPE,
101                                          g_param_spec_int ("type",
102                                                            "Message Type",
103                                                            "The type of message",
104                                                            GOSSIP_MESSAGE_TYPE_NORMAL,
105                                                            GOSSIP_MESSAGE_TYPE_LAST,
106                                                            GOSSIP_MESSAGE_TYPE_NORMAL,
107                                                            G_PARAM_READWRITE));
108         g_object_class_install_property (object_class,
109                                          PROP_SENDER,
110                                          g_param_spec_object ("sender",
111                                                               "Message Sender",
112                                                               "The sender of the message",
113                                                               GOSSIP_TYPE_CONTACT,
114                                                               G_PARAM_READWRITE));
115
116         g_object_class_install_property (object_class,
117                                          PROP_BODY,
118                                          g_param_spec_string ("body",
119                                                               "Message Body",
120                                                               "The content of the message",
121                                                               NULL,
122                                                               G_PARAM_READWRITE));
123         g_object_class_install_property (object_class,
124                                          PROP_TIMESTAMP,
125                                          g_param_spec_long ("timestamp",
126                                                             "timestamp",
127                                                             "timestamp",
128                                                             -1,
129                                                             G_MAXLONG,
130                                                             -1,
131                                                             G_PARAM_READWRITE));
132
133
134         g_type_class_add_private (object_class, sizeof (GossipMessagePriv));
135
136 }
137
138 static void
139 gossip_message_init (GossipMessage *message)
140 {
141         GossipMessagePriv *priv;
142
143         priv = GET_PRIV (message);
144
145         priv->type = GOSSIP_MESSAGE_TYPE_NORMAL;
146         priv->sender = NULL;
147         priv->body = NULL;
148         priv->timestamp = gossip_time_get_current ();
149 }
150
151 static void
152 gossip_message_finalize (GObject *object)
153 {
154         GossipMessagePriv *priv;
155
156         priv = GET_PRIV (object);
157
158         if (priv->sender) {
159                 g_object_unref (priv->sender);
160         }
161
162         g_free (priv->body);
163
164         (G_OBJECT_CLASS (parent_class)->finalize) (object);
165 }
166
167 static void
168 message_get_property (GObject    *object,
169                       guint       param_id,
170                       GValue     *value,
171                       GParamSpec *pspec)
172 {
173         GossipMessagePriv *priv;
174
175         priv = GET_PRIV (object);
176
177         switch (param_id) {
178         case PROP_TYPE:
179                 g_value_set_int (value, priv->type);
180                 break;
181         case PROP_SENDER:
182                 g_value_set_object (value, priv->sender);
183                 break;
184         case PROP_BODY:
185                 g_value_set_string (value, priv->body);
186                 break;
187         default:
188                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
189                 break;
190         };
191 }
192
193 static void
194 message_set_property (GObject      *object,
195                       guint         param_id,
196                       const GValue *value,
197                       GParamSpec   *pspec)
198 {
199         GossipMessagePriv *priv;
200
201         priv = GET_PRIV (object);
202
203         switch (param_id) {
204         case PROP_TYPE:
205                 gossip_message_set_type (GOSSIP_MESSAGE (object),
206                                          g_value_get_int (value));
207                 break;
208         case PROP_SENDER:
209                 gossip_message_set_sender (GOSSIP_MESSAGE (object),
210                                            GOSSIP_CONTACT (g_value_get_object (value)));
211                 break;
212         case PROP_BODY:
213                 gossip_message_set_body (GOSSIP_MESSAGE (object),
214                                          g_value_get_string (value));
215                 break;
216         default:
217                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
218                 break;
219         };
220 }
221
222 GossipMessage *
223 gossip_message_new (const gchar *body)
224 {
225         return g_object_new (GOSSIP_TYPE_MESSAGE,
226                              "body", body,
227                              NULL);
228 }
229
230 GossipMessageType
231 gossip_message_get_type (GossipMessage *message)
232 {
233         GossipMessagePriv *priv;
234
235         g_return_val_if_fail (GOSSIP_IS_MESSAGE (message),
236                               GOSSIP_MESSAGE_TYPE_NORMAL);
237
238         priv = GET_PRIV (message);
239
240         return priv->type;
241 }
242
243 void
244 gossip_message_set_type (GossipMessage     *message,
245                          GossipMessageType  type)
246 {
247         GossipMessagePriv *priv;
248
249         g_return_if_fail (GOSSIP_IS_MESSAGE (message));
250
251         priv = GET_PRIV (message);
252
253         priv->type = type;
254
255         g_object_notify (G_OBJECT (message), "type");
256 }
257
258 GossipContact *
259 gossip_message_get_sender (GossipMessage *message)
260 {
261         GossipMessagePriv *priv;
262
263         g_return_val_if_fail (GOSSIP_IS_MESSAGE (message), NULL);
264
265         priv = GET_PRIV (message);
266
267         return priv->sender;
268 }
269
270 void
271 gossip_message_set_sender (GossipMessage *message, GossipContact *contact)
272 {
273         GossipMessagePriv *priv;
274         GossipContact     *old_sender;
275
276         g_return_if_fail (GOSSIP_IS_MESSAGE (message));
277         g_return_if_fail (GOSSIP_IS_CONTACT (contact));
278
279         priv = GET_PRIV (message);
280
281         old_sender = priv->sender;
282         priv->sender = g_object_ref (contact);
283
284         if (old_sender) {
285                 g_object_unref (old_sender);
286         }
287
288         g_object_notify (G_OBJECT (message), "sender");
289 }
290
291 const gchar *
292 gossip_message_get_body (GossipMessage *message)
293 {
294         GossipMessagePriv *priv;
295
296         g_return_val_if_fail (GOSSIP_IS_MESSAGE (message), NULL);
297
298         priv = GET_PRIV (message);
299
300         return priv->body;
301 }
302
303 void
304 gossip_message_set_body (GossipMessage *message,
305                          const gchar   *body)
306 {
307         GossipMessagePriv *priv;
308         GossipMessageType  type;
309
310         g_return_if_fail (GOSSIP_IS_MESSAGE (message));
311
312         priv = GET_PRIV (message);
313
314         g_free (priv->body);
315         priv->body = NULL;
316
317         type = GOSSIP_MESSAGE_TYPE_NORMAL;
318         if (g_str_has_prefix (body, "/me")) {
319                 type = GOSSIP_MESSAGE_TYPE_ACTION;
320                 body += 4;
321         }
322
323         if (body) {
324                 priv->body = g_strdup (body);
325         }
326
327         if (type != priv->type) {
328                 gossip_message_set_type (message, type);
329         }
330
331         g_object_notify (G_OBJECT (message), "body");
332 }
333
334 GossipTime
335 gossip_message_get_timestamp (GossipMessage *message)
336 {
337         GossipMessagePriv *priv;
338
339         g_return_val_if_fail (GOSSIP_IS_MESSAGE (message), -1);
340
341         priv = GET_PRIV (message);
342
343         return priv->timestamp;
344 }
345
346 void
347 gossip_message_set_timestamp (GossipMessage *message,
348                               GossipTime     timestamp)
349 {
350         GossipMessagePriv *priv;
351
352         g_return_if_fail (GOSSIP_IS_MESSAGE (message));
353         g_return_if_fail (timestamp >= -1);
354
355         priv = GET_PRIV (message);
356
357         if (timestamp <= 0) {
358                 priv->timestamp = gossip_time_get_current ();
359         } else {
360                 priv->timestamp = timestamp;
361         }
362
363         g_object_notify (G_OBJECT (message), "timestamp");
364 }
365