empathy r1993 - trunk/libempathy-gtk



Author: xclaesse
Date: Tue Dec 16 09:24:35 2008
New Revision: 1993
URL: http://svn.gnome.org/viewvc/empathy?rev=1993&view=rev

Log:
Completely rework the theming system to make easy implementing themes based on other classes like webkit.

Modified:
   trunk/libempathy-gtk/empathy-chat-text-view.c
   trunk/libempathy-gtk/empathy-chat-text-view.h
   trunk/libempathy-gtk/empathy-chat.c
   trunk/libempathy-gtk/empathy-log-window.c
   trunk/libempathy-gtk/empathy-theme-boxes.c
   trunk/libempathy-gtk/empathy-theme-boxes.h
   trunk/libempathy-gtk/empathy-theme-irc.c
   trunk/libempathy-gtk/empathy-theme-irc.h
   trunk/libempathy-gtk/empathy-theme-manager.c
   trunk/libempathy-gtk/empathy-theme-manager.h

Modified: trunk/libempathy-gtk/empathy-chat-text-view.c
==============================================================================
--- trunk/libempathy-gtk/empathy-chat-text-view.c	(original)
+++ trunk/libempathy-gtk/empathy-chat-text-view.c	Tue Dec 16 09:24:35 2008
@@ -49,7 +49,6 @@
 #include "empathy-chat-text-view.h"
 #include "empathy-chat.h"
 #include "empathy-conf.h"
-#include "empathy-theme-manager.h"
 #include "empathy-ui-utils.h"
 #include "empathy-smiley-manager.h"
 
@@ -63,31 +62,31 @@
 #define MAX_SCROLL_TIME 0.4 /* seconds */
 #define SCROLL_DELAY 33     /* milliseconds */
 
+#define SCHEMES "(https?|ftps?|nntp|news|javascript|about|ghelp|apt|telnet|"\
+		"file|webcal|mailto)"
+#define BODY "([^\\ ]+)"
+#define END_BODY "([^\\ ]*[^,;\?><()\\ \"\\.])"
+#define URI_REGEX "("SCHEMES"://"END_BODY")" \
+		  "|((mailto:)?"BODY"@"BODY"\\."END_BODY")"\
+		  "|((www|ftp)\\."END_BODY")"
+static GRegex *uri_regex = NULL;
+
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyChatTextView)
 
 typedef struct {
-	GtkTextBuffer *buffer;
-	
-	EmpathyTheme   *theme;
-	
-	time_t         last_timestamp;
-	
-	gboolean       allow_scrolling;
-	guint          scroll_timeout;
-	GTimer        *scroll_time;
-	
-	GtkTextMark   *find_mark_previous;
-	GtkTextMark   *find_mark_next;
-	gboolean       find_wrapped;
-	gboolean       find_last_direction;
-	
-	/* This is for the group chat so we know if the "other" last contact
-	  * changed, so we know whether to insert a header or not.
-	  */
-	EmpathyContact *last_contact;
-	
-	guint          notify_system_fonts_id;
-	guint          notify_show_avatars_id;
+	GtkTextBuffer        *buffer;
+	guint                 scroll_timeout;
+	GTimer               *scroll_time;
+	GtkTextMark          *find_mark_previous;
+	GtkTextMark          *find_mark_next;
+	gboolean              find_wrapped;
+	gboolean              find_last_direction;
+	EmpathyContact       *last_contact;
+	time_t                last_timestamp;
+	gboolean              allow_scrolling;
+	guint                 notify_system_fonts_id;
+	EmpathySmileyManager *smiley_manager;
+	gboolean              only_if_date;
 } EmpathyChatTextViewPriv;
 
 static void chat_text_view_iface_init (EmpathyChatViewIface *iface);
@@ -97,6 +96,12 @@
 			 G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CHAT_VIEW,
 						chat_text_view_iface_init));
 
+enum {
+	PROP_0,
+	PROP_LAST_CONTACT,
+	PROP_ONLY_IF_DATE
+};
+
 static gboolean
 chat_text_view_url_event_cb (GtkTextTag          *tag,
 			     GObject             *object,
@@ -187,35 +192,25 @@
 }
 
 static void
-chat_text_view_setup_tags (EmpathyChatTextView *view)
+chat_text_view_create_tags (EmpathyChatTextView *view)
 {
-	EmpathyChatTextViewPriv *priv;
-	GtkTextTag         *tag;
-	
-	priv = GET_PRIV (view);
-	
-	gtk_text_buffer_create_tag (priv->buffer,
-				    "cut",
-				    NULL);
-	
-	/* FIXME: Move to the theme and come up with something that looks a bit
-	 * nicer. */
-	gtk_text_buffer_create_tag (priv->buffer,
-				    "highlight",
-				    "background", "yellow",
-				    NULL);
-	
-	tag = gtk_text_buffer_create_tag (priv->buffer,
-					  "link",
-					  NULL);
-	
-	g_signal_connect (tag,
-			  "event",
+	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
+	GtkTextTag              *tag;
+
+	gtk_text_buffer_create_tag (priv->buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_CUT, NULL);
+	gtk_text_buffer_create_tag (priv->buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_HIGHLIGHT, NULL);
+	gtk_text_buffer_create_tag (priv->buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_SPACING, NULL);
+	gtk_text_buffer_create_tag (priv->buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_TIME, NULL);
+	gtk_text_buffer_create_tag (priv->buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_ACTION, NULL);
+	gtk_text_buffer_create_tag (priv->buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_BODY, NULL);
+	gtk_text_buffer_create_tag (priv->buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_EVENT, NULL);
+
+	tag = gtk_text_buffer_create_tag (priv->buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_LINK, NULL);
+	g_signal_connect (tag, "event",
 			  G_CALLBACK (chat_text_view_url_event_cb),
 			  view);
 	
-	g_signal_connect (view,
-			  "motion-notify-event",
+	g_signal_connect (view, "motion-notify-event",
 			  G_CALLBACK (chat_text_view_event_cb),
 			  tag);
 }
@@ -247,38 +242,9 @@
 				      const gchar *key,
 				      gpointer     user_data)
 {
-	EmpathyChatTextView     *view = user_data;
-	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
-	gboolean                 show_avatars = FALSE;
+	EmpathyChatTextView *view = user_data;
 	
 	chat_text_view_system_font_update (view);
-	
-	/* Ugly, again, to adjust the vertical position of the nick... Will fix
-	  * this when reworking the theme manager so that view register
-	  * themselves with it instead of the other way around.
-	  */
-	empathy_conf_get_bool (conf,
-			       EMPATHY_PREFS_UI_SHOW_AVATARS,
-			       &show_avatars);
-	
-	empathy_theme_set_show_avatars (priv->theme, show_avatars);
-}
-
-static void
-chat_text_view_notify_show_avatars_cb (EmpathyConf *conf,
-				       const gchar *key,
-				       gpointer     user_data)
-{
-	EmpathyChatTextView     *view;
-	EmpathyChatTextViewPriv *priv;
-	gboolean            show_avatars = FALSE;
-	
-	view = user_data;
-	priv = GET_PRIV (view);
-	
-	empathy_conf_get_bool (conf, key, &show_avatars);
-	
-	empathy_theme_set_show_avatars (priv->theme, show_avatars);
 }
 
 static void
@@ -338,7 +304,7 @@
 	
 	/* Link context menu items */
 	table = gtk_text_buffer_get_tag_table (priv->buffer);
-	tag = gtk_text_tag_table_lookup (table, "link");
+	tag = gtk_text_tag_table_lookup (table, EMPATHY_CHAT_TEXT_VIEW_TAG_LINK);
 	
 	gtk_widget_get_pointer (GTK_WIDGET (view), &x, &y);
 	
@@ -437,7 +403,7 @@
 	  * the middle of a tag.
 	  */
 	table = gtk_text_buffer_get_tag_table (priv->buffer);
-	tag = gtk_text_tag_table_lookup (table, "cut");
+	tag = gtk_text_tag_table_lookup (table, EMPATHY_CHAT_TEXT_VIEW_TAG_CUT);
 	if (!tag) {
 		return;
 	}
@@ -452,23 +418,85 @@
 }
 
 static void
-chat_text_view_theme_changed_cb (EmpathyThemeManager *manager,
-			    EmpathyChatTextView     *view)
+chat_text_view_append_timestamp (EmpathyChatTextView *view,
+				 time_t               timestamp,
+				 gboolean             show_date)
 {
-	EmpathyChatTextViewPriv *priv;
-	gboolean            show_avatars = FALSE;
-	
-	priv = GET_PRIV (view);
+	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
+	GtkTextIter              iter;
+	gchar                   *tmp;
+	GString                 *str;
+
+	str = g_string_new ("- ");
+
+	/* Append date if needed */
+	if (show_date) {
+		GDate *date;
+		gchar  buf[256];
+
+		date = g_date_new ();
+		g_date_set_time_t (date, timestamp);
+		g_date_strftime (buf, 256, _("%A %d %B %Y"), date);
+		g_string_append (str, buf);
+		g_string_append (str, ", ");
+		g_date_free (date);
+	}
+
+	/* Append time */
+	tmp = empathy_time_to_string_local (timestamp, EMPATHY_TIME_FORMAT_DISPLAY_SHORT);
+	g_string_append (str, tmp);
+	g_free (tmp);
+
+	g_string_append (str, " -\n");
+
+	/* Insert the string in the buffer */
+	empathy_chat_text_view_append_spacing (view);
+	gtk_text_buffer_get_end_iter (priv->buffer, &iter);
+	gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
+						  &iter,
+						  str->str, -1,
+						  EMPATHY_CHAT_TEXT_VIEW_TAG_TIME,
+						  NULL);
+
+	priv->last_timestamp = timestamp;
+
+	g_string_free (str, TRUE);	
+}
+
+static void
+chat_text_maybe_append_date_and_time (EmpathyChatTextView *view,
+				      time_t               timestamp)
+{
+	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
+	GDate                   *date, *last_date;
+	gboolean                 append_date = FALSE;
+	gboolean                 append_time = FALSE;
+
+	/* Get the date from last message */
+	last_date = g_date_new ();
+	g_date_set_time_t (last_date, priv->last_timestamp);
+
+	/* Get the date of the message we are appending */
+	date = g_date_new ();
+	g_date_set_time_t (date, timestamp);
+
+	/* If last message was from another day we append date and time */
+	if (g_date_compare (date, last_date) > 0) {
+		append_date = TRUE;
+		append_time = TRUE;
+	}
 	
-	empathy_theme_manager_apply_saved (manager, EMPATHY_CHAT_VIEW (view));
+	g_date_free (last_date);
+	g_date_free (date);
 
-	/* 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);
+	/* If last message is 'old' append the time */
+	if (timestamp - priv->last_timestamp >= TIMESTAMP_INTERVAL) {
+		append_time = TRUE;
+	}
+
+	if (append_date || (!priv->only_if_date && append_time)) {
+		chat_text_view_append_timestamp (view, timestamp, append_date);
+	}
 }
 
 static void
@@ -503,11 +531,42 @@
 }
 
 static void
-chat_text_view_theme_notify_cb (EmpathyTheme        *theme,
-				GParamSpec          *param,
-				EmpathyChatTextView *view)
-{
-	empathy_theme_update_view (theme, EMPATHY_CHAT_VIEW (view));
+chat_text_view_get_property (GObject    *object,
+			     guint       param_id,
+			     GValue     *value,
+			     GParamSpec *pspec)
+{
+	EmpathyChatTextViewPriv *priv = GET_PRIV (object);
+
+	switch (param_id) {
+	case PROP_LAST_CONTACT:
+		g_value_set_object (value, priv->last_contact);
+		break;
+	case PROP_ONLY_IF_DATE:
+		g_value_set_boolean (value, priv->only_if_date);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
+}
+
+static void
+chat_text_view_set_property (GObject      *object,
+			     guint         param_id,
+			     const GValue *value,
+			     GParamSpec   *pspec)
+{
+	EmpathyChatTextViewPriv *priv = GET_PRIV (object);
+
+	switch (param_id) {
+	case PROP_ONLY_IF_DATE:
+		priv->only_if_date = g_value_get_boolean (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	};
 }
 
 static void
@@ -522,7 +581,6 @@
 	DEBUG ("%p", 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->last_contact) {
 		g_object_unref (priv->last_contact);
@@ -534,13 +592,6 @@
 		g_source_remove (priv->scroll_timeout);
 	}
 	
-	if (priv->theme) {
-		g_signal_handlers_disconnect_by_func (priv->theme,
-						      chat_text_view_theme_notify_cb,
-						      view);
-		g_object_unref (priv->theme);
-	}
-	
 	G_OBJECT_CLASS (empathy_chat_text_view_parent_class)->finalize (object);
 }
 
@@ -551,16 +602,34 @@
 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 	
 	object_class->finalize = chat_text_view_finalize;
+	object_class->get_property = chat_text_view_get_property;
+	object_class->set_property = chat_text_view_set_property;
+
 	widget_class->size_allocate = chat_text_view_size_allocate;
 	widget_class->drag_motion = chat_text_view_drag_motion; 
-	
+
+	g_object_class_install_property (object_class,
+					 PROP_LAST_CONTACT,
+					 g_param_spec_object ("last-contact",
+							      "Last contact",
+							      "The sender of the last received message",
+							      EMPATHY_TYPE_CONTACT,
+							      G_PARAM_READABLE));
+	g_object_class_install_property (object_class,
+					 PROP_ONLY_IF_DATE,
+					 g_param_spec_boolean ("only-if-date",
+							      "Only if date",
+							      "Display timestamp only if the date changes",
+							      FALSE,
+							      G_PARAM_READWRITE));
+
+
 	g_type_class_add_private (object_class, sizeof (EmpathyChatTextViewPriv));
 }
 
 static void
 empathy_chat_text_view_init (EmpathyChatTextView *view)
 {
-	gboolean             show_avatars;
 	EmpathyChatTextViewPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (view,
 		EMPATHY_TYPE_CHAT_TEXT_VIEW, EmpathyChatTextViewPriv);
 
@@ -568,6 +637,7 @@
 	priv->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
 	priv->last_timestamp = 0;
 	priv->allow_scrolling = TRUE;
+	priv->smiley_manager = empathy_smiley_manager_new ();
 	
 	g_object_set (view,
 		      "wrap-mode", GTK_WRAP_WORD_CHAR,
@@ -581,40 +651,12 @@
 					 chat_text_view_notify_system_font_cb,
 					 view);
 	chat_text_view_system_font_update (view);
-	
-	priv->notify_show_avatars_id =
-		empathy_conf_notify_add (empathy_conf_get (),
-					 EMPATHY_PREFS_UI_SHOW_AVATARS,
-					 chat_text_view_notify_show_avatars_cb,
-					 view);
-	
-	chat_text_view_setup_tags (view);
-	
-	empathy_theme_manager_apply_saved (empathy_theme_manager_get (), EMPATHY_CHAT_VIEW(view));
-	
-	show_avatars = FALSE;
-	empathy_conf_get_bool (empathy_conf_get (),
-			       EMPATHY_PREFS_UI_SHOW_AVATARS,
-			       &show_avatars);
-	
-	empathy_theme_set_show_avatars (priv->theme, show_avatars);
-	
+	chat_text_view_create_tags (view);
+
 	g_signal_connect (view,
 			  "populate-popup",
 			  G_CALLBACK (chat_text_view_populate_popup),
 			  NULL);
-	
-	g_signal_connect_object (empathy_theme_manager_get (),
-				 "theme-changed",
-				 G_CALLBACK (chat_text_view_theme_changed_cb),
-				 EMPATHY_CHAT_VIEW(view),
-				 0);
-}
-
-EmpathyChatTextView *
-empathy_chat_text_view_new (void)
-{
-	return g_object_new (EMPATHY_TYPE_CHAT_TEXT_VIEW, NULL);
 }
 
 /* Code stolen from pidgin/gtkimhtml.c */
@@ -672,10 +714,12 @@
 
 static void
 chat_text_view_append_message (EmpathyChatView *view,
-				 EmpathyMessage  *msg)
+			       EmpathyMessage  *msg)
 {
-	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
-	gboolean             bottom;
+	EmpathyChatTextView     *text_view = EMPATHY_CHAT_TEXT_VIEW (view);
+	EmpathyChatTextViewPriv *priv = GET_PRIV (text_view);
+	gboolean                 bottom;
+	time_t                   timestamp;
 	
 	g_return_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view));
 	g_return_if_fail (EMPATHY_IS_MESSAGE (msg));
@@ -684,11 +728,16 @@
 		return;
 	}
 	
-	bottom = chat_text_view_is_scrolled_down (EMPATHY_CHAT_TEXT_VIEW (view));
+	bottom = chat_text_view_is_scrolled_down (text_view);
 	
 	chat_text_view_maybe_trim_buffer (EMPATHY_CHAT_TEXT_VIEW (view));
 	
-	empathy_theme_append_message (priv->theme, EMPATHY_CHAT_VIEW(view), msg);
+	timestamp = empathy_message_get_timestamp (msg);
+	chat_text_maybe_append_date_and_time (text_view, timestamp);
+	if (EMPATHY_CHAT_TEXT_VIEW_GET_CLASS (view)->append_message) {
+		EMPATHY_CHAT_TEXT_VIEW_GET_CLASS (view)->append_message (text_view,
+									 msg);
+	}
 	
 	if (bottom) {
 		chat_text_view_scroll_down (view);
@@ -698,26 +747,36 @@
 		g_object_unref (priv->last_contact);
 	}
 	priv->last_contact = g_object_ref (empathy_message_get_sender (msg));
+	g_object_notify (G_OBJECT (view), "last-contact");
 }
 
 static void
 chat_text_view_append_event (EmpathyChatView *view,
-			       const gchar     *str)
+			     const gchar     *str)
 {
-	EmpathyChatTextViewPriv *priv;
-	gboolean            bottom;
-	
+	EmpathyChatTextView     *text_view = EMPATHY_CHAT_TEXT_VIEW (view);
+	EmpathyChatTextViewPriv *priv = GET_PRIV (text_view);
+	gboolean                 bottom;
+	GtkTextIter              iter;
+	gchar                   *msg;
+
+
 	g_return_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view));
 	g_return_if_fail (!G_STR_EMPTY (str));
-	
-	priv = GET_PRIV (view);
-	
-	bottom = chat_text_view_is_scrolled_down (EMPATHY_CHAT_TEXT_VIEW (view));
-	
+
+	bottom = chat_text_view_is_scrolled_down (text_view);
 	chat_text_view_maybe_trim_buffer (EMPATHY_CHAT_TEXT_VIEW (view));
-	
-	empathy_theme_append_event (priv->theme, EMPATHY_CHAT_VIEW(view), str);
-	
+	chat_text_maybe_append_date_and_time (text_view,
+					      empathy_time_get_current ());
+
+	gtk_text_buffer_get_end_iter (priv->buffer, &iter);
+	msg = g_strdup_printf (" - %s\n", str);
+	gtk_text_buffer_insert_with_tags_by_name (priv->buffer, &iter,
+						  msg, -1,
+						  EMPATHY_CHAT_TEXT_VIEW_TAG_EVENT,
+						  NULL);
+	g_free (msg);
+
 	if (bottom) {
 		chat_text_view_scroll_down (view);
 	}
@@ -725,12 +784,13 @@
 	if (priv->last_contact) {
 		g_object_unref (priv->last_contact);
 		priv->last_contact = NULL;
+		g_object_notify (G_OBJECT (view), "last-contact");
 	}
 }
 
 static void
 chat_text_view_scroll (EmpathyChatView *view,
-			 gboolean         allow_scrolling)
+		       gboolean         allow_scrolling)
 {
 	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
 	
@@ -1013,10 +1073,10 @@
 				 gboolean       *can_do_next)
 {
 	EmpathyChatTextViewPriv *priv;
-	GtkTextBuffer      *buffer;
-	GtkTextIter         iter_at_mark;
-	GtkTextIter         iter_match_start;
-	GtkTextIter         iter_match_end;
+	GtkTextBuffer           *buffer;
+	GtkTextIter              iter_at_mark;
+	GtkTextIter              iter_match_start;
+	GtkTextIter              iter_match_end;
 	
 	g_return_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view));
 	g_return_if_fail (search_criteria != NULL);
@@ -1078,7 +1138,7 @@
 	gtk_text_buffer_get_start_iter (buffer, &iter);
 	
 	gtk_text_buffer_get_bounds (buffer, &iter_start, &iter_end);
-	gtk_text_buffer_remove_tag_by_name (buffer, "highlight",
+	gtk_text_buffer_remove_tag_by_name (buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_HIGHLIGHT,
 					    &iter_start,
 					    &iter_end);
 	
@@ -1097,7 +1157,7 @@
 			break;
 		}
 		
-		gtk_text_buffer_apply_tag_by_name (buffer, "highlight",
+		gtk_text_buffer_apply_tag_by_name (buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_HIGHLIGHT,
 						   &iter_match_start,
 						   &iter_match_end);
 		
@@ -1120,117 +1180,195 @@
 	gtk_text_buffer_copy_clipboard (buffer, clipboard);
 }
 
-static EmpathyTheme *
-chat_text_view_get_theme (EmpathyChatView *view)
+static void
+chat_text_view_iface_init (EmpathyChatViewIface *iface)
 {
-	EmpathyChatTextViewPriv *priv;
+	iface->append_message = chat_text_view_append_message;
+	iface->append_event = chat_text_view_append_event;
+	iface->scroll = chat_text_view_scroll;
+	iface->scroll_down = chat_text_view_scroll_down;
+	iface->get_has_selection = chat_text_view_get_has_selection;
+	iface->clear = chat_text_view_clear;
+	iface->find_previous = chat_text_view_find_previous;
+	iface->find_next = chat_text_view_find_next;
+	iface->find_abilities = chat_text_view_find_abilities;
+	iface->highlight = chat_text_view_highlight;
+	iface->copy_clipboard = chat_text_view_copy_clipboard;
+}
+
+EmpathyContact *
+empathy_chat_text_view_get_last_contact (EmpathyChatTextView *view)
+{
+	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
 	
 	g_return_val_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view), NULL);
 	
-	priv = GET_PRIV (view);
-	
-	return priv->theme;
+	return priv->last_contact;
 }
 
-static void
-chat_text_view_set_theme (EmpathyChatView *view, EmpathyTheme *theme)
+void
+empathy_chat_text_view_set_only_if_date (EmpathyChatTextView *view,
+					 gboolean             only_if_date)
 {
-	EmpathyChatTextViewPriv *priv;
+	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
 	
 	g_return_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view));
-	g_return_if_fail (EMPATHY_IS_THEME (theme));
-	
-	priv = GET_PRIV (view);
-	
-	if (priv->theme) {
-		g_signal_handlers_disconnect_by_func (priv->theme,
-						      chat_text_view_theme_notify_cb,
-						      EMPATHY_CHAT_TEXT_VIEW (view));
-		g_object_unref (priv->theme);
+
+	if (only_if_date != priv->only_if_date) {
+		priv->only_if_date = only_if_date;
+		g_object_notify (G_OBJECT (view), "only-if-date");
 	}
-	
-	priv->theme = g_object_ref (theme);
-	
-	empathy_theme_update_view (theme, view);
-	g_signal_connect (priv->theme, "notify",
-			  G_CALLBACK (chat_text_view_theme_notify_cb),
-			  EMPATHY_CHAT_TEXT_VIEW (view));
-	
-	/* FIXME: Redraw all messages using the new theme */
 }
 
 static void
-chat_text_view_set_margin (EmpathyChatView *view,
-			     gint             margin)
+chat_text_view_insert_text_with_emoticons (EmpathyChatTextView *view,
+					   GtkTextIter         *iter,
+					   const gchar         *str)
 {
-	EmpathyChatTextViewPriv *priv;
-	
-	g_return_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view));
-	
-	priv = GET_PRIV (view);
-	
-	g_object_set (view,
-		      "left-margin", margin,
-		      "right-margin", margin,
-		      NULL);
+	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
+	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 (priv->buffer, 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 (priv->buffer, iter, smiley->pixbuf);
+		} else {
+			gtk_text_buffer_insert (priv->buffer, iter, smiley->str, -1);
+		}
+		empathy_smiley_free (smiley);
+	}
+	g_slist_free (smileys);
 }
 
-static time_t
-chat_text_view_get_last_timestamp (EmpathyChatView *view)
+void
+empathy_chat_text_view_append_body (EmpathyChatTextView *view,
+				    const gchar         *body,
+				    const gchar         *tag)
 {
-	EmpathyChatTextViewPriv *priv;
-	
-	g_return_val_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view), 0);
-	
+	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
+	GtkTextIter              start_iter, end_iter;
+	GtkTextMark             *mark;
+	GtkTextIter              iter;
+	GMatchInfo              *match_info;
+	gboolean                 match;
+	gint                     last = 0;
+	gint                     s = 0, e = 0;
+	gchar                   *tmp;
+
 	priv = GET_PRIV (view);
-	
-	return priv->last_timestamp;
+
+	gtk_text_buffer_get_end_iter (priv->buffer, &start_iter);
+	mark = gtk_text_buffer_create_mark (priv->buffer, NULL, &start_iter, TRUE);
+
+	if (!uri_regex) {
+		uri_regex = g_regex_new (URI_REGEX, 0, 0, NULL);
+	}
+
+	for (match = g_regex_match (uri_regex, body, 0, &match_info); match;
+	     match = g_match_info_next (match_info, NULL)) {
+		if (!g_match_info_fetch_pos (match_info, 0, &s, &e))
+			continue;
+
+		if (s > last) {
+			tmp = empathy_substring (body, last, s);
+
+			gtk_text_buffer_get_end_iter (priv->buffer, &iter);
+			chat_text_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,
+							  EMPATHY_CHAT_TEXT_VIEW_TAG_LINK,
+							  NULL);
+
+		g_free (tmp);
+		last = e;
+	}
+	g_match_info_free (match_info);
+
+	if (last < strlen (body)) {
+		gtk_text_buffer_get_end_iter (priv->buffer, &iter);
+		chat_text_view_insert_text_with_emoticons (view,
+							   &iter,
+							   body + last);
+	}
+
+	gtk_text_buffer_get_end_iter (priv->buffer, &iter);
+	gtk_text_buffer_insert (priv->buffer, &iter, "\n", 1);
+
+	/* 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);
+
+	gtk_text_buffer_apply_tag_by_name (priv->buffer,
+					   tag,
+					   &start_iter,
+					   &end_iter);
+
+	gtk_text_buffer_delete_mark (priv->buffer, mark);
 }
 
-static void
-chat_text_view_set_last_timestamp (EmpathyChatView *view,
-				     time_t           timestamp)
+void
+empathy_chat_text_view_append_spacing (EmpathyChatTextView *view)
 {
-	EmpathyChatTextViewPriv *priv;
-	
-	g_return_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view));
-	
-	priv = GET_PRIV (view);
-	
-	priv->last_timestamp = timestamp;
+	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
+	GtkTextIter              iter;
+
+	gtk_text_buffer_get_end_iter (priv->buffer, &iter);
+	gtk_text_buffer_insert_with_tags_by_name (priv->buffer,
+						  &iter,
+						  "\n",
+						  -1,
+						  EMPATHY_CHAT_TEXT_VIEW_TAG_CUT,
+						  EMPATHY_CHAT_TEXT_VIEW_TAG_SPACING,
+						  NULL);
 }
 
-static EmpathyContact *
-chat_text_view_get_last_contact (EmpathyChatView *view)
+GtkTextTag *
+empathy_chat_text_view_tag_set (EmpathyChatTextView *view,
+				const gchar         *tag_name,
+				const gchar         *first_property_name,
+				...)
 {
-	EmpathyChatTextViewPriv *priv;
-	
+	EmpathyChatTextViewPriv *priv = GET_PRIV (view);
+	GtkTextTag              *tag;
+	GtkTextTagTable         *table;
+	va_list                  list;
+
 	g_return_val_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view), NULL);
-	
-	priv = GET_PRIV (view);
-	
-	return priv->last_contact;
-}
+	g_return_val_if_fail (tag_name != NULL, NULL);
 
-static void
-chat_text_view_iface_init (EmpathyChatViewIface *iface)
-{
-	iface->append_message = chat_text_view_append_message;
-	iface->append_event = chat_text_view_append_event;
-	iface->set_margin = chat_text_view_set_margin;
-	iface->scroll = chat_text_view_scroll;
-	iface->scroll_down = chat_text_view_scroll_down;
-	iface->get_has_selection = chat_text_view_get_has_selection;
-	iface->clear = chat_text_view_clear;
-	iface->find_previous = chat_text_view_find_previous;
-	iface->find_next = chat_text_view_find_next;
-	iface->find_abilities = chat_text_view_find_abilities;
-	iface->highlight = chat_text_view_highlight;
-	iface->copy_clipboard = chat_text_view_copy_clipboard;
-	iface->get_theme = chat_text_view_get_theme;
-	iface->set_theme = chat_text_view_set_theme;
-	iface->get_last_timestamp = chat_text_view_get_last_timestamp;
-	iface->set_last_timestamp = chat_text_view_set_last_timestamp;
-	iface->get_last_contact = chat_text_view_get_last_contact;
+	table = gtk_text_buffer_get_tag_table (priv->buffer);
+	tag = gtk_text_tag_table_lookup (table, tag_name);
+	g_return_val_if_fail (tag != NULL, NULL);
+
+	if (first_property_name) {
+		va_start (list, first_property_name);
+		g_object_set_valist (G_OBJECT (tag), first_property_name, list);
+		va_end (list);
+	}
+
+	return tag;
 }
 

Modified: trunk/libempathy-gtk/empathy-chat-text-view.h
==============================================================================
--- trunk/libempathy-gtk/empathy-chat-text-view.h	(original)
+++ trunk/libempathy-gtk/empathy-chat-text-view.h	Tue Dec 16 09:24:35 2008
@@ -38,16 +38,14 @@
 
 #define EMPATHY_TYPE_CHAT_TEXT_VIEW         (empathy_chat_text_view_get_type ())
 #define EMPATHY_CHAT_TEXT_VIEW(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_CHAT_TEXT_VIEW, EmpathyChatTextView))
-#define EMPATHY_CHAT_TEXT_VIEW_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_CHAT_TEXT_VIEW, EmpathyChatViewClass))
+#define EMPATHY_CHAT_TEXT_VIEW_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_CHAT_TEXT_VIEW, EmpathyChatTextViewClass))
 #define EMPATHY_IS_CHAT_TEXT_VIEW(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_CHAT_TEXT_VIEW))
 #define EMPATHY_IS_CHAT_TEXT_VIEW_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_CHAT_TEXT_VIEW))
-#define EMPATHY_CHAT_TEXT_VIEW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_CHAT_TEXT_VIEW, EmpathyChatViewClass))
+#define EMPATHY_CHAT_TEXT_VIEW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_CHAT_TEXT_VIEW, EmpathyChatTextViewClass))
 
 typedef struct _EmpathyChatTextView      EmpathyChatTextView;
 typedef struct _EmpathyChatTextViewClass EmpathyChatTextViewClass;
 
-#include "empathy-theme.h"
-
 struct _EmpathyChatTextView {
 	GtkTextView parent;
 	gpointer priv;
@@ -55,10 +53,33 @@
 
 struct _EmpathyChatTextViewClass {
 	GtkTextViewClass parent_class;
+
+	/* <vtable> */
+	void (*append_message) (EmpathyChatTextView *view,
+				EmpathyMessage      *message);
 };
 
-GType                empathy_chat_text_view_get_type (void) G_GNUC_CONST;
-EmpathyChatTextView *empathy_chat_text_view_new      (void);
+#define EMPATHY_CHAT_TEXT_VIEW_TAG_CUT "cut"
+#define EMPATHY_CHAT_TEXT_VIEW_TAG_HIGHLIGHT "highlight"
+#define EMPATHY_CHAT_TEXT_VIEW_TAG_SPACING "spacing"
+#define EMPATHY_CHAT_TEXT_VIEW_TAG_TIME "time"
+#define EMPATHY_CHAT_TEXT_VIEW_TAG_ACTION "action"
+#define EMPATHY_CHAT_TEXT_VIEW_TAG_BODY "body"
+#define EMPATHY_CHAT_TEXT_VIEW_TAG_EVENT "event"
+#define EMPATHY_CHAT_TEXT_VIEW_TAG_LINK "link"
+
+GType                empathy_chat_text_view_get_type         (void) G_GNUC_CONST;
+EmpathyContact *     empathy_chat_text_view_get_last_contact (EmpathyChatTextView *view);
+void                 empathy_chat_text_view_set_only_if_date (EmpathyChatTextView *view,
+							      gboolean             only_if_date);
+void                 empathy_chat_text_view_append_body      (EmpathyChatTextView *view,
+							      const gchar         *body,
+							      const gchar         *tag);
+void                 empathy_chat_text_view_append_spacing   (EmpathyChatTextView *view);
+GtkTextTag *         empathy_chat_text_view_tag_set          (EmpathyChatTextView *view,
+							      const gchar         *tag_name,
+							      const gchar         *first_property_name,
+							      ...);
 
 G_END_DECLS
 

Modified: trunk/libempathy-gtk/empathy-chat.c
==============================================================================
--- trunk/libempathy-gtk/empathy-chat.c	(original)
+++ trunk/libempathy-gtk/empathy-chat.c	Tue Dec 16 09:24:35 2008
@@ -48,7 +48,7 @@
 #include "empathy-contact-list-store.h"
 #include "empathy-contact-list-view.h"
 #include "empathy-contact-menu.h"
-#include "empathy-chat-text-view.h"
+#include "empathy-theme-manager.h"
 #include "empathy-smiley-manager.h"
 #include "empathy-ui-utils.h"
 
@@ -1269,8 +1269,8 @@
 	g_free (filename);
 	g_object_unref (glade);
 
-	/* Add message GtkTextView. */
-	chat->view = EMPATHY_CHAT_VIEW (empathy_chat_text_view_new ());
+	/* Add message view. */
+	chat->view = empathy_theme_manager_create_view (empathy_theme_manager_get ());
 	g_signal_connect (chat->view, "focus_in_event",
 			  G_CALLBACK (chat_text_view_focus_in_event_cb),
 			  chat);

Modified: trunk/libempathy-gtk/empathy-log-window.c
==============================================================================
--- trunk/libempathy-gtk/empathy-log-window.c	(original)
+++ trunk/libempathy-gtk/empathy-log-window.c	Tue Dec 16 09:24:35 2008
@@ -41,7 +41,7 @@
 #include "empathy-log-window.h"
 #include "empathy-account-chooser.h"
 #include "empathy-chat-view.h"
-#include "empathy-chat-text-view.h"
+#include "empathy-theme-manager.h"
 #include "empathy-ui-utils.h"
 
 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
@@ -208,13 +208,13 @@
 			  window);
 
 	/* Configure Search EmpathyChatView */
-	window->chatview_find = EMPATHY_CHAT_VIEW (empathy_chat_text_view_new ());
+	window->chatview_find = empathy_theme_manager_create_view (empathy_theme_manager_get ());
 	gtk_container_add (GTK_CONTAINER (window->scrolledwindow_find),
 			   GTK_WIDGET (window->chatview_find));
 	gtk_widget_show (GTK_WIDGET (window->chatview_find));
 
 	/* Configure Contacts EmpathyChatView */
-	window->chatview_chats = EMPATHY_CHAT_VIEW (empathy_chat_text_view_new ());
+	window->chatview_chats = empathy_theme_manager_create_view (empathy_theme_manager_get ());
 	gtk_container_add (GTK_CONTAINER (window->scrolledwindow_chats),
 			   GTK_WIDGET (window->chatview_chats));
 	gtk_widget_show (GTK_WIDGET (window->chatview_chats));

Modified: trunk/libempathy-gtk/empathy-theme-boxes.c
==============================================================================
--- trunk/libempathy-gtk/empathy-theme-boxes.c	(original)
+++ trunk/libempathy-gtk/empathy-theme-boxes.c	Tue Dec 16 09:24:35 2008
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2007 Imendio AB
+ * Copyright (C) 2008 Collabora Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -16,6 +17,8 @@
  * 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: Xavier Claessens <xclaesse gmail com>
  */
 
 #include <config.h>
@@ -26,9 +29,11 @@
 #include <gtk/gtk.h>
 
 #include <telepathy-glib/util.h>
+
 #include <libempathy/empathy-utils.h>
-#include "empathy-ui-utils.h"
 #include "empathy-theme-boxes.h"
+#include "empathy-ui-utils.h"
+#include "empathy-conf.h"
 
 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
 #include <libempathy/empathy-debug.h>
@@ -38,485 +43,25 @@
 
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyThemeBoxes)
 typedef struct {
-	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;
+	gboolean show_avatars;
+	guint    notify_show_avatars_id;
 } EmpathyThemeBoxesPriv;
 
-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 void     theme_boxes_update_view       (EmpathyTheme        *theme,
-					       EmpathyChatView     *view);
-static void     theme_boxes_append_message    (EmpathyTheme        *theme,
-					       EmpathyChatView     *view,
-					       EmpathyMessage      *message);
-static void     theme_boxes_append_event      (EmpathyTheme        *theme,
-					       EmpathyChatView     *view,
-					       const gchar        *str);
-static void     theme_boxes_append_timestamp  (EmpathyTheme        *theme,
-					       EmpathyChatView     *view,
-					       EmpathyMessage      *message,
-					       gboolean            show_date,
-					       gboolean            show_time);
-static void     theme_boxes_append_spacing    (EmpathyTheme        *theme,
-					       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->update_view      = theme_boxes_update_view;
-	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 = G_TYPE_INSTANCE_GET_PRIVATE (theme,
-		EMPATHY_TYPE_THEME_BOXES, EmpathyThemeBoxesPriv);
-
-	theme->priv = priv;
-}
-
-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);
-		g_object_notify (object, "header-foreground");
-		break;
-	case PROP_HEADER_BACKGROUND:
-		g_free (priv->header_background);
-		priv->header_background = g_value_dup_string (value);
-		g_object_notify (object, "header-background");
-		break;
-	case PROP_HEADER_LINE_BACKGROUND:
-		g_free (priv->header_line_background);
-		priv->header_line_background = g_value_dup_string (value);
-		g_object_notify (object, "header-line_background");
-		break;
-	case PROP_TEXT_FOREGROUND:
-		g_free (priv->text_foreground);
-		priv->text_foreground = g_value_dup_string (value);
-		g_object_notify (object, "text-foreground");
-		break;
-	case PROP_TEXT_BACKGROUND:
-		g_free (priv->text_background);
-		priv->text_background = g_value_dup_string (value);
-		g_object_notify (object, "text-background");
-		break;
-	case PROP_ACTION_FOREGROUND:
-		g_free (priv->action_foreground);
-		priv->action_foreground = g_value_dup_string (value);
-		g_object_notify (object, "action-foreground");
-		break;
-	case PROP_HIGHLIGHT_FOREGROUND:
-		g_free (priv->highlight_foreground);
-		priv->highlight_foreground = g_value_dup_string (value);
-		g_object_notify (object, "highlight-foreground");
-		break;
-	case PROP_TIME_FOREGROUND:
-		g_free (priv->time_foreground);
-		priv->time_foreground = g_value_dup_string (value);
-		g_object_notify (object, "time-foreground");
-		break;
-	case PROP_EVENT_FOREGROUND:
-		g_free (priv->event_foreground);
-		priv->event_foreground = g_value_dup_string (value);
-		g_object_notify (object, "event-foreground");
-		break;
-	case PROP_INVITE_FOREGROUND:
-		g_free (priv->invite_foreground);
-		priv->invite_foreground = g_value_dup_string (value);
-		g_object_notify (object, "invite-foreground");
-		break;
-	case PROP_LINK_FOREGROUND:
-		g_free (priv->link_foreground);
-		priv->link_foreground = g_value_dup_string (value);
-		g_object_notify (object, "link-foreground");
-		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;
-	GtkTextTag            *tag;
-
-	priv = GET_PRIV (theme);
-
-	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-
-	empathy_text_buffer_tag_set (buffer, "fancy-spacing",
-				     "size", 3000,
-				     "pixels-above-lines", 8,
-				     NULL);
-
-	tag = empathy_text_buffer_tag_set (buffer, "fancy-header",
-					   "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);
-	}
-
-	tag = empathy_text_buffer_tag_set (buffer, "fancy-header-line",
-					   "size", 1,
-					   NULL);
-	if (priv->header_line_background) {
-		g_object_set (tag,
-			      "paragraph-background", priv->header_line_background,
-			      NULL);
-	}
-
-	tag = empathy_text_buffer_tag_set (buffer, "fancy-body",
-					   "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);
-	}
-
-	tag = empathy_text_buffer_tag_set (buffer, "fancy-action",
-					   "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);
-	}
-
-	tag = empathy_text_buffer_tag_set (buffer, "fancy-highlight",
-					   "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);
-	}
-
-	tag = empathy_text_buffer_tag_set (buffer, "fancy-time",
-					   "justification", GTK_JUSTIFY_CENTER,
-					   NULL);
-	if (priv->time_foreground) {
-		g_object_set (tag,
-			      "foreground", priv->time_foreground,
-			      NULL);
-	}
-
-	tag = empathy_text_buffer_tag_set (buffer, "fancy-event",
-					   "justification", GTK_JUSTIFY_LEFT,
-					   NULL);
-	if (priv->event_foreground) {
-		g_object_set (tag,
-			      "foreground", priv->event_foreground,
-			      NULL);
-	}
-
-	tag = empathy_text_buffer_tag_set (buffer, "invite", NULL);
-	if (priv->invite_foreground) {
-		g_object_set (tag,
-			      "foreground", priv->invite_foreground,
-			      NULL);
-	}
-
-	tag = empathy_text_buffer_tag_set (buffer, "fancy-link",
-					   "underline", PANGO_UNDERLINE_SINGLE,
-					   NULL);
-	if (priv->link_foreground) {
-		g_object_set (tag,
-			      "foreground", priv->link_foreground,
-			      NULL);
-	} 
-}
-
-static void
-theme_boxes_update_view (EmpathyTheme *theme, EmpathyChatView *view)
-{
-	EmpathyThemeBoxesPriv *priv;
-
-	g_return_if_fail (EMPATHY_IS_THEME_BOXES (theme));
-	g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
-
-	priv = GET_PRIV (theme);
-
-	theme_boxes_define_theme_tags (theme, view);
-	
-	empathy_chat_view_set_margin (view, MARGIN);
-}
+G_DEFINE_TYPE (EmpathyThemeBoxes, empathy_theme_boxes, EMPATHY_TYPE_CHAT_TEXT_VIEW);
 
 static void
-table_size_allocate_cb (GtkWidget     *view,
-			GtkAllocation *allocation,
-			GtkWidget     *box)
+theme_boxes_create_tags (EmpathyThemeBoxes *theme)
 {
-	gint width, height;
+	GtkTextBuffer *buffer;
 
-        gtk_widget_get_size_request (box, NULL, &height);
+	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (theme));
 
-	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_text_buffer_create_tag (buffer, EMPATHY_THEME_BOXES_TAG_HEADER,
+				    "pixels-above-lines", HEADER_PADDING,
+				    "pixels-below-lines", HEADER_PADDING,
+				    NULL);
 
-        gtk_widget_set_size_request (box, width, height);
+	gtk_text_buffer_create_tag (buffer, EMPATHY_THEME_BOXES_TAG_HEADER_LINE, NULL);
 }
 
 /* Pads a pixbuf to the specified size, by centering it in a larger transparent
@@ -613,13 +158,33 @@
 }
 
 static void
-theme_boxes_maybe_append_header (EmpathyTheme        *theme,
-				 EmpathyChatView     *view,
-				 EmpathyMessage      *msg)
-{
-	EmpathyThemeBoxesPriv *priv;
-	EmpathyContact        *contact;
-	EmpathyContact        *last_contact;
+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 (EmpathyThemeBoxes *theme,
+				 EmpathyMessage    *msg)
+{
+	EmpathyChatTextView  *view = EMPATHY_CHAT_TEXT_VIEW (theme);
+	EmpathyThemeBoxesPriv*priv = GET_PRIV (theme);
+	EmpathyContact       *contact;
+	EmpathyContact       *last_contact;
 	GdkPixbuf            *avatar = NULL;
 	GtkTextBuffer        *buffer;
 	const gchar          *name;
@@ -631,15 +196,14 @@
 	time_t                time;
 	gchar                *tmp;
 	GtkTextIter           start;
-	GdkColor              color;
-	gboolean              parse_success;
-
-	priv = GET_PRIV (theme);
+	gboolean              color_set;
+	GtkTextTagTable      *table;
+	GtkTextTag           *tag;
 
 	contact = empathy_message_get_sender (msg);
 	name = empathy_contact_get_name (contact);
-	last_contact = empathy_chat_view_get_last_contact (view);
-	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+	last_contact = empathy_chat_text_view_get_last_contact (view);
+	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (theme));
 
 	DEBUG ("Maybe add fancy header");
 
@@ -650,23 +214,29 @@
 		return;
 	}
 
-	empathy_theme_append_spacing (theme, view);
+	empathy_chat_text_view_append_spacing (view);
 
+	/* Insert header line */
 	gtk_text_buffer_get_end_iter (buffer, &iter);
 	gtk_text_buffer_insert_with_tags_by_name (buffer,
 						  &iter,
 						  "\n",
 						  -1,
-						  "fancy-header-line",
+						  EMPATHY_THEME_BOXES_TAG_HEADER_LINE,
 						  NULL);
 
 	gtk_text_buffer_get_end_iter (buffer, &iter);
 	anchor = gtk_text_buffer_create_child_anchor (buffer, &iter);
 
+	/* Create a hbox for the header and resize it when the view allocation
+	 * changes */
 	box = gtk_hbox_new (FALSE, 0);
+	g_signal_connect_object (view, "size-allocate",
+				 G_CALLBACK (table_size_allocate_cb),
+				 box, 0);
 
-
-	if (empathy_theme_get_show_avatars (theme)) {
+	/* Add avatar to the box if needed */
+	if (priv->show_avatars) {
 		avatar = theme_boxes_get_avatar_pixbuf_with_cache (contact);
 		if (avatar) {
 			GtkWidget *image;
@@ -678,218 +248,167 @@
 		}
 	}
 
-	g_signal_connect_object (view, "size-allocate",
-				 G_CALLBACK (table_size_allocate_cb),
-				 box, 0);
-
+	/* Add contact alias */
 	str = g_markup_printf_escaped ("<b>%s</b>", name);
-
 	label1 = g_object_new (GTK_TYPE_LABEL,
 			       "label", str,
 			       "use-markup", TRUE,
 			       "xalign", 0.0,
 			       NULL);
-
-	parse_success = priv->header_foreground &&
-			gdk_color_parse (priv->header_foreground, &color);
-
-	if (parse_success) {
-		gtk_widget_modify_fg (label1, GTK_STATE_NORMAL, &color);
-	}
-
 	g_free (str);
 
+	/* Add the message receive time */
 	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);
+	g_free (tmp);
+	g_free (str);
 	
-	if (parse_success) {
+	/* Set foreground color of labels to the same color than the header tag. */
+	table = gtk_text_buffer_get_tag_table (buffer);
+	tag = gtk_text_tag_table_lookup (table, EMPATHY_THEME_BOXES_TAG_HEADER);
+	g_object_get (tag, "foreground-set", &color_set, NULL);
+	if (color_set) {
+		GdkColor color;
+		g_object_get (tag, "foreground-gdk", &color, NULL);
+		gtk_widget_modify_fg (label1, GTK_STATE_NORMAL, &color);
 		gtk_widget_modify_fg (label2, GTK_STATE_NORMAL, &color);
 	}
 
-	g_free (str);
-
+	/* Pack labels into the box */
 	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);
 
+	/* Add the header box to the text view */
 	gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW (view),
 					   box,
 					   anchor);
-
 	gtk_widget_show_all (box);
 
+	/* Insert a header line */
 	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",
+					   EMPATHY_THEME_BOXES_TAG_HEADER,
 					   &start, &iter);
-
 	gtk_text_buffer_insert_with_tags_by_name (buffer,
 						  &iter,
 						  "\n",
 						  -1,
-						  "fancy-header",
+						  EMPATHY_THEME_BOXES_TAG_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",
+						  EMPATHY_THEME_BOXES_TAG_HEADER_LINE,
 						  NULL);
 }
 
 static void
-theme_boxes_append_message (EmpathyTheme        *theme,
-			    EmpathyChatView     *view,
+theme_boxes_append_message (EmpathyChatTextView *view,
 			    EmpathyMessage      *message)
 {
 	EmpathyContact *sender;
 
-	empathy_theme_maybe_append_date_and_time (theme, view, message);
-	theme_boxes_maybe_append_header (theme, view, message);
+	theme_boxes_maybe_append_header (EMPATHY_THEME_BOXES (view), message);
 
 	sender = empathy_message_get_sender (message);
-
-	if (empathy_message_get_tptype (message) == TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION) {
+	if (empathy_message_get_tptype (message) ==
+	    TP_CHANNEL_TEXT_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, view, body,
-					   "fancy-action", "fancy-link");
+		empathy_chat_text_view_append_body (EMPATHY_CHAT_TEXT_VIEW (view),
+						    body,
+						    EMPATHY_CHAT_TEXT_VIEW_TAG_ACTION);
 	} else {
-		empathy_theme_append_text (theme, view,
-					   empathy_message_get_body (message),
-					   "fancy-body", "fancy-link");
+		empathy_chat_text_view_append_body (EMPATHY_CHAT_TEXT_VIEW (view),
+						    empathy_message_get_body (message),
+						    EMPATHY_CHAT_TEXT_VIEW_TAG_BODY);
 	}
 }
 
 static void
-theme_boxes_append_event (EmpathyTheme        *theme,
-			  EmpathyChatView     *view,
-			  const gchar        *str)
+theme_boxes_notify_show_avatars_cb (EmpathyConf *conf,
+				    const gchar *key,
+				    gpointer     user_data)
 {
-	GtkTextBuffer *buffer;
-	GtkTextIter    iter;
-	gchar         *msg;
-
-	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-
-	empathy_theme_maybe_append_date_and_time (theme, 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);
+	EmpathyThemeBoxesPriv *priv = GET_PRIV (user_data);
+	
+	empathy_conf_get_bool (conf, key, &priv->show_avatars);
 }
 
 static void
-theme_boxes_append_timestamp (EmpathyTheme        *theme,
-			      EmpathyChatView     *view,
-			      EmpathyMessage      *message,
-			      gboolean            show_date,
-			      gboolean            show_time)
+theme_boxes_finalize (GObject *object)
 {
-	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);
+	EmpathyThemeBoxesPriv *priv = GET_PRIV (object);
 
-	str = g_string_new (NULL);
-
-	if (show_time || show_date) {
-		empathy_theme_append_spacing (theme, 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, ", ");
-		}
-	}
+	empathy_conf_notify_remove (empathy_conf_get (),
+				    priv->notify_show_avatars_id);
 
-	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);
-	}
+	G_OBJECT_CLASS (empathy_theme_boxes_parent_class)->finalize (object);
+}
 
-	if (show_time || show_date) {
-		g_string_append (str, " -\n");
+static void
+empathy_theme_boxes_class_init (EmpathyThemeBoxesClass *class)
+{
+	GObjectClass             *object_class;
+	EmpathyChatTextViewClass *chat_text_view_class;
 
-		gtk_text_buffer_get_end_iter (buffer, &iter);
-		gtk_text_buffer_insert_with_tags_by_name (buffer,
-							  &iter,
-							  str->str, -1,
-							  "fancy-time",
-							  NULL);
+	object_class = G_OBJECT_CLASS (class);
+	chat_text_view_class  = EMPATHY_CHAT_TEXT_VIEW_CLASS (class);
 
-		empathy_chat_view_set_last_timestamp (view, timestamp);
-	}
+	object_class->finalize = theme_boxes_finalize;
+	chat_text_view_class->append_message = theme_boxes_append_message;
 
-	g_string_free (str, TRUE);
-	
+	g_type_class_add_private (object_class, sizeof (EmpathyThemeBoxesPriv));
 }
 
 static void
-theme_boxes_append_spacing (EmpathyTheme        *theme,
-			    EmpathyChatView     *view)
+empathy_theme_boxes_init (EmpathyThemeBoxes *theme)
 {
-	GtkTextBuffer *buffer;
-	GtkTextIter    iter;
+	EmpathyThemeBoxesPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (theme,
+		EMPATHY_TYPE_THEME_BOXES, EmpathyThemeBoxesPriv);
 
-	g_return_if_fail (EMPATHY_IS_THEME (theme));
-	g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
+	theme->priv = priv;
 
-	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+	theme_boxes_create_tags (theme);
 
-	gtk_text_buffer_get_end_iter (buffer, &iter);
-	gtk_text_buffer_insert_with_tags_by_name (buffer,
-						  &iter,
-						  "\n",
-						  -1,
-						  "cut",
-						  "fancy-spacing",
-						  NULL);
+	priv->notify_show_avatars_id =
+		empathy_conf_notify_add (empathy_conf_get (),
+					 EMPATHY_PREFS_UI_SHOW_AVATARS,
+					 theme_boxes_notify_show_avatars_cb,
+					 theme);
+
+	empathy_conf_get_bool (empathy_conf_get (),
+			       EMPATHY_PREFS_UI_SHOW_AVATARS,
+			       &priv->show_avatars);
+
+	/* Define margin */
+	g_object_set (theme,
+		      "left-margin", MARGIN,
+		      "right-margin", MARGIN,
+		      NULL);
+}
+
+EmpathyThemeBoxes *
+empathy_theme_boxes_new (void)
+{
+	return g_object_new (EMPATHY_TYPE_THEME_BOXES,
+			     "only-if-date", TRUE,
+			     NULL);
 }
 

Modified: trunk/libempathy-gtk/empathy-theme-boxes.h
==============================================================================
--- trunk/libempathy-gtk/empathy-theme-boxes.h	(original)
+++ trunk/libempathy-gtk/empathy-theme-boxes.h	Tue Dec 16 09:24:35 2008
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2007 Imendio AB
+ * Copyright (C) 2008 Collabora Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -16,6 +17,8 @@
  * 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: Xavier Claessens <xclaesse gmail com>
  */
 
 #ifndef __EMPATHY_THEME_BOXES_H__
@@ -23,7 +26,7 @@
 
 #include <glib-object.h>
 
-#include "empathy-theme.h"
+#include "empathy-chat-text-view.h"
 
 G_BEGIN_DECLS
 
@@ -38,15 +41,19 @@
 typedef struct _EmpathyThemeBoxesClass EmpathyThemeBoxesClass;
 
 struct _EmpathyThemeBoxes {
-	EmpathyTheme parent;
+	EmpathyChatTextView parent;
 	gpointer priv;
 };
 
 struct _EmpathyThemeBoxesClass {
-	EmpathyThemeClass parent_class;
+	EmpathyChatTextViewClass parent_class;
 };
 
-GType empathy_theme_boxes_get_type (void) G_GNUC_CONST;
+#define EMPATHY_THEME_BOXES_TAG_HEADER "fancy-header"
+#define EMPATHY_THEME_BOXES_TAG_HEADER_LINE "fancy-header-line"
+
+GType              empathy_theme_boxes_get_type (void) G_GNUC_CONST;
+EmpathyThemeBoxes *empathy_theme_boxes_new      (void);
 
 G_END_DECLS
 

Modified: trunk/libempathy-gtk/empathy-theme-irc.c
==============================================================================
--- trunk/libempathy-gtk/empathy-theme-irc.c	(original)
+++ trunk/libempathy-gtk/empathy-theme-irc.c	Tue Dec 16 09:24:35 2008
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2007 Imendio AB
+ * Copyright (C) 2008 Collabora Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -16,6 +17,8 @@
  * 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: Xavier Claessens <xclaesse gmail com>
  */
 
 #include "config.h"
@@ -23,201 +26,62 @@
 #include <glib/gi18n-lib.h>
 
 #include <libempathy/empathy-utils.h>
-#include "empathy-chat.h"
-#include "empathy-ui-utils.h"
 #include "empathy-theme-irc.h"
+#include "empathy-ui-utils.h"
 
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyThemeIrc)
 typedef struct {
-	gint my_prop;
+	gpointer dummy;
 } EmpathyThemeIrcPriv;
 
-static void         theme_irc_finalize         (GObject             *object);
-static void         theme_irc_update_view      (EmpathyTheme         *theme,
-						EmpathyChatView      *view);
-static void         theme_irc_append_message   (EmpathyTheme        *theme,
-						EmpathyChatView     *view,
-						EmpathyMessage      *message);
-static void         theme_irc_append_event     (EmpathyTheme        *theme,
-						EmpathyChatView     *view,
-						const gchar        *str);
-static void         theme_irc_append_timestamp (EmpathyTheme        *theme,
-						EmpathyChatView     *view,
-						EmpathyMessage      *message,
-						gboolean            show_date,
-						gboolean            show_time);
-static void         theme_irc_append_spacing   (EmpathyTheme        *theme,
-						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;
-
-	theme_class->update_view      = theme_irc_update_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_type_class_add_private (object_class, sizeof (EmpathyThemeIrcPriv));
-}
-
-static void
-empathy_theme_irc_init (EmpathyThemeIrc *theme)
-{
-	EmpathyThemeIrcPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (theme,
-		EMPATHY_TYPE_THEME_IRC, EmpathyThemeIrcPriv);
-
-	theme->priv = priv;
-}
-
-static void
-theme_irc_finalize (GObject *object)
-{
-	EmpathyThemeIrcPriv *priv;
-
-	priv = GET_PRIV (object);
-
-	(G_OBJECT_CLASS (empathy_theme_irc_parent_class)->finalize) (object);
-}
+G_DEFINE_TYPE (EmpathyThemeIrc, empathy_theme_irc, EMPATHY_TYPE_CHAT_TEXT_VIEW);
 
 static void
-theme_irc_apply_theme_classic (EmpathyTheme *theme, EmpathyChatView *view)
+theme_irc_create_tags (EmpathyThemeIrc *theme)
 {
-	EmpathyThemeIrcPriv *priv;
-	GtkTextBuffer       *buffer;
-
-	priv = GET_PRIV (theme);
-
-	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-
-	empathy_text_buffer_tag_set (buffer, "irc-spacing",
-				     "size", 2000,
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "irc-nick-self",
-				     "foreground", "sea green",
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "irc-body-self",
-				     /* To get the default theme color: */
-				     "foreground-set", FALSE,
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "irc-action-self",
-				     "foreground", "brown4",
-				     "style", PANGO_STYLE_ITALIC,
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "irc-nick-highlight",
-				     "foreground", "indian red",
-				     "weight", PANGO_WEIGHT_BOLD,
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "irc-nick-other",
-				     "foreground", "skyblue4",
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "irc-body-other",
-				     /* To get the default theme color: */
-				     "foreground-set", FALSE,
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "irc-action-other",
-				     "foreground", "brown4",
-				     "style", PANGO_STYLE_ITALIC,
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "irc-time",
-				     "foreground", "darkgrey",
-				     "justification", GTK_JUSTIFY_CENTER,
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "irc-event",
-				     "foreground", "PeachPuff4",
-				     "justification", GTK_JUSTIFY_LEFT,
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "invite",
-				     "foreground", "sienna",
-				     NULL);
-
-	empathy_text_buffer_tag_set (buffer, "irc-link",
-				     "foreground", "steelblue",
-				     "underline", PANGO_UNDERLINE_SINGLE,
-				     NULL);
-}
+	GtkTextBuffer *buffer;
 
+	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (theme));
 
-static void
-theme_irc_update_view (EmpathyTheme *theme, EmpathyChatView *view)
-{
-	theme_irc_apply_theme_classic (theme, view);
-	empathy_chat_view_set_margin (view, 3);
+	gtk_text_buffer_create_tag (buffer, EMPATHY_THEME_IRC_TAG_NICK_SELF, NULL);
+	gtk_text_buffer_create_tag (buffer, EMPATHY_THEME_IRC_TAG_NICK_OTHER, NULL);
+	gtk_text_buffer_create_tag (buffer, EMPATHY_THEME_IRC_TAG_NICK_HIGHLIGHT, NULL);
 }
 
 static void
-theme_irc_append_message (EmpathyTheme        *theme,
-			  EmpathyChatView     *view,
+theme_irc_append_message (EmpathyChatTextView *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, 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_tptype (message) == TP_CHANNEL_TEXT_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, view, tmp,
-					   body_tag, "irc-link");
+		empathy_chat_text_view_append_body (view, tmp,
+						    EMPATHY_CHAT_TEXT_VIEW_TAG_ACTION);
 		g_free (tmp);
 		return;
 	}
 
 	if (empathy_contact_is_user (contact)) {
-		nick_tag = "irc-nick-self";
-		body_tag = "irc-body-self";
+		nick_tag = EMPATHY_THEME_IRC_TAG_NICK_SELF;
 	} else {
 		if (empathy_message_should_highlight (message)) {
-			nick_tag = "irc-nick-highlight";
+			nick_tag = EMPATHY_THEME_IRC_TAG_NICK_HIGHLIGHT;
 		} else {
-			nick_tag = "irc-nick-other";
+			nick_tag = EMPATHY_THEME_IRC_TAG_NICK_OTHER;
 		}
-
-		body_tag = "irc-body-other";
 	}
 		
 	gtk_text_buffer_get_end_iter (buffer, &iter);
@@ -234,115 +98,52 @@
 	g_free (tmp);
 
 	/* The text body. */
-	empathy_theme_append_text (theme, view, 
-				  empathy_message_get_body (message),
-				  body_tag, "irc-link");
+	empathy_chat_text_view_append_body (view,
+					    empathy_message_get_body (message),
+					    EMPATHY_CHAT_TEXT_VIEW_TAG_BODY);
 }
 
 static void
-theme_irc_append_event (EmpathyTheme        *theme,
-		    EmpathyChatView     *view,
-		    const gchar        *str)
+theme_irc_finalize (GObject *object)
 {
-	GtkTextBuffer *buffer;
-	GtkTextIter    iter;
-	gchar         *msg;
-
-	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-	
-	empathy_theme_maybe_append_date_and_time (theme, 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);
+	(G_OBJECT_CLASS (empathy_theme_irc_parent_class)->finalize) (object);
 }
 
 static void
-theme_irc_append_timestamp (EmpathyTheme        *theme,
-			    EmpathyChatView     *view,
-			    EmpathyMessage      *message,
-			    gboolean            show_date,
-			    gboolean            show_time)
+empathy_theme_irc_class_init (EmpathyThemeIrcClass *class)
 {
-	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, 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;
+	GObjectClass             *object_class;
+	EmpathyChatTextViewClass *chat_text_view_class;
 
-		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);
+	object_class = G_OBJECT_CLASS (class);
+	chat_text_view_class = EMPATHY_CHAT_TEXT_VIEW_CLASS (class);
 
-		empathy_chat_view_set_last_timestamp (view, timestamp);
-	}
+	object_class->finalize = theme_irc_finalize;
+	chat_text_view_class->append_message = theme_irc_append_message;
 
-	g_string_free (str, TRUE);
+	g_type_class_add_private (object_class, sizeof (EmpathyThemeIrcPriv));
 }
 
 static void
-theme_irc_append_spacing (EmpathyTheme        *theme,
-			  EmpathyChatView     *view)
+empathy_theme_irc_init (EmpathyThemeIrc *theme)
 {
-	GtkTextBuffer *buffer;
-	GtkTextIter    iter;
+	EmpathyThemeIrcPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (theme,
+		EMPATHY_TYPE_THEME_IRC, EmpathyThemeIrcPriv);
 
-	g_return_if_fail (EMPATHY_IS_THEME (theme));
-	g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view));
+	theme->priv = priv;
 
-	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+	theme_irc_create_tags (theme);
 
-	gtk_text_buffer_get_end_iter (buffer, &iter);
-	gtk_text_buffer_insert_with_tags_by_name (buffer,
-						  &iter,
-						  "\n",
-						  -1,
-						  "cut",
-						  "irc-spacing",
-						  NULL);
+	/* Define margin */
+	g_object_set (theme,
+		      "left-margin", 3,
+		      "right-margin", 3,
+		      NULL);
+}
+
+EmpathyThemeIrc *
+empathy_theme_irc_new (void)
+{
+	return g_object_new (EMPATHY_TYPE_THEME_IRC, NULL);
 }
 

Modified: trunk/libempathy-gtk/empathy-theme-irc.h
==============================================================================
--- trunk/libempathy-gtk/empathy-theme-irc.h	(original)
+++ trunk/libempathy-gtk/empathy-theme-irc.h	Tue Dec 16 09:24:35 2008
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2007 Imendio AB
+ * Copyright (C) 2008 Collabora Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -16,6 +17,8 @@
  * 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: Xavier Claessens <xclaesse gmail com>
  */
 
 #ifndef __EMPATHY_THEME_IRC_H__
@@ -23,7 +26,7 @@
 
 #include <glib-object.h>
 
-#include "empathy-theme.h"
+#include "empathy-chat-text-view.h"
 
 G_BEGIN_DECLS
 
@@ -38,15 +41,20 @@
 typedef struct _EmpathyThemeIrcClass EmpathyThemeIrcClass;
 
 struct _EmpathyThemeIrc {
-	EmpathyTheme parent;
+	EmpathyChatTextView parent;
 	gpointer priv;
 };
 
 struct _EmpathyThemeIrcClass {
-	EmpathyThemeClass parent_class;
+	EmpathyChatTextViewClass parent_class;
 };
 
-GType               empathy_theme_irc_get_type                 (void) G_GNUC_CONST;
+#define EMPATHY_THEME_IRC_TAG_NICK_SELF "irc-nick-self"
+#define EMPATHY_THEME_IRC_TAG_NICK_OTHER "irc-nick-other"
+#define EMPATHY_THEME_IRC_TAG_NICK_HIGHLIGHT "irc-nick-highlight"
+
+GType empathy_theme_irc_get_type (void) G_GNUC_CONST;
+EmpathyThemeIrc *empathy_theme_irc_new (void);
 
 G_END_DECLS
 

Modified: trunk/libempathy-gtk/empathy-theme-manager.c
==============================================================================
--- trunk/libempathy-gtk/empathy-theme-manager.c	(original)
+++ trunk/libempathy-gtk/empathy-theme-manager.c	Tue Dec 16 09:24:35 2008
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2005-2007 Imendio AB
+ * Copyright (C) 2008 Collabora Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -16,6 +17,8 @@
  * 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: Xavier Claessens <xclaesse gmail com>
  */
 
 #include "config.h"
@@ -27,41 +30,23 @@
 
 #include <libempathy/empathy-utils.h>
 
+#include "empathy-theme-manager.h"
 #include "empathy-chat-view.h"
 #include "empathy-conf.h"
-#include "empathy-theme.h"
+#include "empathy-chat-text-view.h"
 #include "empathy-theme-boxes.h"
 #include "empathy-theme-irc.h"
-#include "empathy-theme-manager.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
+#include <libempathy/empathy-debug.h>
 
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyThemeManager)
 typedef struct {
 	gchar       *name;
 	guint        name_notify_id;
-
-	gboolean     show_avatars;
-	guint        show_avatars_notify_id;
-
-	EmpathyTheme *clean_theme;
-	EmpathyTheme *simple_theme;
-	EmpathyTheme *blue_theme;
-	EmpathyTheme *classic_theme;
-
-	GtkSettings  *settings;
+	GtkSettings *settings;
 } EmpathyThemeManagerPriv;
 
-static void        theme_manager_finalize                 (GObject            *object);
-static void        theme_manager_notify_name_cb           (EmpathyConf         *conf,
-							   const gchar        *key,
-							   gpointer            user_data);
-
-static void        theme_manager_notify_show_avatars_cb   (EmpathyConf         *conf,
-							   const gchar        *key,
-							   gpointer            user_data);
-static void        theme_manager_apply_theme              (EmpathyThemeManager *manager,
-							   EmpathyChatView     *view,
-							   const gchar        *name);
-
 enum {
 	THEME_CHANGED,
 	LAST_SIGNAL
@@ -78,7 +63,7 @@
 };
 
 G_DEFINE_TYPE (EmpathyThemeManager, empathy_theme_manager, G_TYPE_OBJECT);
-
+/*
 static void
 theme_manager_gdk_color_to_hex (GdkColor *gdk_color, gchar *str_color)
 {
@@ -88,10 +73,15 @@
 		    gdk_color->green >> 8,
 		    gdk_color->blue >> 8);
 }
- 
- static void
+*/ 
+static void
 theme_manager_color_hash_notify_cb (EmpathyThemeManager *manager)
 {
+#if 0
+
+FIXME: Make that work, it should update color when theme changes but it
+       doesnt seems to work with all themes.
+
 	EmpathyThemeManagerPriv *priv;
 	GtkStyle                *style;
 	gchar                    color[10];
@@ -100,8 +90,6 @@
 
 	style = gtk_widget_get_default_style ();
 
-	g_object_freeze_notify (G_OBJECT (priv->simple_theme));
-
 	theme_manager_gdk_color_to_hex (&style->base[GTK_STATE_SELECTED], color);
 	g_object_set (priv->simple_theme,
 		      "action-foreground", color,
@@ -122,14 +110,9 @@
 	g_object_set (priv->simple_theme,
 		      "header-foreground", color,
 		      NULL);
-
-	g_object_thaw_notify (G_OBJECT (priv->simple_theme));
-
-#if 0
-
-FIXME: Make that work, it should update color when theme changes but it
-       doesnt seems to work with all themes.
   
+--------
+
 	g_object_get (priv->settings,
 		      "color-hash", &color_hash,
 		      NULL);
@@ -187,6 +170,58 @@
 #endif
 }
 
+static gboolean
+theme_manager_ensure_theme_exists (const gchar *name)
+{
+	gint i;
+
+	if (G_STR_EMPTY (name)) {
+		return FALSE;
+	}
+
+	for (i = 0; themes[i]; i += 2) {
+		if (strcmp (themes[i], name) == 0) {
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+static void
+theme_manager_notify_name_cb (EmpathyConf *conf,
+			      const gchar *key,
+			      gpointer     user_data)
+{
+	EmpathyThemeManager     *manager = EMPATHY_THEME_MANAGER (user_data);
+	EmpathyThemeManagerPriv *priv = GET_PRIV (manager);
+	gchar                   *name;
+
+	g_free (priv->name);
+
+	name = NULL;
+	if (!empathy_conf_get_string (conf, key, &name) ||
+	    !theme_manager_ensure_theme_exists (name)) {
+		priv->name = g_strdup ("classic");
+		g_free (name);
+	} else {
+		priv->name = name;
+	}
+
+	g_signal_emit (manager, signals[THEME_CHANGED], 0, NULL);
+}
+
+static void
+theme_manager_finalize (GObject *object)
+{
+	EmpathyThemeManagerPriv *priv = GET_PRIV (object);
+
+	empathy_conf_notify_remove (empathy_conf_get (), priv->name_notify_id);
+	g_free (priv->name);
+
+	G_OBJECT_CLASS (empathy_theme_manager_parent_class)->finalize (object);
+}
+
 static void
 empathy_theme_manager_class_init (EmpathyThemeManagerClass *klass)
 {
@@ -214,176 +249,193 @@
 		EMPATHY_TYPE_THEME_MANAGER, EmpathyThemeManagerPriv);
 
 	manager->priv = priv;
-	priv->name_notify_id =
-		empathy_conf_notify_add (empathy_conf_get (),
-					EMPATHY_PREFS_CHAT_THEME,
-					theme_manager_notify_name_cb,
-					manager);
-
-	empathy_conf_get_string (empathy_conf_get (),
-				EMPATHY_PREFS_CHAT_THEME,
-				&priv->name);
 
-	/* Unused right now, but will be used soon. */
-	priv->show_avatars_notify_id =
+	/* Take the theme name and track changes */
+	priv->name_notify_id =
 		empathy_conf_notify_add (empathy_conf_get (),
-					EMPATHY_PREFS_UI_SHOW_AVATARS,
-					theme_manager_notify_show_avatars_cb,
-					manager);
-
-	empathy_conf_get_bool (empathy_conf_get (),
-			      EMPATHY_PREFS_UI_SHOW_AVATARS,
-			      &priv->show_avatars);
+					 EMPATHY_PREFS_CHAT_THEME,
+					 theme_manager_notify_name_cb,
+					 manager);
+	theme_manager_notify_name_cb (empathy_conf_get (),
+				      EMPATHY_PREFS_CHAT_THEME,
+				      manager);
 
+	/* Track GTK color changes */
 	priv->settings = gtk_settings_get_default ();
 	g_signal_connect_swapped (priv->settings, "notify::color-hash",
 				  G_CALLBACK (theme_manager_color_hash_notify_cb),
 				  manager);
-
-	priv->simple_theme = g_object_new (EMPATHY_TYPE_THEME_BOXES, NULL);
-	theme_manager_color_hash_notify_cb (manager);
-
-	priv->clean_theme = g_object_new (EMPATHY_TYPE_THEME_BOXES,
-					  "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);
-
-	priv->blue_theme = g_object_new (EMPATHY_TYPE_THEME_BOXES,
-					 "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);
-
-	priv->classic_theme = g_object_new (EMPATHY_TYPE_THEME_IRC, NULL);
 }
 
-static void
-theme_manager_finalize (GObject *object)
+static EmpathyChatView *
+theme_manager_create_irc_view (EmpathyThemeManager *manager)
 {
-	EmpathyThemeManagerPriv *priv;
+	EmpathyChatTextView *view;
 
-	priv = GET_PRIV (object);
+	view = EMPATHY_CHAT_TEXT_VIEW (empathy_theme_irc_new ());
 
-	empathy_conf_notify_remove (empathy_conf_get (), priv->name_notify_id);
-	empathy_conf_notify_remove (empathy_conf_get (), priv->show_avatars_notify_id);
-
-	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);
-}
+	/* Define base tags */
+	/* FIXME: Missing define for highlight */
+	empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_SPACING,
+					"size", 2000,
+					NULL);
+	empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_TIME,
+					"foreground", "darkgrey",
+					"justification", GTK_JUSTIFY_CENTER,
+					NULL);
+	empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_ACTION,
+					"foreground", "brown4",
+					"style", PANGO_STYLE_ITALIC,
+					NULL);
+	empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_BODY,
+					"foreground-set", FALSE,
+					NULL);
+	empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_EVENT,
+					"foreground", "PeachPuff4",
+					"justification", GTK_JUSTIFY_LEFT,
+					NULL);
+	empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_LINK,
+					"foreground", "steelblue",
+					"underline", PANGO_UNDERLINE_SINGLE,
+					NULL);
+
+	/* Define IRC tags */
+	empathy_chat_text_view_tag_set (view, EMPATHY_THEME_IRC_TAG_NICK_SELF,
+					"foreground", "sea green",
+					NULL);
+	empathy_chat_text_view_tag_set (view, EMPATHY_THEME_IRC_TAG_NICK_OTHER,
+					"foreground", "skyblue4",
+					NULL);
+	empathy_chat_text_view_tag_set (view, EMPATHY_THEME_IRC_TAG_NICK_HIGHLIGHT,
+					"foreground", "indian red",
+					"weight", PANGO_WEIGHT_BOLD,
+					NULL);
+
+	return EMPATHY_CHAT_VIEW (view);
+}
+
+static EmpathyChatView *
+theme_manager_create_boxes_view (EmpathyThemeManager *manager,
+				 const gchar         *header_foreground,
+				 const gchar         *header_background,
+				 const gchar         *header_line_background,
+				 const gchar         *action_foreground,
+				 const gchar         *time_foreground,
+				 const gchar         *event_foreground,
+				 const gchar         *link_foreground,
+				 const gchar         *text_foreground,
+				 const gchar         *text_background,
+				 const gchar         *highlight_foreground)
+
+{
+	EmpathyChatTextView *view;
+	GtkTextTag          *tag;
+
+	view = EMPATHY_CHAT_TEXT_VIEW (empathy_theme_boxes_new ());
+
+	#define TAG_SET(prop, value) \
+		if (value != NULL) { \
+			g_object_set (tag, prop, value, NULL); \
+		}
 
-static void
-theme_manager_notify_name_cb (EmpathyConf  *conf,
-			      const gchar *key,
-			      gpointer     user_data)
+	/* Define base tags */
+	tag = empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_HIGHLIGHT,
+					      "weight", PANGO_WEIGHT_BOLD,
+					      "pixels-above-lines", 4,
+					      NULL);
+	TAG_SET ("paragraph-background", text_background);
+	TAG_SET ("foreground", highlight_foreground);
+
+	empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_SPACING,
+					"size", 3000,
+					"pixels-above-lines", 8,
+					NULL);
+	tag = empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_TIME,
+					      "justification", GTK_JUSTIFY_CENTER,
+					      NULL);
+	TAG_SET ("foreground", time_foreground);
+	tag = empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_ACTION,
+					      "style", PANGO_STYLE_ITALIC,
+					      "pixels-above-lines", 4,
+					      NULL);
+	TAG_SET ("paragraph-background", text_background);
+	TAG_SET ("foreground", action_foreground);
+	tag = empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_BODY,
+					      "pixels-above-lines", 4,
+					      NULL);
+	TAG_SET ("paragraph-background", text_background);
+	TAG_SET ("foreground", text_foreground);
+	tag = empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_EVENT,
+					      "justification", GTK_JUSTIFY_LEFT,
+					      NULL);
+	TAG_SET ("foreground", event_foreground);
+	tag = empathy_chat_text_view_tag_set (view, EMPATHY_CHAT_TEXT_VIEW_TAG_LINK,
+					      "underline", PANGO_UNDERLINE_SINGLE,
+					      NULL);
+	TAG_SET ("foreground", link_foreground);
+
+	/* Define BOXES tags */
+	tag = empathy_chat_text_view_tag_set (view, EMPATHY_THEME_BOXES_TAG_HEADER,
+					      "weight", PANGO_WEIGHT_BOLD,
+					      "foreground", header_foreground,
+					      "paragraph-background", header_background,
+					      NULL);
+	TAG_SET ("foreground", header_foreground);
+	TAG_SET ("paragraph-background", header_background);
+	tag = empathy_chat_text_view_tag_set (view, EMPATHY_THEME_BOXES_TAG_HEADER_LINE,
+					      "size", 1,
+					      "paragraph-background", header_line_background,
+					      NULL);
+	TAG_SET ("paragraph-background", header_line_background);
+
+	#undef TAG_SET
+
+	return EMPATHY_CHAT_VIEW (view);
+}
+
+EmpathyChatView *
+empathy_theme_manager_create_view (EmpathyThemeManager *manager)
 {
-	EmpathyThemeManager     *manager;
-	EmpathyThemeManagerPriv *priv;
-	gchar                  *name;
+	EmpathyThemeManagerPriv *priv = GET_PRIV (manager);
 
-	manager = user_data;
-	priv = GET_PRIV (manager);
+	g_return_val_if_fail (EMPATHY_IS_THEME_MANAGER (manager), NULL);
 
-	g_free (priv->name);
+	DEBUG ("Using theme %s", priv->name);
 
-	name = NULL;
-	if (!empathy_conf_get_string (conf, key, &name) ||
-	    name == NULL || name[0] == 0) {
-		priv->name = g_strdup ("classic");
-		g_free (name);
-	} else {
-		priv->name = name;
+	if (strcmp (priv->name, "classic") == 0)  {
+		return theme_manager_create_irc_view (manager);
 	}
-
-	g_signal_emit (manager, signals[THEME_CHANGED], 0, NULL);
-}
-
-static void
-theme_manager_notify_show_avatars_cb (EmpathyConf  *conf,
-				      const gchar *key,
-				      gpointer     user_data)
-{
-	EmpathyThemeManager     *manager;
-	EmpathyThemeManagerPriv *priv;
-	gboolean                value;
-
-	manager = user_data;
-	priv = GET_PRIV (manager);
-
-	if (!empathy_conf_get_bool (conf, key, &value)) {
-		priv->show_avatars = FALSE;
-	} else {
-		priv->show_avatars = value;
+	else if (strcmp (priv->name, "simple") == 0) {
+		return theme_manager_create_irc_view (manager);
 	}
-}
-
-static gboolean
-theme_manager_ensure_theme_exists (const gchar *name)
-{
-	gint i;
-
-	if (G_STR_EMPTY (name)) {
-		return FALSE;
-	}
-
-	for (i = 0; themes[i]; i += 2) {
-		if (strcmp (themes[i], name) == 0) {
-			return TRUE;
-		}
+	else if (strcmp (priv->name, "clean") == 0) {
+		return theme_manager_create_boxes_view (manager,
+							"black",    /* header_foreground */
+							"#efefdf",  /* header_background */
+							"#e3e3d3",  /* header_line_background */
+							"brown4",   /* action_foreground */
+							"darkgrey", /* time_foreground */
+							"darkgrey", /* event_foreground */
+							"#49789e",  /* link_foreground */
+							NULL,       /* text_foreground */
+							NULL,       /* text_background */
+							NULL);      /* highlight_foreground */
 	}
-
-	return FALSE;
-}
-
-static void
-theme_manager_apply_theme (EmpathyThemeManager *manager,
-			   EmpathyChatView     *view,
-			   const gchar        *name)
-{
-	EmpathyThemeManagerPriv *priv;
-	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.
-	 */
-	if (theme_manager_ensure_theme_exists (name)) {
-		if (strcmp (name, "clean") == 0) {
-			theme = priv->clean_theme;
-		}
-		else if (strcmp (name, "simple") == 0) {
-			theme = priv->simple_theme;
-		}
-		else if (strcmp (name, "blue") == 0) {
-			theme = priv->blue_theme;
-		} else {
-			theme = priv->classic_theme;
-		}
-	} else {
-		theme = priv->classic_theme;
+	else if (strcmp (priv->name, "blue") == 0) {
+		return theme_manager_create_boxes_view (manager,
+							"black",    /* header_foreground */
+							"#88a2b4",  /* header_background */
+							"#7f96a4",  /* header_line_background */
+							"brown4",   /* action_foreground */
+							"darkgrey", /* time_foreground */
+							"#7f96a4",  /* event_foreground */
+							"#49789e",  /* link_foreground */
+							"black",    /* text_foreground */
+							"#adbdc8",  /* text_background */
+							"black");   /* highlight_foreground */
 	}
 
-	empathy_chat_view_set_theme (view, theme);
+	return NULL;
 }
 
 EmpathyThemeManager *
@@ -404,26 +456,121 @@
 	return themes;
 }
 
-void
-empathy_theme_manager_apply (EmpathyThemeManager *manager,
-			    EmpathyChatView     *view,
-			    const gchar        *name)
-{
-	EmpathyThemeManagerPriv *priv;
 
-	priv = GET_PRIV (manager);
+#if 0
+// theme boxes
+	empathy_text_buffer_tag_set (buffer, "fancy-spacing",
+				     "size", 3000,
+				     "pixels-above-lines", 8,
+				     NULL);
+
+	tag = empathy_text_buffer_tag_set (buffer, "fancy-header",
+					   "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);
+	}
 
-	theme_manager_apply_theme (manager, view, name);
-}
+	tag = empathy_text_buffer_tag_set (buffer, "fancy-header-line",
+					   "size", 1,
+					   NULL);
+	if (priv->header_line_background) {
+		g_object_set (tag,
+			      "paragraph-background", priv->header_line_background,
+			      NULL);
+	}
 
-void
-empathy_theme_manager_apply_saved (EmpathyThemeManager *manager,
-				  EmpathyChatView     *view)
-{
-	EmpathyThemeManagerPriv *priv;
+	tag = empathy_text_buffer_tag_set (buffer, "fancy-body",
+					   "pixels-above-lines", 4,
+					   NULL);
+	if (priv->text_background) {
+		g_object_set (tag,
+			      "paragraph-background", priv->text_background,
+			      NULL);
+	}
 
-	priv = GET_PRIV (manager);
+	if (priv->text_foreground) {
+		g_object_set (tag,
+			      "foreground", priv->text_foreground,
+			      NULL);
+	}
 
-	theme_manager_apply_theme (manager, view, priv->name);
-}
+	tag = empathy_text_buffer_tag_set (buffer, "fancy-action",
+					   "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);
+	}
 
+	tag = empathy_text_buffer_tag_set (buffer, "fancy-highlight",
+					   "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);
+	}
+
+	tag = empathy_text_buffer_tag_set (buffer, "fancy-time",
+					   "justification", GTK_JUSTIFY_CENTER,
+					   NULL);
+	if (priv->time_foreground) {
+		g_object_set (tag,
+			      "foreground", priv->time_foreground,
+			      NULL);
+	}
+
+	tag = empathy_text_buffer_tag_set (buffer, "fancy-event",
+					   "justification", GTK_JUSTIFY_LEFT,
+					   NULL);
+	if (priv->event_foreground) {
+		g_object_set (tag,
+			      "foreground", priv->event_foreground,
+			      NULL);
+	}
+
+	tag = empathy_text_buffer_tag_set (buffer, "invite", NULL);
+	if (priv->invite_foreground) {
+		g_object_set (tag,
+			      "foreground", priv->invite_foreground,
+			      NULL);
+	}
+
+	tag = empathy_text_buffer_tag_set (buffer, "fancy-link",
+					   "underline", PANGO_UNDERLINE_SINGLE,
+					   NULL);
+	if (priv->link_foreground) {
+		g_object_set (tag,
+			      "foreground", priv->link_foreground,
+			      NULL);
+	} 
+	empathy_chat_view_set_margin (view, MARGIN);
+
+
+
+	priv->simple_theme = g_object_new (EMPATHY_TYPE_THEME_BOXES, NULL);
+	theme_manager_color_hash_notify_cb (manager);
+#endif

Modified: trunk/libempathy-gtk/empathy-theme-manager.h
==============================================================================
--- trunk/libempathy-gtk/empathy-theme-manager.h	(original)
+++ trunk/libempathy-gtk/empathy-theme-manager.h	Tue Dec 16 09:24:35 2008
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * Copyright (C) 2005-2007 Imendio AB
+ * Copyright (C) 2008 Collabora Ltd.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -16,12 +17,15 @@
  * 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: Xavier Claessens <xclaesse gmail com>
  */
 
 #ifndef __EMPATHY_THEME_MANAGER_H__
 #define __EMPATHY_THEME_MANAGER_H__
 
 #include <glib-object.h>
+#include "empathy-chat-view.h"
 
 G_BEGIN_DECLS
 
@@ -44,14 +48,10 @@
 	GObjectClass parent_class;
 };
 
-GType               empathy_theme_manager_get_type            (void) G_GNUC_CONST;
-EmpathyThemeManager *empathy_theme_manager_get                 (void);
-const gchar **      empathy_theme_manager_get_themes          (void);
-void                empathy_theme_manager_apply               (EmpathyThemeManager *manager,
-							      EmpathyChatView     *view,
-							      const gchar        *theme);
-void                empathy_theme_manager_apply_saved         (EmpathyThemeManager *manager,
-							      EmpathyChatView     *view);
+GType                   empathy_theme_manager_get_type    (void) G_GNUC_CONST;
+EmpathyThemeManager *   empathy_theme_manager_get         (void);
+const gchar **          empathy_theme_manager_get_themes  (void);
+EmpathyChatView *       empathy_theme_manager_create_view (EmpathyThemeManager *manager);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]