LCOV - code coverage report
Current view: top level - src/plugins/sms - valent-message-row.c (source / functions) Coverage Total Hit
Test: Code Coverage Lines: 94.2 % 120 113
Test Date: 2024-04-23 06:02:46 Functions: 100.0 % 15 15
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 57.5 % 73 42

             Branch data     Line data    Source code
       1                 :             : // SPDX-License-Identifier: GPL-3.0-or-later
       2                 :             : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
       3                 :             : 
       4                 :             : #define G_LOG_DOMAIN "valent-message-row"
       5                 :             : 
       6                 :             : #include "config.h"
       7                 :             : 
       8                 :             : #include <adwaita.h>
       9                 :             : #include <gtk/gtk.h>
      10                 :             : #include <pango/pango.h>
      11                 :             : #include <valent.h>
      12                 :             : 
      13                 :             : #include "valent-date-label.h"
      14                 :             : #include "valent-message-row.h"
      15                 :             : #include "valent-message.h"
      16                 :             : #include "valent-sms-utils.h"
      17                 :             : 
      18                 :             : 
      19                 :             : struct _ValentMessageRow
      20                 :             : {
      21                 :             :   GtkListBoxRow  parent_instance;
      22                 :             : 
      23                 :             :   ValentMessage *message;
      24                 :             :   EContact      *contact;
      25                 :             : 
      26                 :             :   GtkWidget     *grid;
      27                 :             :   GtkWidget     *avatar;
      28                 :             :   GtkWidget     *name_label;
      29                 :             :   GtkWidget     *date_label;
      30                 :             :   GtkWidget     *body_label;
      31                 :             : };
      32                 :             : 
      33   [ +  +  +  - ]:          25 : G_DEFINE_FINAL_TYPE (ValentMessageRow, valent_message_row, GTK_TYPE_LIST_BOX_ROW)
      34                 :             : 
      35                 :             : 
      36                 :             : enum {
      37                 :             :   PROP_0,
      38                 :             :   PROP_CONTACT,
      39                 :             :   PROP_MESSAGE,
      40                 :             :   PROP_THREAD_ID,
      41                 :             :   N_PROPERTIES
      42                 :             : };
      43                 :             : 
      44                 :             : static GParamSpec *properties[N_PROPERTIES] = { NULL, };
      45                 :             : 
      46                 :             : 
      47                 :             : /*
      48                 :             :  * GObject
      49                 :             :  */
      50                 :             : static void
      51                 :           3 : valent_message_row_finalize (GObject *object)
      52                 :             : {
      53                 :           3 :   ValentMessageRow *self = VALENT_MESSAGE_ROW (object);
      54                 :             : 
      55         [ +  - ]:           3 :   g_clear_object (&self->contact);
      56         [ +  - ]:           3 :   g_clear_object (&self->message);
      57                 :             : 
      58                 :           3 :   G_OBJECT_CLASS (valent_message_row_parent_class)->finalize (object);
      59                 :           3 : }
      60                 :             : 
      61                 :             : static void
      62                 :           3 : valent_message_row_get_property (GObject    *object,
      63                 :             :                                  guint       prop_id,
      64                 :             :                                  GValue     *value,
      65                 :             :                                  GParamSpec *pspec)
      66                 :             : {
      67                 :           3 :   ValentMessageRow *self = VALENT_MESSAGE_ROW (object);
      68                 :             : 
      69   [ +  +  +  - ]:           3 :   switch (prop_id)
      70                 :             :     {
      71                 :           1 :     case PROP_CONTACT:
      72                 :           1 :       g_value_set_object (value, self->contact);
      73                 :           1 :       break;
      74                 :             : 
      75                 :           1 :     case PROP_MESSAGE:
      76                 :           1 :       g_value_set_object (value, self->message);
      77                 :           1 :       break;
      78                 :             : 
      79                 :           1 :     case PROP_THREAD_ID:
      80                 :           1 :       g_value_set_int64 (value, valent_message_row_get_thread_id (self));
      81                 :           1 :       break;
      82                 :             : 
      83                 :           0 :     default:
      84                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      85                 :             :     }
      86                 :           3 : }
      87                 :             : 
      88                 :             : static void
      89                 :           6 : valent_message_row_set_property (GObject      *object,
      90                 :             :                                  guint         prop_id,
      91                 :             :                                  const GValue *value,
      92                 :             :                                  GParamSpec   *pspec)
      93                 :             : {
      94                 :           6 :   ValentMessageRow *self = VALENT_MESSAGE_ROW (object);
      95                 :             : 
      96      [ +  +  - ]:           6 :   switch (prop_id)
      97                 :             :     {
      98                 :           3 :     case PROP_CONTACT:
      99                 :           3 :       valent_message_row_set_contact (self, g_value_get_object (value));
     100                 :           3 :       break;
     101                 :             : 
     102                 :           3 :     case PROP_MESSAGE:
     103                 :           3 :       valent_message_row_set_message (self, g_value_get_object (value));
     104                 :           3 :       break;
     105                 :             : 
     106                 :           0 :     default:
     107                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     108                 :             :     }
     109                 :           6 : }
     110                 :             : 
     111                 :             : static void
     112                 :           2 : valent_message_row_class_init (ValentMessageRowClass *klass)
     113                 :             : {
     114                 :           2 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     115                 :             : 
     116                 :           2 :   object_class->finalize = valent_message_row_finalize;
     117                 :           2 :   object_class->get_property = valent_message_row_get_property;
     118                 :           2 :   object_class->set_property = valent_message_row_set_property;
     119                 :             : 
     120                 :             :   /**
     121                 :             :    * ValentMessageRow:contact
     122                 :             :    *
     123                 :             :    * The `EContact` that sent this message.
     124                 :             :    */
     125                 :           4 :   properties [PROP_CONTACT] =
     126                 :           2 :     g_param_spec_object ("contact", NULL, NULL,
     127                 :             :                          E_TYPE_CONTACT,
     128                 :             :                          (G_PARAM_READWRITE |
     129                 :             :                           G_PARAM_CONSTRUCT |
     130                 :             :                           G_PARAM_EXPLICIT_NOTIFY |
     131                 :             :                           G_PARAM_STATIC_STRINGS));
     132                 :             : 
     133                 :             :   /**
     134                 :             :    * ValentMessageRow:message
     135                 :             :    *
     136                 :             :    * The message this row displays.
     137                 :             :    */
     138                 :           4 :   properties [PROP_MESSAGE] =
     139                 :           2 :     g_param_spec_object ("message", NULL, NULL,
     140                 :             :                           VALENT_TYPE_MESSAGE,
     141                 :             :                           (G_PARAM_READWRITE |
     142                 :             :                            G_PARAM_CONSTRUCT |
     143                 :             :                            G_PARAM_EXPLICIT_NOTIFY |
     144                 :             :                            G_PARAM_STATIC_STRINGS));
     145                 :             : 
     146                 :             :   /**
     147                 :             :    * ValentMessageRow:thread-id
     148                 :             :    *
     149                 :             :    * The thread id this message belongs to.
     150                 :             :    */
     151                 :           4 :   properties [PROP_THREAD_ID] =
     152                 :           2 :     g_param_spec_int64 ("thread-id", NULL, NULL,
     153                 :             :                         G_MININT64, G_MAXINT64,
     154                 :             :                         0,
     155                 :             :                         (G_PARAM_READABLE |
     156                 :             :                          G_PARAM_EXPLICIT_NOTIFY |
     157                 :             :                          G_PARAM_STATIC_STRINGS));
     158                 :             : 
     159                 :           2 :   g_object_class_install_properties (object_class, N_PROPERTIES, properties);
     160                 :           2 : }
     161                 :             : 
     162                 :             : static void
     163                 :           3 : valent_message_row_init (ValentMessageRow *self)
     164                 :             : {
     165                 :           3 :   gtk_widget_add_css_class (GTK_WIDGET (self), "valent-message-row");
     166                 :             : 
     167                 :           3 :   self->grid = g_object_new (GTK_TYPE_GRID,
     168                 :             :                              "column-spacing", 8,
     169                 :             :                              "margin-start",   8,
     170                 :             :                              "margin-end",     8,
     171                 :             :                              "margin-top",     6,
     172                 :             :                              "margin-bottom",  6,
     173                 :             :                              NULL);
     174                 :           3 :   gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (self), self->grid);
     175                 :             : 
     176                 :           3 :   self->avatar = g_object_new (ADW_TYPE_AVATAR,
     177                 :             :                                "size",    32,
     178                 :             :                                "halign",  GTK_ALIGN_START,
     179                 :             :                                "valign",  GTK_ALIGN_CENTER,
     180                 :             :                                "vexpand", TRUE,
     181                 :             :                                NULL);
     182                 :           3 :   gtk_grid_attach (GTK_GRID (self->grid), self->avatar, 0, 0, 1, 2);
     183                 :             : 
     184                 :           3 :   self->name_label = g_object_new (GTK_TYPE_LABEL,
     185                 :             :                                    "ellipsize",  PANGO_ELLIPSIZE_END,
     186                 :             :                                    "halign",     GTK_ALIGN_START,
     187                 :             :                                    "hexpand",    TRUE,
     188                 :             :                                    "valign",     GTK_ALIGN_START,
     189                 :             :                                    "vexpand",    TRUE,
     190                 :             :                                    "use-markup", TRUE,
     191                 :             :                                    "xalign",     0.0,
     192                 :             :                                    NULL);
     193                 :           3 :   gtk_grid_attach (GTK_GRID (self->grid), self->name_label, 1, 0, 1, 1);
     194                 :             : 
     195                 :           3 :   self->date_label = g_object_new (VALENT_TYPE_DATE_LABEL,
     196                 :             :                                    "halign",     GTK_ALIGN_END,
     197                 :             :                                    NULL);
     198                 :           3 :   gtk_widget_add_css_class (self->date_label, "dim-label");
     199                 :           3 :   gtk_grid_attach (GTK_GRID (self->grid), self->date_label, 2, 0, 1, 1);
     200                 :             : 
     201                 :           3 :   self->body_label = g_object_new (GTK_TYPE_LABEL,
     202                 :             :                                    "ellipsize",        PANGO_ELLIPSIZE_END,
     203                 :             :                                    "halign",           GTK_ALIGN_START,
     204                 :             :                                    "hexpand",          TRUE,
     205                 :             :                                    "valign",           GTK_ALIGN_END,
     206                 :             :                                    "vexpand",          TRUE,
     207                 :             :                                    "single-line-mode", TRUE,
     208                 :             :                                    "use-markup",       TRUE,
     209                 :             :                                    "xalign",           0.0,
     210                 :             :                                    NULL);
     211                 :           3 :   gtk_grid_attach (GTK_GRID (self->grid), self->body_label, 1, 1, 2, 1);
     212                 :           3 : }
     213                 :             : 
     214                 :             : /**
     215                 :             :  * valent_message_row_new:
     216                 :             :  * @message: (nullable): a `ValentMessage`
     217                 :             :  * @contact: (nullable): a `EContact`
     218                 :             :  *
     219                 :             :  * Create a new message row for @contact and @message.
     220                 :             :  *
     221                 :             :  * Returns: a `ValentMessageRow`
     222                 :             :  */
     223                 :             : GtkWidget *
     224                 :           1 : valent_message_row_new (ValentMessage *message,
     225                 :             :                         EContact      *contact)
     226                 :             : {
     227                 :           1 :   return g_object_new (VALENT_TYPE_MESSAGE_ROW,
     228                 :             :                        "contact", contact,
     229                 :             :                        "message", message,
     230                 :             :                        NULL);
     231                 :             : }
     232                 :             : 
     233                 :             : /**
     234                 :             :  * valent_message_row_get_contact:
     235                 :             :  * @row: a `ValentMessageRow`
     236                 :             :  *
     237                 :             :  * Get the contact.
     238                 :             :  *
     239                 :             :  * Returns: (transfer none) (nullable): a `ValentContact`
     240                 :             :  */
     241                 :             : EContact *
     242                 :           1 : valent_message_row_get_contact (ValentMessageRow *row)
     243                 :             : {
     244         [ +  - ]:           1 :   g_return_val_if_fail (VALENT_IS_MESSAGE_ROW (row), NULL);
     245                 :             : 
     246                 :           1 :   return row->contact;
     247                 :             : }
     248                 :             : 
     249                 :             : /**
     250                 :             :  * valent_message_row_set_contact:
     251                 :             :  * @row: a `ValentMessageRow`
     252                 :             :  * @contact: a `ValentContact`
     253                 :             :  *
     254                 :             :  * Set or update the contact.
     255                 :             :  */
     256                 :             : void
     257                 :           5 : valent_message_row_set_contact (ValentMessageRow *row,
     258                 :             :                                 EContact         *contact)
     259                 :             : {
     260         [ +  - ]:           5 :   g_return_if_fail (VALENT_IS_MESSAGE_ROW (row));
     261   [ +  +  +  -  :           5 :   g_return_if_fail (contact == NULL || E_IS_CONTACT (contact));
             -  +  -  - ]
     262                 :             : 
     263         [ +  + ]:           5 :   if (!g_set_object (&row->contact, contact))
     264                 :             :     return;
     265                 :             : 
     266         [ +  - ]:           3 :   if (row->contact != NULL)
     267                 :           3 :     valent_sms_avatar_from_contact (ADW_AVATAR (row->avatar), contact);
     268                 :             : 
     269                 :           3 :   valent_message_row_update (row);
     270                 :           3 :   g_object_notify_by_pspec (G_OBJECT (row), properties [PROP_CONTACT]);
     271                 :             : }
     272                 :             : 
     273                 :             : /**
     274                 :             :  * valent_message_row_get_thread_id:
     275                 :             :  * @row: a `ValentMessageRow`
     276                 :             :  *
     277                 :             :  * Get the thread_id of the message.
     278                 :             :  *
     279                 :             :  * Returns: a thread id
     280                 :             :  */
     281                 :             : int64_t
     282                 :           2 : valent_message_row_get_thread_id (ValentMessageRow *row)
     283                 :             : {
     284         [ +  - ]:           2 :   g_return_val_if_fail (VALENT_IS_MESSAGE_ROW (row), 0);
     285                 :             : 
     286         [ -  + ]:           2 :   if G_UNLIKELY (row->message == NULL)
     287                 :             :     return 0;
     288                 :             : 
     289                 :           2 :   return valent_message_get_thread_id (row->message);
     290                 :             : }
     291                 :             : 
     292                 :             : /**
     293                 :             :  * valent_message_row_get_message:
     294                 :             :  * @row: a `ValentMessageRow`
     295                 :             :  *
     296                 :             :  * Get the message.
     297                 :             :  *
     298                 :             :  * Returns: (transfer none): a `ValentMessage`
     299                 :             :  */
     300                 :             : ValentMessage *
     301                 :           1 : valent_message_row_get_message (ValentMessageRow *row)
     302                 :             : {
     303         [ +  - ]:           1 :   g_return_val_if_fail (VALENT_IS_MESSAGE_ROW (row), NULL);
     304                 :             : 
     305                 :           1 :   return row->message;
     306                 :             : }
     307                 :             : 
     308                 :             : /**
     309                 :             :  * valent_message_row_set_message:
     310                 :             :  * @row: a `ValentMessageRow`
     311                 :             :  * @message: a `ValentMessage`
     312                 :             :  *
     313                 :             :  * Set or update the message.
     314                 :             :  */
     315                 :             : void
     316                 :           3 : valent_message_row_set_message (ValentMessageRow *row,
     317                 :             :                                 ValentMessage    *message)
     318                 :             : {
     319         [ +  - ]:           3 :   g_return_if_fail (VALENT_IS_MESSAGE_ROW (row));
     320   [ +  -  -  + ]:           3 :   g_return_if_fail (message == NULL || VALENT_IS_MESSAGE (message));
     321                 :             : 
     322         [ +  - ]:           3 :   if (row->message == message)
     323                 :             :     return;
     324                 :             : 
     325         [ -  + ]:           3 :   if (row->message != NULL)
     326                 :             :     {
     327                 :           0 :       g_signal_handlers_disconnect_by_data (row->message, row);
     328         [ #  # ]:           0 :       g_clear_object (&row->message);
     329                 :             :     }
     330                 :             : 
     331         [ +  - ]:           3 :   if (message != NULL)
     332                 :             :     {
     333                 :           3 :       row->message = g_object_ref (message);
     334                 :           3 :       g_signal_connect_swapped (row->message,
     335                 :             :                                 "notify",
     336                 :             :                                 G_CALLBACK (valent_message_row_update),
     337                 :             :                                 row);
     338                 :             : 
     339                 :           3 :       valent_message_row_update (row);
     340                 :           3 :       g_object_notify_by_pspec (G_OBJECT (row), properties [PROP_MESSAGE]);
     341                 :             :     }
     342                 :             : }
     343                 :             : 
     344                 :             : /**
     345                 :             :  * valent_message_row_update:
     346                 :             :  * @row: a `ValentMessageRow`
     347                 :             :  *
     348                 :             :  * Update the conversation row with data from `ValentMessageRow`:contact
     349                 :             :  * and `ValentMessageRow`:message properties.
     350                 :             :  */
     351                 :             : void
     352                 :           6 : valent_message_row_update (ValentMessageRow *row)
     353                 :             : {
     354                 :           6 :   gboolean read;
     355                 :           6 :   const char *body;
     356                 :           6 :   const char *name;
     357                 :           6 :   int64_t date;
     358                 :           6 :   g_autofree char *body_label = NULL;
     359                 :           6 :   g_autofree char *name_label = NULL;
     360                 :             : 
     361         [ +  - ]:           6 :   g_return_if_fail (VALENT_IS_MESSAGE_ROW (row));
     362                 :             : 
     363         [ +  + ]:           6 :   if (row->message == NULL)
     364                 :             :     return;
     365                 :             : 
     366                 :             :   /* Message Sender/Name */
     367   [ +  +  +  -  :           5 :   if (E_IS_CONTACT (row->contact))
             -  +  -  - ]
     368                 :           3 :     name = e_contact_get_const (row->contact, E_CONTACT_FULL_NAME);
     369                 :             :   else
     370                 :           2 :     name = valent_message_get_sender (row->message);
     371                 :             : 
     372                 :             :   /* Message Read/Unread */
     373         [ +  + ]:           5 :   if ((read = valent_message_get_read (row->message)))
     374         [ -  + ]:           1 :     name_label = g_strdup (name);
     375                 :             :   else
     376                 :           4 :     name_label = g_strdup_printf ("<b>%s</b>", name);
     377                 :             : 
     378                 :           5 :   gtk_label_set_label (GTK_LABEL (row->name_label), name_label);
     379                 :             : 
     380                 :             :   /* Message Body */
     381         [ +  - ]:           5 :   if ((body = valent_message_get_text (row->message)) != NULL)
     382                 :             :     {
     383                 :           5 :       g_autofree char *text = NULL;
     384                 :             : 
     385                 :           5 :       text = g_markup_escape_text (body, -1);
     386                 :             : 
     387         [ +  + ]:           5 :       if (valent_message_get_box (row->message) == VALENT_MESSAGE_BOX_SENT)
     388                 :           4 :         body_label = g_strdup_printf ("<small>You: %s</small>", text);
     389         [ +  - ]:           1 :       else if (read)
     390                 :           1 :         body_label = g_strdup_printf ("<small>%s</small>", text);
     391                 :             :       else
     392                 :           0 :         body_label = g_strdup_printf ("<b><small>%s</small></b>", text);
     393                 :             :     }
     394                 :             : 
     395                 :           5 :   gtk_label_set_label (GTK_LABEL (row->body_label), body_label);
     396                 :             : 
     397                 :             :   /* Message Date */
     398                 :           5 :   date = valent_message_get_date (row->message);
     399                 :           5 :   valent_date_label_set_date (VALENT_DATE_LABEL (row->date_label), date);
     400                 :             : }
     401                 :             : 
        

Generated by: LCOV version 2.0-1