]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-theme-boxes.c
Updated Basque translation.
[empathy.git] / libempathy-gtk / empathy-theme-boxes.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2007 Imendio AB
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <config.h>
22
23 #include <string.h>
24
25 #include <glib/gi18n.h>
26 #include <gtk/gtk.h>
27
28 #include <libempathy/empathy-utils.h>
29 #include "empathy-ui-utils.h"
30 #include "empathy-theme-boxes.h"
31
32 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
33 #include <libempathy/empathy-debug.h>
34
35 #define MARGIN 4
36 #define HEADER_PADDING 2
37
38 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyThemeBoxes)
39 typedef struct {
40         gchar *header_foreground;
41         gchar *header_background;
42         gchar *header_line_background;
43         gchar *text_foreground;
44         gchar *text_background;
45         gchar *action_foreground;
46         gchar *highlight_foreground;
47         gchar *time_foreground;
48         gchar *event_foreground;
49         gchar *invite_foreground;
50         gchar *link_foreground;
51 } EmpathyThemeBoxesPriv;
52
53 static void     theme_boxes_finalize          (GObject            *object);
54 static void     theme_boxes_get_property      (GObject            *object,
55                                                guint               param_id,
56                                                GValue             *value,
57                                                GParamSpec         *pspec);
58 static void     theme_boxes_set_property      (GObject            *object,
59                                                guint               param_id,
60                                                const GValue       *value,
61                                                GParamSpec         *pspec);
62 static void     theme_boxes_define_theme_tags (EmpathyTheme        *theme,
63                                                EmpathyChatView     *view);
64 static void     theme_boxes_update_view       (EmpathyTheme        *theme,
65                                                EmpathyChatView     *view);
66 static void     theme_boxes_append_message    (EmpathyTheme        *theme,
67                                                EmpathyChatView     *view,
68                                                EmpathyMessage      *message);
69 static void     theme_boxes_append_event      (EmpathyTheme        *theme,
70                                                EmpathyChatView     *view,
71                                                const gchar        *str);
72 static void     theme_boxes_append_timestamp  (EmpathyTheme        *theme,
73                                                EmpathyChatView     *view,
74                                                EmpathyMessage      *message,
75                                                gboolean            show_date,
76                                                gboolean            show_time);
77 static void     theme_boxes_append_spacing    (EmpathyTheme        *theme,
78                                                EmpathyChatView     *view);
79
80 enum {
81         PROP_0,
82         PROP_HEADER_FOREGROUND,
83         PROP_HEADER_BACKGROUND,
84         PROP_HEADER_LINE_BACKGROUND,
85         PROP_TEXT_FOREGROUND,
86         PROP_TEXT_BACKGROUND,
87         PROP_ACTION_FOREGROUND,
88         PROP_HIGHLIGHT_FOREGROUND,
89         PROP_TIME_FOREGROUND,
90         PROP_EVENT_FOREGROUND,
91         PROP_INVITE_FOREGROUND,
92         PROP_LINK_FOREGROUND
93 };
94
95 enum {
96         PROP_FLOP,
97         PROP_MY_PROP
98 };
99
100 G_DEFINE_TYPE (EmpathyThemeBoxes, empathy_theme_boxes, EMPATHY_TYPE_THEME);
101
102 static void
103 empathy_theme_boxes_class_init (EmpathyThemeBoxesClass *class)
104 {
105         GObjectClass     *object_class;
106         EmpathyThemeClass *theme_class;
107
108         object_class = G_OBJECT_CLASS (class);
109         theme_class  = EMPATHY_THEME_CLASS (class);
110
111         object_class->finalize       = theme_boxes_finalize;
112         object_class->get_property   = theme_boxes_get_property;
113         object_class->set_property   = theme_boxes_set_property;
114
115         theme_class->update_view      = theme_boxes_update_view;
116         theme_class->append_message   = theme_boxes_append_message;
117         theme_class->append_event     = theme_boxes_append_event;
118         theme_class->append_timestamp = theme_boxes_append_timestamp;
119         theme_class->append_spacing   = theme_boxes_append_spacing;
120
121         g_object_class_install_property (object_class,
122                                          PROP_HEADER_FOREGROUND,
123                                          g_param_spec_string ("header-foreground",
124                                                               "",
125                                                               "",
126                                                               NULL,
127                                                               G_PARAM_READWRITE));
128
129         g_object_class_install_property (object_class,
130                                          PROP_HEADER_BACKGROUND,
131                                          g_param_spec_string ("header-background",
132                                                               "",
133                                                               "",
134                                                               NULL,
135                                                               G_PARAM_READWRITE));
136
137         g_object_class_install_property (object_class,
138                                          PROP_HEADER_LINE_BACKGROUND,
139                                          g_param_spec_string ("header-line-background",
140                                                               "",
141                                                               "",
142                                                               NULL,
143                                                               G_PARAM_READWRITE));
144
145
146         g_object_class_install_property (object_class,
147                                          PROP_TEXT_FOREGROUND,
148                                          g_param_spec_string ("text-foreground",
149                                                               "",
150                                                               "",
151                                                               NULL,
152                                                               G_PARAM_READWRITE));
153
154         g_object_class_install_property (object_class,
155                                          PROP_TEXT_BACKGROUND,
156                                          g_param_spec_string ("text-background",
157                                                               "",
158                                                               "",
159                                                               NULL,
160                                                               G_PARAM_READWRITE));
161
162         g_object_class_install_property (object_class,
163                                          PROP_ACTION_FOREGROUND,
164                                          g_param_spec_string ("action-foreground",
165                                                               "",
166                                                               "",
167                                                               NULL,
168                                                               G_PARAM_READWRITE));
169
170         g_object_class_install_property (object_class,
171                                          PROP_HIGHLIGHT_FOREGROUND,
172                                          g_param_spec_string ("highlight-foreground",
173                                                               "",
174                                                               "",
175                                                               NULL,
176                                                               G_PARAM_READWRITE));
177
178         g_object_class_install_property (object_class,
179                                          PROP_TIME_FOREGROUND,
180                                          g_param_spec_string ("time-foreground",
181                                                               "",
182                                                               "",
183                                                               NULL,
184                                                               G_PARAM_READWRITE));
185
186         g_object_class_install_property (object_class,
187                                          PROP_EVENT_FOREGROUND,
188                                          g_param_spec_string ("event-foreground",
189                                                               "",
190                                                               "",
191                                                               NULL,
192                                                               G_PARAM_READWRITE));
193
194         g_object_class_install_property (object_class,
195                                          PROP_INVITE_FOREGROUND,
196                                          g_param_spec_string ("invite-foreground",
197                                                               "",
198                                                               "",
199                                                               NULL,
200                                                               G_PARAM_READWRITE));
201
202         g_object_class_install_property (object_class,
203                                          PROP_LINK_FOREGROUND,
204                                          g_param_spec_string ("link-foreground",
205                                                               "",
206                                                               "",
207                                                               NULL,
208                                                               G_PARAM_READWRITE));
209
210         g_type_class_add_private (object_class, sizeof (EmpathyThemeBoxesPriv));
211 }
212
213 static void
214 empathy_theme_boxes_init (EmpathyThemeBoxes *theme)
215 {
216         EmpathyThemeBoxesPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (theme,
217                 EMPATHY_TYPE_THEME_BOXES, EmpathyThemeBoxesPriv);
218
219         theme->priv = priv;
220 }
221
222 static void
223 theme_boxes_finalize (GObject *object)
224 {
225         EmpathyThemeBoxesPriv *priv;
226
227         priv = GET_PRIV (object);
228
229         g_free (priv->header_foreground);
230         g_free (priv->header_background);
231         g_free (priv->header_line_background);
232         g_free (priv->text_foreground);
233         g_free (priv->text_background);
234         g_free (priv->action_foreground);
235         g_free (priv->highlight_foreground);
236         g_free (priv->time_foreground);
237         g_free (priv->event_foreground);
238         g_free (priv->invite_foreground);
239         g_free (priv->link_foreground);
240         
241         (G_OBJECT_CLASS (empathy_theme_boxes_parent_class)->finalize) (object);
242 }
243
244 static void
245 theme_boxes_get_property (GObject    *object,
246                           guint       param_id,
247                           GValue     *value,
248                           GParamSpec *pspec)
249 {
250         EmpathyThemeBoxesPriv *priv;
251
252         priv = GET_PRIV (object);
253
254         switch (param_id) {
255         case PROP_HEADER_FOREGROUND:
256                 g_value_set_string (value, priv->header_foreground);
257                 break;
258         case PROP_HEADER_BACKGROUND:
259                 g_value_set_string (value, priv->header_background);
260                 break;
261         case PROP_HEADER_LINE_BACKGROUND:
262                 g_value_set_string (value, priv->header_line_background);
263                 break;
264         case PROP_TEXT_FOREGROUND:
265                 g_value_set_string (value, priv->text_foreground);
266                 break;
267         case PROP_TEXT_BACKGROUND:
268                 g_value_set_string (value, priv->text_background);
269                 break;
270         case PROP_ACTION_FOREGROUND:
271                 g_value_set_string (value, priv->action_foreground);
272                 break;
273         case PROP_HIGHLIGHT_FOREGROUND:
274                 g_value_set_string (value, priv->highlight_foreground);
275                 break;
276         case PROP_TIME_FOREGROUND:
277                 g_value_set_string (value, priv->time_foreground);
278                 break;
279         case PROP_EVENT_FOREGROUND:
280                 g_value_set_string (value, priv->event_foreground);
281                 break;
282         case PROP_INVITE_FOREGROUND:
283                 g_value_set_string (value, priv->invite_foreground);
284                 break;
285         case PROP_LINK_FOREGROUND:
286                 g_value_set_string (value, priv->link_foreground);
287                 break;
288         default:
289                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
290                 break;
291         }
292 }
293 static void
294 theme_boxes_set_property (GObject      *object,
295                           guint         param_id,
296                           const GValue *value,
297                           GParamSpec   *pspec)
298 {
299         EmpathyThemeBoxesPriv *priv;
300
301         priv = GET_PRIV (object);
302
303         switch (param_id) {
304         case PROP_HEADER_FOREGROUND:
305                 g_free (priv->header_foreground);
306                 priv->header_foreground = g_value_dup_string (value);
307                 g_object_notify (object, "header-foreground");
308                 break;
309         case PROP_HEADER_BACKGROUND:
310                 g_free (priv->header_background);
311                 priv->header_background = g_value_dup_string (value);
312                 g_object_notify (object, "header-background");
313                 break;
314         case PROP_HEADER_LINE_BACKGROUND:
315                 g_free (priv->header_line_background);
316                 priv->header_line_background = g_value_dup_string (value);
317                 g_object_notify (object, "header-line_background");
318                 break;
319         case PROP_TEXT_FOREGROUND:
320                 g_free (priv->text_foreground);
321                 priv->text_foreground = g_value_dup_string (value);
322                 g_object_notify (object, "text-foreground");
323                 break;
324         case PROP_TEXT_BACKGROUND:
325                 g_free (priv->text_background);
326                 priv->text_background = g_value_dup_string (value);
327                 g_object_notify (object, "text-background");
328                 break;
329         case PROP_ACTION_FOREGROUND:
330                 g_free (priv->action_foreground);
331                 priv->action_foreground = g_value_dup_string (value);
332                 g_object_notify (object, "action-foreground");
333                 break;
334         case PROP_HIGHLIGHT_FOREGROUND:
335                 g_free (priv->highlight_foreground);
336                 priv->highlight_foreground = g_value_dup_string (value);
337                 g_object_notify (object, "highlight-foreground");
338                 break;
339         case PROP_TIME_FOREGROUND:
340                 g_free (priv->time_foreground);
341                 priv->time_foreground = g_value_dup_string (value);
342                 g_object_notify (object, "time-foreground");
343                 break;
344         case PROP_EVENT_FOREGROUND:
345                 g_free (priv->event_foreground);
346                 priv->event_foreground = g_value_dup_string (value);
347                 g_object_notify (object, "event-foreground");
348                 break;
349         case PROP_INVITE_FOREGROUND:
350                 g_free (priv->invite_foreground);
351                 priv->invite_foreground = g_value_dup_string (value);
352                 g_object_notify (object, "invite-foreground");
353                 break;
354         case PROP_LINK_FOREGROUND:
355                 g_free (priv->link_foreground);
356                 priv->link_foreground = g_value_dup_string (value);
357                 g_object_notify (object, "link-foreground");
358                 break;
359         default:
360                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
361                 break;
362         }
363 }
364
365 static void
366 theme_boxes_define_theme_tags (EmpathyTheme *theme, EmpathyChatView *view)
367 {
368         EmpathyThemeBoxesPriv *priv;
369         GtkTextBuffer         *buffer;
370         GtkTextTag            *tag;
371
372         priv = GET_PRIV (theme);
373
374         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
375
376         empathy_text_buffer_tag_set (buffer, "fancy-spacing",
377                                      "size", 3000,
378                                      "pixels-above-lines", 8,
379                                      NULL);
380
381         tag = empathy_text_buffer_tag_set (buffer, "fancy-header",
382                                            "weight", PANGO_WEIGHT_BOLD,
383                                            "pixels-above-lines", HEADER_PADDING,
384                                            "pixels-below-lines", HEADER_PADDING,
385                                            NULL);
386         if (priv->header_foreground) {
387                 g_object_set (tag,
388                               "foreground", priv->header_foreground,
389                               "paragraph-background", priv->header_background,
390                               NULL);
391         }
392
393         tag = empathy_text_buffer_tag_set (buffer, "fancy-header-line",
394                                            "size", 1,
395                                            NULL);
396         if (priv->header_line_background) {
397                 g_object_set (tag,
398                               "paragraph-background", priv->header_line_background,
399                               NULL);
400         }
401
402         tag = empathy_text_buffer_tag_set (buffer, "fancy-body",
403                                            "pixels-above-lines", 4,
404                                            NULL);
405         if (priv->text_background) {
406                 g_object_set (tag,
407                               "paragraph-background", priv->text_background,
408                               NULL);
409         }
410
411         if (priv->text_foreground) {
412                 g_object_set (tag,
413                               "foreground", priv->text_foreground,
414                               NULL);
415         }
416
417         tag = empathy_text_buffer_tag_set (buffer, "fancy-action",
418                                            "style", PANGO_STYLE_ITALIC,
419                                            "pixels-above-lines", 4,
420                                            NULL);
421
422         if (priv->text_background) {
423                 g_object_set (tag,
424                               "paragraph-background", priv->text_background,
425                               NULL);
426         }
427
428         if (priv->action_foreground) {
429                 g_object_set (tag,
430                               "foreground", priv->action_foreground,
431                               NULL);
432         }
433
434         tag = empathy_text_buffer_tag_set (buffer, "fancy-highlight",
435                                            "weight", PANGO_WEIGHT_BOLD,
436                                            "pixels-above-lines", 4,
437                                            NULL);
438         if (priv->text_background) {
439                 g_object_set (tag,
440                               "paragraph-background", priv->text_background,
441                               NULL);
442         }
443
444
445         if (priv->highlight_foreground) {
446                 g_object_set (tag,
447                               "foreground", priv->highlight_foreground,
448                               NULL);
449         }
450
451         tag = empathy_text_buffer_tag_set (buffer, "fancy-time",
452                                            "justification", GTK_JUSTIFY_CENTER,
453                                            NULL);
454         if (priv->time_foreground) {
455                 g_object_set (tag,
456                               "foreground", priv->time_foreground,
457                               NULL);
458         }
459
460         tag = empathy_text_buffer_tag_set (buffer, "fancy-event",
461                                            "justification", GTK_JUSTIFY_LEFT,
462                                            NULL);
463         if (priv->event_foreground) {
464                 g_object_set (tag,
465                               "foreground", priv->event_foreground,
466                               NULL);
467         }
468
469         tag = empathy_text_buffer_tag_set (buffer, "invite", NULL);
470         if (priv->invite_foreground) {
471                 g_object_set (tag,
472                               "foreground", priv->invite_foreground,
473                               NULL);
474         }
475
476         tag = empathy_text_buffer_tag_set (buffer, "fancy-link",
477                                            "underline", PANGO_UNDERLINE_SINGLE,
478                                            NULL);
479         if (priv->link_foreground) {
480                 g_object_set (tag,
481                               "foreground", priv->link_foreground,
482                               NULL);
483         } 
484 }
485
486 static void
487 theme_boxes_update_view (EmpathyTheme *theme, EmpathyChatView *view)
488 {
489         EmpathyThemeBoxesPriv *priv;
490
491         g_return_if_fail (EMPATHY_IS_THEME_BOXES (theme));
492         g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
493
494         priv = GET_PRIV (theme);
495
496         theme_boxes_define_theme_tags (theme, view);
497         
498         empathy_chat_view_set_margin (view, MARGIN);
499 }
500
501 static void
502 table_size_allocate_cb (GtkWidget     *view,
503                         GtkAllocation *allocation,
504                         GtkWidget     *box)
505 {
506         gint width, height;
507
508         gtk_widget_get_size_request (box, NULL, &height);
509
510         width = allocation->width;
511         
512         width -= \
513                 gtk_text_view_get_right_margin (GTK_TEXT_VIEW (view)) - \
514                 gtk_text_view_get_left_margin (GTK_TEXT_VIEW (view));
515         width -= 2 * MARGIN;
516         width -= 2 * HEADER_PADDING;
517
518         gtk_widget_set_size_request (box, width, height);
519 }
520
521 static void
522 theme_boxes_maybe_append_header (EmpathyTheme        *theme,
523                                  EmpathyChatView     *view,
524                                  EmpathyMessage      *msg)
525 {
526         EmpathyThemeBoxesPriv *priv;
527         EmpathyContact        *contact;
528         EmpathyContact        *last_contact;
529         GdkPixbuf            *avatar = NULL;
530         GtkTextBuffer        *buffer;
531         const gchar          *name;
532         GtkTextIter           iter;
533         GtkWidget            *label1, *label2;
534         GtkTextChildAnchor   *anchor;
535         GtkWidget            *box;
536         gchar                *str;
537         time_t                time;
538         gchar                *tmp;
539         GtkTextIter           start;
540         GdkColor              color;
541         gboolean              parse_success;
542
543         priv = GET_PRIV (theme);
544
545         contact = empathy_message_get_sender (msg);
546         name = empathy_contact_get_name (contact);
547         last_contact = empathy_chat_view_get_last_contact (view);
548         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
549
550         DEBUG ("Maybe add fancy header");
551
552         /* Only insert a header if the previously inserted block is not the same
553          * as this one. This catches all the different cases:
554          */
555         if (last_contact && empathy_contact_equal (last_contact, contact)) {
556                 return;
557         }
558
559         empathy_theme_append_spacing (theme, view);
560
561         gtk_text_buffer_get_end_iter (buffer, &iter);
562         gtk_text_buffer_insert_with_tags_by_name (buffer,
563                                                   &iter,
564                                                   "\n",
565                                                   -1,
566                                                   "fancy-header-line",
567                                                   NULL);
568
569         gtk_text_buffer_get_end_iter (buffer, &iter);
570         anchor = gtk_text_buffer_create_child_anchor (buffer, &iter);
571
572         box = gtk_hbox_new (FALSE, 0);
573
574
575         if (empathy_theme_get_show_avatars (theme)) {
576                 avatar = empathy_chat_view_get_avatar_pixbuf_with_cache (contact);
577                 if (avatar) {
578                         GtkWidget *image;
579
580                         image = gtk_image_new_from_pixbuf (avatar);
581
582                         gtk_box_pack_start (GTK_BOX (box), image,
583                                             FALSE, TRUE, 2);
584                 }
585         }
586
587         g_signal_connect_object (view, "size-allocate",
588                                  G_CALLBACK (table_size_allocate_cb),
589                                  box, 0);
590
591         str = g_markup_printf_escaped ("<b>%s</b>", name);
592
593         label1 = g_object_new (GTK_TYPE_LABEL,
594                                "label", str,
595                                "use-markup", TRUE,
596                                "xalign", 0.0,
597                                NULL);
598
599         parse_success = priv->header_foreground &&
600                         gdk_color_parse (priv->header_foreground, &color);
601
602         if (parse_success) {
603                 gtk_widget_modify_fg (label1, GTK_STATE_NORMAL, &color);
604         }
605
606         g_free (str);
607
608         time = empathy_message_get_timestamp (msg);
609
610         tmp = empathy_time_to_string_local (time, 
611                                            EMPATHY_TIME_FORMAT_DISPLAY_SHORT);
612         str = g_strdup_printf ("<i>%s</i>", tmp);
613         g_free (tmp);
614
615         label2 = g_object_new (GTK_TYPE_LABEL,
616                                "label", str,
617                                "use-markup", TRUE,
618                                "xalign", 1.0,
619                                NULL);
620         
621         if (parse_success) {
622                 gtk_widget_modify_fg (label2, GTK_STATE_NORMAL, &color);
623         }
624
625         g_free (str);
626
627         gtk_misc_set_alignment (GTK_MISC (label1), 0.0, 0.5);
628         gtk_misc_set_alignment (GTK_MISC (label2), 1.0, 0.5);
629
630         gtk_box_pack_start (GTK_BOX (box), label1, TRUE, TRUE, 0);
631         gtk_box_pack_start (GTK_BOX (box), label2, TRUE, TRUE, 0);
632
633         gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (view),
634                                            box,
635                                            anchor);
636
637         gtk_widget_show_all (box);
638
639         gtk_text_buffer_get_end_iter (buffer, &iter);
640         start = iter;
641         gtk_text_iter_backward_char (&start);
642         gtk_text_buffer_apply_tag_by_name (buffer,
643                                            "fancy-header",
644                                            &start, &iter);
645
646         gtk_text_buffer_insert_with_tags_by_name (buffer,
647                                                   &iter,
648                                                   "\n",
649                                                   -1,
650                                                   "fancy-header",
651                                                   NULL);
652
653         gtk_text_buffer_get_end_iter (buffer, &iter);
654         gtk_text_buffer_insert_with_tags_by_name (buffer,
655                                                   &iter,
656                                                   "\n",
657                                                   -1,
658                                                   "fancy-header-line",
659                                                   NULL);
660 }
661
662 static void
663 theme_boxes_append_message (EmpathyTheme        *theme,
664                             EmpathyChatView     *view,
665                             EmpathyMessage      *message)
666 {
667         EmpathyContact *sender;
668
669         empathy_theme_maybe_append_date_and_time (theme, view, message);
670         theme_boxes_maybe_append_header (theme, view, message);
671
672         sender = empathy_message_get_sender (message);
673
674         if (empathy_message_get_tptype (message) == TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION) {
675                 gchar *body;
676
677                 body = g_strdup_printf (" * %s %s", 
678                                         empathy_contact_get_name (sender),
679                                         empathy_message_get_body (message));
680                 empathy_theme_append_text (theme, view, body,
681                                            "fancy-action", "fancy-link");
682         } else {
683                 empathy_theme_append_text (theme, view,
684                                            empathy_message_get_body (message),
685                                            "fancy-body", "fancy-link");
686         }
687 }
688
689 static void
690 theme_boxes_append_event (EmpathyTheme        *theme,
691                           EmpathyChatView     *view,
692                           const gchar        *str)
693 {
694         GtkTextBuffer *buffer;
695         GtkTextIter    iter;
696         gchar         *msg;
697
698         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
699
700         empathy_theme_maybe_append_date_and_time (theme, view, NULL);
701
702         gtk_text_buffer_get_end_iter (buffer, &iter);
703
704         msg = g_strdup_printf (" - %s\n", str);
705
706         gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
707                                                   msg, -1,
708                                                   "fancy-event",
709                                                   NULL);
710         g_free (msg);
711 }
712
713 static void
714 theme_boxes_append_timestamp (EmpathyTheme        *theme,
715                               EmpathyChatView     *view,
716                               EmpathyMessage      *message,
717                               gboolean            show_date,
718                               gboolean            show_time)
719 {
720         GtkTextBuffer *buffer;
721         time_t         timestamp;
722         GDate         *date;
723         GtkTextIter    iter;
724         GString       *str;
725         
726         if (!show_date) {
727                 return;
728         }
729
730         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
731
732         date = empathy_message_get_date_and_time (message, &timestamp);
733
734         str = g_string_new (NULL);
735
736         if (show_time || show_date) {
737                 empathy_theme_append_spacing (theme, view);
738
739                 g_string_append (str, "- ");
740         }
741
742         if (show_date) {
743                 gchar buf[256];
744
745                 g_date_strftime (buf, 256, _("%A %d %B %Y"), date);
746                 g_string_append (str, buf);
747
748                 if (show_time) {
749                         g_string_append (str, ", ");
750                 }
751         }
752
753         g_date_free (date);
754
755         if (show_time) {
756                 gchar *tmp;
757
758                 tmp = empathy_time_to_string_local (timestamp, EMPATHY_TIME_FORMAT_DISPLAY_SHORT);
759                 g_string_append (str, tmp);
760                 g_free (tmp);
761         }
762
763         if (show_time || show_date) {
764                 g_string_append (str, " -\n");
765
766                 gtk_text_buffer_get_end_iter (buffer, &iter);
767                 gtk_text_buffer_insert_with_tags_by_name (buffer,
768                                                           &iter,
769                                                           str->str, -1,
770                                                           "fancy-time",
771                                                           NULL);
772
773                 empathy_chat_view_set_last_timestamp (view, timestamp);
774         }
775
776         g_string_free (str, TRUE);
777         
778 }
779
780 static void
781 theme_boxes_append_spacing (EmpathyTheme        *theme,
782                             EmpathyChatView     *view)
783 {
784         GtkTextBuffer *buffer;
785         GtkTextIter    iter;
786
787         g_return_if_fail (EMPATHY_IS_THEME (theme));
788         g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
789
790         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
791
792         gtk_text_buffer_get_end_iter (buffer, &iter);
793         gtk_text_buffer_insert_with_tags_by_name (buffer,
794                                                   &iter,
795                                                   "\n",
796                                                   -1,
797                                                   "cut",
798                                                   "fancy-spacing",
799                                                   NULL);
800 }
801