aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Claessens <xclaesse@src.gnome.org>2007-12-21 00:39:49 +0800
committerXavier Claessens <xclaesse@src.gnome.org>2007-12-21 00:39:49 +0800
commit63e82d2437ba18c31876defafb691422862fc91b (patch)
treebccd4385c38e6d7b2345a944b2d797cf0eaaeddf
parent94d5a22a766d6ad184a1ea9ae6468a875e847312 (diff)
downloadgsoc2013-empathy-63e82d2437ba18c31876defafb691422862fc91b.tar
gsoc2013-empathy-63e82d2437ba18c31876defafb691422862fc91b.tar.gz
gsoc2013-empathy-63e82d2437ba18c31876defafb691422862fc91b.tar.bz2
gsoc2013-empathy-63e82d2437ba18c31876defafb691422862fc91b.tar.lz
gsoc2013-empathy-63e82d2437ba18c31876defafb691422862fc91b.tar.xz
gsoc2013-empathy-63e82d2437ba18c31876defafb691422862fc91b.tar.zst
gsoc2013-empathy-63e82d2437ba18c31876defafb691422862fc91b.zip
New chat theme engine imported from Gossip (Daniel Gryniewicz, Xavier Claessens).
svn path=/trunk/; revision=494
-rw-r--r--libempathy-gtk/Makefile.am8
-rw-r--r--libempathy-gtk/empathy-chat-view.c932
-rw-r--r--libempathy-gtk/empathy-chat-view.h27
-rw-r--r--libempathy-gtk/empathy-theme-boxes.c1036
-rw-r--r--libempathy-gtk/empathy-theme-boxes.h55
-rw-r--r--libempathy-gtk/empathy-theme-irc.c486
-rw-r--r--libempathy-gtk/empathy-theme-irc.h53
-rw-r--r--libempathy-gtk/empathy-theme-manager.c798
-rw-r--r--libempathy-gtk/empathy-theme-manager.h7
-rw-r--r--libempathy-gtk/empathy-theme-utils.c90
-rw-r--r--libempathy-gtk/empathy-theme-utils.h40
-rw-r--r--libempathy-gtk/empathy-theme.c475
-rw-r--r--libempathy-gtk/empathy-theme.h132
-rw-r--r--libempathy/empathy-marshal.list1
-rw-r--r--libempathy/empathy-message.c20
-rw-r--r--libempathy/empathy-message.h2
16 files changed, 2669 insertions, 1493 deletions
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index 2e9966536..494e3c4ce 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -32,7 +32,11 @@ libempathy_gtk_la_SOURCES = \
empathy-contact-list-store.c \
empathy-contact-list-view.c \
empathy-preferences.c \
+ empathy-theme.c \
+ empathy-theme-boxes.c \
+ empathy-theme-irc.c \
empathy-theme-manager.c \
+ empathy-theme-utils.c \
empathy-smiley-manager.c \
empathy-chat-window.c \
empathy-chat.c \
@@ -85,7 +89,11 @@ libempathy_gtk_headers = \
empathy-contact-list-store.h \
empathy-contact-list-view.h \
empathy-preferences.h \
+ empathy-theme.h \
+ empathy-theme-boxes.h \
+ empathy-theme-irc.h \
empathy-theme-manager.h \
+ empathy-theme-utils.h \
empathy-smiley-manager.h \
empathy-chat-window.h \
empathy-chat.h \
diff --git a/libempathy-gtk/empathy-chat-view.c b/libempathy-gtk/empathy-chat-view.c
index 9f10f024f..947281590 100644
--- a/libempathy-gtk/empathy-chat-view.c
+++ b/libempathy-gtk/empathy-chat-view.c
@@ -64,21 +64,12 @@
#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_CHAT_VIEW, EmpathyChatViewPriv))
-typedef enum {
- BLOCK_TYPE_NONE,
- BLOCK_TYPE_SELF,
- BLOCK_TYPE_OTHER,
- BLOCK_TYPE_EVENT,
- BLOCK_TYPE_TIME,
- BLOCK_TYPE_INVITE
-} BlockType;
-
struct _EmpathyChatViewPriv {
- EmpathySmileyManager *smiley_manager;
-
GtkTextBuffer *buffer;
- gboolean irc_style;
+ EmpathyTheme *theme;
+ gpointer theme_context;
+
time_t last_timestamp;
BlockType last_block_type;
@@ -136,32 +127,11 @@ static void chat_view_copy_address_cb (GtkMenuItem *
const gchar *url);
static void chat_view_clear_view_cb (GtkMenuItem *menuitem,
EmpathyChatView *view);
-static void chat_view_insert_text_with_emoticons (EmpathyChatView *view,
- GtkTextIter *iter,
- const gchar *str);
static gboolean chat_view_is_scrolled_down (EmpathyChatView *view);
static void chat_view_theme_changed_cb (EmpathyThemeManager *manager,
EmpathyChatView *view);
-static void chat_view_maybe_append_date_and_time (EmpathyChatView *view,
- EmpathyMessage *msg);
-static void chat_view_append_spacing (EmpathyChatView *view);
-static void chat_view_append_text (EmpathyChatView *view,
- const gchar *body,
- const gchar *tag);
-static void chat_view_maybe_append_fancy_header (EmpathyChatView *view,
- EmpathyMessage *msg);
-static void chat_view_append_irc_action (EmpathyChatView *view,
- EmpathyMessage *msg);
-static void chat_view_append_fancy_action (EmpathyChatView *view,
- EmpathyMessage *msg);
-static void chat_view_append_irc_message (EmpathyChatView *view,
- EmpathyMessage *msg);
-static void chat_view_append_fancy_message (EmpathyChatView *view,
- EmpathyMessage *msg);
-static GdkPixbuf *chat_view_pad_to_size (GdkPixbuf *pixbuf,
- gint width,
- gint height,
- gint extra_padding_right);
+static void chat_view_theme_updated_cb (EmpathyTheme *theme,
+ EmpathyChatView *view);
G_DEFINE_TYPE (EmpathyChatView, empathy_chat_view, GTK_TYPE_TEXT_VIEW);
@@ -186,7 +156,6 @@ empathy_chat_view_init (EmpathyChatView *view)
priv = GET_PRIV (view);
- priv->smiley_manager = empathy_smiley_manager_new ();
priv->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
priv->last_block_type = BLOCK_TYPE_NONE;
@@ -224,8 +193,7 @@ empathy_chat_view_init (EmpathyChatView *view)
EMPATHY_PREFS_UI_SHOW_AVATARS,
&show_avatars);
- empathy_theme_manager_update_show_avatars (empathy_theme_manager_get (),
- view, show_avatars);
+ empathy_theme_set_show_avatars (priv->theme, show_avatars);
g_signal_connect (view,
"populate-popup",
@@ -253,9 +221,6 @@ chat_view_finalize (GObject *object)
empathy_conf_notify_remove (empathy_conf_get (), priv->notify_system_fonts_id);
empathy_conf_notify_remove (empathy_conf_get (), priv->notify_show_avatars_id);
- if (priv->smiley_manager) {
- g_object_unref (priv->smiley_manager);
- }
if (priv->last_contact) {
g_object_unref (priv->last_contact);
}
@@ -266,6 +231,17 @@ chat_view_finalize (GObject *object)
g_source_remove (priv->scroll_timeout);
}
+ if (priv->theme) {
+ g_signal_handlers_disconnect_by_func (priv->theme,
+ chat_view_theme_updated_cb,
+ view);
+
+ empathy_theme_detach_from_view (priv->theme, priv->theme_context,
+ view);
+
+ g_object_unref (priv->theme);
+ }
+
G_OBJECT_CLASS (empathy_chat_view_parent_class)->finalize (object);
}
@@ -364,9 +340,11 @@ chat_view_notify_system_font_cb (EmpathyConf *conf,
gpointer user_data)
{
EmpathyChatView *view;
+ EmpathyChatViewPriv *priv;
gboolean show_avatars = FALSE;
view = user_data;
+ priv = GET_PRIV (view);
chat_view_system_font_update (view);
@@ -378,8 +356,7 @@ chat_view_notify_system_font_cb (EmpathyConf *conf,
EMPATHY_PREFS_UI_SHOW_AVATARS,
&show_avatars);
- empathy_theme_manager_update_show_avatars (empathy_theme_manager_get (),
- view, show_avatars);
+ empathy_theme_set_show_avatars (priv->theme, show_avatars);
}
static void
@@ -396,8 +373,7 @@ chat_view_notify_show_avatars_cb (EmpathyConf *conf,
empathy_conf_get_bool (conf, key, &show_avatars);
- empathy_theme_manager_update_show_avatars (empathy_theme_manager_get (),
- view, show_avatars);
+ empathy_theme_set_show_avatars (priv->theme, show_avatars);
}
static void
@@ -593,40 +569,6 @@ chat_view_clear_view_cb (GtkMenuItem *menuitem, EmpathyChatView *view)
empathy_chat_view_clear (view);
}
-static void
-chat_view_insert_text_with_emoticons (EmpathyChatView *view,
- GtkTextIter *iter,
- const gchar *str)
-{
- EmpathyChatViewPriv *priv = GET_PRIV (view);
- GtkTextBuffer *buf = priv->buffer;
- gboolean use_smileys = FALSE;
- GSList *smileys, *l;
-
- empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_CHAT_SHOW_SMILEYS,
- &use_smileys);
-
- if (!use_smileys) {
- gtk_text_buffer_insert (buf, iter, str, -1);
- return;
- }
-
- smileys = empathy_smiley_manager_parse (priv->smiley_manager, str);
- for (l = smileys; l; l = l->next) {
- EmpathySmiley *smiley;
-
- smiley = l->data;
- if (smiley->pixbuf) {
- gtk_text_buffer_insert_pixbuf (buf, iter, smiley->pixbuf);
- } else {
- gtk_text_buffer_insert (buf, iter, smiley->str, -1);
- }
- empathy_smiley_free (smiley);
- }
- g_slist_free (smileys);
-}
-
static gboolean
chat_view_is_scrolled_down (EmpathyChatView *view)
{
@@ -691,222 +633,72 @@ chat_view_maybe_trim_buffer (EmpathyChatView *view)
}
static void
-chat_view_maybe_append_date_and_time (EmpathyChatView *view,
- EmpathyMessage *msg)
+chat_view_theme_changed_cb (EmpathyThemeManager *manager,
+ EmpathyChatView *view)
{
EmpathyChatViewPriv *priv;
- const gchar *tag;
- time_t timestamp;
- GDate *date, *last_date;
- GtkTextIter iter;
- gboolean append_date, append_time;
- GString *str;
+ gboolean show_avatars = FALSE;
+ gboolean theme_rooms = FALSE;
priv = GET_PRIV (view);
- if (priv->irc_style) {
- tag = "irc-time";
- } else {
- tag = "fancy-time";
- }
-
- if (priv->last_block_type == BLOCK_TYPE_TIME) {
- return;
- }
-
- str = g_string_new (NULL);
-
- timestamp = 0;
- if (msg) {
- timestamp = empathy_message_get_timestamp (msg);
- }
-
- if (timestamp <= 0) {
- timestamp = empathy_time_get_current ();
- }
-
- date = g_date_new ();
- g_date_set_time_t (date, timestamp);
-
- last_date = g_date_new ();
- g_date_set_time_t (last_date, priv->last_timestamp);
-
- append_date = FALSE;
- append_time = FALSE;
-
- if (g_date_compare (date, last_date) > 0) {
- append_date = TRUE;
- append_time = TRUE;
- }
-
- if (priv->last_timestamp + TIMESTAMP_INTERVAL < timestamp) {
- append_time = TRUE;
- }
-
- if (append_time || append_date) {
- chat_view_append_spacing (view);
-
- g_string_append (str, "- ");
- }
-
- if (append_date) {
- gchar buf[256];
-
- g_date_strftime (buf, 256, _("%A %d %B %Y"), date);
- g_string_append (str, buf);
-
- if (append_time) {
- g_string_append (str, ", ");
- }
- }
-
- g_date_free (date);
- g_date_free (last_date);
-
- if (append_time) {
- gchar *tmp;
-
- tmp = empathy_time_to_string_local (timestamp, EMPATHY_TIME_FORMAT_DISPLAY_SHORT);
- g_string_append (str, tmp);
- g_free (tmp);
- }
-
- if (append_time || append_date) {
- g_string_append (str, " -\n");
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
- &iter,
- str->str, -1,
- tag,
- NULL);
-
- priv->last_block_type = BLOCK_TYPE_TIME;
- priv->last_timestamp = timestamp;
- }
-
- g_string_free (str, TRUE);
-}
-
-static void
-chat_view_append_spacing (EmpathyChatView *view)
-{
- EmpathyChatViewPriv *priv;
- const gchar *tag;
- GtkTextIter iter;
-
- priv = GET_PRIV (view);
+ priv->last_block_type = BLOCK_TYPE_NONE;
- if (priv->irc_style) {
- tag = "irc-spacing";
+ empathy_conf_get_bool (empathy_conf_get (),
+ EMPATHY_PREFS_CHAT_THEME_CHAT_ROOM,
+ &theme_rooms);
+ if (!theme_rooms && priv->is_group_chat) {
+ empathy_theme_manager_apply (manager, view, NULL);
} else {
- tag = "fancy-spacing";
+ empathy_theme_manager_apply_saved (manager, view);
}
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
- &iter,
- "\n",
- -1,
- "cut",
- tag,
- NULL);
+ /* Needed for now to update the "rise" property of the names to get it
+ * vertically centered.
+ */
+ empathy_conf_get_bool (empathy_conf_get (),
+ EMPATHY_PREFS_UI_SHOW_AVATARS,
+ &show_avatars);
+ empathy_theme_set_show_avatars (priv->theme, show_avatars);
}
-static void
-chat_view_append_text (EmpathyChatView *view,
- const gchar *body,
- const gchar *tag)
+/* Pads a pixbuf to the specified size, by centering it in a larger transparent
+ * pixbuf. Returns a new ref.
+ */
+static GdkPixbuf *
+chat_view_pad_to_size (GdkPixbuf *pixbuf,
+ gint width,
+ gint height,
+ gint extra_padding_right)
{
- EmpathyChatViewPriv *priv;
- GtkTextIter start_iter, end_iter;
- GtkTextMark *mark;
- GtkTextIter iter;
- gint num_matches, i;
- GArray *start, *end;
- const gchar *link_tag;
-
- priv = GET_PRIV (view);
-
- if (priv->irc_style) {
- link_tag = "irc-link";
- } else {
- link_tag = "fancy-link";
- }
-
- gtk_text_buffer_get_end_iter (priv->buffer, &start_iter);
- mark = gtk_text_buffer_create_mark (priv->buffer, NULL, &start_iter, TRUE);
-
- start = g_array_new (FALSE, FALSE, sizeof (gint));
- end = g_array_new (FALSE, FALSE, sizeof (gint));
-
- num_matches = empathy_regex_match (EMPATHY_REGEX_ALL, body, start, end);
-
- if (num_matches == 0) {
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- chat_view_insert_text_with_emoticons (view, &iter, body);
- } else {
- gint last = 0;
- gint s = 0, e = 0;
- gchar *tmp;
-
- for (i = 0; i < num_matches; i++) {
- s = g_array_index (start, gint, i);
- e = g_array_index (end, gint, i);
-
- if (s > last) {
- tmp = empathy_substring (body, last, s);
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- chat_view_insert_text_with_emoticons (view,
- &iter,
- tmp);
- g_free (tmp);
- }
-
- tmp = empathy_substring (body, s, e);
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
- &iter,
- tmp,
- -1,
- link_tag,
- "link",
- NULL);
-
- g_free (tmp);
-
- last = e;
- }
-
- if (e < strlen (body)) {
- tmp = empathy_substring (body, e, strlen (body));
+ gint src_width, src_height;
+ GdkPixbuf *padded;
+ gint x_offset, y_offset;
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- chat_view_insert_text_with_emoticons (view,
- &iter,
- tmp);
- g_free (tmp);
- }
- }
+ src_width = gdk_pixbuf_get_width (pixbuf);
+ src_height = gdk_pixbuf_get_height (pixbuf);
- g_array_free (start, TRUE);
- g_array_free (end, TRUE);
+ x_offset = (width - src_width) / 2;
+ y_offset = (height - src_height) / 2;
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- gtk_text_buffer_insert (priv->buffer, &iter, "\n", 1);
+ padded = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (pixbuf),
+ TRUE, /* alpha */
+ gdk_pixbuf_get_bits_per_sample (pixbuf),
+ width + extra_padding_right,
+ height);
- /* Apply the style to the inserted text. */
- gtk_text_buffer_get_iter_at_mark (priv->buffer, &start_iter, mark);
- gtk_text_buffer_get_end_iter (priv->buffer, &end_iter);
+ gdk_pixbuf_fill (padded, 0);
- gtk_text_buffer_apply_tag_by_name (priv->buffer,
- tag,
- &start_iter,
- &end_iter);
+ gdk_pixbuf_copy_area (pixbuf,
+ 0, /* source coords */
+ 0,
+ src_width,
+ src_height,
+ padded,
+ x_offset, /* dest coords */
+ y_offset);
- gtk_text_buffer_delete_mark (priv->buffer, mark);
+ return padded;
}
typedef struct {
@@ -924,8 +716,8 @@ chat_view_avatar_cache_data_free (gpointer ptr)
g_slice_free (AvatarData, data);
}
-static GdkPixbuf *
-chat_view_get_avatar_pixbuf_with_cache (EmpathyContact *contact)
+GdkPixbuf *
+empathy_chat_view_get_avatar_pixbuf_with_cache (EmpathyContact *contact)
{
static GHashTable *avatar_cache = NULL;
AvatarData *data;
@@ -976,425 +768,38 @@ chat_view_get_avatar_pixbuf_with_cache (EmpathyContact *contact)
return data->pixbuf;
}
-static void
-chat_view_maybe_append_fancy_header (EmpathyChatView *view,
- EmpathyMessage *msg)
-{
- EmpathyChatViewPriv *priv;
- EmpathyContact *sender;
- const gchar *name;
- gboolean header;
- GtkTextIter iter;
- gchar *tmp;
- const gchar *tag;
- const gchar *avatar_tag;
- const gchar *line_top_tag;
- const gchar *line_bottom_tag;
- gboolean from_self;
- GdkPixbuf *avatar = NULL;
-
- priv = GET_PRIV (view);
-
- sender = empathy_message_get_sender (msg);
- name = empathy_contact_get_name (sender);
- from_self = empathy_contact_is_user (sender);
-
- empathy_debug (DEBUG_DOMAIN, "Maybe add fancy header");
-
- if (from_self) {
- tag = "fancy-header-self";
- line_top_tag = "fancy-line-top-self";
- line_bottom_tag = "fancy-line-bottom-self";
- } else {
- tag = "fancy-header-other";
- line_top_tag = "fancy-line-top-other";
- line_bottom_tag = "fancy-line-bottom-other";
- }
-
- header = FALSE;
-
- /* Only insert a header if the previously inserted block is not the same
- * as this one. This catches all the different cases:
- */
- if (priv->last_block_type != BLOCK_TYPE_SELF &&
- priv->last_block_type != BLOCK_TYPE_OTHER) {
- header = TRUE;
- }
- else if (from_self && priv->last_block_type == BLOCK_TYPE_OTHER) {
- header = TRUE;
- }
- else if (!from_self && priv->last_block_type == BLOCK_TYPE_SELF) {
- header = TRUE;
- }
- else if (!from_self &&
- (!priv->last_contact ||
- !empathy_contact_equal (sender, priv->last_contact))) {
- header = TRUE;
- }
-
- if (!header) {
- return;
- }
-
- chat_view_append_spacing (view);
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
- &iter,
- "\n",
- -1,
- line_top_tag,
- NULL);
- avatar = chat_view_get_avatar_pixbuf_with_cache (sender);
- if (avatar) {
- GtkTextIter start;
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- gtk_text_buffer_insert_pixbuf (priv->buffer, &iter, avatar);
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- start = iter;
- gtk_text_iter_backward_char (&start);
-
- if (from_self) {
- gtk_text_buffer_apply_tag_by_name (priv->buffer,
- "fancy-avatar-self",
- &start, &iter);
- avatar_tag = "fancy-header-self-avatar";
- } else {
- gtk_text_buffer_apply_tag_by_name (priv->buffer,
- "fancy-avatar-other",
- &start, &iter);
- avatar_tag = "fancy-header-other-avatar";
- }
- } else {
- avatar_tag = NULL;
- }
-
- tmp = g_strdup_printf ("%s\n", name);
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
- &iter,
- tmp,
- -1,
- tag,
- avatar_tag,
- NULL);
- g_free (tmp);
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
- &iter,
- "\n",
- -1,
- line_bottom_tag,
- NULL);
-}
-
-static void
-chat_view_append_irc_action (EmpathyChatView *view,
- EmpathyMessage *msg)
-{
- EmpathyChatViewPriv *priv;
- EmpathyContact *sender;
- const gchar *name;
- GtkTextIter iter;
- const gchar *body;
- gchar *tmp;
- const gchar *tag;
-
- priv = GET_PRIV (view);
-
- empathy_debug (DEBUG_DOMAIN, "Add IRC action");
-
- sender = empathy_message_get_sender (msg);
- name = empathy_contact_get_name (sender);
-
- if (empathy_contact_is_user (sender)) {
- tag = "irc-action-self";
- } else {
- tag = "irc-action-other";
- }
-
- if (priv->last_block_type != BLOCK_TYPE_SELF &&
- priv->last_block_type != BLOCK_TYPE_OTHER) {
- chat_view_append_spacing (view);
- }
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
-
- tmp = g_strdup_printf (" * %s ", name);
- gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
- &iter,
- tmp,
- -1,
- "cut",
- tag,
- NULL);
- g_free (tmp);
-
- body = empathy_message_get_body (msg);
- chat_view_append_text (view, body, tag);
-}
-
-static void
-chat_view_append_fancy_action (EmpathyChatView *view,
- EmpathyMessage *msg)
-{
- EmpathyChatViewPriv *priv;
- EmpathyContact *sender;
- const gchar *name;
- const gchar *body;
- GtkTextIter iter;
- gchar *tmp;
- const gchar *tag;
- const gchar *line_tag;
-
- priv = GET_PRIV (view);
-
- empathy_debug (DEBUG_DOMAIN, "Add fancy action");
-
- sender = empathy_message_get_sender (msg);
- name = empathy_contact_get_name (sender);
-
- if (empathy_contact_is_user (sender)) {
- tag = "fancy-action-self";
- line_tag = "fancy-line-self";
- } else {
- tag = "fancy-action-other";
- line_tag = "fancy-line-other";
- }
-
- tmp = g_strdup_printf (" * %s ", name);
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
- gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
- &iter,
- tmp,
- -1,
- tag,
- NULL);
- g_free (tmp);
-
- body = empathy_message_get_body (msg);
- chat_view_append_text (view, body, tag);
-}
-
-static void
-chat_view_append_irc_message (EmpathyChatView *view,
- EmpathyMessage *msg)
-{
- EmpathyChatViewPriv *priv;
- EmpathyContact *sender;
- const gchar *name;
- const gchar *body;
- const gchar *nick_tag;
- const gchar *body_tag;
- GtkTextIter iter;
- gchar *tmp;
-
- priv = GET_PRIV (view);
-
- empathy_debug (DEBUG_DOMAIN, "Add IRC message");
-
- body = empathy_message_get_body (msg);
- sender = empathy_message_get_sender (msg);
- name = empathy_contact_get_name (sender);
-
- if (empathy_contact_is_user (sender)) {
- nick_tag = "irc-nick-self";
- body_tag = "irc-body-self";
- } else {
- if (empathy_chat_should_highlight_nick (msg)) {
- nick_tag = "irc-nick-highlight";
- } else {
- nick_tag = "irc-nick-other";
- }
-
- body_tag = "irc-body-other";
- }
-
- if (priv->last_block_type != BLOCK_TYPE_SELF &&
- priv->last_block_type != BLOCK_TYPE_OTHER) {
- chat_view_append_spacing (view);
- }
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
-
- /* The nickname. */
- tmp = g_strdup_printf ("%s: ", name);
- gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
- &iter,
- tmp,
- -1,
- "cut",
- nick_tag,
- NULL);
- g_free (tmp);
-
- /* The text body. */
- chat_view_append_text (view, body, body_tag);
-}
-
-static void
-chat_view_append_fancy_message (EmpathyChatView *view,
- EmpathyMessage *msg)
-{
- EmpathyChatViewPriv *priv;
- EmpathyContact *sender;
- const gchar *body;
- const gchar *tag;
-
- priv = GET_PRIV (view);
-
- sender = empathy_message_get_sender (msg);
-
- if (empathy_contact_is_user (sender)) {
- tag = "fancy-body-self";
- } else {
- tag = "fancy-body-other";
-
- /* FIXME: Might want to support nick highlighting here... */
- }
-
- body = empathy_message_get_body (msg);
- chat_view_append_text (view, body, tag);
-}
-
-static void
-chat_view_theme_changed_cb (EmpathyThemeManager *manager,
- EmpathyChatView *view)
-{
- EmpathyChatViewPriv *priv;
- gboolean show_avatars = FALSE;
- gboolean theme_rooms = FALSE;
-
- priv = GET_PRIV (view);
-
- priv->last_block_type = BLOCK_TYPE_NONE;
-
- empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_CHAT_THEME_CHAT_ROOM,
- &theme_rooms);
- if (!theme_rooms && priv->is_group_chat) {
- empathy_theme_manager_apply (manager, view, NULL);
- } else {
- empathy_theme_manager_apply_saved (manager, view);
- }
-
- /* Needed for now to update the "rise" property of the names to get it
- * vertically centered.
- */
- empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_UI_SHOW_AVATARS,
- &show_avatars);
- empathy_theme_manager_update_show_avatars (manager, view, show_avatars);
-}
-
-/* Pads a pixbuf to the specified size, by centering it in a larger transparent
- * pixbuf. Returns a new ref.
- */
-static GdkPixbuf *
-chat_view_pad_to_size (GdkPixbuf *pixbuf,
- gint width,
- gint height,
- gint extra_padding_right)
-{
- gint src_width, src_height;
- GdkPixbuf *padded;
- gint x_offset, y_offset;
-
- src_width = gdk_pixbuf_get_width (pixbuf);
- src_height = gdk_pixbuf_get_height (pixbuf);
-
- x_offset = (width - src_width) / 2;
- y_offset = (height - src_height) / 2;
-
- padded = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (pixbuf),
- TRUE, /* alpha */
- gdk_pixbuf_get_bits_per_sample (pixbuf),
- width + extra_padding_right,
- height);
-
- gdk_pixbuf_fill (padded, 0);
-
- gdk_pixbuf_copy_area (pixbuf,
- 0, /* source coords */
- 0,
- src_width,
- src_height,
- padded,
- x_offset, /* dest coords */
- y_offset);
-
- return padded;
-}
-
EmpathyChatView *
empathy_chat_view_new (void)
{
return g_object_new (EMPATHY_TYPE_CHAT_VIEW, NULL);
}
-/* The name is optional, if NULL, the sender for msg is used. */
void
empathy_chat_view_append_message (EmpathyChatView *view,
- EmpathyMessage *msg)
+ EmpathyMessage *msg)
{
- EmpathyChatViewPriv *priv;
+ EmpathyChatViewPriv *priv = GET_PRIV (view);
EmpathyContact *sender;
- const gchar *body;
- gboolean scroll_down;
+ gboolean bottom;
+ gboolean from_self;
g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
g_return_if_fail (EMPATHY_IS_MESSAGE (msg));
- priv = GET_PRIV (view);
-
- body = empathy_message_get_body (msg);
- if (!body) {
+ if (!empathy_message_get_body (msg)) {
return;
}
- scroll_down = chat_view_is_scrolled_down (view);
-
- chat_view_maybe_trim_buffer (view);
- chat_view_maybe_append_date_and_time (view, msg);
-
+ bottom = chat_view_is_scrolled_down (view);
sender = empathy_message_get_sender (msg);
+ from_self = empathy_contact_is_user (sender);
+
+ chat_view_maybe_trim_buffer (view);
- if (!priv->irc_style) {
- chat_view_maybe_append_fancy_header (view, msg);
- }
-
- if (empathy_message_get_type (msg) == EMPATHY_MESSAGE_TYPE_ACTION) {
- if (priv->irc_style) {
- chat_view_append_irc_action (view, msg);
- } else {
- chat_view_append_fancy_action (view, msg);
- }
- } else {
- if (priv->irc_style) {
- chat_view_append_irc_message (view, msg);
- } else {
- chat_view_append_fancy_message (view, msg);
- }
- }
-
- /* Reset the last inserted contact. */
- if (priv->last_contact) {
- g_object_unref (priv->last_contact);
- }
+ empathy_theme_append_message (priv->theme, priv->theme_context,
+ view, msg);
- if (empathy_contact_is_user (sender)) {
- priv->last_block_type = BLOCK_TYPE_SELF;
- priv->last_contact = NULL;
- } else {
- priv->last_block_type = BLOCK_TYPE_OTHER;
- priv->last_contact = g_object_ref (sender);
- }
-
- if (scroll_down) {
+ if (bottom) {
empathy_chat_view_scroll_down (view);
}
}
@@ -1405,9 +810,6 @@ empathy_chat_view_append_event (EmpathyChatView *view,
{
EmpathyChatViewPriv *priv;
gboolean bottom;
- GtkTextIter iter;
- gchar *msg;
- const gchar *tag;
g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
g_return_if_fail (!G_STR_EMPTY (str));
@@ -1418,28 +820,9 @@ empathy_chat_view_append_event (EmpathyChatView *view,
chat_view_maybe_trim_buffer (view);
- if (priv->irc_style) {
- tag = "irc-event";
- msg = g_strdup_printf (" - %s\n", str);
- } else {
- tag = "fancy-event";
- msg = g_strdup_printf (" - %s\n", str);
- }
-
- if (priv->last_block_type != BLOCK_TYPE_EVENT) {
- /* Comment out for now. */
- /*chat_view_append_spacing (view);*/
- }
-
- chat_view_maybe_append_date_and_time (view, NULL);
-
- gtk_text_buffer_get_end_iter (priv->buffer, &iter);
-
- gtk_text_buffer_insert_with_tags_by_name (priv->buffer, &iter,
- msg, -1,
- tag,
- NULL);
- g_free (msg);
+ empathy_theme_append_event (priv->theme,
+ priv->theme_context,
+ view, str);
if (bottom) {
empathy_chat_view_scroll_down (view);
@@ -1465,18 +848,17 @@ empathy_chat_view_append_button (EmpathyChatView *view,
priv = GET_PRIV (view);
- if (priv->irc_style) {
- tag = "irc-invite";
- } else {
- tag = "fancy-invite";
- }
+ tag = "invite";
bottom = chat_view_is_scrolled_down (view);
- chat_view_maybe_append_date_and_time (view, NULL);
+ empathy_theme_append_timestamp (priv->theme, priv->theme_context,
+ view, NULL,
+ TRUE, TRUE);
if (message) {
- chat_view_append_text (view, message, tag);
+ empathy_theme_append_text (priv->theme, priv->theme_context,
+ view, message, tag, NULL);
}
gtk_text_buffer_get_end_iter (priv->buffer, &iter);
@@ -1624,6 +1006,8 @@ empathy_chat_view_clear (EmpathyChatView *view)
*/
priv = GET_PRIV (view);
+ empathy_theme_view_cleared (priv->theme, priv->theme_context, view);
+
priv->last_block_type = BLOCK_TYPE_NONE;
priv->last_timestamp = 0;
}
@@ -1973,29 +1357,61 @@ empathy_chat_view_copy_clipboard (EmpathyChatView *view)
gtk_text_buffer_copy_clipboard (buffer, clipboard);
}
-gboolean
-empathy_chat_view_get_irc_style (EmpathyChatView *view)
+EmpathyTheme *
+empathy_chat_view_get_theme (EmpathyChatView *view)
{
EmpathyChatViewPriv *priv;
- g_return_val_if_fail (EMPATHY_IS_CHAT_VIEW (view), FALSE);
+ g_return_val_if_fail (EMPATHY_IS_CHAT_VIEW (view), NULL);
priv = GET_PRIV (view);
- return priv->irc_style;
+ return priv->theme;
+}
+
+static void
+chat_view_theme_updated_cb (EmpathyTheme *theme, EmpathyChatView *view)
+{
+ EmpathyChatViewPriv *priv;
+
+ priv = GET_PRIV (view);
+
+ empathy_theme_detach_from_view (priv->theme, priv->theme_context,
+ view);
+
+ priv->theme_context = empathy_theme_setup_with_view (theme, view);
}
void
-empathy_chat_view_set_irc_style (EmpathyChatView *view,
- gboolean irc_style)
+empathy_chat_view_set_theme (EmpathyChatView *view, EmpathyTheme *theme)
{
EmpathyChatViewPriv *priv;
g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
+ g_return_if_fail (EMPATHY_IS_THEME (theme));
priv = GET_PRIV (view);
- priv->irc_style = irc_style;
+ if (priv->theme) {
+ g_signal_handlers_disconnect_by_func (priv->theme,
+ chat_view_theme_updated_cb,
+ view);
+ empathy_theme_detach_from_view (priv->theme, priv->theme_context,
+ view);
+
+ g_object_unref (priv->theme);
+ }
+
+ priv->theme = g_object_ref (theme);
+
+ g_signal_connect (priv->theme,
+ "updated",
+ G_CALLBACK (chat_view_theme_updated_cb),
+ view);
+
+ priv->theme_context = empathy_theme_setup_with_view (theme, view);
+
+ /* FIXME: Possibly redraw the function and make it a property */
}
void
@@ -2092,3 +1508,85 @@ empathy_chat_view_set_is_group_chat (EmpathyChatView *view,
view);
}
}
+
+time_t
+empathy_chat_view_get_last_timestamp (EmpathyChatView *view)
+{
+ EmpathyChatViewPriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_CHAT_VIEW (view), 0);
+
+ priv = GET_PRIV (view);
+
+ return priv->last_timestamp;
+}
+
+void
+empathy_chat_view_set_last_timestamp (EmpathyChatView *view,
+ time_t timestamp)
+{
+ EmpathyChatViewPriv *priv;
+
+ g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
+
+ priv = GET_PRIV (view);
+
+ priv->last_timestamp = timestamp;
+}
+
+BlockType
+empathy_chat_view_get_last_block_type (EmpathyChatView *view)
+{
+ EmpathyChatViewPriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_CHAT_VIEW (view), 0);
+
+ priv = GET_PRIV (view);
+
+ return priv->last_block_type;
+}
+
+void
+empathy_chat_view_set_last_block_type (EmpathyChatView *view,
+ BlockType block_type)
+{
+ EmpathyChatViewPriv *priv;
+
+ g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
+
+ priv = GET_PRIV (view);
+
+ priv->last_block_type = block_type;
+}
+
+EmpathyContact *
+empathy_chat_view_get_last_contact (EmpathyChatView *view)
+{
+ EmpathyChatViewPriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_CHAT_VIEW (view), NULL);
+
+ priv = GET_PRIV (view);
+
+ return priv->last_contact;
+}
+
+void
+empathy_chat_view_set_last_contact (EmpathyChatView *view, EmpathyContact *contact)
+{
+ EmpathyChatViewPriv *priv;
+
+ g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
+
+ priv = GET_PRIV (view);
+
+ if (priv->last_contact) {
+ g_object_unref (priv->last_contact);
+ priv->last_contact = NULL;
+ }
+
+ if (contact) {
+ priv->last_contact = g_object_ref (contact);
+ }
+}
+
diff --git a/libempathy-gtk/empathy-chat-view.h b/libempathy-gtk/empathy-chat-view.h
index 0402bd7c0..37a7f9977 100644
--- a/libempathy-gtk/empathy-chat-view.h
+++ b/libempathy-gtk/empathy-chat-view.h
@@ -43,6 +43,8 @@ typedef struct _EmpathyChatView EmpathyChatView;
typedef struct _EmpathyChatViewClass EmpathyChatViewClass;
typedef struct _EmpathyChatViewPriv EmpathyChatViewPriv;
+#include "empathy-theme.h"
+
struct _EmpathyChatView {
GtkTextView parent;
};
@@ -51,6 +53,15 @@ struct _EmpathyChatViewClass {
GtkTextViewClass parent_class;
};
+typedef enum {
+ BLOCK_TYPE_NONE,
+ BLOCK_TYPE_SELF,
+ BLOCK_TYPE_OTHER,
+ BLOCK_TYPE_EVENT,
+ BLOCK_TYPE_TIME,
+ BLOCK_TYPE_INVITE
+} BlockType;
+
GType empathy_chat_view_get_type (void) G_GNUC_CONST;
EmpathyChatView *empathy_chat_view_new (void);
void empathy_chat_view_append_message (EmpathyChatView *view,
@@ -83,15 +94,25 @@ void empathy_chat_view_find_abilities (EmpathyChatView *view,
void empathy_chat_view_highlight (EmpathyChatView *view,
const gchar *text);
void empathy_chat_view_copy_clipboard (EmpathyChatView *view);
-gboolean empathy_chat_view_get_irc_style (EmpathyChatView *view);
-void empathy_chat_view_set_irc_style (EmpathyChatView *view,
- gboolean irc_style);
+EmpathyTheme * empathy_chat_view_get_theme (EmpathyChatView *view);
+void empathy_chat_view_set_theme (EmpathyChatView *view,
+ EmpathyTheme *theme);
void empathy_chat_view_set_margin (EmpathyChatView *view,
gint margin);
GtkWidget * empathy_chat_view_get_smiley_menu (GCallback callback,
gpointer user_data);
void empathy_chat_view_set_is_group_chat (EmpathyChatView *view,
gboolean is_group_chat);
+time_t empathy_chat_view_get_last_timestamp (EmpathyChatView *view);
+void empathy_chat_view_set_last_timestamp (EmpathyChatView *view,
+ time_t timestamp);
+BlockType empathy_chat_view_get_last_block_type (EmpathyChatView *view);
+void empathy_chat_view_set_last_block_type (EmpathyChatView *view,
+ BlockType block_type);
+EmpathyContact * empathy_chat_view_get_last_contact (EmpathyChatView *view);
+void empathy_chat_view_set_last_contact (EmpathyChatView *view,
+ EmpathyContact *contact);
+GdkPixbuf * empathy_chat_view_get_avatar_pixbuf_with_cache (EmpathyContact *contact);
G_END_DECLS
diff --git a/libempathy-gtk/empathy-theme-boxes.c b/libempathy-gtk/empathy-theme-boxes.c
new file mode 100644
index 000000000..2905f2bec
--- /dev/null
+++ b/libempathy-gtk/empathy-theme-boxes.c
@@ -0,0 +1,1036 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-debug.h>
+
+#include "empathy-ui-utils.h"
+#include "empathy-main-window.h"
+#include "empathy-theme-utils.h"
+#include "empathy-theme-boxes.h"
+
+#define DEBUG_DOMAIN "FancyTheme"
+
+#define MARGIN 4
+#define HEADER_PADDING 2
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_THEME_BOXES, EmpathyThemeBoxesPriv))
+
+typedef struct _EmpathyThemeBoxesPriv EmpathyThemeBoxesPriv;
+
+struct _EmpathyThemeBoxesPriv {
+ gchar *header_foreground;
+ gchar *header_background;
+ gchar *header_line_background;
+ gchar *text_foreground;
+ gchar *text_background;
+ gchar *action_foreground;
+ gchar *highlight_foreground;
+ gchar *time_foreground;
+ gchar *event_foreground;
+ gchar *invite_foreground;
+ gchar *link_foreground;
+};
+
+static void theme_boxes_finalize (GObject *object);
+static void theme_boxes_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void theme_boxes_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void theme_boxes_define_theme_tags (EmpathyTheme *theme,
+ EmpathyChatView *view);
+static EmpathyThemeContext *
+theme_boxes_setup_with_view (EmpathyTheme *theme,
+ EmpathyChatView *view);
+static void theme_boxes_detach_from_view (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+static void theme_boxes_view_cleared (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+
+static void theme_boxes_append_message (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message);
+static void theme_boxes_append_event (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ const gchar *str);
+static void theme_boxes_append_timestamp (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message,
+ gboolean show_date,
+ gboolean show_time);
+static void theme_boxes_append_spacing (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+
+enum {
+ PROP_0,
+ PROP_HEADER_FOREGROUND,
+ PROP_HEADER_BACKGROUND,
+ PROP_HEADER_LINE_BACKGROUND,
+ PROP_TEXT_FOREGROUND,
+ PROP_TEXT_BACKGROUND,
+ PROP_ACTION_FOREGROUND,
+ PROP_HIGHLIGHT_FOREGROUND,
+ PROP_TIME_FOREGROUND,
+ PROP_EVENT_FOREGROUND,
+ PROP_INVITE_FOREGROUND,
+ PROP_LINK_FOREGROUND
+};
+
+enum {
+ PROP_FLOP,
+ PROP_MY_PROP
+};
+
+G_DEFINE_TYPE (EmpathyThemeBoxes, empathy_theme_boxes, EMPATHY_TYPE_THEME);
+
+static void
+empathy_theme_boxes_class_init (EmpathyThemeBoxesClass *class)
+{
+ GObjectClass *object_class;
+ EmpathyThemeClass *theme_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ theme_class = EMPATHY_THEME_CLASS (class);
+
+ object_class->finalize = theme_boxes_finalize;
+ object_class->get_property = theme_boxes_get_property;
+ object_class->set_property = theme_boxes_set_property;
+
+ theme_class->setup_with_view = theme_boxes_setup_with_view;
+ theme_class->detach_from_view = theme_boxes_detach_from_view;
+ theme_class->view_cleared = theme_boxes_view_cleared;
+ theme_class->append_message = theme_boxes_append_message;
+ theme_class->append_event = theme_boxes_append_event;
+ theme_class->append_timestamp = theme_boxes_append_timestamp;
+ theme_class->append_spacing = theme_boxes_append_spacing;
+
+ g_object_class_install_property (object_class,
+ PROP_HEADER_FOREGROUND,
+ g_param_spec_string ("header-foreground",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_HEADER_BACKGROUND,
+ g_param_spec_string ("header-background",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_HEADER_LINE_BACKGROUND,
+ g_param_spec_string ("header-line-background",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+
+ g_object_class_install_property (object_class,
+ PROP_TEXT_FOREGROUND,
+ g_param_spec_string ("text-foreground",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_TEXT_BACKGROUND,
+ g_param_spec_string ("text-background",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_ACTION_FOREGROUND,
+ g_param_spec_string ("action-foreground",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_HIGHLIGHT_FOREGROUND,
+ g_param_spec_string ("highlight-foreground",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_TIME_FOREGROUND,
+ g_param_spec_string ("time-foreground",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_EVENT_FOREGROUND,
+ g_param_spec_string ("event-foreground",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_INVITE_FOREGROUND,
+ g_param_spec_string ("invite-foreground",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_LINK_FOREGROUND,
+ g_param_spec_string ("link-foreground",
+ "",
+ "",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (object_class, sizeof (EmpathyThemeBoxesPriv));
+}
+
+static void
+empathy_theme_boxes_init (EmpathyThemeBoxes *theme)
+{
+ EmpathyThemeBoxesPriv *priv;
+
+ priv = GET_PRIV (theme);
+}
+
+static void
+theme_boxes_finalize (GObject *object)
+{
+ EmpathyThemeBoxesPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ g_free (priv->header_foreground);
+ g_free (priv->header_background);
+ g_free (priv->header_line_background);
+ g_free (priv->text_foreground);
+ g_free (priv->text_background);
+ g_free (priv->action_foreground);
+ g_free (priv->highlight_foreground);
+ g_free (priv->time_foreground);
+ g_free (priv->event_foreground);
+ g_free (priv->invite_foreground);
+ g_free (priv->link_foreground);
+
+ (G_OBJECT_CLASS (empathy_theme_boxes_parent_class)->finalize) (object);
+}
+
+static void
+theme_boxes_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyThemeBoxesPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_HEADER_FOREGROUND:
+ g_value_set_string (value, priv->header_foreground);
+ break;
+ case PROP_HEADER_BACKGROUND:
+ g_value_set_string (value, priv->header_background);
+ break;
+ case PROP_HEADER_LINE_BACKGROUND:
+ g_value_set_string (value, priv->header_line_background);
+ break;
+ case PROP_TEXT_FOREGROUND:
+ g_value_set_string (value, priv->text_foreground);
+ break;
+ case PROP_TEXT_BACKGROUND:
+ g_value_set_string (value, priv->text_background);
+ break;
+ case PROP_ACTION_FOREGROUND:
+ g_value_set_string (value, priv->action_foreground);
+ break;
+ case PROP_HIGHLIGHT_FOREGROUND:
+ g_value_set_string (value, priv->highlight_foreground);
+ break;
+ case PROP_TIME_FOREGROUND:
+ g_value_set_string (value, priv->time_foreground);
+ break;
+ case PROP_EVENT_FOREGROUND:
+ g_value_set_string (value, priv->event_foreground);
+ break;
+ case PROP_INVITE_FOREGROUND:
+ g_value_set_string (value, priv->invite_foreground);
+ break;
+ case PROP_LINK_FOREGROUND:
+ g_value_set_string (value, priv->link_foreground);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+static void
+theme_boxes_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyThemeBoxesPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_HEADER_FOREGROUND:
+ g_free (priv->header_foreground);
+ priv->header_foreground = g_value_dup_string (value);
+ break;
+ case PROP_HEADER_BACKGROUND:
+ g_free (priv->header_background);
+ priv->header_background = g_value_dup_string (value);
+ break;
+ case PROP_HEADER_LINE_BACKGROUND:
+ g_free (priv->header_line_background);
+ priv->header_line_background = g_value_dup_string (value);
+ break;
+ case PROP_TEXT_FOREGROUND:
+ g_free (priv->text_foreground);
+ priv->text_foreground = g_value_dup_string (value);
+ break;
+ case PROP_TEXT_BACKGROUND:
+ g_free (priv->text_background);
+ priv->text_background = g_value_dup_string (value);
+ break;
+ case PROP_ACTION_FOREGROUND:
+ g_free (priv->action_foreground);
+ priv->action_foreground = g_value_dup_string (value);
+ break;
+ case PROP_HIGHLIGHT_FOREGROUND:
+ g_free (priv->highlight_foreground);
+ priv->highlight_foreground = g_value_dup_string (value);
+ break;
+ case PROP_TIME_FOREGROUND:
+ g_free (priv->time_foreground);
+ priv->time_foreground = g_value_dup_string (value);
+ break;
+ case PROP_EVENT_FOREGROUND:
+ g_free (priv->event_foreground);
+ priv->event_foreground = g_value_dup_string (value);
+ break;
+ case PROP_INVITE_FOREGROUND:
+ g_free (priv->invite_foreground);
+ priv->invite_foreground = g_value_dup_string (value);
+ break;
+ case PROP_LINK_FOREGROUND:
+ g_free (priv->link_foreground);
+ priv->link_foreground = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+theme_boxes_define_theme_tags (EmpathyTheme *theme, EmpathyChatView *view)
+{
+ EmpathyThemeBoxesPriv *priv;
+ GtkTextBuffer *buffer;
+ GtkTextTagTable *table;
+ GtkTextTag *tag;
+
+ priv = GET_PRIV (theme);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+ table = gtk_text_buffer_get_tag_table (buffer);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "fancy-spacing");
+ g_object_set (tag,
+ "size", 3000,
+ "pixels-above-lines", 8,
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table,
+ "fancy-header");
+ g_object_set (tag,
+ "weight", PANGO_WEIGHT_BOLD,
+ "pixels-above-lines", HEADER_PADDING,
+ "pixels-below-lines", HEADER_PADDING,
+ NULL);
+ if (priv->header_foreground) {
+ g_object_set (tag,
+ "foreground", priv->header_foreground,
+ "paragraph-background", priv->header_background,
+ NULL);
+ }
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "fancy-header-line");
+ g_object_set (tag,
+ "size", 1,
+ NULL);
+ if (priv->header_line_background) {
+ g_object_set (tag,
+ "paragraph-background", priv->header_line_background,
+ NULL);
+ }
+
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "fancy-body");
+ g_object_set (tag,
+ "pixels-above-lines", 4,
+ NULL);
+ if (priv->text_background) {
+ g_object_set (tag,
+ "paragraph-background", priv->text_background,
+ NULL);
+ }
+
+ if (priv->text_foreground) {
+ g_object_set (tag,
+ "foreground", priv->text_foreground,
+ NULL);
+ }
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "fancy-action");
+ g_object_set (tag,
+ "style", PANGO_STYLE_ITALIC,
+ "pixels-above-lines", 4,
+ NULL);
+
+ if (priv->text_background) {
+ g_object_set (tag,
+ "paragraph-background", priv->text_background,
+ NULL);
+ }
+
+ if (priv->action_foreground) {
+ g_object_set (tag,
+ "foreground", priv->action_foreground,
+ NULL);
+ }
+
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table,
+ "fancy-highlight");
+ g_object_set (tag,
+ "weight", PANGO_WEIGHT_BOLD,
+ "pixels-above-lines", 4,
+ NULL);
+ if (priv->text_background) {
+ g_object_set (tag,
+ "paragraph-background", priv->text_background,
+ NULL);
+ }
+
+
+ if (priv->highlight_foreground) {
+ g_object_set (tag,
+ "foreground", priv->highlight_foreground,
+ NULL);
+ }
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "fancy-time");
+ g_object_set (tag,
+ "justification", GTK_JUSTIFY_CENTER,
+ NULL);
+ if (priv->time_foreground) {
+ g_object_set (tag,
+ "foreground", priv->time_foreground,
+ NULL);
+ }
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "fancy-event");
+ g_object_set (tag,
+ "justification", GTK_JUSTIFY_LEFT,
+ NULL);
+ if (priv->event_foreground) {
+ g_object_set (tag,
+ "foreground", priv->event_foreground,
+ NULL);
+ }
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "invite");
+ if (priv->invite_foreground) {
+ g_object_set (tag,
+ "foreground", priv->invite_foreground,
+ NULL);
+ }
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "fancy-link");
+ g_object_set (tag,
+ "underline", PANGO_UNDERLINE_SINGLE,
+ NULL);
+ if (priv->link_foreground) {
+ g_object_set (tag,
+ "foreground", priv->link_foreground,
+ NULL);
+ }
+ empathy_theme_utils_add_tag (table, tag);
+}
+
+static void
+theme_boxes_fixup_tag_table (EmpathyTheme *theme, EmpathyChatView *view)
+{
+ GtkTextBuffer *buffer;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ /* "Fancy" style tags. */
+ empathy_theme_utils_ensure_tag_by_name (buffer, "fancy-header");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "fancy-header-line");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "fancy-body");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "fancy-action");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "fancy-highlight");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "fancy-spacing");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "fancy-time");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "fancy-event");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "fancy-link");
+}
+
+typedef struct {
+ BlockType last_block_type;
+ time_t last_timestamp;
+} FancyContext;
+
+static EmpathyThemeContext *
+theme_boxes_setup_with_view (EmpathyTheme *theme, EmpathyChatView *view)
+{
+ EmpathyThemeBoxesPriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_THEME_BOXES (theme), NULL);
+
+ priv = GET_PRIV (theme);
+
+ theme_boxes_fixup_tag_table (theme, view);
+
+ theme_boxes_define_theme_tags (theme, view);
+
+ empathy_chat_view_set_margin (view, MARGIN);
+
+ return NULL;
+}
+
+static void
+theme_boxes_detach_from_view (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view)
+{
+ /* FIXME: Free the context */
+}
+
+static void
+theme_boxes_view_cleared (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view)
+{
+ /* FIXME: clear the context data */
+}
+
+static void
+table_size_allocate_cb (GtkWidget *view,
+ GtkAllocation *allocation,
+ GtkWidget *box)
+{
+ gint width, height;
+
+ gtk_widget_get_size_request (box, NULL, &height);
+
+ width = allocation->width;
+
+ width -= \
+ gtk_text_view_get_right_margin (GTK_TEXT_VIEW (view)) - \
+ gtk_text_view_get_left_margin (GTK_TEXT_VIEW (view));
+ width -= 2 * MARGIN;
+ width -= 2 * HEADER_PADDING;
+
+ gtk_widget_set_size_request (box, width, height);
+}
+
+static void
+theme_boxes_maybe_append_header (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *msg)
+{
+ EmpathyThemeBoxesPriv *priv;
+ EmpathyContact *contact;
+ GdkPixbuf *avatar = NULL;
+ GtkTextBuffer *buffer;
+ const gchar *name;
+ gboolean header;
+ GtkTextIter iter;
+ GtkWidget *label1, *label2;
+ GtkTextChildAnchor *anchor;
+ GtkWidget *box;
+ gchar *str;
+ time_t time;
+ gchar *tmp;
+ GtkTextIter start;
+ GdkColor color;
+ gboolean parse_success;
+ gboolean from_self;
+
+ priv = GET_PRIV (theme);
+
+ contact = empathy_message_get_sender (msg);
+ from_self = empathy_contact_is_user (contact);
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ empathy_debug (DEBUG_DOMAIN, "Maybe add fancy header");
+
+ name = empathy_contact_get_name (contact);
+
+ header = FALSE;
+
+ /* Only insert a header if the previously inserted block is not the same
+ * as this one. This catches all the different cases:
+ */
+ if (empathy_chat_view_get_last_block_type (view) != BLOCK_TYPE_SELF &&
+ empathy_chat_view_get_last_block_type (view) != BLOCK_TYPE_OTHER) {
+ header = TRUE;
+ }
+ else if (from_self &&
+ empathy_chat_view_get_last_block_type (view) == BLOCK_TYPE_OTHER) {
+ header = TRUE;
+ }
+ else if (!from_self &&
+ empathy_chat_view_get_last_block_type (view) == BLOCK_TYPE_SELF) {
+ header = TRUE;
+ }
+ else if (!from_self &&
+ (!empathy_chat_view_get_last_contact (view) ||
+ !empathy_contact_equal (contact, empathy_chat_view_get_last_contact (view)))) {
+ header = TRUE;
+ }
+
+ if (!header) {
+ return;
+ }
+
+ empathy_theme_append_spacing (theme, context, view);
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ "\n",
+ -1,
+ "fancy-header-line",
+ NULL);
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ anchor = gtk_text_buffer_create_child_anchor (buffer, &iter);
+
+ box = gtk_hbox_new (FALSE, 0);
+
+
+ avatar = empathy_chat_view_get_avatar_pixbuf_with_cache (contact);
+ if (avatar && empathy_theme_get_show_avatars (theme)) {
+ GtkWidget *image;
+
+ image = gtk_image_new_from_pixbuf (avatar);
+
+ gtk_box_pack_start (GTK_BOX (box), image,
+ FALSE, TRUE, 2);
+
+ }
+
+ g_signal_connect_object (view, "size-allocate",
+ G_CALLBACK (table_size_allocate_cb),
+ box, 0);
+
+ str = g_strdup_printf ("<b>%s</b>", name);
+
+ label1 = g_object_new (GTK_TYPE_LABEL,
+ "label", str,
+ "use-markup", TRUE,
+ "xalign", 0.0,
+ NULL);
+
+ parse_success = gdk_color_parse (priv->header_foreground, &color);
+
+ if (parse_success) {
+ gtk_widget_modify_fg (label1, GTK_STATE_NORMAL, &color);
+ }
+
+ g_free (str);
+
+ time = empathy_message_get_timestamp (msg);
+
+ tmp = empathy_time_to_string_local (time,
+ EMPATHY_TIME_FORMAT_DISPLAY_SHORT);
+ str = g_strdup_printf ("<i>%s</i>", tmp);
+ g_free (tmp);
+
+ label2 = g_object_new (GTK_TYPE_LABEL,
+ "label", str,
+ "use-markup", TRUE,
+ "xalign", 1.0,
+ NULL);
+
+ if (parse_success) {
+ gtk_widget_modify_fg (label2, GTK_STATE_NORMAL, &color);
+ }
+
+ g_free (str);
+
+ gtk_misc_set_alignment (GTK_MISC (label1), 0.0, 0.5);
+ gtk_misc_set_alignment (GTK_MISC (label2), 1.0, 0.5);
+
+ gtk_box_pack_start (GTK_BOX (box), label1, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), label2, TRUE, TRUE, 0);
+
+ gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (view),
+ box,
+ anchor);
+
+ gtk_widget_show_all (box);
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ start = iter;
+ gtk_text_iter_backward_char (&start);
+ gtk_text_buffer_apply_tag_by_name (buffer,
+ "fancy-header",
+ &start, &iter);
+
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ "\n",
+ -1,
+ "fancy-header",
+ NULL);
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ "\n",
+ -1,
+ "fancy-header-line",
+ NULL);
+}
+
+static void
+theme_boxes_append_message (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message)
+{
+ EmpathyContact *sender;
+
+ empathy_theme_maybe_append_date_and_time (theme, context, view, message);
+ theme_boxes_maybe_append_header (theme, context, view, message);
+
+ sender = empathy_message_get_sender (message);
+
+ if (empathy_message_get_type (message) == EMPATHY_MESSAGE_TYPE_ACTION) {
+ gchar *body;
+
+ body = g_strdup_printf (" * %s %s",
+ empathy_contact_get_name (sender),
+ empathy_message_get_body (message));
+ empathy_theme_append_text (theme, context, view, body,
+ "fancy-action", "fancy-link");
+ } else {
+ empathy_theme_append_text (theme, context, view,
+ empathy_message_get_body (message),
+ "fancy-body", "fancy-link");
+ }
+
+ if (empathy_contact_is_user (sender)) {
+ empathy_chat_view_set_last_block_type (view, BLOCK_TYPE_SELF);
+ empathy_chat_view_set_last_contact (view, NULL);
+ } else {
+ empathy_chat_view_set_last_block_type (view, BLOCK_TYPE_OTHER);
+ empathy_chat_view_set_last_contact (view, sender);
+ }
+}
+
+static void
+theme_boxes_append_event (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ const gchar *str)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+ gchar *msg;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ empathy_theme_maybe_append_date_and_time (theme, context, view, NULL);
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+
+ msg = g_strdup_printf (" - %s\n", str);
+
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ msg, -1,
+ "fancy-event",
+ NULL);
+ g_free (msg);
+
+ empathy_chat_view_set_last_block_type (view, BLOCK_TYPE_EVENT);
+}
+
+static void
+theme_boxes_append_timestamp (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message,
+ gboolean show_date,
+ gboolean show_time)
+{
+ GtkTextBuffer *buffer;
+ time_t timestamp;
+ GDate *date;
+ GtkTextIter iter;
+ GString *str;
+
+ if (!show_date) {
+ return;
+ }
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ date = empathy_message_get_date_and_time (message, &timestamp);
+
+ str = g_string_new (NULL);
+
+ if (show_time || show_date) {
+ empathy_theme_append_spacing (theme,
+ context,
+ view);
+
+ g_string_append (str, "- ");
+ }
+
+ if (show_date) {
+ gchar buf[256];
+
+ g_date_strftime (buf, 256, _("%A %d %B %Y"), date);
+ g_string_append (str, buf);
+
+ if (show_time) {
+ g_string_append (str, ", ");
+ }
+ }
+
+ g_date_free (date);
+
+ if (show_time) {
+ gchar *tmp;
+
+ tmp = empathy_time_to_string_local (timestamp, EMPATHY_TIME_FORMAT_DISPLAY_SHORT);
+ g_string_append (str, tmp);
+ g_free (tmp);
+ }
+
+ if (show_time || show_date) {
+ g_string_append (str, " -\n");
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ str->str, -1,
+ "fancy-time",
+ NULL);
+
+ empathy_chat_view_set_last_block_type (view, BLOCK_TYPE_TIME);
+ empathy_chat_view_set_last_timestamp (view, timestamp);
+ }
+
+ g_string_free (str, TRUE);
+
+}
+
+static void
+theme_boxes_append_spacing (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+
+ g_return_if_fail (EMPATHY_IS_THEME (theme));
+ g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ "\n",
+ -1,
+ "cut",
+ "fancy-spacing",
+ NULL);
+}
+
+static void
+theme_boxes_setup_clean (EmpathyTheme *theme)
+{
+ g_object_set (theme,
+ "header-foreground", "black",
+ "header-background", "#efefdf",
+ "header_line_background", "#e3e3d3",
+ "action_foreground", "brown4",
+ "time_foreground", "darkgrey",
+ "event_foreground", "darkgrey",
+ "invite_foreground", "sienna",
+ "link_foreground","#49789e",
+ NULL);
+}
+
+static void
+theme_boxes_gdk_color_to_hex (GdkColor *gdk_color, gchar *str_color)
+{
+ g_snprintf (str_color, 10,
+ "#%02x%02x%02x",
+ gdk_color->red >> 8,
+ gdk_color->green >> 8,
+ gdk_color->blue >> 8);
+}
+
+static void
+theme_boxes_setup_themed (EmpathyTheme *theme)
+{
+ EmpathyThemeBoxesPriv *priv;
+ GtkWidget *widget;
+ GtkStyle *style;
+ gchar color[10];
+
+ priv = GET_PRIV (theme);
+
+ widget = gtk_entry_new ();
+ style = gtk_widget_get_style (widget);
+ gtk_widget_destroy (widget);
+
+ theme_boxes_gdk_color_to_hex (&style->base[GTK_STATE_SELECTED], color);
+
+ g_object_set (theme,
+ "action-foreground", color,
+ "link-foreground", color,
+ NULL);
+
+ theme_boxes_gdk_color_to_hex (&style->bg[GTK_STATE_SELECTED], color);
+
+ g_object_set (theme,
+ "header-background", color,
+ NULL);
+
+ theme_boxes_gdk_color_to_hex (&style->dark[GTK_STATE_SELECTED], color);
+
+ g_object_set (theme,
+ "header_line-background", color,
+ NULL);
+
+ theme_boxes_gdk_color_to_hex (&style->fg[GTK_STATE_SELECTED], color);
+
+ g_object_set (theme,
+ "header-foreground", color,
+ NULL);
+}
+
+static void
+theme_boxes_theme_changed_cb (GtkWidget *widget,
+ GtkStyle *previous_style,
+ gpointer user_data)
+{
+ theme_boxes_setup_themed (EMPATHY_THEME (user_data));
+
+ g_signal_emit_by_name (G_OBJECT (user_data), "updated");
+}
+
+static void
+theme_boxes_setup_blue (EmpathyTheme *theme)
+{
+ g_object_set (theme,
+ "header_foreground", "black",
+ "header_background", "#88a2b4",
+ "header_line_background", "#7f96a4",
+ "text_foreground", "black",
+ "text_background", "#adbdc8",
+ "highlight_foreground", "black",
+ "action_foreground", "brown4",
+ "time_foreground", "darkgrey",
+ "event_foreground", "#7f96a4",
+ "invite_foreground", "sienna",
+ "link_foreground", "#49789e",
+ NULL);
+}
+
+EmpathyTheme *
+empathy_theme_boxes_new (const gchar *name)
+{
+ EmpathyTheme *theme;
+ EmpathyThemeBoxesPriv *priv;
+
+ theme = g_object_new (EMPATHY_TYPE_THEME_BOXES, NULL);
+ priv = GET_PRIV (theme);
+
+ if (strcmp (name, "clean") == 0) {
+ theme_boxes_setup_clean (theme);
+ }
+ else if (strcmp (name, "simple") == 0) {
+ /* FIXME: Make an actual accessor function */
+ g_signal_connect (empathy_main_window_show (),
+ "style-set",
+ G_CALLBACK (theme_boxes_theme_changed_cb),
+ theme);
+
+ theme_boxes_setup_themed (theme);
+ }
+ else if (strcmp (name, "blue") == 0) {
+ theme_boxes_setup_blue (theme);
+ }
+
+ return theme;
+}
+
+
diff --git a/libempathy-gtk/empathy-theme-boxes.h b/libempathy-gtk/empathy-theme-boxes.h
new file mode 100644
index 000000000..a54283693
--- /dev/null
+++ b/libempathy-gtk/empathy-theme-boxes.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EMPATHY_THEME_BOXES_H__
+#define __EMPATHY_THEME_BOXES_H__
+
+#include <glib-object.h>
+
+#include "empathy-theme.h"
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_THEME_BOXES (empathy_theme_boxes_get_type ())
+#define EMPATHY_THEME_BOXES(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_THEME_BOXES, EmpathyThemeBoxes))
+#define EMPATHY_THEME_BOXES_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_THEME_BOXES, EmpathyThemeBoxesClass))
+#define EMPATHY_IS_THEME_BOXES(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_THEME_BOXES))
+#define EMPATHY_IS_THEME_BOXES_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_THEME_BOXES))
+#define EMPATHY_THEME_BOXES_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_THEME_BOXES, EmpathyThemeBoxesClass))
+
+typedef struct _EmpathyThemeBoxes EmpathyThemeBoxes;
+typedef struct _EmpathyThemeBoxesClass EmpathyThemeBoxesClass;
+
+struct _EmpathyThemeBoxes {
+ EmpathyTheme parent;
+};
+
+struct _EmpathyThemeBoxesClass {
+ EmpathyThemeClass parent_class;
+};
+
+GType empathy_theme_boxes_get_type (void) G_GNUC_CONST;
+
+EmpathyTheme * empathy_theme_boxes_new (const gchar *name);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_THEME_BOXES_H__ */
+
diff --git a/libempathy-gtk/empathy-theme-irc.c b/libempathy-gtk/empathy-theme-irc.c
new file mode 100644
index 000000000..afe71e5ea
--- /dev/null
+++ b/libempathy-gtk/empathy-theme-irc.c
@@ -0,0 +1,486 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <libempathy/empathy-debug.h>
+
+#include "empathy-chat.h"
+#include "empathy-theme-utils.h"
+#include "empathy-theme-irc.h"
+
+#define DEBUG_DOMAIN "Theme"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_THEME_IRC, EmpathyThemeIrcPriv))
+
+typedef struct _EmpathyThemeIrcPriv EmpathyThemeIrcPriv;
+
+struct _EmpathyThemeIrcPriv {
+ gint my_prop;
+};
+
+static void theme_irc_finalize (GObject *object);
+static void theme_irc_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void theme_irc_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static EmpathyThemeContext *
+theme_irc_setup_with_view (EmpathyTheme *theme,
+ EmpathyChatView *view);
+static void theme_irc_detach_from_view (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+static void theme_irc_append_message (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message);
+static void theme_irc_append_event (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ const gchar *str);
+static void theme_irc_append_timestamp (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message,
+ gboolean show_date,
+ gboolean show_time);
+static void theme_irc_append_spacing (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+
+
+enum {
+ PROP_0,
+ PROP_MY_PROP
+};
+
+G_DEFINE_TYPE (EmpathyThemeIrc, empathy_theme_irc, EMPATHY_TYPE_THEME);
+
+static void
+empathy_theme_irc_class_init (EmpathyThemeIrcClass *class)
+{
+ GObjectClass *object_class;
+ EmpathyThemeClass *theme_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ theme_class = EMPATHY_THEME_CLASS (class);
+
+ object_class->finalize = theme_irc_finalize;
+ object_class->get_property = theme_irc_get_property;
+ object_class->set_property = theme_irc_set_property;
+
+ theme_class->setup_with_view = theme_irc_setup_with_view;
+ theme_class->detach_from_view = theme_irc_detach_from_view;
+ theme_class->append_message = theme_irc_append_message;
+ theme_class->append_event = theme_irc_append_event;
+ theme_class->append_timestamp = theme_irc_append_timestamp;
+ theme_class->append_spacing = theme_irc_append_spacing;
+
+ g_object_class_install_property (object_class,
+ PROP_MY_PROP,
+ g_param_spec_int ("my-prop",
+ "",
+ "",
+ 0, 1,
+ 1,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (object_class, sizeof (EmpathyThemeIrcPriv));
+}
+
+static void
+empathy_theme_irc_init (EmpathyThemeIrc *presence)
+{
+ EmpathyThemeIrcPriv *priv;
+
+ priv = GET_PRIV (presence);
+}
+
+static void
+theme_irc_finalize (GObject *object)
+{
+ EmpathyThemeIrcPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ (G_OBJECT_CLASS (empathy_theme_irc_parent_class)->finalize) (object);
+}
+
+static void
+theme_irc_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyThemeIrcPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_MY_PROP:
+ g_value_set_int (value, priv->my_prop);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+static void
+theme_irc_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyThemeIrcPriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_MY_PROP:
+ priv->my_prop = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+theme_irc_fixup_tag_table (EmpathyTheme *theme, EmpathyChatView *view)
+{
+ GtkTextBuffer *buffer;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ /* IRC style tags. */
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-nick-self");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-body-self");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-action-self");
+
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-nick-other");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-body-other");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-action-other");
+
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-nick-highlight");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-spacing");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-time");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-event");
+ empathy_theme_utils_ensure_tag_by_name (buffer, "irc-link");
+}
+
+static void
+theme_irc_apply_theme_classic (EmpathyTheme *theme, EmpathyChatView *view)
+{
+ EmpathyThemeIrcPriv *priv;
+ GtkTextBuffer *buffer;
+ GtkTextTagTable *table;
+ GtkTextTag *tag;
+
+ priv = GET_PRIV (theme);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+ table = gtk_text_buffer_get_tag_table (buffer);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-spacing");
+ g_object_set (tag,
+ "size", 2000,
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-nick-self");
+ g_object_set (tag,
+ "foreground", "sea green",
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-body-self");
+ g_object_set (tag,
+ /* To get the default theme color: */
+ "foreground-set", FALSE,
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-action-self");
+ g_object_set (tag,
+ "foreground", "brown4",
+ "style", PANGO_STYLE_ITALIC,
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-nick-highlight");
+ g_object_set (tag,
+ "foreground", "indian red",
+ "weight", PANGO_WEIGHT_BOLD,
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-nick-other");
+ g_object_set (tag,
+ "foreground", "skyblue4",
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-body-other");
+ g_object_set (tag,
+ /* To get the default theme color: */
+ "foreground-set", FALSE,
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-action-other");
+ g_object_set (tag,
+ "foreground", "brown4",
+ "style", PANGO_STYLE_ITALIC,
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-time");
+ g_object_set (tag,
+ "foreground", "darkgrey",
+ "justification", GTK_JUSTIFY_CENTER,
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-event");
+ g_object_set (tag,
+ "foreground", "PeachPuff4",
+ "justification", GTK_JUSTIFY_LEFT,
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "invite");
+ g_object_set (tag,
+ "foreground", "sienna",
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+
+ tag = empathy_theme_utils_init_tag_by_name (table, "irc-link");
+ g_object_set (tag,
+ "foreground", "steelblue",
+ "underline", PANGO_UNDERLINE_SINGLE,
+ NULL);
+ empathy_theme_utils_add_tag (table, tag);
+}
+
+
+static EmpathyThemeContext *
+theme_irc_setup_with_view (EmpathyTheme *theme, EmpathyChatView *view)
+{
+ theme_irc_fixup_tag_table (theme, view);
+ theme_irc_apply_theme_classic (theme, view);
+ empathy_chat_view_set_margin (view, 3);
+
+ return NULL;
+}
+
+static void
+theme_irc_detach_from_view (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view)
+{
+ /* Free the context */
+}
+
+static void
+theme_irc_append_message (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message)
+{
+ GtkTextBuffer *buffer;
+ const gchar *name;
+ const gchar *nick_tag;
+ const gchar *body_tag;
+ GtkTextIter iter;
+ gchar *tmp;
+ EmpathyContact *contact;
+
+ empathy_theme_maybe_append_date_and_time (theme, context, view, message);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ contact = empathy_message_get_sender (message);
+ name = empathy_contact_get_name (contact);
+
+ if (empathy_message_get_type (message) == EMPATHY_MESSAGE_TYPE_ACTION) {
+ if (empathy_contact_is_user (contact)) {
+ body_tag = "irc-action-self";
+ } else {
+ body_tag = "irc-action-other";
+ }
+
+ tmp = g_strdup_printf (" * %s %s",
+ empathy_contact_get_name (contact),
+ empathy_message_get_body (message));
+ empathy_theme_append_text (theme, context, view, tmp,
+ body_tag, "irc-link");
+ g_free (tmp);
+ return;
+ }
+
+ if (empathy_contact_is_user (contact)) {
+ nick_tag = "irc-nick-self";
+ body_tag = "irc-body-self";
+ } else {
+ if (empathy_chat_should_highlight_nick (message)) {
+ nick_tag = "irc-nick-highlight";
+ } else {
+ nick_tag = "irc-nick-other";
+ }
+
+ body_tag = "irc-body-other";
+ }
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+
+ /* The nickname. */
+ tmp = g_strdup_printf ("%s: ", name);
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ tmp,
+ -1,
+ "cut",
+ nick_tag,
+ NULL);
+ g_free (tmp);
+
+ /* The text body. */
+ empathy_theme_append_text (theme, context, view,
+ empathy_message_get_body (message),
+ body_tag, "irc-link");
+}
+
+static void
+theme_irc_append_event (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ const gchar *str)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+ gchar *msg;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ empathy_theme_maybe_append_date_and_time (theme, context, view, NULL);
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+
+ msg = g_strdup_printf (" - %s\n", str);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ msg, -1,
+ "irc-event",
+ NULL);
+ g_free (msg);
+}
+
+static void
+theme_irc_append_timestamp (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message,
+ gboolean show_date,
+ gboolean show_time)
+{
+ GtkTextBuffer *buffer;
+ time_t timestamp;
+ GDate *date;
+ GtkTextIter iter;
+ GString *str;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ date = empathy_message_get_date_and_time (message, &timestamp);
+
+ str = g_string_new (NULL);
+
+ if (show_time || show_date) {
+ empathy_theme_append_spacing (theme,
+ context,
+ view);
+
+ g_string_append (str, "- ");
+ }
+
+ if (show_date) {
+ gchar buf[256];
+
+ g_date_strftime (buf, 256, _("%A %d %B %Y"), date);
+ g_string_append (str, buf);
+
+ if (show_time) {
+ g_string_append (str, ", ");
+ }
+ }
+
+ g_date_free (date);
+
+ if (show_time) {
+ gchar *tmp;
+
+ tmp = empathy_time_to_string_local (timestamp, EMPATHY_TIME_FORMAT_DISPLAY_SHORT);
+ g_string_append (str, tmp);
+ g_free (tmp);
+ }
+
+ if (show_time || show_date) {
+ g_string_append (str, " -\n");
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ str->str, -1,
+ "irc-time",
+ NULL);
+
+ empathy_chat_view_set_last_timestamp (view, timestamp);
+ }
+
+ g_string_free (str, TRUE);
+}
+
+static void
+theme_irc_append_spacing (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+
+ g_return_if_fail (EMPATHY_IS_THEME (theme));
+ g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ "\n",
+ -1,
+ "cut",
+ "irc-spacing",
+ NULL);
+}
+
diff --git a/libempathy-gtk/empathy-theme-irc.h b/libempathy-gtk/empathy-theme-irc.h
new file mode 100644
index 000000000..dc52a56c5
--- /dev/null
+++ b/libempathy-gtk/empathy-theme-irc.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EMPATHY_THEME_IRC_H__
+#define __EMPATHY_THEME_IRC_H__
+
+#include <glib-object.h>
+
+#include "empathy-theme.h"
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_THEME_IRC (empathy_theme_irc_get_type ())
+#define EMPATHY_THEME_IRC(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_THEME_IRC, EmpathyThemeIrc))
+#define EMPATHY_THEME_IRC_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_THEME_IRC, EmpathyThemeIrcClass))
+#define EMPATHY_IS_THEME_IRC(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_THEME_IRC))
+#define EMPATHY_IS_THEME_IRC_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_THEME_IRC))
+#define EMPATHY_THEME_IRC_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_THEME_IRC, EmpathyThemeIrcClass))
+
+typedef struct _EmpathyThemeIrc EmpathyThemeIrc;
+typedef struct _EmpathyThemeIrcClass EmpathyThemeIrcClass;
+
+struct _EmpathyThemeIrc {
+ EmpathyTheme parent;
+};
+
+struct _EmpathyThemeIrcClass {
+ EmpathyThemeClass parent_class;
+};
+
+GType empathy_theme_irc_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __EMPATHY_THEME_IRC_H__ */
+
diff --git a/libempathy-gtk/empathy-theme-manager.c b/libempathy-gtk/empathy-theme-manager.c
index 268760a54..6feea2fc4 100644
--- a/libempathy-gtk/empathy-theme-manager.c
+++ b/libempathy-gtk/empathy-theme-manager.c
@@ -16,8 +16,6 @@
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
- *
- * Authors: Richard Hult <richard@imendio.com>
*/
#include "config.h"
@@ -27,24 +25,32 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#include <libempathy/empathy-conf.h>
#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-conf.h>
#include "empathy-chat-view.h"
#include "empathy-preferences.h"
+#include "empathy-theme.h"
+#include "empathy-theme-boxes.h"
+#include "empathy-theme-irc.h"
#include "empathy-theme-manager.h"
#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_THEME_MANAGER, EmpathyThemeManagerPriv))
typedef struct {
- gchar *name;
- guint name_notify_id;
- guint room_notify_id;
+ gchar *name;
+ guint name_notify_id;
+ guint room_notify_id;
+
+ gboolean show_avatars;
+ guint show_avatars_notify_id;
- gboolean show_avatars;
- guint show_avatars_notify_id;
+ EmpathyTheme *clean_theme;
+ EmpathyTheme *simple_theme;
+ EmpathyTheme *blue_theme;
+ EmpathyTheme *classic_theme;
- gboolean irc_style;
+ gboolean irc_style;
} EmpathyThemeManagerPriv;
static void theme_manager_finalize (GObject *object);
@@ -57,21 +63,6 @@ static void theme_manager_notify_room_cb (EmpathyConf *
static void theme_manager_notify_show_avatars_cb (EmpathyConf *conf,
const gchar *key,
gpointer user_data);
-static void theme_manager_ensure_tag_by_name (GtkTextBuffer *buffer,
- const gchar *name);
-static gboolean theme_manager_ensure_theme_exists (const gchar *name);
-static GtkTextTag *theme_manager_init_tag_by_name (GtkTextTagTable *table,
- const gchar *name);
-static void theme_manager_add_tag (GtkTextTagTable *table,
- GtkTextTag *tag);
-static void theme_manager_fixup_tag_table (EmpathyThemeManager *theme_manager,
- EmpathyChatView *view);
-static void theme_manager_apply_theme_classic (EmpathyThemeManager *manager,
- EmpathyChatView *view);
-static void theme_manager_apply_theme_clean (EmpathyThemeManager *manager,
- EmpathyChatView *view);
-static void theme_manager_apply_theme_blue (EmpathyThemeManager *manager,
- EmpathyChatView *view);
static void theme_manager_apply_theme (EmpathyThemeManager *manager,
EmpathyChatView *view,
const gchar *name);
@@ -146,6 +137,11 @@ empathy_theme_manager_init (EmpathyThemeManager *manager)
empathy_conf_get_bool (empathy_conf_get (),
EMPATHY_PREFS_UI_SHOW_AVATARS,
&priv->show_avatars);
+
+ priv->clean_theme = empathy_theme_boxes_new ("clean");
+ priv->simple_theme = empathy_theme_boxes_new ("simple");
+ priv->blue_theme = empathy_theme_boxes_new ("blue");
+ priv->classic_theme = g_object_new (EMPATHY_TYPE_THEME_IRC, NULL);
}
static void
@@ -161,6 +157,11 @@ theme_manager_finalize (GObject *object)
g_free (priv->name);
+ g_object_unref (priv->clean_theme);
+ g_object_unref (priv->simple_theme);
+ g_object_unref (priv->blue_theme);
+ g_object_unref (priv->classic_theme);
+
G_OBJECT_CLASS (empathy_theme_manager_parent_class)->finalize (object);
}
@@ -217,23 +218,6 @@ theme_manager_notify_show_avatars_cb (EmpathyConf *conf,
}
}
-static void
-theme_manager_ensure_tag_by_name (GtkTextBuffer *buffer,
- const gchar *name)
-{
- GtkTextTagTable *table;
- GtkTextTag *tag;
-
- table = gtk_text_buffer_get_tag_table (buffer);
- tag = gtk_text_tag_table_lookup (table, name);
-
- if (!tag) {
- gtk_text_buffer_create_tag (buffer,
- name,
- NULL);
- }
-}
-
static gboolean
theme_manager_ensure_theme_exists (const gchar *name)
{
@@ -252,690 +236,36 @@ theme_manager_ensure_theme_exists (const gchar *name)
return FALSE;
}
-static GtkTextTag *
-theme_manager_init_tag_by_name (GtkTextTagTable *table,
- const gchar *name)
-{
- GtkTextTag *tag;
-
- tag = gtk_text_tag_table_lookup (table, name);
-
- if (!tag) {
- return gtk_text_tag_new (name);
- }
-
- /* Clear the old values so that we don't affect the new theme. */
- g_object_set (tag,
- "background-set", FALSE,
- "foreground-set", FALSE,
- "invisible-set", FALSE,
- "justification-set", FALSE,
- "paragraph-background-set", FALSE,
- "pixels-above-lines-set", FALSE,
- "pixels-below-lines-set", FALSE,
- "rise-set", FALSE,
- "scale-set", FALSE,
- "size-set", FALSE,
- "style-set", FALSE,
- "weight-set", FALSE,
- NULL);
-
- return tag;
-}
-
-static void
-theme_manager_add_tag (GtkTextTagTable *table,
- GtkTextTag *tag)
-{
- gchar *name;
- GtkTextTag *check_tag;
-
- g_object_get (tag, "name", &name, NULL);
- check_tag = gtk_text_tag_table_lookup (table, name);
- g_free (name);
- if (check_tag) {
- return;
- }
-
- gtk_text_tag_table_add (table, tag);
-
- g_object_unref (tag);
-}
-
-static void
-theme_manager_fixup_tag_table (EmpathyThemeManager *theme_manager,
- EmpathyChatView *view)
-{
- GtkTextBuffer *buffer;
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-
- /* "Fancy" style tags. */
- theme_manager_ensure_tag_by_name (buffer, "fancy-header-self");
- theme_manager_ensure_tag_by_name (buffer, "fancy-header-self-avatar");
- theme_manager_ensure_tag_by_name (buffer, "fancy-avatar-self");
- theme_manager_ensure_tag_by_name (buffer, "fancy-line-top-self");
- theme_manager_ensure_tag_by_name (buffer, "fancy-line-bottom-self");
- theme_manager_ensure_tag_by_name (buffer, "fancy-body-self");
- theme_manager_ensure_tag_by_name (buffer, "fancy-action-self");
- theme_manager_ensure_tag_by_name (buffer, "fancy-highlight-self");
-
- theme_manager_ensure_tag_by_name (buffer, "fancy-header-other");
- theme_manager_ensure_tag_by_name (buffer, "fancy-header-other-avatar");
- theme_manager_ensure_tag_by_name (buffer, "fancy-avatar-other");
- theme_manager_ensure_tag_by_name (buffer, "fancy-line-top-other");
- theme_manager_ensure_tag_by_name (buffer, "fancy-line-bottom-other");
- theme_manager_ensure_tag_by_name (buffer, "fancy-body-other");
- theme_manager_ensure_tag_by_name (buffer, "fancy-action-other");
- theme_manager_ensure_tag_by_name (buffer, "fancy-highlight-other");
-
- theme_manager_ensure_tag_by_name (buffer, "fancy-spacing");
- theme_manager_ensure_tag_by_name (buffer, "fancy-time");
- theme_manager_ensure_tag_by_name (buffer, "fancy-event");
- theme_manager_ensure_tag_by_name (buffer, "fancy-invite");
- theme_manager_ensure_tag_by_name (buffer, "fancy-link");
-
- /* IRC style tags. */
- theme_manager_ensure_tag_by_name (buffer, "irc-nick-self");
- theme_manager_ensure_tag_by_name (buffer, "irc-body-self");
- theme_manager_ensure_tag_by_name (buffer, "irc-action-self");
-
- theme_manager_ensure_tag_by_name (buffer, "irc-nick-other");
- theme_manager_ensure_tag_by_name (buffer, "irc-body-other");
- theme_manager_ensure_tag_by_name (buffer, "irc-action-other");
-
- theme_manager_ensure_tag_by_name (buffer, "irc-nick-highlight");
- theme_manager_ensure_tag_by_name (buffer, "irc-spacing");
- theme_manager_ensure_tag_by_name (buffer, "irc-time");
- theme_manager_ensure_tag_by_name (buffer, "irc-event");
- theme_manager_ensure_tag_by_name (buffer, "irc-invite");
- theme_manager_ensure_tag_by_name (buffer, "irc-link");
-}
-
-static void
-theme_manager_apply_theme_classic (EmpathyThemeManager *manager,
- EmpathyChatView *view)
-{
- EmpathyThemeManagerPriv *priv;
- GtkTextBuffer *buffer;
- GtkTextTagTable *table;
- GtkTextTag *tag;
-
- priv = GET_PRIV (manager);
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
- table = gtk_text_buffer_get_tag_table (buffer);
-
- priv->irc_style = TRUE;
-
- tag = theme_manager_init_tag_by_name (table, "irc-spacing");
- g_object_set (tag,
- "size", 2000,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-nick-self");
- g_object_set (tag,
- "foreground", "sea green",
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-body-self");
- g_object_set (tag,
- /* To get the default theme color: */
- "foreground-set", FALSE,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-action-self");
- g_object_set (tag,
- "foreground", "brown4",
- "style", PANGO_STYLE_ITALIC,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-nick-highlight");
- g_object_set (tag,
- "foreground", "indian red",
- "weight", PANGO_WEIGHT_BOLD,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-nick-other");
- g_object_set (tag,
- "foreground", "skyblue4",
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-body-other");
- g_object_set (tag,
- /* To get the default theme color: */
- "foreground-set", FALSE,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-action-other");
- g_object_set (tag,
- "foreground", "brown4",
- "style", PANGO_STYLE_ITALIC,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-time");
- g_object_set (tag,
- "foreground", "darkgrey",
- "justification", GTK_JUSTIFY_CENTER,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-event");
- g_object_set (tag,
- "foreground", "PeachPuff4",
- "justification", GTK_JUSTIFY_LEFT,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-invite");
- g_object_set (tag,
- "foreground", "sienna",
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "irc-link");
- g_object_set (tag,
- "foreground", "steelblue",
- "underline", PANGO_UNDERLINE_SINGLE,
- NULL);
- theme_manager_add_tag (table, tag);
-}
-
-static void
-theme_manager_apply_theme_simple (EmpathyThemeManager *manager,
- EmpathyChatView *view)
-{
- EmpathyThemeManagerPriv *priv;
- GtkTextBuffer *buffer;
- GtkTextTagTable *table;
- GtkTextTag *tag;
- GtkWidget *widget;
- GtkStyle *style;
-
- priv = GET_PRIV (manager);
-
- widget = gtk_entry_new ();
- style = gtk_widget_get_style (widget);
- gtk_widget_destroy (widget);
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
- table = gtk_text_buffer_get_tag_table (buffer);
-
- priv->irc_style = FALSE;
-
- tag = theme_manager_init_tag_by_name (table, "fancy-spacing");
- g_object_set (tag,
- "size", 3000,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-header-self");
- g_object_set (tag,
- "weight", PANGO_WEIGHT_BOLD,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-header-self-avatar");
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-avatar-self");
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-top-self");
- g_object_set (tag,
- "size", 6 * PANGO_SCALE,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-self");
- g_object_set (tag,
- "size", 1,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-body-self");
- g_object_set (tag,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-action-self");
- g_object_set (tag,
- "foreground-gdk", &style->base[GTK_STATE_SELECTED],
- "style", PANGO_STYLE_ITALIC,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-highlight-self");
- g_object_set (tag,
- "weight", PANGO_WEIGHT_BOLD,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-header-other");
- g_object_set (tag,
- "weight", PANGO_WEIGHT_BOLD,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-header-other-avatar");
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-avatar-other");
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-top-other");
- g_object_set (tag,
- "size", 6 * PANGO_SCALE,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-other");
- g_object_set (tag,
- "size", 1,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-body-other");
- g_object_set (tag,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-action-other");
- g_object_set (tag,
- "foreground-gdk", &style->base[GTK_STATE_SELECTED],
- "style", PANGO_STYLE_ITALIC,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-highlight-other");
- g_object_set (tag,
- "weight", PANGO_WEIGHT_BOLD,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-time");
- g_object_set (tag,
- "foreground", "darkgrey",
- "justification", GTK_JUSTIFY_CENTER,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-event");
- g_object_set (tag,
- "foreground", "darkgrey",
- "justification", GTK_JUSTIFY_LEFT,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-invite");
- g_object_set (tag,
- "foreground", "darkgrey",
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-link");
- g_object_set (tag,
- "foreground-gdk", &style->base[GTK_STATE_SELECTED],
- "underline", PANGO_UNDERLINE_SINGLE,
- NULL);
- theme_manager_add_tag (table, tag);
-}
-
-static void
-theme_manager_apply_theme_clean (EmpathyThemeManager *manager,
- EmpathyChatView *view)
-{
- EmpathyThemeManagerPriv *priv;
- GtkTextBuffer *buffer;
- GtkTextTagTable *table;
- GtkTextTag *tag;
-
- priv = GET_PRIV (manager);
-
- /* Inherit the simple theme. */
- theme_manager_apply_theme_simple (manager, view);
-
-#define ELEGANT_HEAD "#efefdf"
-#define ELEGANT_LINE "#e3e3d3"
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
- table = gtk_text_buffer_get_tag_table (buffer);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-spacing");
- g_object_set (tag,
- "size", PANGO_SCALE * 10,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-header-self");
- g_object_set (tag,
- "foreground", "black",
- "weight", PANGO_WEIGHT_BOLD,
- "paragraph-background", ELEGANT_HEAD,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-avatar-self");
- g_object_set (tag,
- "paragraph-background", ELEGANT_HEAD,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-top-self");
- g_object_set (tag,
- "size", 1 * PANGO_SCALE,
- "paragraph-background", ELEGANT_LINE,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-self");
- g_object_set (tag,
- "size", 1 * PANGO_SCALE,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-action-self");
- g_object_set (tag,
- "foreground", "brown4",
- "style", PANGO_STYLE_ITALIC,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-highlight-self");
- g_object_set (tag,
- "foreground", "black",
- "weight", PANGO_WEIGHT_BOLD,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-header-other");
- g_object_set (tag,
- "foreground", "black",
- "weight", PANGO_WEIGHT_BOLD,
- "paragraph-background", ELEGANT_HEAD,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-avatar-other");
- g_object_set (tag,
- "paragraph-background", ELEGANT_HEAD,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-top-other");
- g_object_set (tag,
- "size", 1 * PANGO_SCALE,
- "paragraph-background", ELEGANT_LINE,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-other");
- g_object_set (tag,
- "size", 1 * PANGO_SCALE,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-action-other");
- g_object_set (tag,
- "foreground", "brown4",
- "style", PANGO_STYLE_ITALIC,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-time");
- g_object_set (tag,
- "foreground", "darkgrey",
- "justification", GTK_JUSTIFY_CENTER,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-event");
- g_object_set (tag,
- "foreground", "darkgrey",
- "justification", GTK_JUSTIFY_LEFT,
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-invite");
- g_object_set (tag,
- "foreground", "sienna",
- NULL);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-link");
- g_object_set (tag,
- "foreground", "#49789e",
- "underline", PANGO_UNDERLINE_SINGLE,
- NULL);
-}
-
-static void
-theme_manager_apply_theme_blue (EmpathyThemeManager *manager,
- EmpathyChatView *view)
-{
- EmpathyThemeManagerPriv *priv;
- GtkTextBuffer *buffer;
- GtkTextTagTable *table;
- GtkTextTag *tag;
-
- priv = GET_PRIV (manager);
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
- table = gtk_text_buffer_get_tag_table (buffer);
-
- priv->irc_style = FALSE;
-
-#define BLUE_BODY_SELF "#dcdcdc"
-#define BLUE_HEAD_SELF "#b9b9b9"
-#define BLUE_LINE_SELF "#aeaeae"
-
-#define BLUE_BODY_OTHER "#adbdc8"
-#define BLUE_HEAD_OTHER "#88a2b4"
-#define BLUE_LINE_OTHER "#7f96a4"
-
- tag = theme_manager_init_tag_by_name (table, "fancy-spacing");
- g_object_set (tag,
- "size", 3000,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-header-self");
- g_object_set (tag,
- "foreground", "black",
- "paragraph-background", BLUE_HEAD_SELF,
- "weight", PANGO_WEIGHT_BOLD,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-header-self-avatar");
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-avatar-self");
- g_object_set (tag,
- "paragraph-background", BLUE_HEAD_SELF,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-top-self");
- g_object_set (tag,
- "size", 1,
- "paragraph-background", BLUE_LINE_SELF,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-self");
- g_object_set (tag,
- "size", 1,
- "paragraph-background", BLUE_LINE_SELF,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-body-self");
- g_object_set (tag,
- "foreground", "black",
- "paragraph-background", BLUE_BODY_SELF,
- "pixels-above-lines", 4,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-action-self");
- g_object_set (tag,
- "foreground", "brown4",
- "style", PANGO_STYLE_ITALIC,
- "paragraph-background", BLUE_BODY_SELF,
- "pixels-above-lines", 4,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-highlight-self");
- g_object_set (tag,
- "foreground", "black",
- "weight", PANGO_WEIGHT_BOLD,
- "paragraph-background", BLUE_BODY_SELF,
- "pixels-above-lines", 4,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-header-other");
- g_object_set (tag,
- "foreground", "black",
- "paragraph-background", BLUE_HEAD_OTHER,
- "weight", PANGO_WEIGHT_BOLD,
- "pixels-above-lines", 2,
- "pixels-below-lines", 2,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-header-other-avatar");
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-avatar-other");
- g_object_set (tag,
- "paragraph-background", BLUE_HEAD_OTHER,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-top-other");
- g_object_set (tag,
- "size", 1,
- "paragraph-background", BLUE_LINE_OTHER,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-line-bottom-other");
- g_object_set (tag,
- "size", 1,
- "paragraph-background", BLUE_LINE_OTHER,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-body-other");
- g_object_set (tag,
- "foreground", "black",
- "paragraph-background", BLUE_BODY_OTHER,
- "pixels-above-lines", 4,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-action-other");
- g_object_set (tag,
- "foreground", "brown4",
- "style", PANGO_STYLE_ITALIC,
- "paragraph-background", BLUE_BODY_OTHER,
- "pixels-above-lines", 4,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-highlight-other");
- g_object_set (tag,
- "foreground", "black",
- "weight", PANGO_WEIGHT_BOLD,
- "paragraph-background", BLUE_BODY_OTHER,
- "pixels-above-lines", 4,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-time");
- g_object_set (tag,
- "foreground", "darkgrey",
- "justification", GTK_JUSTIFY_CENTER,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-event");
- g_object_set (tag,
- "foreground", BLUE_LINE_OTHER,
- "justification", GTK_JUSTIFY_LEFT,
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-invite");
- g_object_set (tag,
- "foreground", "sienna",
- NULL);
- theme_manager_add_tag (table, tag);
-
- tag = theme_manager_init_tag_by_name (table, "fancy-link");
- g_object_set (tag,
- "foreground", "#49789e",
- "underline", PANGO_UNDERLINE_SINGLE,
- NULL);
- theme_manager_add_tag (table, tag);
-}
-
static void
theme_manager_apply_theme (EmpathyThemeManager *manager,
EmpathyChatView *view,
const gchar *name)
{
EmpathyThemeManagerPriv *priv;
- gint margin;
+ EmpathyTheme *theme;
priv = GET_PRIV (manager);
/* Make sure all tags are present. Note: not useful now but when we have
* user defined theme it will be.
*/
- theme_manager_fixup_tag_table (manager, view);
-
if (theme_manager_ensure_theme_exists (name)) {
if (strcmp (name, "clean") == 0) {
- theme_manager_apply_theme_clean (manager, view);
- margin = 3;
+ theme = priv->clean_theme;
}
else if (strcmp (name, "simple") == 0) {
- theme_manager_apply_theme_simple (manager, view);
- margin = 3;
+ theme = priv->simple_theme;
}
else if (strcmp (name, "blue") == 0) {
- theme_manager_apply_theme_blue (manager, view);
- margin = 0;
+ theme = priv->blue_theme;
} else {
- theme_manager_apply_theme_classic (manager, view);
- margin = 3;
+ theme = priv->classic_theme;
}
} else {
- theme_manager_apply_theme_classic (manager, view);
- margin = 3;
+ theme = priv->classic_theme;
}
- empathy_chat_view_set_margin (view, margin);
- empathy_chat_view_set_irc_style (view, priv->irc_style);
+ empathy_chat_view_set_theme (view, theme);
}
EmpathyThemeManager *
@@ -979,67 +309,3 @@ empathy_theme_manager_apply_saved (EmpathyThemeManager *manager,
theme_manager_apply_theme (manager, view, priv->name);
}
-/* FIXME: A bit ugly. We should probably change the scheme so that instead of
- * the manager signalling, views are registered and applied to automatically.
- */
-void
-empathy_theme_manager_update_show_avatars (EmpathyThemeManager *manager,
- EmpathyChatView *view,
- gboolean show)
-{
- EmpathyThemeManagerPriv *priv;
- GtkTextBuffer *buffer;
- GtkTextTagTable *table;
- GtkTextTag *tag_text_self, *tag_text_other;
- GtkTextTag *tag_image_self, *tag_image_other;
-
- priv = GET_PRIV (manager);
-
- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
- table = gtk_text_buffer_get_tag_table (buffer);
-
- tag_text_self = gtk_text_tag_table_lookup (table, "fancy-header-self-avatar");
- tag_text_other = gtk_text_tag_table_lookup (table, "fancy-header-other-avatar");
-
- tag_image_self = gtk_text_tag_table_lookup (table, "fancy-avatar-self");
- tag_image_other = gtk_text_tag_table_lookup (table, "fancy-avatar-other");
-
- if (!show) {
- g_object_set (tag_text_self,
- "rise", 0,
- NULL);
- g_object_set (tag_text_other,
- "rise", 0,
- NULL);
- g_object_set (tag_image_self,
- "invisible", TRUE,
- NULL);
- g_object_set (tag_image_other,
- "invisible", TRUE,
- NULL);
- } else {
- GtkTextAttributes *attrs;
- gint size;
- gint rise;
-
- attrs = gtk_text_view_get_default_attributes (GTK_TEXT_VIEW (view));
- size = pango_font_description_get_size (attrs->font);
- rise = MAX (0, (32 * PANGO_SCALE - size) / 2.0);
-
- g_object_set (tag_text_self,
- "rise", rise,
- NULL);
- g_object_set (tag_text_other,
- "rise", rise,
- NULL);
- g_object_set (tag_image_self,
- "invisible", FALSE,
- NULL);
- g_object_set (tag_image_other,
- "invisible", FALSE,
- NULL);
-
- gtk_text_attributes_unref (attrs);
- }
-}
-
diff --git a/libempathy-gtk/empathy-theme-manager.h b/libempathy-gtk/empathy-theme-manager.h
index d20a916e1..6bd2d41f5 100644
--- a/libempathy-gtk/empathy-theme-manager.h
+++ b/libempathy-gtk/empathy-theme-manager.h
@@ -16,8 +16,6 @@
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
- *
- * Authors: Richard Hult <richard@imendio.com>
*/
#ifndef __EMPATHY_THEME_MANAGER_H__
@@ -25,8 +23,6 @@
#include <glib-object.h>
-#include "empathy-chat-view.h"
-
G_BEGIN_DECLS
#define EMPATHY_TYPE_THEME_MANAGER (empathy_theme_manager_get_type ())
@@ -55,9 +51,6 @@ void empathy_theme_manager_apply (EmpathyThemeManag
const gchar *theme);
void empathy_theme_manager_apply_saved (EmpathyThemeManager *manager,
EmpathyChatView *view);
-void empathy_theme_manager_update_show_avatars (EmpathyThemeManager *manager,
- EmpathyChatView *view,
- gboolean show);
G_END_DECLS
diff --git a/libempathy-gtk/empathy-theme-utils.c b/libempathy-gtk/empathy-theme-utils.c
new file mode 100644
index 000000000..56b758e2a
--- /dev/null
+++ b/libempathy-gtk/empathy-theme-utils.c
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <gtk/gtktexttag.h>
+
+#include "empathy-theme-utils.h"
+
+void
+empathy_theme_utils_ensure_tag_by_name (GtkTextBuffer *buffer, const gchar *name)
+{
+ GtkTextTagTable *table;
+ GtkTextTag *tag;
+
+ table = gtk_text_buffer_get_tag_table (buffer);
+ tag = gtk_text_tag_table_lookup (table, name);
+
+ if (!tag) {
+ gtk_text_buffer_create_tag (buffer,
+ name,
+ NULL);
+ }
+}
+
+GtkTextTag *
+empathy_theme_utils_init_tag_by_name (GtkTextTagTable *table, const gchar *name)
+{
+ GtkTextTag *tag;
+
+ tag = gtk_text_tag_table_lookup (table, name);
+
+ if (!tag) {
+ return gtk_text_tag_new (name);
+ }
+
+ /* Clear the old values so that we don't affect the new theme. */
+ g_object_set (tag,
+ "background-set", FALSE,
+ "foreground-set", FALSE,
+ "invisible-set", FALSE,
+ "justification-set", FALSE,
+ "paragraph-background-set", FALSE,
+ "pixels-above-lines-set", FALSE,
+ "pixels-below-lines-set", FALSE,
+ "rise-set", FALSE,
+ "scale-set", FALSE,
+ "size-set", FALSE,
+ "style-set", FALSE,
+ "weight-set", FALSE,
+ NULL);
+
+ return tag;
+}
+
+void
+empathy_theme_utils_add_tag (GtkTextTagTable *table, GtkTextTag *tag)
+{
+ gchar *name;
+ GtkTextTag *check_tag;
+
+ g_object_get (tag, "name", &name, NULL);
+ check_tag = gtk_text_tag_table_lookup (table, name);
+ g_free (name);
+ if (check_tag) {
+ return;
+ }
+
+ gtk_text_tag_table_add (table, tag);
+
+ g_object_unref (tag);
+}
+
diff --git a/libempathy-gtk/empathy-theme-utils.h b/libempathy-gtk/empathy-theme-utils.h
new file mode 100644
index 000000000..af970775f
--- /dev/null
+++ b/libempathy-gtk/empathy-theme-utils.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EMPATHY_THEME_UTILS_H__
+#define __EMPATHY_THEME_UTILS_H__
+
+#include <gtk/gtktextbuffer.h>
+#include <gtk/gtktexttag.h>
+
+G_BEGIN_DECLS
+
+void empathy_theme_utils_ensure_tag_by_name (GtkTextBuffer *buffer,
+ const gchar *name);
+GtkTextTag * empathy_theme_utils_init_tag_by_name (GtkTextTagTable *table,
+ const gchar *name);
+void empathy_theme_utils_add_tag (GtkTextTagTable *table,
+ GtkTextTag *tag);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_THEME_UTILS_H__ */
+
+
diff --git a/libempathy-gtk/empathy-theme.c b/libempathy-gtk/empathy-theme.c
new file mode 100644
index 000000000..185ad925a
--- /dev/null
+++ b/libempathy-gtk/empathy-theme.c
@@ -0,0 +1,475 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-conf.h>
+#include <libempathy/empathy-debug.h>
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-marshal.h>
+
+#include "empathy-chat.h"
+#include "empathy-preferences.h"
+#include "empathy-theme-utils.h"
+#include "empathy-theme.h"
+#include "empathy-smiley-manager.h"
+
+#define DEBUG_DOMAIN "Theme"
+
+/* Number of seconds between timestamps when using normal mode, 5 minutes. */
+#define TIMESTAMP_INTERVAL 300
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_THEME, EmpathyThemePriv))
+
+typedef struct _EmpathyThemePriv EmpathyThemePriv;
+
+struct _EmpathyThemePriv {
+ EmpathySmileyManager *smiley_manager;
+ gboolean show_avatars;
+};
+
+static void theme_finalize (GObject *object);
+static void theme_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void theme_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+
+G_DEFINE_TYPE (EmpathyTheme, empathy_theme, G_TYPE_OBJECT);
+
+enum {
+ PROP_0,
+ PROP_SHOW_AVATARS
+};
+
+enum {
+ UPDATED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+empathy_theme_class_init (EmpathyThemeClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+
+ object_class->finalize = theme_finalize;
+ object_class->get_property = theme_get_property;
+ object_class->set_property = theme_set_property;
+
+ class->setup_with_view = NULL;
+ class->view_cleared = NULL;
+ class->append_message = NULL;
+ class->append_event = NULL;
+ class->append_timestamp = NULL;
+ class->append_spacing = NULL;
+
+ g_object_class_install_property (object_class,
+ PROP_SHOW_AVATARS,
+ g_param_spec_boolean ("show-avatars",
+ "", "",
+ TRUE,
+ G_PARAM_READWRITE));
+
+ signals[UPDATED] =
+ g_signal_new ("updated",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ empathy_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private (object_class, sizeof (EmpathyThemePriv));
+}
+
+static void
+empathy_theme_init (EmpathyTheme *presence)
+{
+ EmpathyThemePriv *priv;
+
+ priv = GET_PRIV (presence);
+
+ priv->smiley_manager = empathy_smiley_manager_new ();
+}
+
+static void
+theme_finalize (GObject *object)
+{
+ EmpathyThemePriv *priv;
+
+ priv = GET_PRIV (object);
+
+ if (priv->smiley_manager) {
+ g_object_unref (priv->smiley_manager);
+ }
+
+ (G_OBJECT_CLASS (empathy_theme_parent_class)->finalize) (object);
+}
+
+static void
+theme_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyThemePriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_SHOW_AVATARS:
+ g_value_set_boolean (value, priv->show_avatars);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+theme_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyThemePriv *priv;
+
+ priv = GET_PRIV (object);
+
+ switch (param_id) {
+ case PROP_SHOW_AVATARS:
+ priv->show_avatars = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+void
+empathy_theme_maybe_append_date_and_time (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message)
+{
+ time_t timestamp;
+ GDate *date, *last_date;
+ gboolean append_date, append_time;
+
+ date = empathy_message_get_date_and_time (message, &timestamp);
+
+ last_date = g_date_new ();
+ g_date_set_time (last_date, empathy_chat_view_get_last_timestamp (view));
+
+ append_date = FALSE;
+ append_time = FALSE;
+
+ if (g_date_compare (date, last_date) > 0) {
+ append_date = TRUE;
+ append_time = TRUE;
+ }
+
+ g_date_free (last_date);
+ g_date_free (date);
+
+ if (empathy_chat_view_get_last_timestamp (view) + TIMESTAMP_INTERVAL < timestamp) {
+ append_time = TRUE;
+ }
+
+ if (append_time || append_date) {
+ empathy_theme_append_timestamp (theme, context,
+ view, message,
+ append_date, append_time);
+ }
+}
+
+EmpathyTheme *
+empathy_theme_new (void)
+{
+ EmpathyTheme *theme;
+
+ theme = g_object_new (EMPATHY_TYPE_THEME, NULL);
+
+ return theme;
+}
+
+EmpathyThemeContext *
+empathy_theme_setup_with_view (EmpathyTheme *theme,
+ EmpathyChatView *view)
+{
+ if (!EMPATHY_THEME_GET_CLASS(theme)->setup_with_view) {
+ g_error ("Theme must override setup_with_view");
+ }
+
+ return EMPATHY_THEME_GET_CLASS(theme)->setup_with_view (theme, view);
+}
+
+void
+empathy_theme_detach_from_view (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view)
+{
+ if (!EMPATHY_THEME_GET_CLASS(theme)->detach_from_view) {
+ g_error ("Theme must override detach_from_view");
+ }
+
+ return EMPATHY_THEME_GET_CLASS(theme)->detach_from_view (theme, context,
+ view);
+}
+
+void
+empathy_theme_view_cleared (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view)
+{
+ if (!EMPATHY_THEME_GET_CLASS(theme)->view_cleared) {
+ return;
+ }
+
+ EMPATHY_THEME_GET_CLASS(theme)->view_cleared (theme, context, view);
+}
+
+void
+empathy_theme_append_message (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message)
+{
+ if (!EMPATHY_THEME_GET_CLASS(theme)->append_message) {
+ g_warning ("Theme should override append_message");
+ return;
+ }
+
+ EMPATHY_THEME_GET_CLASS(theme)->append_message (theme, context, view,
+ message);
+}
+
+static void
+theme_insert_text_with_emoticons (GtkTextBuffer *buf,
+ GtkTextIter *iter,
+ const gchar *str,
+ EmpathySmileyManager *smiley_manager)
+{
+ gboolean use_smileys = FALSE;
+ GSList *smileys, *l;
+
+ empathy_conf_get_bool (empathy_conf_get (),
+ EMPATHY_PREFS_CHAT_SHOW_SMILEYS,
+ &use_smileys);
+
+ if (!use_smileys) {
+ gtk_text_buffer_insert (buf, iter, str, -1);
+ return;
+ }
+
+ smileys = empathy_smiley_manager_parse (smiley_manager, str);
+ for (l = smileys; l; l = l->next) {
+ EmpathySmiley *smiley;
+
+ smiley = l->data;
+ if (smiley->pixbuf) {
+ gtk_text_buffer_insert_pixbuf (buf, iter, smiley->pixbuf);
+ } else {
+ gtk_text_buffer_insert (buf, iter, smiley->str, -1);
+ }
+ empathy_smiley_free (smiley);
+ }
+ g_slist_free (smileys);
+}
+
+void
+empathy_theme_append_text (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ const gchar *body,
+ const gchar *tag,
+ const gchar *link_tag)
+{
+ EmpathyThemePriv *priv;
+ GtkTextBuffer *buffer;
+ GtkTextIter start_iter, end_iter;
+ GtkTextMark *mark;
+ GtkTextIter iter;
+ gint num_matches, i;
+ GArray *start, *end;
+
+ priv = GET_PRIV (theme);
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ gtk_text_buffer_get_end_iter (buffer, &start_iter);
+ mark = gtk_text_buffer_create_mark (buffer, NULL, &start_iter, TRUE);
+
+ start = g_array_new (FALSE, FALSE, sizeof (gint));
+ end = g_array_new (FALSE, FALSE, sizeof (gint));
+
+ num_matches = empathy_regex_match (EMPATHY_REGEX_ALL, body, start, end);
+
+ if (num_matches == 0) {
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ theme_insert_text_with_emoticons (buffer, &iter, body, priv->smiley_manager);
+ } else {
+ gint last = 0;
+ gint s = 0, e = 0;
+ gchar *tmp;
+
+ for (i = 0; i < num_matches; i++) {
+ s = g_array_index (start, gint, i);
+ e = g_array_index (end, gint, i);
+
+ if (s > last) {
+ tmp = empathy_substring (body, last, s);
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ theme_insert_text_with_emoticons (buffer,
+ &iter,
+ tmp,
+ priv->smiley_manager);
+ g_free (tmp);
+ }
+
+ tmp = empathy_substring (body, s, e);
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ if (!link_tag) {
+ gtk_text_buffer_insert (buffer, &iter,
+ tmp, -1);
+ } {
+ gtk_text_buffer_insert_with_tags_by_name (buffer,
+ &iter,
+ tmp,
+ -1,
+ link_tag,
+ "link",
+ NULL);
+ }
+
+ g_free (tmp);
+
+ last = e;
+ }
+
+ if (e < strlen (body)) {
+ tmp = empathy_substring (body, e, strlen (body));
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ theme_insert_text_with_emoticons (buffer,
+ &iter,
+ tmp,
+ priv->smiley_manager);
+ g_free (tmp);
+ }
+ }
+
+ g_array_free (start, TRUE);
+ g_array_free (end, TRUE);
+
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+ gtk_text_buffer_insert (buffer, &iter, "\n", 1);
+
+ /* Apply the style to the inserted text. */
+ gtk_text_buffer_get_iter_at_mark (buffer, &start_iter, mark);
+ gtk_text_buffer_get_end_iter (buffer, &end_iter);
+
+ gtk_text_buffer_apply_tag_by_name (buffer,
+ tag,
+ &start_iter,
+ &end_iter);
+
+ gtk_text_buffer_delete_mark (buffer, mark);
+}
+
+void
+empathy_theme_append_event (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ const gchar *str)
+{
+ EMPATHY_THEME_GET_CLASS(theme)->append_event (theme, context, view, str);
+}
+
+void
+empathy_theme_append_spacing (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view)
+{
+ if (!EMPATHY_THEME_GET_CLASS(theme)->append_spacing) {
+ return;
+ }
+
+ EMPATHY_THEME_GET_CLASS(theme)->append_spacing (theme, context, view);
+}
+
+
+void
+empathy_theme_append_timestamp (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message,
+ gboolean show_date,
+ gboolean show_time)
+{
+ if (!EMPATHY_THEME_GET_CLASS(theme)->append_timestamp) {
+ return;
+ }
+
+ EMPATHY_THEME_GET_CLASS(theme)->append_timestamp (theme, context, view,
+ message, show_date,
+ show_time);
+}
+
+gboolean
+empathy_theme_get_show_avatars (EmpathyTheme *theme)
+{
+ EmpathyThemePriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_THEME (theme), FALSE);
+
+ priv = GET_PRIV (theme);
+
+ return priv->show_avatars;
+}
+
+void
+empathy_theme_set_show_avatars (EmpathyTheme *theme, gboolean show)
+{
+ EmpathyThemePriv *priv;
+
+ g_return_if_fail (EMPATHY_IS_THEME (theme));
+
+ priv = GET_PRIV (theme);
+
+ priv->show_avatars = show;
+
+ g_object_notify (G_OBJECT (theme), "show-avatars");
+}
+
diff --git a/libempathy-gtk/empathy-theme.h b/libempathy-gtk/empathy-theme.h
new file mode 100644
index 000000000..b05342aa7
--- /dev/null
+++ b/libempathy-gtk/empathy-theme.h
@@ -0,0 +1,132 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Imendio AB
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EMPATHY_THEME_H__
+#define __EMPATHY_THEME_H__
+
+#include <glib-object.h>
+#include <gtk/gtktextbuffer.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_THEME (empathy_theme_get_type ())
+#define EMPATHY_THEME(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_THEME, EmpathyTheme))
+#define EMPATHY_THEME_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_THEME, EmpathyThemeClass))
+#define EMPATHY_IS_THEME(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_THEME))
+#define EMPATHY_IS_THEME_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_THEME))
+#define EMPATHY_THEME_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_THEME, EmpathyThemeClass))
+
+typedef struct _EmpathyTheme EmpathyTheme;
+typedef struct _EmpathyThemeClass EmpathyThemeClass;
+
+#include "empathy-chat-view.h"
+
+struct _EmpathyTheme {
+ GObject parent;
+};
+
+typedef void EmpathyThemeContext;
+
+struct _EmpathyThemeClass {
+ GObjectClass parent_class;
+
+ /* <vtable> */
+ EmpathyThemeContext * (*setup_with_view) (EmpathyTheme *theme,
+ EmpathyChatView *view);
+ void (*detach_from_view) (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+ void (*view_cleared) (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+ void (*append_message) (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message);
+ void (*append_event) (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ const gchar *str);
+ void (*append_timestamp) (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message,
+ gboolean show_date,
+ gboolean show_time);
+ void (*append_spacing) (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+ void (*update_show_avatars) (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ gboolean show);
+};
+
+GType empathy_theme_get_type (void) G_GNUC_CONST;
+
+EmpathyTheme * empathy_theme_new (void);
+
+EmpathyThemeContext *
+empathy_theme_setup_with_view (EmpathyTheme *theme,
+ EmpathyChatView *view);
+void empathy_theme_detach_from_view (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+void empathy_theme_view_cleared (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+
+void empathy_theme_append_message (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *msg);
+void empathy_theme_append_text (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ const gchar *body,
+ const gchar *tag,
+ const gchar *link_tag);
+void empathy_theme_append_spacing (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view);
+void empathy_theme_append_event (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ const gchar *str);
+void empathy_theme_append_timestamp (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message,
+ gboolean show_date,
+ gboolean show_time);
+
+void
+empathy_theme_maybe_append_date_and_time (EmpathyTheme *theme,
+ EmpathyThemeContext *context,
+ EmpathyChatView *view,
+ EmpathyMessage *message);
+gboolean empathy_theme_get_show_avatars (EmpathyTheme *theme);
+void empathy_theme_set_show_avatars (EmpathyTheme *theme,
+ gboolean show);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_THEME_H__ */
+
diff --git a/libempathy/empathy-marshal.list b/libempathy/empathy-marshal.list
index 383bfbbed..1a79b058a 100644
--- a/libempathy/empathy-marshal.list
+++ b/libempathy/empathy-marshal.list
@@ -1,3 +1,4 @@
+VOID:VOID
VOID:OBJECT,UINT
VOID:OBJECT,BOOLEAN
VOID:OBJECT,POINTER
diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c
index 5c2028bd0..2d3fd69e4 100644
--- a/libempathy/empathy-message.c
+++ b/libempathy/empathy-message.c
@@ -417,6 +417,26 @@ empathy_message_set_timestamp (EmpathyMessage *message,
g_object_notify (G_OBJECT (message), "timestamp");
}
+GDate *
+empathy_message_get_date_and_time (EmpathyMessage *message, time_t *timestamp)
+{
+ GDate *date;
+
+ *timestamp = 0;
+ if (message) {
+ *timestamp = empathy_message_get_timestamp (message);
+ }
+
+ if (timestamp <= 0) {
+ *timestamp = empathy_time_get_current ();
+ }
+
+ date = g_date_new ();
+ g_date_set_time (date, *timestamp);
+
+ return date;
+}
+
EmpathyMessageType
empathy_message_type_from_str (const gchar *type_str)
{
diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h
index af19d364c..668b33311 100644
--- a/libempathy/empathy-message.h
+++ b/libempathy/empathy-message.h
@@ -75,6 +75,8 @@ void empathy_message_set_body (EmpathyMessage *message,
time_t empathy_message_get_timestamp (EmpathyMessage *message);
void empathy_message_set_timestamp (EmpathyMessage *message,
time_t timestamp);
+GDate * empathy_message_get_date_and_time (EmpathyMessage *message,
+ time_t *timestamp);
EmpathyMessageType empathy_message_type_from_str (const gchar *type_str);
const gchar * empathy_message_type_to_str (EmpathyMessageType type);