]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-theme.c
Updated Basque translation.
[empathy.git] / libempathy-gtk / empathy-theme.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 #include <glib/gi18n.h>
25 #include <gtk/gtk.h>
26
27 #include <libempathy/empathy-utils.h>
28
29 #include "empathy-chat.h"
30 #include "empathy-conf.h"
31 #include "empathy-theme.h"
32 #include "empathy-smiley-manager.h"
33
34 /* Number of seconds between timestamps when using normal mode, 5 minutes. */
35 #define TIMESTAMP_INTERVAL 300
36
37 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTheme)
38 typedef struct {
39         EmpathySmileyManager *smiley_manager;
40         gboolean show_avatars;
41 } EmpathyThemePriv;
42
43 static void         theme_finalize            (GObject            *object);
44 static void         theme_get_property        (GObject            *object,
45                                                guint               param_id,
46                                                GValue             *value,
47                                                GParamSpec         *pspec);
48 static void         theme_set_property        (GObject            *object,
49                                                guint               param_id,
50                                                const GValue       *value,
51                                                GParamSpec         *pspec);
52
53
54 G_DEFINE_TYPE (EmpathyTheme, empathy_theme, G_TYPE_OBJECT);
55
56 enum {
57         PROP_0,
58         PROP_SHOW_AVATARS
59 };
60
61 static void
62 empathy_theme_class_init (EmpathyThemeClass *class)
63 {
64         GObjectClass *object_class;
65
66         object_class = G_OBJECT_CLASS (class);
67
68         object_class->finalize     = theme_finalize;
69         object_class->get_property = theme_get_property;
70         object_class->set_property = theme_set_property;
71
72         class->update_view      = NULL;
73         class->append_message   = NULL;
74         class->append_event     = NULL;
75         class->append_timestamp = NULL;
76         class->append_spacing   = NULL;
77
78         g_object_class_install_property (object_class,
79                                          PROP_SHOW_AVATARS,
80                                          g_param_spec_boolean ("show-avatars",
81                                                                "", "",
82                                                                TRUE,
83                                                                G_PARAM_READWRITE));
84
85         g_type_class_add_private (object_class, sizeof (EmpathyThemePriv));
86 }
87
88 static void
89 empathy_theme_init (EmpathyTheme *theme)
90 {
91         EmpathyThemePriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (theme,
92                 EMPATHY_TYPE_THEME, EmpathyThemePriv);
93
94         theme->priv = priv;
95         priv->smiley_manager = empathy_smiley_manager_new ();
96 }
97
98 static void
99 theme_finalize (GObject *object)
100 {
101         EmpathyThemePriv *priv;
102
103         priv = GET_PRIV (object);
104
105         if (priv->smiley_manager) {
106                 g_object_unref (priv->smiley_manager);
107         }
108
109         (G_OBJECT_CLASS (empathy_theme_parent_class)->finalize) (object);
110 }
111
112 static void
113 theme_get_property (GObject    *object,
114                     guint       param_id,
115                     GValue     *value,
116                     GParamSpec *pspec)
117 {
118         EmpathyThemePriv *priv;
119
120         priv = GET_PRIV (object);
121
122         switch (param_id) {
123         case PROP_SHOW_AVATARS:
124                 g_value_set_boolean (value, priv->show_avatars);
125                 break;
126         default:
127                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
128                 break;
129         }
130 }
131
132 static void
133 theme_set_property (GObject      *object,
134                     guint         param_id,
135                     const GValue *value,
136                     GParamSpec   *pspec)
137 {
138         EmpathyThemePriv *priv;
139
140         priv = GET_PRIV (object);
141
142         switch (param_id) {
143         case PROP_SHOW_AVATARS:
144                 empathy_theme_set_show_avatars (EMPATHY_THEME (object),
145                                                 g_value_get_boolean (value));
146                 break;
147         default:
148                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
149                 break;
150         }
151 }
152
153 void
154 empathy_theme_maybe_append_date_and_time (EmpathyTheme        *theme,
155                                          EmpathyChatView     *view,
156                                          EmpathyMessage      *message)
157 {
158         time_t    timestamp;
159         GDate    *date, *last_date;
160         gboolean  append_date, append_time;
161
162         date = empathy_message_get_date_and_time (message, &timestamp);
163
164         last_date = g_date_new ();
165         g_date_set_time_t (last_date, empathy_chat_view_get_last_timestamp (view));
166
167         append_date = FALSE;
168         append_time = FALSE;
169
170         if (g_date_compare (date, last_date) > 0) {
171                 append_date = TRUE;
172                 append_time = TRUE;
173         }
174         
175         g_date_free (last_date);
176         g_date_free (date);
177
178         if (empathy_chat_view_get_last_timestamp (view) + TIMESTAMP_INTERVAL < timestamp) {
179                 append_time = TRUE;
180         }
181
182         if (append_time || append_date) {
183                 empathy_theme_append_timestamp (theme, view, message,
184                                                append_date, append_time);
185         }
186 }
187
188 void
189 empathy_theme_update_view (EmpathyTheme    *theme,
190                            EmpathyChatView *view)
191 {
192         if (!EMPATHY_THEME_GET_CLASS(theme)->update_view) {
193                 g_error ("Theme must override update_view");
194         }
195
196         return EMPATHY_THEME_GET_CLASS(theme)->update_view (theme, view);
197 }
198
199 void
200 empathy_theme_append_message (EmpathyTheme        *theme,
201                              EmpathyChatView     *view,
202                              EmpathyMessage      *message)
203 {
204         if (!EMPATHY_THEME_GET_CLASS(theme)->append_message) {
205                 g_warning ("Theme should override append_message");
206                 return;
207         }
208
209         EMPATHY_THEME_GET_CLASS(theme)->append_message (theme, view, message);
210 }
211
212 static void
213 theme_insert_text_with_emoticons (GtkTextBuffer *buf,
214                                   GtkTextIter   *iter,
215                                   const gchar   *str,
216                                   EmpathySmileyManager *smiley_manager)
217 {
218         gboolean             use_smileys = FALSE;
219         GSList              *smileys, *l;
220
221         empathy_conf_get_bool (empathy_conf_get (),
222                               EMPATHY_PREFS_CHAT_SHOW_SMILEYS,
223                               &use_smileys);
224
225         if (!use_smileys) {
226                 gtk_text_buffer_insert (buf, iter, str, -1);
227                 return;
228         }
229
230         smileys = empathy_smiley_manager_parse (smiley_manager, str);
231         for (l = smileys; l; l = l->next) {
232                 EmpathySmiley *smiley;
233
234                 smiley = l->data;
235                 if (smiley->pixbuf) {
236                         gtk_text_buffer_insert_pixbuf (buf, iter, smiley->pixbuf);
237                 } else {
238                         gtk_text_buffer_insert (buf, iter, smiley->str, -1);
239                 }
240                 empathy_smiley_free (smiley);
241         }
242         g_slist_free (smileys);
243 }
244
245 void
246 empathy_theme_append_text (EmpathyTheme        *theme,
247                           EmpathyChatView     *view,
248                           const gchar        *body,
249                           const gchar        *tag,
250                           const gchar        *link_tag)
251 {
252         EmpathyThemePriv *priv;
253         GtkTextBuffer   *buffer;
254         GtkTextIter      start_iter, end_iter;
255         GtkTextMark     *mark;
256         GtkTextIter      iter;
257         gint             num_matches, i;
258         GArray          *start, *end;
259
260         priv = GET_PRIV (theme);
261         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
262
263         gtk_text_buffer_get_end_iter (buffer, &start_iter);
264         mark = gtk_text_buffer_create_mark (buffer, NULL, &start_iter, TRUE);
265
266         start = g_array_new (FALSE, FALSE, sizeof (gint));
267         end = g_array_new (FALSE, FALSE, sizeof (gint));
268
269         num_matches = empathy_regex_match (EMPATHY_REGEX_ALL, body, start, end);
270
271         if (num_matches == 0) {
272                 gtk_text_buffer_get_end_iter (buffer, &iter);
273                 theme_insert_text_with_emoticons (buffer, &iter, body, priv->smiley_manager);
274         } else {
275                 gint   last = 0;
276                 gint   s = 0, e = 0;
277                 gchar *tmp;
278
279                 for (i = 0; i < num_matches; i++) {
280                         s = g_array_index (start, gint, i);
281                         e = g_array_index (end, gint, i);
282
283                         if (s > last) {
284                                 tmp = empathy_substring (body, last, s);
285
286                                 gtk_text_buffer_get_end_iter (buffer, &iter);
287                                 theme_insert_text_with_emoticons (buffer,
288                                                                   &iter,
289                                                                   tmp,
290                                                                   priv->smiley_manager);
291                                 g_free (tmp);
292                         }
293
294                         tmp = empathy_substring (body, s, e);
295
296                         gtk_text_buffer_get_end_iter (buffer, &iter);
297                         if (!link_tag) {
298                                 gtk_text_buffer_insert (buffer, &iter,
299                                                         tmp, -1);
300                         } {
301                                 gtk_text_buffer_insert_with_tags_by_name (buffer,
302                                                                           &iter,
303                                                                           tmp,
304                                                                           -1,
305                                                                           link_tag,
306                                                                           "link",
307                                                                           NULL);
308                         }
309
310                         g_free (tmp);
311
312                         last = e;
313                 }
314
315                 if (e < strlen (body)) {
316                         tmp = empathy_substring (body, e, strlen (body));
317
318                         gtk_text_buffer_get_end_iter (buffer, &iter);
319                         theme_insert_text_with_emoticons (buffer,
320                                                           &iter,
321                                                           tmp,
322                                                           priv->smiley_manager);
323                         g_free (tmp);
324                 }
325         }
326
327         g_array_free (start, TRUE);
328         g_array_free (end, TRUE);
329
330         gtk_text_buffer_get_end_iter (buffer, &iter);
331         gtk_text_buffer_insert (buffer, &iter, "\n", 1);
332
333         /* Apply the style to the inserted text. */
334         gtk_text_buffer_get_iter_at_mark (buffer, &start_iter, mark);
335         gtk_text_buffer_get_end_iter (buffer, &end_iter);
336
337         gtk_text_buffer_apply_tag_by_name (buffer,
338                                            tag,
339                                            &start_iter,
340                                            &end_iter);
341
342         gtk_text_buffer_delete_mark (buffer, mark);
343 }
344
345 void 
346 empathy_theme_append_event (EmpathyTheme        *theme,
347                            EmpathyChatView     *view,
348                            const gchar        *str)
349 {
350         if (!EMPATHY_THEME_GET_CLASS(theme)->append_event) {
351                 return;
352         }
353
354         EMPATHY_THEME_GET_CLASS(theme)->append_event (theme, view, str);
355 }
356
357 void
358 empathy_theme_append_spacing (EmpathyTheme        *theme, 
359                              EmpathyChatView     *view)
360 {
361         if (!EMPATHY_THEME_GET_CLASS(theme)->append_spacing) {
362                 return;
363         }
364
365         EMPATHY_THEME_GET_CLASS(theme)->append_spacing (theme, view);
366 }
367
368
369 void 
370 empathy_theme_append_timestamp (EmpathyTheme        *theme,
371                                EmpathyChatView     *view,
372                                EmpathyMessage      *message,
373                                gboolean            show_date,
374                                gboolean            show_time)
375 {
376         if (!EMPATHY_THEME_GET_CLASS(theme)->append_timestamp) {
377                 return;
378         }
379
380         EMPATHY_THEME_GET_CLASS(theme)->append_timestamp (theme, view,
381                                                          message, show_date,
382                                                          show_time);
383 }
384
385 gboolean
386 empathy_theme_get_show_avatars (EmpathyTheme *theme)
387 {
388         EmpathyThemePriv *priv;
389
390         g_return_val_if_fail (EMPATHY_IS_THEME (theme), FALSE);
391
392         priv = GET_PRIV (theme);
393
394         return priv->show_avatars;
395 }
396
397 void
398 empathy_theme_set_show_avatars (EmpathyTheme *theme, gboolean show)
399 {
400         EmpathyThemePriv *priv;
401
402         g_return_if_fail (EMPATHY_IS_THEME (theme));
403
404         priv = GET_PRIV (theme);
405
406         priv->show_avatars = show;
407
408         g_object_notify (G_OBJECT (theme), "show-avatars");
409 }
410