]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-theme-irc.c
afe71e5ea665a58d637ff7e0da0b370936dea745
[empathy.git] / libempathy-gtk / empathy-theme-irc.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 <glib/gi18n.h>
24 #include <libempathy/empathy-debug.h>
25
26 #include "empathy-chat.h"
27 #include "empathy-theme-utils.h"
28 #include "empathy-theme-irc.h"
29
30 #define DEBUG_DOMAIN "Theme"
31
32 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_THEME_IRC, EmpathyThemeIrcPriv))
33
34 typedef struct _EmpathyThemeIrcPriv EmpathyThemeIrcPriv;
35
36 struct _EmpathyThemeIrcPriv {
37         gint my_prop;
38 };
39
40 static void         theme_irc_finalize      (GObject             *object);
41 static void         theme_irc_get_property  (GObject             *object,
42                                              guint                param_id,
43                                              GValue              *value,
44                                              GParamSpec          *pspec);
45 static void         theme_irc_set_property  (GObject             *object,
46                                              guint                param_id,
47                                              const GValue        *value,
48                                              GParamSpec          *pspec);
49 static EmpathyThemeContext *
50 theme_irc_setup_with_view                      (EmpathyTheme         *theme,
51                                                 EmpathyChatView      *view);
52 static void         theme_irc_detach_from_view (EmpathyTheme        *theme,
53                                                 EmpathyThemeContext *context,
54                                                 EmpathyChatView     *view);
55 static void         theme_irc_append_message   (EmpathyTheme        *theme,
56                                                 EmpathyThemeContext *context,
57                                                 EmpathyChatView     *view,
58                                                 EmpathyMessage      *message);
59 static void         theme_irc_append_event     (EmpathyTheme        *theme,
60                                                 EmpathyThemeContext *context,
61                                                 EmpathyChatView     *view,
62                                                 const gchar        *str);
63 static void         theme_irc_append_timestamp (EmpathyTheme        *theme,
64                                                 EmpathyThemeContext *context,
65                                                 EmpathyChatView     *view,
66                                                 EmpathyMessage      *message,
67                                                 gboolean            show_date,
68                                                 gboolean            show_time);
69 static void         theme_irc_append_spacing   (EmpathyTheme        *theme,
70                                                 EmpathyThemeContext *context,
71                                                 EmpathyChatView     *view);
72
73
74 enum {
75         PROP_0,
76         PROP_MY_PROP
77 };
78
79 G_DEFINE_TYPE (EmpathyThemeIrc, empathy_theme_irc, EMPATHY_TYPE_THEME);
80
81 static void
82 empathy_theme_irc_class_init (EmpathyThemeIrcClass *class)
83 {
84         GObjectClass *object_class;
85         EmpathyThemeClass *theme_class;
86
87         object_class = G_OBJECT_CLASS (class);
88         theme_class  = EMPATHY_THEME_CLASS (class);
89
90         object_class->finalize     = theme_irc_finalize;
91         object_class->get_property = theme_irc_get_property;
92         object_class->set_property = theme_irc_set_property;
93
94         theme_class->setup_with_view  = theme_irc_setup_with_view;
95         theme_class->detach_from_view = theme_irc_detach_from_view;
96         theme_class->append_message   = theme_irc_append_message;
97         theme_class->append_event     = theme_irc_append_event;
98         theme_class->append_timestamp = theme_irc_append_timestamp;
99         theme_class->append_spacing   = theme_irc_append_spacing;
100
101         g_object_class_install_property (object_class,
102                                          PROP_MY_PROP,
103                                          g_param_spec_int ("my-prop",
104                                                            "",
105                                                            "",
106                                                            0, 1,
107                                                            1,
108                                                            G_PARAM_READWRITE));
109
110         g_type_class_add_private (object_class, sizeof (EmpathyThemeIrcPriv));
111 }
112
113 static void
114 empathy_theme_irc_init (EmpathyThemeIrc *presence)
115 {
116         EmpathyThemeIrcPriv *priv;
117
118         priv = GET_PRIV (presence);
119 }
120
121 static void
122 theme_irc_finalize (GObject *object)
123 {
124         EmpathyThemeIrcPriv *priv;
125
126         priv = GET_PRIV (object);
127
128         (G_OBJECT_CLASS (empathy_theme_irc_parent_class)->finalize) (object);
129 }
130
131 static void
132 theme_irc_get_property (GObject    *object,
133                     guint       param_id,
134                     GValue     *value,
135                     GParamSpec *pspec)
136 {
137         EmpathyThemeIrcPriv *priv;
138
139         priv = GET_PRIV (object);
140
141         switch (param_id) {
142         case PROP_MY_PROP:
143                 g_value_set_int (value, priv->my_prop);
144                 break;
145         default:
146                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
147                 break;
148         }
149 }
150 static void
151 theme_irc_set_property (GObject      *object,
152                     guint         param_id,
153                     const GValue *value,
154                     GParamSpec   *pspec)
155 {
156         EmpathyThemeIrcPriv *priv;
157
158         priv = GET_PRIV (object);
159
160         switch (param_id) {
161         case PROP_MY_PROP:
162                 priv->my_prop = g_value_get_int (value);
163                 break;
164         default:
165                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
166                 break;
167         }
168 }
169
170 static void
171 theme_irc_fixup_tag_table (EmpathyTheme *theme, EmpathyChatView *view)
172 {
173         GtkTextBuffer *buffer;
174
175         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
176
177         /* IRC style tags. */
178         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-nick-self");
179         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-body-self");
180         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-action-self");
181
182         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-nick-other");
183         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-body-other");
184         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-action-other");
185
186         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-nick-highlight");
187         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-spacing");
188         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-time");
189         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-event");
190         empathy_theme_utils_ensure_tag_by_name (buffer, "irc-link");
191 }
192
193 static void
194 theme_irc_apply_theme_classic (EmpathyTheme *theme, EmpathyChatView *view)
195 {
196         EmpathyThemeIrcPriv *priv;
197         GtkTextBuffer      *buffer;
198         GtkTextTagTable    *table;
199         GtkTextTag         *tag;
200
201         priv = GET_PRIV (theme);
202
203         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
204         table = gtk_text_buffer_get_tag_table (buffer);
205
206         tag = empathy_theme_utils_init_tag_by_name (table, "irc-spacing");
207         g_object_set (tag,
208                       "size", 2000,
209                       NULL);
210         empathy_theme_utils_add_tag (table, tag);
211
212         tag = empathy_theme_utils_init_tag_by_name (table, "irc-nick-self");
213         g_object_set (tag,
214                       "foreground", "sea green",
215                       NULL);
216         empathy_theme_utils_add_tag (table, tag);
217
218         tag = empathy_theme_utils_init_tag_by_name (table, "irc-body-self");
219         g_object_set (tag,
220                       /* To get the default theme color: */
221                       "foreground-set", FALSE,
222                       NULL);
223         empathy_theme_utils_add_tag (table, tag);
224
225         tag = empathy_theme_utils_init_tag_by_name (table, "irc-action-self");
226         g_object_set (tag,
227                       "foreground", "brown4",
228                       "style", PANGO_STYLE_ITALIC,
229                       NULL);
230         empathy_theme_utils_add_tag (table, tag);
231
232         tag = empathy_theme_utils_init_tag_by_name (table, "irc-nick-highlight");
233         g_object_set (tag,
234                       "foreground", "indian red",
235                       "weight", PANGO_WEIGHT_BOLD,
236                       NULL);
237         empathy_theme_utils_add_tag (table, tag);
238
239         tag = empathy_theme_utils_init_tag_by_name (table, "irc-nick-other");
240         g_object_set (tag,
241                       "foreground", "skyblue4",
242                       NULL);
243         empathy_theme_utils_add_tag (table, tag);
244
245         tag = empathy_theme_utils_init_tag_by_name (table, "irc-body-other");
246         g_object_set (tag,
247                       /* To get the default theme color: */
248                       "foreground-set", FALSE,
249                       NULL);
250         empathy_theme_utils_add_tag (table, tag);
251
252         tag = empathy_theme_utils_init_tag_by_name (table, "irc-action-other");
253         g_object_set (tag,
254                       "foreground", "brown4",
255                       "style", PANGO_STYLE_ITALIC,
256                       NULL);
257         empathy_theme_utils_add_tag (table, tag);
258
259         tag = empathy_theme_utils_init_tag_by_name (table, "irc-time");
260         g_object_set (tag,
261                       "foreground", "darkgrey",
262                       "justification", GTK_JUSTIFY_CENTER,
263                       NULL);
264         empathy_theme_utils_add_tag (table, tag);
265
266         tag = empathy_theme_utils_init_tag_by_name (table, "irc-event");
267         g_object_set (tag,
268                       "foreground", "PeachPuff4",
269                       "justification", GTK_JUSTIFY_LEFT,
270                       NULL);
271         empathy_theme_utils_add_tag (table, tag);
272
273         tag = empathy_theme_utils_init_tag_by_name (table, "invite");
274         g_object_set (tag,
275                       "foreground", "sienna",
276                       NULL);
277         empathy_theme_utils_add_tag (table, tag);
278
279         tag = empathy_theme_utils_init_tag_by_name (table, "irc-link");
280         g_object_set (tag,
281                       "foreground", "steelblue",
282                       "underline", PANGO_UNDERLINE_SINGLE,
283                       NULL);
284         empathy_theme_utils_add_tag (table, tag);
285 }
286
287
288 static EmpathyThemeContext *
289 theme_irc_setup_with_view (EmpathyTheme *theme, EmpathyChatView *view)
290 {
291         theme_irc_fixup_tag_table (theme, view);
292         theme_irc_apply_theme_classic (theme, view);
293         empathy_chat_view_set_margin (view, 3);
294
295         return NULL;
296 }
297
298 static void
299 theme_irc_detach_from_view (EmpathyTheme        *theme,
300                             EmpathyThemeContext *context,
301                             EmpathyChatView     *view)
302 {
303         /* Free the context */
304 }
305
306 static void
307 theme_irc_append_message (EmpathyTheme        *theme,
308                           EmpathyThemeContext *context,
309                           EmpathyChatView     *view,
310                           EmpathyMessage      *message)
311 {
312         GtkTextBuffer *buffer;
313         const gchar   *name;
314         const gchar   *nick_tag;
315         const gchar   *body_tag;
316         GtkTextIter    iter;
317         gchar         *tmp;
318         EmpathyContact *contact;
319
320         empathy_theme_maybe_append_date_and_time (theme, context, view, message);
321
322         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
323
324         contact = empathy_message_get_sender (message);
325         name = empathy_contact_get_name (contact);
326
327         if (empathy_message_get_type (message) == EMPATHY_MESSAGE_TYPE_ACTION) {
328                 if (empathy_contact_is_user (contact)) {
329                         body_tag = "irc-action-self";
330                 } else {
331                         body_tag = "irc-action-other";
332                 }
333
334                 tmp = g_strdup_printf (" * %s %s", 
335                                        empathy_contact_get_name (contact),
336                                        empathy_message_get_body (message));
337                 empathy_theme_append_text (theme, context, view, tmp,
338                                            body_tag, "irc-link");
339                 g_free (tmp);
340                 return;
341         }
342
343         if (empathy_contact_is_user (contact)) {
344                 nick_tag = "irc-nick-self";
345                 body_tag = "irc-body-self";
346         } else {
347                 if (empathy_chat_should_highlight_nick (message)) {
348                         nick_tag = "irc-nick-highlight";
349                 } else {
350                         nick_tag = "irc-nick-other";
351                 }
352
353                 body_tag = "irc-body-other";
354         }
355                 
356         gtk_text_buffer_get_end_iter (buffer, &iter);
357
358         /* The nickname. */
359         tmp = g_strdup_printf ("%s: ", name);
360         gtk_text_buffer_insert_with_tags_by_name (buffer,
361                                                   &iter,
362                                                   tmp,
363                                                   -1,
364                                                   "cut",
365                                                   nick_tag,
366                                                   NULL);
367         g_free (tmp);
368
369         /* The text body. */
370         empathy_theme_append_text (theme, context, view, 
371                                   empathy_message_get_body (message),
372                                   body_tag, "irc-link");
373 }
374
375 static void
376 theme_irc_append_event (EmpathyTheme        *theme,
377                         EmpathyThemeContext *context,
378                     EmpathyChatView     *view,
379                     const gchar        *str)
380 {
381         GtkTextBuffer *buffer;
382         GtkTextIter    iter;
383         gchar         *msg;
384
385         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
386         
387         empathy_theme_maybe_append_date_and_time (theme, context, view, NULL);
388
389         gtk_text_buffer_get_end_iter (buffer, &iter);
390
391         msg = g_strdup_printf (" - %s\n", str);
392         gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
393                                                   msg, -1,
394                                                   "irc-event",
395                                                   NULL);
396         g_free (msg);
397 }
398
399 static void
400 theme_irc_append_timestamp (EmpathyTheme        *theme,
401                             EmpathyThemeContext *context,
402                             EmpathyChatView     *view,
403                             EmpathyMessage      *message,
404                             gboolean            show_date,
405                             gboolean            show_time)
406 {
407         GtkTextBuffer *buffer;
408         time_t         timestamp;
409         GDate         *date;
410         GtkTextIter    iter;
411         GString       *str;
412
413         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
414
415         date = empathy_message_get_date_and_time (message, &timestamp);
416
417         str = g_string_new (NULL);
418
419         if (show_time || show_date) {
420                 empathy_theme_append_spacing (theme, 
421                                              context,
422                                              view);
423
424                 g_string_append (str, "- ");
425         }
426
427         if (show_date) {
428                 gchar buf[256];
429
430                 g_date_strftime (buf, 256, _("%A %d %B %Y"), date);
431                 g_string_append (str, buf);
432
433                 if (show_time) {
434                         g_string_append (str, ", ");
435                 }
436         }
437
438         g_date_free (date);
439
440         if (show_time) {
441                 gchar *tmp;
442
443                 tmp = empathy_time_to_string_local (timestamp, EMPATHY_TIME_FORMAT_DISPLAY_SHORT);
444                 g_string_append (str, tmp);
445                 g_free (tmp);
446         }
447
448         if (show_time || show_date) {
449                 g_string_append (str, " -\n");
450
451                 gtk_text_buffer_get_end_iter (buffer, &iter);
452                 gtk_text_buffer_insert_with_tags_by_name (buffer,
453                                                           &iter,
454                                                           str->str, -1,
455                                                           "irc-time",
456                                                           NULL);
457
458                 empathy_chat_view_set_last_timestamp (view, timestamp);
459         }
460
461         g_string_free (str, TRUE);
462 }
463
464 static void
465 theme_irc_append_spacing (EmpathyTheme        *theme,
466                           EmpathyThemeContext *context,
467                           EmpathyChatView     *view)
468 {
469         GtkTextBuffer *buffer;
470         GtkTextIter    iter;
471
472         g_return_if_fail (EMPATHY_IS_THEME (theme));
473         g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
474
475         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
476
477         gtk_text_buffer_get_end_iter (buffer, &iter);
478         gtk_text_buffer_insert_with_tags_by_name (buffer,
479                                                   &iter,
480                                                   "\n",
481                                                   -1,
482                                                   "cut",
483                                                   "irc-spacing",
484                                                   NULL);
485 }
486