]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-message.c
Merge branch 'sasl'
[empathy.git] / libempathy / empathy-message.c
index b45b41a8338f15f11a9da81af986085c40d80bb2..ca3b020ac9f793d1d8a73231f3e38a2c3c66b83f 100644 (file)
@@ -15,8 +15,8 @@
  *
  * You should have received a copy of the GNU General Public
  * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301  USA
  *
  * Authors: Mikael Hallendal <micke@imendio.com>
  *          Xavier Claessens <xclaesse@gmail.com>
 
 #include <string.h>
 
+#include <telepathy-glib/util.h>
+#include <telepathy-glib/account.h>
+#include <telepathy-glib/account-manager.h>
+
+#include <telepathy-logger/entity.h>
+#include <telepathy-logger/entry.h>
+#include <telepathy-logger/entry-text.h>
+
 #include "empathy-message.h"
 #include "empathy-utils.h"
 #include "empathy-enum-types.h"
@@ -37,6 +45,10 @@ typedef struct {
        EmpathyContact           *receiver;
        gchar                    *body;
        time_t                    timestamp;
+       gboolean                  is_backlog;
+       guint                     id;
+       gboolean                  incoming;
+       TpChannelTextMessageFlags flags;
 } EmpathyMessagePriv;
 
 static void empathy_message_finalize   (GObject            *object);
@@ -58,6 +70,9 @@ enum {
        PROP_RECEIVER,
        PROP_BODY,
        PROP_TIMESTAMP,
+       PROP_IS_BACKLOG,
+       PROP_INCOMING,
+       PROP_FLAGS,
 };
 
 static void
@@ -109,7 +124,30 @@ empathy_message_class_init (EmpathyMessageClass *class)
                                                            G_MAXLONG,
                                                            -1,
                                                            G_PARAM_READWRITE));
+       g_object_class_install_property (object_class,
+                                        PROP_IS_BACKLOG,
+                                        g_param_spec_boolean ("is-backlog",
+                                                              "History message",
+                                                              "If the message belongs to history",
+                                                              FALSE,
+                                                              G_PARAM_READWRITE));
+
 
+       g_object_class_install_property (object_class,
+                                        PROP_INCOMING,
+                                        g_param_spec_boolean ("incoming",
+                                                              "Incoming",
+                                                              "If this is an incoming (as opposed to sent) message",
+                                                              FALSE,
+                                                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+       g_object_class_install_property (object_class,
+                                        PROP_FLAGS,
+                                        g_param_spec_uint ("flags",
+                                                              "Flags",
+                                                              "The TpChannelTextMessageFlags of this message",
+                                                              0, G_MAXUINT, 0,
+                                                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
        g_type_class_add_private (object_class, sizeof (EmpathyMessagePriv));
 
@@ -167,6 +205,9 @@ message_get_property (GObject    *object,
        case PROP_BODY:
                g_value_set_string (value, priv->body);
                break;
+       case PROP_INCOMING:
+               g_value_set_boolean (value, priv->incoming);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
                break;
@@ -200,6 +241,9 @@ message_set_property (GObject      *object,
                empathy_message_set_body (EMPATHY_MESSAGE (object),
                                         g_value_get_string (value));
                break;
+       case PROP_INCOMING:
+               priv->incoming = g_value_get_boolean (value);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
                break;
@@ -214,6 +258,75 @@ empathy_message_new (const gchar *body)
                             NULL);
 }
 
+EmpathyMessage *
+empathy_message_from_tpl_log_entry (TplEntry *logentry)
+{
+       EmpathyMessage *retval = NULL;
+       TpAccountManager *acc_man = NULL;
+       TpAccount *account = NULL;
+       TplEntity *receiver = NULL;
+       TplEntity *sender = NULL;
+       gchar *body= NULL;
+       EmpathyContact *contact;
+
+       g_return_val_if_fail (TPL_IS_ENTRY (logentry), NULL);
+
+       acc_man = tp_account_manager_dup ();
+       /* FIXME Currently Empathy shows in the log viewer only valid accounts, so it
+        * won't be selected any non-existing (ie removed) account.
+        * When #610455 will be fixed, calling tp_account_manager_ensure_account ()
+        * might add a not existing account to the AM. tp_account_new () probably
+        * will be the best way to handle it.
+        * Note: When creating an EmpathyContact from a TplEntity instance, the
+        * TpAccount is passed *only* to let EmpathyContact be able to retrieve the
+        * avatar (contact_get_avatar_filename () need a TpAccount).
+        * If the way EmpathyContact stores the avatar is changes, it might not be
+        * needed anymore any TpAccount passing and the following call will be
+        * useless */
+       account = tp_account_manager_ensure_account (acc_man,
+                       tpl_entry_get_account_path (logentry));
+       g_object_unref (acc_man);
+
+       /* TODO Currently only TplLogEntryText exists as subclass of TplEntry, in
+        * future more TplEntry will exist and EmpathyMessage should probably
+        * be enhanced to support other types of log entries (ie TplLogEntryCall).
+        *
+        * For now we just check (simply) that we are dealing with the only supported type,
+        * then there will be a if/then/else or switch handling all the supported
+        * cases.
+        */
+       if (!TPL_IS_ENTRY_TEXT (logentry))
+               return NULL;
+
+       body = g_strdup (tpl_entry_text_get_message (
+                               TPL_ENTRY_TEXT (logentry)));
+       receiver = tpl_entry_get_receiver (logentry);
+       sender = tpl_entry_get_sender (logentry);
+
+       retval = empathy_message_new (body);
+       if (receiver != NULL) {
+               contact = empathy_contact_from_tpl_contact (account, receiver);
+               empathy_message_set_receiver (retval, contact);
+               g_object_unref (contact);
+       }
+
+       if (sender != NULL) {
+               contact = empathy_contact_from_tpl_contact (account, sender);
+               empathy_message_set_sender (retval, contact);
+               g_object_unref (contact);
+       }
+
+       empathy_message_set_timestamp (retval,
+                       tpl_entry_get_timestamp (logentry));
+       empathy_message_set_id (retval,
+                       tpl_entry_text_get_pending_msg_id (TPL_ENTRY_TEXT (logentry)));
+       empathy_message_set_is_backlog (retval, TRUE);
+
+       g_free (body);
+
+       return retval;
+}
+
 TpChannelTextMessageType
 empathy_message_get_tptype (EmpathyMessage *message)
 {
@@ -325,28 +438,15 @@ empathy_message_set_body (EmpathyMessage *message,
                          const gchar    *body)
 {
        EmpathyMessagePriv       *priv = GET_PRIV (message);
-       TpChannelTextMessageType  type;
 
        g_return_if_fail (EMPATHY_IS_MESSAGE (message));
 
        g_free (priv->body);
-       priv->body = NULL;
-
-       type = TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
-       if (g_str_has_prefix (body, "/me")) {
-               type = TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION;
-               body += 4;
-       }
-       else if (g_str_has_prefix (body, "/say")) {
-               body += 5;
-       }
 
        if (body) {
                priv->body = g_strdup (body);
-       }
-
-       if (type != priv->type) {
-               empathy_message_set_tptype (message, type);
+       } else {
+               priv->body = NULL;
        }
 
        g_object_notify (G_OBJECT (message), "body");
@@ -384,24 +484,31 @@ empathy_message_set_timestamp (EmpathyMessage *message,
        g_object_notify (G_OBJECT (message), "timestamp");
 }
 
-GDate *
-empathy_message_get_date_and_time (EmpathyMessage *message, time_t *timestamp)
+gboolean
+empathy_message_is_backlog (EmpathyMessage *message)
 {
-       GDate *date;
+       EmpathyMessagePriv *priv;
 
-       *timestamp = 0;
-       if (message) {
-               *timestamp = empathy_message_get_timestamp (message);
-       }
+       g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE);
 
-       if (timestamp <= 0) {
-               *timestamp = empathy_time_get_current ();
-       }
+       priv = GET_PRIV (message);
+
+       return priv->is_backlog;
+}
 
-       date = g_date_new ();
-       g_date_set_time_t (date, *timestamp);
+void
+empathy_message_set_is_backlog (EmpathyMessage *message,
+                               gboolean is_backlog)
+{
+       EmpathyMessagePriv *priv;
+
+       g_return_if_fail (EMPATHY_IS_MESSAGE (message));
+
+       priv = GET_PRIV (message);
+
+       priv->is_backlog = is_backlog;
 
-       return date;
+       g_object_notify (G_OBJECT (message), "is-backlog");
 }
 
 #define IS_SEPARATOR(ch) (ch == ' ' || ch == ',' || ch == '.' || ch == ':')
@@ -413,6 +520,7 @@ empathy_message_should_highlight (EmpathyMessage *message)
        gchar         *cf_msg, *cf_to;
        gchar         *ch;
        gboolean       ret_val;
+       TpChannelTextMessageFlags flags;
 
        g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE);
 
@@ -428,11 +536,18 @@ empathy_message_should_highlight (EmpathyMessage *message)
                return FALSE;
        }
 
-       to = empathy_contact_get_name (contact);
+       to = empathy_contact_get_alias (contact);
        if (!to) {
                return FALSE;
        }
 
+       flags = empathy_message_get_flags (message);
+       if (flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_SCROLLBACK) {
+               /* FIXME: Ideally we shouldn't highlight scrollback messages only if they
+                * have already been received by the user before (and so are in the logs) */
+               return FALSE;
+       }
+
        cf_msg = g_utf8_casefold (msg, -1);
        cf_to = g_utf8_casefold (to, -1);
 
@@ -494,8 +609,97 @@ empathy_message_type_to_str (TpChannelTextMessageType type)
                return "notice";
        case TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY:
                return "auto-reply";
+       case TP_CHANNEL_TEXT_MESSAGE_TYPE_DELIVERY_REPORT:
+               return "delivery-report";
+       case TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL:
        default:
                return "normal";
        }
 }
 
+guint
+empathy_message_get_id (EmpathyMessage *message)
+{
+       EmpathyMessagePriv *priv = GET_PRIV (message);
+
+       g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), 0);
+
+       return priv->id;
+}
+
+void
+empathy_message_set_id (EmpathyMessage *message, guint id)
+{
+       EmpathyMessagePriv *priv = GET_PRIV (message);
+
+       priv->id = id;
+}
+
+void
+empathy_message_set_incoming (EmpathyMessage *message, gboolean incoming)
+{
+       EmpathyMessagePriv *priv;
+
+       g_return_if_fail (EMPATHY_IS_MESSAGE (message));
+
+       priv = GET_PRIV (message);
+
+       priv->incoming = incoming;
+
+       g_object_notify (G_OBJECT (message), "incoming");
+}
+
+gboolean
+empathy_message_is_incoming (EmpathyMessage *message)
+{
+       EmpathyMessagePriv *priv = GET_PRIV (message);
+
+       g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE);
+
+       return priv->incoming;
+}
+
+gboolean
+empathy_message_equal (EmpathyMessage *message1, EmpathyMessage *message2)
+{
+       EmpathyMessagePriv *priv1;
+       EmpathyMessagePriv *priv2;
+
+       g_return_val_if_fail (EMPATHY_IS_MESSAGE (message1), FALSE);
+       g_return_val_if_fail (EMPATHY_IS_MESSAGE (message2), FALSE);
+
+       priv1 = GET_PRIV (message1);
+       priv2 = GET_PRIV (message2);
+
+       if (priv1->timestamp == priv2->timestamp &&
+                       !tp_strdiff (priv1->body, priv2->body)) {
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+TpChannelTextMessageFlags
+empathy_message_get_flags (EmpathyMessage *self)
+{
+       EmpathyMessagePriv *priv = GET_PRIV (self);
+
+       g_return_val_if_fail (EMPATHY_IS_MESSAGE (self), 0);
+
+       return priv->flags;
+}
+
+void
+empathy_message_set_flags        (EmpathyMessage           *self,
+                               TpChannelTextMessageFlags flags)
+{
+       EmpathyMessagePriv *priv;
+
+       g_return_if_fail (EMPATHY_IS_MESSAGE (self));
+
+       priv = GET_PRIV (self);
+
+       priv->flags = flags;
+
+       g_object_notify (G_OBJECT (self), "flags");
+}