]> git.0d.be Git - empathy.git/blob - libempathy-gtk/gossip-theme-manager.c
[darcs-to-svn @ initial import]
[empathy.git] / libempathy-gtk / gossip-theme-manager.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2005-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  * Authors: Richard Hult <richard@imendio.com>
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include <glib/gi18n.h>
28 #include <gtk/gtk.h>
29
30 #include <libempathy/gossip-conf.h>
31 #include <libempathy/gossip-utils.h>
32
33 #include "gossip-chat-view.h"
34 #include "gossip-preferences.h"
35 #include "gossip-theme-manager.h"
36
37 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_THEME_MANAGER, GossipThemeManagerPriv))
38
39 typedef struct {
40         gchar    *name;
41         guint     name_notify_id;
42         guint     room_notify_id;
43
44         gboolean  show_avatars;
45         guint     show_avatars_notify_id;
46
47         gboolean  irc_style;
48 } GossipThemeManagerPriv;
49
50 static void        theme_manager_finalize                 (GObject            *object);
51 static void        theme_manager_notify_name_cb           (GossipConf         *conf,
52                                                            const gchar        *key,
53                                                            gpointer            user_data);
54 static void        theme_manager_notify_room_cb           (GossipConf         *conf,
55                                                            const gchar        *key,
56                                                            gpointer            user_data);
57 static void        theme_manager_notify_show_avatars_cb   (GossipConf         *conf,
58                                                            const gchar        *key,
59                                                            gpointer            user_data);
60 static void        theme_manager_ensure_tag_by_name       (GtkTextBuffer      *buffer,
61                                                            const gchar        *name);
62 static gboolean    theme_manager_ensure_theme_exists      (const gchar        *name);
63 static GtkTextTag *theme_manager_init_tag_by_name         (GtkTextTagTable    *table,
64                                                            const gchar        *name);
65 static void        theme_manager_add_tag                  (GtkTextTagTable    *table,
66                                                            GtkTextTag         *tag);
67 static void        theme_manager_fixup_tag_table          (GossipThemeManager *theme_manager,
68                                                            GossipChatView     *view);
69 static void        theme_manager_apply_theme_classic      (GossipThemeManager *manager,
70                                                            GossipChatView     *view);
71 static void        theme_manager_apply_theme_clean        (GossipThemeManager *manager,
72                                                            GossipChatView     *view);
73 static void        theme_manager_apply_theme_blue         (GossipThemeManager *manager,
74                                                            GossipChatView     *view);
75 static void        theme_manager_apply_theme              (GossipThemeManager *manager,
76                                                            GossipChatView     *view,
77                                                            const gchar        *name);
78
79 enum {
80         THEME_CHANGED,
81         LAST_SIGNAL
82 };
83
84 static guint signals[LAST_SIGNAL] = { 0 };
85
86 static const gchar *themes[] = {
87         "classic", N_("Classic"),
88         "simple", N_("Simple"),
89         "clean", N_("Clean"),
90         "blue", N_("Blue"),
91         NULL
92 };
93
94 G_DEFINE_TYPE (GossipThemeManager, gossip_theme_manager, G_TYPE_OBJECT);
95
96 static void
97 gossip_theme_manager_class_init (GossipThemeManagerClass *klass)
98 {
99         GObjectClass *object_class = G_OBJECT_CLASS (klass);
100
101         signals[THEME_CHANGED] =
102                 g_signal_new ("theme-changed",
103                               G_OBJECT_CLASS_TYPE (object_class),
104                               G_SIGNAL_RUN_LAST,
105                               0,
106                               NULL, NULL,
107                               g_cclosure_marshal_VOID__VOID,
108                               G_TYPE_NONE,
109                               0);
110
111         g_type_class_add_private (object_class, sizeof (GossipThemeManagerPriv));
112
113         object_class->finalize = theme_manager_finalize;
114 }
115
116 static void
117 gossip_theme_manager_init (GossipThemeManager *manager)
118 {
119         GossipThemeManagerPriv *priv;
120
121         priv = GET_PRIV (manager);
122
123         priv->name_notify_id =
124                 gossip_conf_notify_add (gossip_conf_get (),
125                                         GOSSIP_PREFS_CHAT_THEME,
126                                         theme_manager_notify_name_cb,
127                                         manager);
128
129         priv->room_notify_id =
130                 gossip_conf_notify_add (gossip_conf_get (),
131                                         GOSSIP_PREFS_CHAT_THEME_CHAT_ROOM,
132                                         theme_manager_notify_room_cb,
133                                         manager);
134
135         gossip_conf_get_string (gossip_conf_get (),
136                                 GOSSIP_PREFS_CHAT_THEME,
137                                 &priv->name);
138
139         /* Unused right now, but will be used soon. */
140         priv->show_avatars_notify_id =
141                 gossip_conf_notify_add (gossip_conf_get (),
142                                         GOSSIP_PREFS_UI_SHOW_AVATARS,
143                                         theme_manager_notify_show_avatars_cb,
144                                         manager);
145
146         gossip_conf_get_bool (gossip_conf_get (),
147                               GOSSIP_PREFS_UI_SHOW_AVATARS,
148                               &priv->show_avatars);
149 }
150
151 static void
152 theme_manager_finalize (GObject *object)
153 {
154         GossipThemeManagerPriv *priv;
155
156         priv = GET_PRIV (object);
157
158         gossip_conf_notify_remove (gossip_conf_get (), priv->name_notify_id);
159         gossip_conf_notify_remove (gossip_conf_get (), priv->room_notify_id);
160         gossip_conf_notify_remove (gossip_conf_get (), priv->show_avatars_notify_id);
161
162         g_free (priv->name);
163
164         G_OBJECT_CLASS (gossip_theme_manager_parent_class)->finalize (object);
165 }
166
167 static void
168 theme_manager_notify_name_cb (GossipConf  *conf,
169                               const gchar *key,
170                               gpointer     user_data)
171 {
172         GossipThemeManager     *manager;
173         GossipThemeManagerPriv *priv;
174         gchar                  *name;
175
176         manager = user_data;
177         priv = GET_PRIV (manager);
178
179         g_free (priv->name);
180
181         name = NULL;
182         if (!gossip_conf_get_string (conf, key, &name) ||
183             name == NULL || name[0] == 0) {
184                 priv->name = g_strdup ("classic");
185                 g_free (name);
186         } else {
187                 priv->name = name;
188         }
189
190         g_signal_emit (manager, signals[THEME_CHANGED], 0, NULL);
191 }
192
193 static void
194 theme_manager_notify_room_cb (GossipConf  *conf,
195                               const gchar *key,
196                               gpointer     user_data)
197 {
198         g_signal_emit (user_data, signals[THEME_CHANGED], 0, NULL);
199 }
200
201 static void
202 theme_manager_notify_show_avatars_cb (GossipConf  *conf,
203                                       const gchar *key,
204                                       gpointer     user_data)
205 {
206         GossipThemeManager     *manager;
207         GossipThemeManagerPriv *priv;
208         gboolean                value;
209
210         manager = user_data;
211         priv = GET_PRIV (manager);
212
213         if (!gossip_conf_get_bool (conf, key, &value)) {
214                 priv->show_avatars = FALSE;
215         } else {
216                 priv->show_avatars = value;
217         }
218 }
219
220 static void
221 theme_manager_ensure_tag_by_name (GtkTextBuffer *buffer,
222                                   const gchar   *name)
223 {
224         GtkTextTagTable *table;
225         GtkTextTag      *tag;
226
227         table = gtk_text_buffer_get_tag_table (buffer);
228         tag = gtk_text_tag_table_lookup (table, name);
229
230         if (!tag) {
231                 gtk_text_buffer_create_tag (buffer,
232                                             name,
233                                             NULL);
234         }
235 }
236
237 static gboolean
238 theme_manager_ensure_theme_exists (const gchar *name)
239 {
240         gint i;
241
242         if (G_STR_EMPTY (name)) {
243                 return FALSE;
244         }
245
246         for (i = 0; themes[i]; i += 2) {
247                 if (strcmp (themes[i], name) == 0) {
248                         return TRUE;
249                 }
250         }
251
252         return FALSE;
253 }
254
255 static GtkTextTag *
256 theme_manager_init_tag_by_name (GtkTextTagTable *table,
257                                 const gchar     *name)
258 {
259         GtkTextTag *tag;
260
261         tag = gtk_text_tag_table_lookup (table, name);
262
263         if (!tag) {
264                 return gtk_text_tag_new (name);
265         }
266
267         /* Clear the old values so that we don't affect the new theme. */
268         g_object_set (tag,
269                       "background-set", FALSE,
270                       "foreground-set", FALSE,
271                       "invisible-set", FALSE,
272                       "justification-set", FALSE,
273                       "paragraph-background-set", FALSE,
274                       "pixels-above-lines-set", FALSE,
275                       "pixels-below-lines-set", FALSE,
276                       "rise-set", FALSE,
277                       "scale-set", FALSE,
278                       "size-set", FALSE,
279                       "style-set", FALSE,
280                       "weight-set", FALSE,
281                       NULL);
282
283         return tag;
284 }
285
286 static void
287 theme_manager_add_tag (GtkTextTagTable *table,
288                        GtkTextTag      *tag)
289 {
290         gchar      *name;
291         GtkTextTag *check_tag;
292
293         g_object_get (tag, "name", &name, NULL);
294         check_tag = gtk_text_tag_table_lookup (table, name);
295         g_free (name);
296         if (check_tag) {
297                 return;
298         }
299
300         gtk_text_tag_table_add (table, tag);
301
302         g_object_unref (tag);
303 }
304
305 static void
306 theme_manager_fixup_tag_table (GossipThemeManager *theme_manager,
307                                GossipChatView     *view)
308 {
309         GtkTextBuffer *buffer;
310
311         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
312
313         /* "Fancy" style tags. */
314         theme_manager_ensure_tag_by_name (buffer, "fancy-header-self");
315         theme_manager_ensure_tag_by_name (buffer, "fancy-header-self-avatar");
316         theme_manager_ensure_tag_by_name (buffer, "fancy-avatar-self");
317         theme_manager_ensure_tag_by_name (buffer, "fancy-line-top-self");
318         theme_manager_ensure_tag_by_name (buffer, "fancy-line-bottom-self");
319         theme_manager_ensure_tag_by_name (buffer, "fancy-body-self");
320         theme_manager_ensure_tag_by_name (buffer, "fancy-action-self");
321         theme_manager_ensure_tag_by_name (buffer, "fancy-highlight-self");
322
323         theme_manager_ensure_tag_by_name (buffer, "fancy-header-other");
324         theme_manager_ensure_tag_by_name (buffer, "fancy-header-other-avatar");
325         theme_manager_ensure_tag_by_name (buffer, "fancy-avatar-other");
326         theme_manager_ensure_tag_by_name (buffer, "fancy-line-top-other");
327         theme_manager_ensure_tag_by_name (buffer, "fancy-line-bottom-other");
328         theme_manager_ensure_tag_by_name (buffer, "fancy-body-other");
329         theme_manager_ensure_tag_by_name (buffer, "fancy-action-other");
330         theme_manager_ensure_tag_by_name (buffer, "fancy-highlight-other");
331
332         theme_manager_ensure_tag_by_name (buffer, "fancy-spacing");
333         theme_manager_ensure_tag_by_name (buffer, "fancy-time");
334         theme_manager_ensure_tag_by_name (buffer, "fancy-event");
335         theme_manager_ensure_tag_by_name (buffer, "fancy-invite");
336         theme_manager_ensure_tag_by_name (buffer, "fancy-link");
337
338         /* IRC style tags. */
339         theme_manager_ensure_tag_by_name (buffer, "irc-nick-self");
340         theme_manager_ensure_tag_by_name (buffer, "irc-body-self");
341         theme_manager_ensure_tag_by_name (buffer, "irc-action-self");
342
343         theme_manager_ensure_tag_by_name (buffer, "irc-nick-other");
344         theme_manager_ensure_tag_by_name (buffer, "irc-body-other");
345         theme_manager_ensure_tag_by_name (buffer, "irc-action-other");
346
347         theme_manager_ensure_tag_by_name (buffer, "irc-nick-highlight");
348         theme_manager_ensure_tag_by_name (buffer, "irc-spacing");
349         theme_manager_ensure_tag_by_name (buffer, "irc-time");
350         theme_manager_ensure_tag_by_name (buffer, "irc-event");
351         theme_manager_ensure_tag_by_name (buffer, "irc-invite");
352         theme_manager_ensure_tag_by_name (buffer, "irc-link");
353 }
354
355 static void
356 theme_manager_apply_theme_classic (GossipThemeManager *manager,
357                                    GossipChatView     *view)
358 {
359         GossipThemeManagerPriv *priv;
360         GtkTextBuffer          *buffer;
361         GtkTextTagTable        *table;
362         GtkTextTag             *tag;
363
364         priv = GET_PRIV (manager);
365
366         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
367         table = gtk_text_buffer_get_tag_table (buffer);
368
369         priv->irc_style = TRUE;
370
371         tag = theme_manager_init_tag_by_name (table, "irc-spacing");
372         g_object_set (tag,
373                       "size", 2000,
374                       NULL);
375         theme_manager_add_tag (table, tag);
376
377         tag = theme_manager_init_tag_by_name (table, "irc-nick-self");
378         g_object_set (tag,
379                       "foreground", "sea green",
380                       NULL);
381         theme_manager_add_tag (table, tag);
382
383         tag = theme_manager_init_tag_by_name (table, "irc-body-self");
384         g_object_set (tag,
385                       /* To get the default theme color: */
386                       "foreground-set", FALSE,
387                       NULL);
388         theme_manager_add_tag (table, tag);
389
390         tag = theme_manager_init_tag_by_name (table, "irc-action-self");
391         g_object_set (tag,
392                       "foreground", "brown4",
393                       "style", PANGO_STYLE_ITALIC,
394                       NULL);
395         theme_manager_add_tag (table, tag);
396
397         tag = theme_manager_init_tag_by_name (table, "irc-nick-highlight");
398         g_object_set (tag,
399                       "foreground", "indian red",
400                       "weight", PANGO_WEIGHT_BOLD,
401                       NULL);
402         theme_manager_add_tag (table, tag);
403
404         tag = theme_manager_init_tag_by_name (table, "irc-nick-other");
405         g_object_set (tag,
406                       "foreground", "skyblue4",
407                       NULL);
408         theme_manager_add_tag (table, tag);
409
410         tag = theme_manager_init_tag_by_name (table, "irc-body-other");
411         g_object_set (tag,
412                       /* To get the default theme color: */
413                       "foreground-set", FALSE,
414                       NULL);
415         theme_manager_add_tag (table, tag);
416
417         tag = theme_manager_init_tag_by_name (table, "irc-action-other");
418         g_object_set (tag,
419                       "foreground", "brown4",
420                       "style", PANGO_STYLE_ITALIC,
421                       NULL);
422         theme_manager_add_tag (table, tag);
423
424         tag = theme_manager_init_tag_by_name (table, "irc-time");
425         g_object_set (tag,
426                       "foreground", "darkgrey",
427                       "justification", GTK_JUSTIFY_CENTER,
428                       NULL);
429         theme_manager_add_tag (table, tag);
430
431         tag = theme_manager_init_tag_by_name (table, "irc-event");
432         g_object_set (tag,
433                       "foreground", "PeachPuff4",
434                       "justification", GTK_JUSTIFY_LEFT,
435                       NULL);
436         theme_manager_add_tag (table, tag);
437
438         tag = theme_manager_init_tag_by_name (table, "irc-invite");
439         g_object_set (tag,
440                       "foreground", "sienna",
441                       NULL);
442         theme_manager_add_tag (table, tag);
443
444         tag = theme_manager_init_tag_by_name (table, "irc-link");
445         g_object_set (tag,
446                       "foreground", "steelblue",
447                       "underline", PANGO_UNDERLINE_SINGLE,
448                       NULL);
449         theme_manager_add_tag (table, tag);
450 }
451
452 static void
453 theme_manager_apply_theme_simple (GossipThemeManager *manager,
454                                   GossipChatView     *view)
455 {
456         GossipThemeManagerPriv *priv;
457         GtkTextBuffer          *buffer;
458         GtkTextTagTable        *table;
459         GtkTextTag             *tag;
460         GtkWidget              *widget;
461         GtkStyle               *style;
462
463         priv = GET_PRIV (manager);
464
465         widget = gtk_entry_new ();
466         style = gtk_widget_get_style (widget);
467         gtk_widget_destroy (widget);
468
469         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
470         table = gtk_text_buffer_get_tag_table (buffer);
471
472         priv->irc_style = FALSE;
473
474         tag = theme_manager_init_tag_by_name (table, "fancy-spacing");
475         g_object_set (tag,
476                       "size", 3000,
477                       NULL);
478         theme_manager_add_tag (table, tag);
479
480         tag = theme_manager_init_tag_by_name (table, "fancy-header-self");
481         g_object_set (tag,
482                       "weight", PANGO_WEIGHT_BOLD,
483                       NULL);
484         theme_manager_add_tag (table, tag);
485
486         tag = theme_manager_init_tag_by_name (table, "fancy-header-self-avatar");
487         theme_manager_add_tag (table, tag);
488
489         tag = theme_manager_init_tag_by_name (table, "fancy-avatar-self");
490         theme_manager_add_tag (table, tag);
491
492         tag = theme_manager_init_tag_by_name (table, "fancy-line-top-self");
493         g_object_set (tag,
494                       "size", 6 * PANGO_SCALE,
495                       NULL);
496         theme_manager_add_tag (table, tag);
497
498         tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-self");
499         g_object_set (tag,
500                       "size", 1,
501                       NULL);
502         theme_manager_add_tag (table, tag);
503
504         tag = theme_manager_init_tag_by_name (table, "fancy-body-self");
505         g_object_set (tag,
506                       "pixels-above-lines", 2,
507                       "pixels-below-lines", 2,
508                       NULL);
509         theme_manager_add_tag (table, tag);
510
511         tag = theme_manager_init_tag_by_name (table, "fancy-action-self");
512         g_object_set (tag,
513                       "foreground-gdk", &style->base[GTK_STATE_SELECTED],
514                       "style", PANGO_STYLE_ITALIC,
515                       "pixels-above-lines", 2,
516                       "pixels-below-lines", 2,
517                       NULL);
518         theme_manager_add_tag (table, tag);
519
520         tag = theme_manager_init_tag_by_name (table, "fancy-highlight-self");
521         g_object_set (tag,
522                       "weight", PANGO_WEIGHT_BOLD,
523                       "pixels-above-lines", 2,
524                       "pixels-below-lines", 2,
525                       NULL);
526         theme_manager_add_tag (table, tag);
527
528         tag = theme_manager_init_tag_by_name (table, "fancy-header-other");
529         g_object_set (tag,
530                       "weight", PANGO_WEIGHT_BOLD,
531                       NULL);
532         theme_manager_add_tag (table, tag);
533
534         tag = theme_manager_init_tag_by_name (table, "fancy-header-other-avatar");
535         theme_manager_add_tag (table, tag);
536
537         tag = theme_manager_init_tag_by_name (table, "fancy-avatar-other");
538         theme_manager_add_tag (table, tag);
539
540         tag = theme_manager_init_tag_by_name (table, "fancy-line-top-other");
541         g_object_set (tag,
542                       "size", 6 * PANGO_SCALE,
543                       NULL);
544         theme_manager_add_tag (table, tag);
545
546         tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-other");
547         g_object_set (tag,
548                       "size", 1,
549                       NULL);
550         theme_manager_add_tag (table, tag);
551
552         tag = theme_manager_init_tag_by_name (table, "fancy-body-other");
553         g_object_set (tag,
554                       "pixels-above-lines", 2,
555                       "pixels-below-lines", 2,
556                       NULL);
557         theme_manager_add_tag (table, tag);
558
559         tag = theme_manager_init_tag_by_name (table, "fancy-action-other");
560         g_object_set (tag,
561                       "foreground-gdk", &style->base[GTK_STATE_SELECTED],
562                       "style", PANGO_STYLE_ITALIC,
563                       "pixels-above-lines", 2,
564                       "pixels-below-lines", 2,
565                       NULL);
566         theme_manager_add_tag (table, tag);
567
568         tag = theme_manager_init_tag_by_name (table, "fancy-highlight-other");
569         g_object_set (tag,
570                       "weight", PANGO_WEIGHT_BOLD,
571                       "pixels-above-lines", 2,
572                       "pixels-below-lines", 2,
573                       NULL);
574         theme_manager_add_tag (table, tag);
575
576         tag = theme_manager_init_tag_by_name (table, "fancy-time");
577         g_object_set (tag,
578                       "foreground", "darkgrey",
579                       "justification", GTK_JUSTIFY_CENTER,
580                       NULL);
581         theme_manager_add_tag (table, tag);
582
583         tag = theme_manager_init_tag_by_name (table, "fancy-event");
584         g_object_set (tag,
585                       "foreground", "darkgrey",
586                       "justification", GTK_JUSTIFY_LEFT,
587                       NULL);
588         theme_manager_add_tag (table, tag);
589
590         tag = theme_manager_init_tag_by_name (table, "fancy-invite");
591         g_object_set (tag,
592                       "foreground", "darkgrey",
593                       NULL);
594         theme_manager_add_tag (table, tag);
595
596         tag = theme_manager_init_tag_by_name (table, "fancy-link");
597         g_object_set (tag,
598                       "foreground-gdk", &style->base[GTK_STATE_SELECTED],
599                       "underline", PANGO_UNDERLINE_SINGLE,
600                       NULL);
601         theme_manager_add_tag (table, tag);
602 }
603
604 static void
605 theme_manager_apply_theme_clean (GossipThemeManager *manager,
606                                  GossipChatView     *view)
607 {
608         GossipThemeManagerPriv *priv;
609         GtkTextBuffer          *buffer;
610         GtkTextTagTable        *table;
611         GtkTextTag             *tag;
612
613         priv = GET_PRIV (manager);
614
615         /* Inherit the simple theme. */
616         theme_manager_apply_theme_simple (manager, view);
617
618 #define ELEGANT_HEAD "#efefdf"
619 #define ELEGANT_LINE "#e3e3d3"
620
621         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
622         table = gtk_text_buffer_get_tag_table (buffer);
623
624         tag = theme_manager_init_tag_by_name (table, "fancy-spacing");
625         g_object_set (tag,
626                       "size", PANGO_SCALE * 10,
627                       NULL);
628
629         tag = theme_manager_init_tag_by_name (table, "fancy-header-self");
630         g_object_set (tag,
631                       "foreground", "black",
632                       "weight", PANGO_WEIGHT_BOLD,
633                       "paragraph-background", ELEGANT_HEAD,
634                       "pixels-above-lines", 2,
635                       "pixels-below-lines", 2,
636                       NULL);
637
638         tag = theme_manager_init_tag_by_name (table, "fancy-avatar-self");
639         g_object_set (tag,
640                       "paragraph-background", ELEGANT_HEAD,
641                       "pixels-above-lines", 2,
642                       "pixels-below-lines", 2,
643                       NULL);
644
645         tag = theme_manager_init_tag_by_name (table, "fancy-line-top-self");
646         g_object_set (tag,
647                       "size", 1 * PANGO_SCALE,
648                       "paragraph-background", ELEGANT_LINE,
649                       NULL);
650
651         tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-self");
652         g_object_set (tag,
653                       "size", 1 * PANGO_SCALE,
654                       NULL);
655
656         tag = theme_manager_init_tag_by_name (table, "fancy-action-self");
657         g_object_set (tag,
658                       "foreground", "brown4",
659                       "style", PANGO_STYLE_ITALIC,
660                       NULL);
661
662         tag = theme_manager_init_tag_by_name (table, "fancy-highlight-self");
663         g_object_set (tag,
664                       "foreground", "black",
665                       "weight", PANGO_WEIGHT_BOLD,
666                       NULL);
667
668         tag = theme_manager_init_tag_by_name (table, "fancy-header-other");
669         g_object_set (tag,
670                       "foreground", "black",
671                       "weight", PANGO_WEIGHT_BOLD,
672                       "paragraph-background", ELEGANT_HEAD,
673                       "pixels-above-lines", 2,
674                       "pixels-below-lines", 2,
675                       NULL);
676
677         tag = theme_manager_init_tag_by_name (table, "fancy-avatar-other");
678         g_object_set (tag,
679                       "paragraph-background", ELEGANT_HEAD,
680                       "pixels-above-lines", 2,
681                       "pixels-below-lines", 2,
682                       NULL);
683
684         tag = theme_manager_init_tag_by_name (table, "fancy-line-top-other");
685         g_object_set (tag,
686                       "size", 1 * PANGO_SCALE,
687                       "paragraph-background", ELEGANT_LINE,
688                       NULL);
689
690         tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-other");
691         g_object_set (tag,
692                       "size", 1 * PANGO_SCALE,
693                       NULL);
694
695         tag = theme_manager_init_tag_by_name (table, "fancy-action-other");
696         g_object_set (tag,
697                       "foreground", "brown4",
698                       "style", PANGO_STYLE_ITALIC,
699                       NULL);
700
701         tag = theme_manager_init_tag_by_name (table, "fancy-time");
702         g_object_set (tag,
703                       "foreground", "darkgrey",
704                       "justification", GTK_JUSTIFY_CENTER,
705                       NULL);
706
707         tag = theme_manager_init_tag_by_name (table, "fancy-event");
708         g_object_set (tag,
709                       "foreground", "darkgrey",
710                       "justification", GTK_JUSTIFY_LEFT,
711                       NULL);
712
713         tag = theme_manager_init_tag_by_name (table, "fancy-invite");
714         g_object_set (tag,
715                       "foreground", "sienna",
716                       NULL);
717
718         tag = theme_manager_init_tag_by_name (table, "fancy-link");
719         g_object_set (tag,
720                       "foreground", "#49789e",
721                       "underline", PANGO_UNDERLINE_SINGLE,
722                       NULL);
723 }
724
725 static void
726 theme_manager_apply_theme_blue (GossipThemeManager *manager,
727                                 GossipChatView     *view)
728 {
729         GossipThemeManagerPriv *priv;
730         GtkTextBuffer          *buffer;
731         GtkTextTagTable        *table;
732         GtkTextTag             *tag;
733
734         priv = GET_PRIV (manager);
735
736         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
737         table = gtk_text_buffer_get_tag_table (buffer);
738
739         priv->irc_style = FALSE;
740
741 #define BLUE_BODY_SELF "#dcdcdc"
742 #define BLUE_HEAD_SELF "#b9b9b9"
743 #define BLUE_LINE_SELF "#aeaeae"
744
745 #define BLUE_BODY_OTHER "#adbdc8"
746 #define BLUE_HEAD_OTHER "#88a2b4"
747 #define BLUE_LINE_OTHER "#7f96a4"
748
749         tag = theme_manager_init_tag_by_name (table, "fancy-spacing");
750         g_object_set (tag,
751                       "size", 3000,
752                       NULL);
753         theme_manager_add_tag (table, tag);
754
755         tag = theme_manager_init_tag_by_name (table, "fancy-header-self");
756         g_object_set (tag,
757                       "foreground", "black",
758                       "paragraph-background", BLUE_HEAD_SELF,
759                       "weight", PANGO_WEIGHT_BOLD,
760                       "pixels-above-lines", 2,
761                       "pixels-below-lines", 2,
762                       NULL);
763         theme_manager_add_tag (table, tag);
764
765         tag = theme_manager_init_tag_by_name (table, "fancy-header-self-avatar");
766         theme_manager_add_tag (table, tag);
767
768         tag = theme_manager_init_tag_by_name (table, "fancy-avatar-self");
769         g_object_set (tag,
770                       "paragraph-background", BLUE_HEAD_SELF,
771                       NULL);
772         theme_manager_add_tag (table, tag);
773
774         tag = theme_manager_init_tag_by_name (table, "fancy-line-top-self");
775         g_object_set (tag,
776                       "size", 1,
777                       "paragraph-background", BLUE_LINE_SELF,
778                       NULL);
779         theme_manager_add_tag (table, tag);
780
781         tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-self");
782         g_object_set (tag,
783                       "size", 1,
784                       "paragraph-background", BLUE_LINE_SELF,
785                       NULL);
786         theme_manager_add_tag (table, tag);
787
788         tag = theme_manager_init_tag_by_name (table, "fancy-body-self");
789         g_object_set (tag,
790                       "foreground", "black",
791                       "paragraph-background", BLUE_BODY_SELF,
792                       "pixels-above-lines", 4,
793                       NULL);
794         theme_manager_add_tag (table, tag);
795
796         tag = theme_manager_init_tag_by_name (table, "fancy-action-self");
797         g_object_set (tag,
798                       "foreground", "brown4",
799                       "style", PANGO_STYLE_ITALIC,
800                       "paragraph-background", BLUE_BODY_SELF,
801                       "pixels-above-lines", 4,
802                       NULL);
803         theme_manager_add_tag (table, tag);
804
805         tag = theme_manager_init_tag_by_name (table, "fancy-highlight-self");
806         g_object_set (tag,
807                       "foreground", "black",
808                       "weight", PANGO_WEIGHT_BOLD,
809                       "paragraph-background", BLUE_BODY_SELF,
810                       "pixels-above-lines", 4,
811                       NULL);
812         theme_manager_add_tag (table, tag);
813
814         tag = theme_manager_init_tag_by_name (table, "fancy-header-other");
815         g_object_set (tag,
816                       "foreground", "black",
817                       "paragraph-background", BLUE_HEAD_OTHER,
818                       "weight", PANGO_WEIGHT_BOLD,
819                       "pixels-above-lines", 2,
820                       "pixels-below-lines", 2,
821                       NULL);
822         theme_manager_add_tag (table, tag);
823
824         tag = theme_manager_init_tag_by_name (table, "fancy-header-other-avatar");
825         theme_manager_add_tag (table, tag);
826
827         tag = theme_manager_init_tag_by_name (table, "fancy-avatar-other");
828         g_object_set (tag,
829                       "paragraph-background", BLUE_HEAD_OTHER,
830                       NULL);
831         theme_manager_add_tag (table, tag);
832
833         tag = theme_manager_init_tag_by_name (table, "fancy-line-top-other");
834         g_object_set (tag,
835                       "size", 1,
836                       "paragraph-background", BLUE_LINE_OTHER,
837                       NULL);
838         theme_manager_add_tag (table, tag);
839
840         tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-other");
841         g_object_set (tag,
842                       "size", 1,
843                       "paragraph-background", BLUE_LINE_OTHER,
844                       NULL);
845         theme_manager_add_tag (table, tag);
846
847         tag = theme_manager_init_tag_by_name (table, "fancy-body-other");
848         g_object_set (tag,
849                       "foreground", "black",
850                       "paragraph-background", BLUE_BODY_OTHER,
851                       "pixels-above-lines", 4,
852                       NULL);
853         theme_manager_add_tag (table, tag);
854
855         tag = theme_manager_init_tag_by_name (table, "fancy-action-other");
856         g_object_set (tag,
857                       "foreground", "brown4",
858                       "style", PANGO_STYLE_ITALIC,
859                       "paragraph-background", BLUE_BODY_OTHER,
860                       "pixels-above-lines", 4,
861                       NULL);
862         theme_manager_add_tag (table, tag);
863
864         tag = theme_manager_init_tag_by_name (table, "fancy-highlight-other");
865         g_object_set (tag,
866                       "foreground", "black",
867                       "weight", PANGO_WEIGHT_BOLD,
868                       "paragraph-background", BLUE_BODY_OTHER,
869                       "pixels-above-lines", 4,
870                       NULL);
871         theme_manager_add_tag (table, tag);
872
873         tag = theme_manager_init_tag_by_name (table, "fancy-time");
874         g_object_set (tag,
875                       "foreground", "darkgrey",
876                       "justification", GTK_JUSTIFY_CENTER,
877                       NULL);
878         theme_manager_add_tag (table, tag);
879
880         tag = theme_manager_init_tag_by_name (table, "fancy-event");
881         g_object_set (tag,
882                       "foreground", BLUE_LINE_OTHER,
883                       "justification", GTK_JUSTIFY_LEFT,
884                       NULL);
885         theme_manager_add_tag (table, tag);
886
887         tag = theme_manager_init_tag_by_name (table, "fancy-invite");
888         g_object_set (tag,
889                       "foreground", "sienna",
890                       NULL);
891         theme_manager_add_tag (table, tag);
892
893         tag = theme_manager_init_tag_by_name (table, "fancy-link");
894         g_object_set (tag,
895                       "foreground", "#49789e",
896                       "underline", PANGO_UNDERLINE_SINGLE,
897                       NULL);
898         theme_manager_add_tag (table, tag);
899 }
900
901 static void
902 theme_manager_apply_theme (GossipThemeManager *manager,
903                            GossipChatView     *view,
904                            const gchar        *name)
905 {
906         GossipThemeManagerPriv *priv;
907         gint                    margin;
908
909         priv = GET_PRIV (manager);
910
911         /* Make sure all tags are present. Note: not useful now but when we have
912          * user defined theme it will be.
913          */
914         theme_manager_fixup_tag_table (manager, view);
915
916         if (theme_manager_ensure_theme_exists (name)) {
917                 if (strcmp (name, "clean") == 0) {
918                         theme_manager_apply_theme_clean (manager, view);
919                         margin = 3;
920                 }
921                 else if (strcmp (name, "simple") == 0) {
922                         theme_manager_apply_theme_simple (manager, view);
923                         margin = 3;
924                 }
925                 else if (strcmp (name, "blue") == 0) {
926                         theme_manager_apply_theme_blue (manager, view);
927                         margin = 0;
928                 } else {
929                         theme_manager_apply_theme_classic (manager, view);
930                         margin = 3;
931                 }
932         } else {
933                 theme_manager_apply_theme_classic (manager, view);
934                 margin = 3;
935         }
936
937         gossip_chat_view_set_margin (view, margin);
938         gossip_chat_view_set_irc_style (view, priv->irc_style);
939 }
940
941 GossipThemeManager *
942 gossip_theme_manager_get (void)
943 {
944         static GossipThemeManager *manager = NULL;
945
946         if (!manager) {
947                 manager = g_object_new (GOSSIP_TYPE_THEME_MANAGER, NULL);
948         }
949
950         return manager;
951 }
952
953 const gchar **
954 gossip_theme_manager_get_themes (void)
955 {
956         return themes;
957 }
958
959 void
960 gossip_theme_manager_apply (GossipThemeManager *manager,
961                             GossipChatView     *view,
962                             const gchar        *name)
963 {
964         GossipThemeManagerPriv *priv;
965
966         priv = GET_PRIV (manager);
967
968         theme_manager_apply_theme (manager, view, name);
969 }
970
971 void
972 gossip_theme_manager_apply_saved (GossipThemeManager *manager,
973                                   GossipChatView     *view)
974 {
975         GossipThemeManagerPriv *priv;
976
977         priv = GET_PRIV (manager);
978
979         theme_manager_apply_theme (manager, view, priv->name);
980 }
981
982 /* FIXME: A bit ugly. We should probably change the scheme so that instead of
983  * the manager signalling, views are registered and applied to automatically.
984  */
985 void
986 gossip_theme_manager_update_show_avatars (GossipThemeManager *manager,
987                                           GossipChatView     *view,
988                                           gboolean            show)
989 {
990         GossipThemeManagerPriv *priv;
991         GtkTextBuffer          *buffer;
992         GtkTextTagTable        *table;
993         GtkTextTag             *tag_text_self, *tag_text_other;
994         GtkTextTag             *tag_image_self, *tag_image_other;
995
996         priv = GET_PRIV (manager);
997
998         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
999         table = gtk_text_buffer_get_tag_table (buffer);
1000
1001         tag_text_self = gtk_text_tag_table_lookup (table, "fancy-header-self-avatar");
1002         tag_text_other = gtk_text_tag_table_lookup (table, "fancy-header-other-avatar");
1003
1004         tag_image_self = gtk_text_tag_table_lookup (table, "fancy-avatar-self");
1005         tag_image_other = gtk_text_tag_table_lookup (table, "fancy-avatar-other");
1006
1007         if (!show) {
1008                 g_object_set (tag_text_self,
1009                               "rise", 0,
1010                               NULL);
1011                 g_object_set (tag_text_other,
1012                               "rise", 0,
1013                               NULL);
1014                 g_object_set (tag_image_self,
1015                               "invisible", TRUE,
1016                               NULL);
1017                 g_object_set (tag_image_other,
1018                               "invisible", TRUE,
1019                               NULL);
1020         } else {
1021                 GtkTextAttributes *attrs;
1022                 gint               size;
1023                 gint               rise;
1024
1025                 attrs = gtk_text_view_get_default_attributes (GTK_TEXT_VIEW (view));
1026                 size = pango_font_description_get_size (attrs->font);
1027                 rise = MAX (0, (32 * PANGO_SCALE - size) / 2.0);
1028
1029                 g_object_set (tag_text_self,
1030                               "rise", rise,
1031                               NULL);
1032                 g_object_set (tag_text_other,
1033                               "rise", rise,
1034                               NULL);
1035                 g_object_set (tag_image_self,
1036                               "invisible", FALSE,
1037                               NULL);
1038                 g_object_set (tag_image_other,
1039                               "invisible", FALSE,
1040                               NULL);
1041
1042                 gtk_text_attributes_unref (attrs);
1043         }
1044 }
1045