1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2004-2007 Imendio AB
4 * Copyright (C) 2007-2008 Collabora Ltd.
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.
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.
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.
21 * Authors: Mikael Hallendal <micke@imendio.com>
22 * Xavier Claessens <xclaesse@gmail.com>
29 #include "empathy-message.h"
30 #include "empathy-utils.h"
31 #include "empathy-enum-types.h"
33 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyMessage)
35 TpChannelTextMessageType type;
36 EmpathyContact *sender;
37 EmpathyContact *receiver;
42 static void empathy_message_finalize (GObject *object);
43 static void message_get_property (GObject *object,
47 static void message_set_property (GObject *object,
52 G_DEFINE_TYPE (EmpathyMessage, empathy_message, G_TYPE_OBJECT);
64 empathy_message_class_init (EmpathyMessageClass *class)
66 GObjectClass *object_class;
68 object_class = G_OBJECT_CLASS (class);
69 object_class->finalize = empathy_message_finalize;
70 object_class->get_property = message_get_property;
71 object_class->set_property = message_set_property;
73 g_object_class_install_property (object_class,
75 g_param_spec_uint ("type",
77 "The type of message",
78 TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
79 TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY,
80 TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
82 g_object_class_install_property (object_class,
84 g_param_spec_object ("sender",
86 "The sender of the message",
89 g_object_class_install_property (object_class,
91 g_param_spec_object ("receiver",
93 "The receiver of the message",
96 g_object_class_install_property (object_class,
98 g_param_spec_string ("body",
100 "The content of the message",
103 g_object_class_install_property (object_class,
105 g_param_spec_long ("timestamp",
114 g_type_class_add_private (object_class, sizeof (EmpathyMessagePriv));
119 empathy_message_init (EmpathyMessage *message)
121 EmpathyMessagePriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (message,
122 EMPATHY_TYPE_MESSAGE, EmpathyMessagePriv);
124 message->priv = priv;
125 priv->timestamp = empathy_time_get_current ();
129 empathy_message_finalize (GObject *object)
131 EmpathyMessagePriv *priv;
133 priv = GET_PRIV (object);
136 g_object_unref (priv->sender);
138 if (priv->receiver) {
139 g_object_unref (priv->receiver);
144 G_OBJECT_CLASS (empathy_message_parent_class)->finalize (object);
148 message_get_property (GObject *object,
153 EmpathyMessagePriv *priv;
155 priv = GET_PRIV (object);
159 g_value_set_uint (value, priv->type);
162 g_value_set_object (value, priv->sender);
165 g_value_set_object (value, priv->receiver);
168 g_value_set_string (value, priv->body);
171 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
177 message_set_property (GObject *object,
182 EmpathyMessagePriv *priv;
184 priv = GET_PRIV (object);
188 empathy_message_set_tptype (EMPATHY_MESSAGE (object),
189 g_value_get_uint (value));
192 empathy_message_set_sender (EMPATHY_MESSAGE (object),
193 EMPATHY_CONTACT (g_value_get_object (value)));
196 empathy_message_set_receiver (EMPATHY_MESSAGE (object),
197 EMPATHY_CONTACT (g_value_get_object (value)));
200 empathy_message_set_body (EMPATHY_MESSAGE (object),
201 g_value_get_string (value));
204 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
210 empathy_message_new (const gchar *body)
212 return g_object_new (EMPATHY_TYPE_MESSAGE,
217 TpChannelTextMessageType
218 empathy_message_get_tptype (EmpathyMessage *message)
220 EmpathyMessagePriv *priv;
222 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message),
223 TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL);
225 priv = GET_PRIV (message);
231 empathy_message_set_tptype (EmpathyMessage *message,
232 TpChannelTextMessageType type)
234 EmpathyMessagePriv *priv;
236 g_return_if_fail (EMPATHY_IS_MESSAGE (message));
238 priv = GET_PRIV (message);
242 g_object_notify (G_OBJECT (message), "type");
246 empathy_message_get_sender (EmpathyMessage *message)
248 EmpathyMessagePriv *priv;
250 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), NULL);
252 priv = GET_PRIV (message);
258 empathy_message_set_sender (EmpathyMessage *message, EmpathyContact *contact)
260 EmpathyMessagePriv *priv;
261 EmpathyContact *old_sender;
263 g_return_if_fail (EMPATHY_IS_MESSAGE (message));
264 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
266 priv = GET_PRIV (message);
268 old_sender = priv->sender;
269 priv->sender = g_object_ref (contact);
272 g_object_unref (old_sender);
275 g_object_notify (G_OBJECT (message), "sender");
279 empathy_message_get_receiver (EmpathyMessage *message)
281 EmpathyMessagePriv *priv;
283 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), NULL);
285 priv = GET_PRIV (message);
287 return priv->receiver;
291 empathy_message_set_receiver (EmpathyMessage *message, EmpathyContact *contact)
293 EmpathyMessagePriv *priv;
294 EmpathyContact *old_receiver;
296 g_return_if_fail (EMPATHY_IS_MESSAGE (message));
297 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
299 priv = GET_PRIV (message);
301 old_receiver = priv->receiver;
302 priv->receiver = g_object_ref (contact);
305 g_object_unref (old_receiver);
308 g_object_notify (G_OBJECT (message), "receiver");
312 empathy_message_get_body (EmpathyMessage *message)
314 EmpathyMessagePriv *priv;
316 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), NULL);
318 priv = GET_PRIV (message);
324 empathy_message_set_body (EmpathyMessage *message,
327 EmpathyMessagePriv *priv = GET_PRIV (message);
328 TpChannelTextMessageType type;
330 g_return_if_fail (EMPATHY_IS_MESSAGE (message));
335 type = TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
336 if (g_str_has_prefix (body, "/me")) {
337 type = TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION;
340 else if (g_str_has_prefix (body, "/say")) {
345 priv->body = g_strdup (body);
348 if (type != priv->type) {
349 empathy_message_set_tptype (message, type);
352 g_object_notify (G_OBJECT (message), "body");
356 empathy_message_get_timestamp (EmpathyMessage *message)
358 EmpathyMessagePriv *priv;
360 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), -1);
362 priv = GET_PRIV (message);
364 return priv->timestamp;
368 empathy_message_set_timestamp (EmpathyMessage *message,
371 EmpathyMessagePriv *priv;
373 g_return_if_fail (EMPATHY_IS_MESSAGE (message));
374 g_return_if_fail (timestamp >= -1);
376 priv = GET_PRIV (message);
378 if (timestamp <= 0) {
379 priv->timestamp = empathy_time_get_current ();
381 priv->timestamp = timestamp;
384 g_object_notify (G_OBJECT (message), "timestamp");
388 empathy_message_get_date_and_time (EmpathyMessage *message, time_t *timestamp)
394 *timestamp = empathy_message_get_timestamp (message);
397 if (timestamp <= 0) {
398 *timestamp = empathy_time_get_current ();
401 date = g_date_new ();
402 g_date_set_time_t (date, *timestamp);
407 #define IS_SEPARATOR(ch) (ch == ' ' || ch == ',' || ch == '.' || ch == ':')
409 empathy_message_should_highlight (EmpathyMessage *message)
411 EmpathyContact *contact;
412 const gchar *msg, *to;
413 gchar *cf_msg, *cf_to;
417 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE);
421 msg = empathy_message_get_body (message);
426 contact = empathy_message_get_receiver (message);
427 if (!contact || !empathy_contact_is_user (contact)) {
431 to = empathy_contact_get_name (contact);
436 cf_msg = g_utf8_casefold (msg, -1);
437 cf_to = g_utf8_casefold (to, -1);
439 ch = strstr (cf_msg, cf_to);
444 /* Not first in the message */
445 if (!IS_SEPARATOR (*(ch - 1))) {
450 ch = ch + strlen (cf_to);
451 if (ch >= cf_msg + strlen (cf_msg)) {
456 if (IS_SEPARATOR (*ch)) {
468 TpChannelTextMessageType
469 empathy_message_type_from_str (const gchar *type_str)
471 if (strcmp (type_str, "normal") == 0) {
472 return TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
474 if (strcmp (type_str, "action") == 0) {
475 return TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION;
477 else if (strcmp (type_str, "notice") == 0) {
478 return TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE;
480 else if (strcmp (type_str, "auto-reply") == 0) {
481 return TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY;
484 return TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
488 empathy_message_type_to_str (TpChannelTextMessageType type)
491 case TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION:
493 case TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE:
495 case TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY: