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;
43 static void empathy_message_finalize (GObject *object);
44 static void message_get_property (GObject *object,
48 static void message_set_property (GObject *object,
53 G_DEFINE_TYPE (EmpathyMessage, empathy_message, G_TYPE_OBJECT);
65 empathy_message_class_init (EmpathyMessageClass *class)
67 GObjectClass *object_class;
69 object_class = G_OBJECT_CLASS (class);
70 object_class->finalize = empathy_message_finalize;
71 object_class->get_property = message_get_property;
72 object_class->set_property = message_set_property;
74 g_object_class_install_property (object_class,
76 g_param_spec_uint ("type",
78 "The type of message",
79 TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
80 TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY,
81 TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
83 g_object_class_install_property (object_class,
85 g_param_spec_object ("sender",
87 "The sender of the message",
90 g_object_class_install_property (object_class,
92 g_param_spec_object ("receiver",
94 "The receiver of the message",
97 g_object_class_install_property (object_class,
99 g_param_spec_string ("body",
101 "The content of the message",
104 g_object_class_install_property (object_class,
106 g_param_spec_long ("timestamp",
115 g_type_class_add_private (object_class, sizeof (EmpathyMessagePriv));
120 empathy_message_init (EmpathyMessage *message)
122 EmpathyMessagePriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (message,
123 EMPATHY_TYPE_MESSAGE, EmpathyMessagePriv);
125 message->priv = priv;
126 priv->timestamp = empathy_time_get_current ();
130 empathy_message_finalize (GObject *object)
132 EmpathyMessagePriv *priv;
134 priv = GET_PRIV (object);
137 g_object_unref (priv->sender);
139 if (priv->receiver) {
140 g_object_unref (priv->receiver);
145 G_OBJECT_CLASS (empathy_message_parent_class)->finalize (object);
149 message_get_property (GObject *object,
154 EmpathyMessagePriv *priv;
156 priv = GET_PRIV (object);
160 g_value_set_uint (value, priv->type);
163 g_value_set_object (value, priv->sender);
166 g_value_set_object (value, priv->receiver);
169 g_value_set_string (value, priv->body);
172 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
178 message_set_property (GObject *object,
183 EmpathyMessagePriv *priv;
185 priv = GET_PRIV (object);
189 empathy_message_set_tptype (EMPATHY_MESSAGE (object),
190 g_value_get_uint (value));
193 empathy_message_set_sender (EMPATHY_MESSAGE (object),
194 EMPATHY_CONTACT (g_value_get_object (value)));
197 empathy_message_set_receiver (EMPATHY_MESSAGE (object),
198 EMPATHY_CONTACT (g_value_get_object (value)));
201 empathy_message_set_body (EMPATHY_MESSAGE (object),
202 g_value_get_string (value));
205 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
211 empathy_message_new (const gchar *body)
213 return g_object_new (EMPATHY_TYPE_MESSAGE,
218 TpChannelTextMessageType
219 empathy_message_get_tptype (EmpathyMessage *message)
221 EmpathyMessagePriv *priv;
223 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message),
224 TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL);
226 priv = GET_PRIV (message);
232 empathy_message_set_tptype (EmpathyMessage *message,
233 TpChannelTextMessageType type)
235 EmpathyMessagePriv *priv;
237 g_return_if_fail (EMPATHY_IS_MESSAGE (message));
239 priv = GET_PRIV (message);
243 g_object_notify (G_OBJECT (message), "type");
247 empathy_message_get_sender (EmpathyMessage *message)
249 EmpathyMessagePriv *priv;
251 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), NULL);
253 priv = GET_PRIV (message);
259 empathy_message_set_sender (EmpathyMessage *message, EmpathyContact *contact)
261 EmpathyMessagePriv *priv;
262 EmpathyContact *old_sender;
264 g_return_if_fail (EMPATHY_IS_MESSAGE (message));
265 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
267 priv = GET_PRIV (message);
269 old_sender = priv->sender;
270 priv->sender = g_object_ref (contact);
273 g_object_unref (old_sender);
276 g_object_notify (G_OBJECT (message), "sender");
280 empathy_message_get_receiver (EmpathyMessage *message)
282 EmpathyMessagePriv *priv;
284 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), NULL);
286 priv = GET_PRIV (message);
288 return priv->receiver;
292 empathy_message_set_receiver (EmpathyMessage *message, EmpathyContact *contact)
294 EmpathyMessagePriv *priv;
295 EmpathyContact *old_receiver;
297 g_return_if_fail (EMPATHY_IS_MESSAGE (message));
298 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
300 priv = GET_PRIV (message);
302 old_receiver = priv->receiver;
303 priv->receiver = g_object_ref (contact);
306 g_object_unref (old_receiver);
309 g_object_notify (G_OBJECT (message), "receiver");
313 empathy_message_get_body (EmpathyMessage *message)
315 EmpathyMessagePriv *priv;
317 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), NULL);
319 priv = GET_PRIV (message);
325 empathy_message_set_body (EmpathyMessage *message,
328 EmpathyMessagePriv *priv = GET_PRIV (message);
329 TpChannelTextMessageType type;
331 g_return_if_fail (EMPATHY_IS_MESSAGE (message));
336 type = TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
337 if (g_str_has_prefix (body, "/me")) {
338 type = TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION;
341 else if (g_str_has_prefix (body, "/say")) {
346 priv->body = g_strdup (body);
349 if (type != priv->type) {
350 empathy_message_set_tptype (message, type);
353 g_object_notify (G_OBJECT (message), "body");
357 empathy_message_get_timestamp (EmpathyMessage *message)
359 EmpathyMessagePriv *priv;
361 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), -1);
363 priv = GET_PRIV (message);
365 return priv->timestamp;
369 empathy_message_set_timestamp (EmpathyMessage *message,
372 EmpathyMessagePriv *priv;
374 g_return_if_fail (EMPATHY_IS_MESSAGE (message));
375 g_return_if_fail (timestamp >= -1);
377 priv = GET_PRIV (message);
379 if (timestamp <= 0) {
380 priv->timestamp = empathy_time_get_current ();
382 priv->timestamp = timestamp;
385 g_object_notify (G_OBJECT (message), "timestamp");
388 #define IS_SEPARATOR(ch) (ch == ' ' || ch == ',' || ch == '.' || ch == ':')
390 empathy_message_should_highlight (EmpathyMessage *message)
392 EmpathyContact *contact;
393 const gchar *msg, *to;
394 gchar *cf_msg, *cf_to;
398 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE);
402 msg = empathy_message_get_body (message);
407 contact = empathy_message_get_receiver (message);
408 if (!contact || !empathy_contact_is_user (contact)) {
412 to = empathy_contact_get_name (contact);
417 cf_msg = g_utf8_casefold (msg, -1);
418 cf_to = g_utf8_casefold (to, -1);
420 ch = strstr (cf_msg, cf_to);
425 /* Not first in the message */
426 if (!IS_SEPARATOR (*(ch - 1))) {
431 ch = ch + strlen (cf_to);
432 if (ch >= cf_msg + strlen (cf_msg)) {
437 if (IS_SEPARATOR (*ch)) {
449 TpChannelTextMessageType
450 empathy_message_type_from_str (const gchar *type_str)
452 if (strcmp (type_str, "normal") == 0) {
453 return TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
455 if (strcmp (type_str, "action") == 0) {
456 return TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION;
458 else if (strcmp (type_str, "notice") == 0) {
459 return TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE;
461 else if (strcmp (type_str, "auto-reply") == 0) {
462 return TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY;
465 return TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
469 empathy_message_type_to_str (TpChannelTextMessageType type)
472 case TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION:
474 case TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE:
476 case TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY:
484 empathy_message_get_id (EmpathyMessage *message)
486 EmpathyMessagePriv *priv = GET_PRIV (message);
488 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), 0);
494 empathy_message_set_id (EmpathyMessage *message, guint id)
496 EmpathyMessagePriv *priv = GET_PRIV (message);
502 empathy_message_get_unique_id (EmpathyMessage *message)
504 EmpathyMessagePriv *priv = GET_PRIV (message);
506 return g_strdup_printf ("%d.%d", priv->id, g_str_hash (priv->body));
510 empathy_message_equal (EmpathyMessage *message1, EmpathyMessage *message2)
512 EmpathyMessagePriv *priv1;
513 EmpathyMessagePriv *priv2;
515 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message1), FALSE);
516 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message2), FALSE);
518 priv1 = GET_PRIV (message1);
519 priv2 = GET_PRIV (message2);
521 if (priv1->id == priv2->id && g_str_hash (priv1->body) == g_str_hash (priv2->body)) {