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 <telepathy-glib/util.h>
31 #include "empathy-message.h"
32 #include "empathy-utils.h"
33 #include "empathy-enum-types.h"
35 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyMessage)
37 TpChannelTextMessageType type
;
38 EmpathyContact
*sender
;
39 EmpathyContact
*receiver
;
45 static void empathy_message_finalize (GObject
*object
);
46 static void message_get_property (GObject
*object
,
50 static void message_set_property (GObject
*object
,
55 G_DEFINE_TYPE (EmpathyMessage
, empathy_message
, G_TYPE_OBJECT
);
67 empathy_message_class_init (EmpathyMessageClass
*class)
69 GObjectClass
*object_class
;
71 object_class
= G_OBJECT_CLASS (class);
72 object_class
->finalize
= empathy_message_finalize
;
73 object_class
->get_property
= message_get_property
;
74 object_class
->set_property
= message_set_property
;
76 g_object_class_install_property (object_class
,
78 g_param_spec_uint ("type",
80 "The type of message",
81 TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL
,
82 TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY
,
83 TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL
,
85 g_object_class_install_property (object_class
,
87 g_param_spec_object ("sender",
89 "The sender of the message",
92 g_object_class_install_property (object_class
,
94 g_param_spec_object ("receiver",
96 "The receiver of the message",
99 g_object_class_install_property (object_class
,
101 g_param_spec_string ("body",
103 "The content of the message",
106 g_object_class_install_property (object_class
,
108 g_param_spec_long ("timestamp",
117 g_type_class_add_private (object_class
, sizeof (EmpathyMessagePriv
));
122 empathy_message_init (EmpathyMessage
*message
)
124 EmpathyMessagePriv
*priv
= G_TYPE_INSTANCE_GET_PRIVATE (message
,
125 EMPATHY_TYPE_MESSAGE
, EmpathyMessagePriv
);
127 message
->priv
= priv
;
128 priv
->timestamp
= empathy_time_get_current ();
132 empathy_message_finalize (GObject
*object
)
134 EmpathyMessagePriv
*priv
;
136 priv
= GET_PRIV (object
);
139 g_object_unref (priv
->sender
);
141 if (priv
->receiver
) {
142 g_object_unref (priv
->receiver
);
147 G_OBJECT_CLASS (empathy_message_parent_class
)->finalize (object
);
151 message_get_property (GObject
*object
,
156 EmpathyMessagePriv
*priv
;
158 priv
= GET_PRIV (object
);
162 g_value_set_uint (value
, priv
->type
);
165 g_value_set_object (value
, priv
->sender
);
168 g_value_set_object (value
, priv
->receiver
);
171 g_value_set_string (value
, priv
->body
);
174 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
180 message_set_property (GObject
*object
,
185 EmpathyMessagePriv
*priv
;
187 priv
= GET_PRIV (object
);
191 empathy_message_set_tptype (EMPATHY_MESSAGE (object
),
192 g_value_get_uint (value
));
195 empathy_message_set_sender (EMPATHY_MESSAGE (object
),
196 EMPATHY_CONTACT (g_value_get_object (value
)));
199 empathy_message_set_receiver (EMPATHY_MESSAGE (object
),
200 EMPATHY_CONTACT (g_value_get_object (value
)));
203 empathy_message_set_body (EMPATHY_MESSAGE (object
),
204 g_value_get_string (value
));
207 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
213 empathy_message_new (const gchar
*body
)
215 return g_object_new (EMPATHY_TYPE_MESSAGE
,
220 TpChannelTextMessageType
221 empathy_message_get_tptype (EmpathyMessage
*message
)
223 EmpathyMessagePriv
*priv
;
225 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message
),
226 TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL
);
228 priv
= GET_PRIV (message
);
234 empathy_message_set_tptype (EmpathyMessage
*message
,
235 TpChannelTextMessageType type
)
237 EmpathyMessagePriv
*priv
;
239 g_return_if_fail (EMPATHY_IS_MESSAGE (message
));
241 priv
= GET_PRIV (message
);
245 g_object_notify (G_OBJECT (message
), "type");
249 empathy_message_get_sender (EmpathyMessage
*message
)
251 EmpathyMessagePriv
*priv
;
253 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message
), NULL
);
255 priv
= GET_PRIV (message
);
261 empathy_message_set_sender (EmpathyMessage
*message
, EmpathyContact
*contact
)
263 EmpathyMessagePriv
*priv
;
264 EmpathyContact
*old_sender
;
266 g_return_if_fail (EMPATHY_IS_MESSAGE (message
));
267 g_return_if_fail (EMPATHY_IS_CONTACT (contact
));
269 priv
= GET_PRIV (message
);
271 old_sender
= priv
->sender
;
272 priv
->sender
= g_object_ref (contact
);
275 g_object_unref (old_sender
);
278 g_object_notify (G_OBJECT (message
), "sender");
282 empathy_message_get_receiver (EmpathyMessage
*message
)
284 EmpathyMessagePriv
*priv
;
286 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message
), NULL
);
288 priv
= GET_PRIV (message
);
290 return priv
->receiver
;
294 empathy_message_set_receiver (EmpathyMessage
*message
, EmpathyContact
*contact
)
296 EmpathyMessagePriv
*priv
;
297 EmpathyContact
*old_receiver
;
299 g_return_if_fail (EMPATHY_IS_MESSAGE (message
));
300 g_return_if_fail (EMPATHY_IS_CONTACT (contact
));
302 priv
= GET_PRIV (message
);
304 old_receiver
= priv
->receiver
;
305 priv
->receiver
= g_object_ref (contact
);
308 g_object_unref (old_receiver
);
311 g_object_notify (G_OBJECT (message
), "receiver");
315 empathy_message_get_body (EmpathyMessage
*message
)
317 EmpathyMessagePriv
*priv
;
319 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message
), NULL
);
321 priv
= GET_PRIV (message
);
327 empathy_message_set_body (EmpathyMessage
*message
,
330 EmpathyMessagePriv
*priv
= GET_PRIV (message
);
331 TpChannelTextMessageType type
;
333 g_return_if_fail (EMPATHY_IS_MESSAGE (message
));
338 type
= TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL
;
339 if (g_str_has_prefix (body
, "/me")) {
340 type
= TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION
;
343 else if (g_str_has_prefix (body
, "/say")) {
348 priv
->body
= g_strdup (body
);
351 if (type
!= priv
->type
) {
352 empathy_message_set_tptype (message
, type
);
355 g_object_notify (G_OBJECT (message
), "body");
359 empathy_message_get_timestamp (EmpathyMessage
*message
)
361 EmpathyMessagePriv
*priv
;
363 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message
), -1);
365 priv
= GET_PRIV (message
);
367 return priv
->timestamp
;
371 empathy_message_set_timestamp (EmpathyMessage
*message
,
374 EmpathyMessagePriv
*priv
;
376 g_return_if_fail (EMPATHY_IS_MESSAGE (message
));
377 g_return_if_fail (timestamp
>= -1);
379 priv
= GET_PRIV (message
);
381 if (timestamp
<= 0) {
382 priv
->timestamp
= empathy_time_get_current ();
384 priv
->timestamp
= timestamp
;
387 g_object_notify (G_OBJECT (message
), "timestamp");
390 #define IS_SEPARATOR(ch) (ch == ' ' || ch == ',' || ch == '.' || ch == ':')
392 empathy_message_should_highlight (EmpathyMessage
*message
)
394 EmpathyContact
*contact
;
395 const gchar
*msg
, *to
;
396 gchar
*cf_msg
, *cf_to
;
400 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message
), FALSE
);
404 msg
= empathy_message_get_body (message
);
409 contact
= empathy_message_get_receiver (message
);
410 if (!contact
|| !empathy_contact_is_user (contact
)) {
414 to
= empathy_contact_get_name (contact
);
419 cf_msg
= g_utf8_casefold (msg
, -1);
420 cf_to
= g_utf8_casefold (to
, -1);
422 ch
= strstr (cf_msg
, cf_to
);
427 /* Not first in the message */
428 if (!IS_SEPARATOR (*(ch
- 1))) {
433 ch
= ch
+ strlen (cf_to
);
434 if (ch
>= cf_msg
+ strlen (cf_msg
)) {
439 if (IS_SEPARATOR (*ch
)) {
451 TpChannelTextMessageType
452 empathy_message_type_from_str (const gchar
*type_str
)
454 if (strcmp (type_str
, "normal") == 0) {
455 return TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL
;
457 if (strcmp (type_str
, "action") == 0) {
458 return TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION
;
460 else if (strcmp (type_str
, "notice") == 0) {
461 return TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE
;
463 else if (strcmp (type_str
, "auto-reply") == 0) {
464 return TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY
;
467 return TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL
;
471 empathy_message_type_to_str (TpChannelTextMessageType type
)
474 case TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION
:
476 case TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE
:
478 case TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY
:
486 empathy_message_get_id (EmpathyMessage
*message
)
488 EmpathyMessagePriv
*priv
= GET_PRIV (message
);
490 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message
), 0);
496 empathy_message_set_id (EmpathyMessage
*message
, guint id
)
498 EmpathyMessagePriv
*priv
= GET_PRIV (message
);
504 empathy_message_equal (EmpathyMessage
*message1
, EmpathyMessage
*message2
)
506 EmpathyMessagePriv
*priv1
;
507 EmpathyMessagePriv
*priv2
;
509 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message1
), FALSE
);
510 g_return_val_if_fail (EMPATHY_IS_MESSAGE (message2
), FALSE
);
512 priv1
= GET_PRIV (message1
);
513 priv2
= GET_PRIV (message2
);
515 if (priv1
->id
== priv2
->id
&& !tp_strdiff (priv1
->body
, priv2
->body
)) {