[balsa] Add filter for colorizing messages



commit dda066ecc209b424da23f88fb4f242b0f2558e91
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Mon May 4 22:49:25 2009 -0400

    Add filter for colorizing messages
---
 ChangeLog                   |   29 ++++++++++++
 libbalsa/filter.c           |   14 ++++++
 libbalsa/filter.h           |    4 +-
 libbalsa/libbalsa_private.h |    6 ++-
 libbalsa/mailbox.c          |   71 ++++++++++++++++++++++++++++++
 libbalsa/mailbox.h          |   10 ++++
 src/balsa-index.c           |   95 +++++++++++++++++++++++++---------------
 src/filter-edit-callbacks.c |  101 ++++++++++++++++++++++++++++++++++++++++---
 src/filter-edit-dialog.c    |   43 ++++++++++++++++++
 src/filter-edit.h           |    5 ++
 src/filter-run-callbacks.c  |   12 +++--
 src/save-restore.c          |   22 +---------
 12 files changed, 343 insertions(+), 69 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 98e2cb3..17ee0a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2009-05-04  Peter Bloomfield
+
+	Add filter for colorizing messages
+
+	* libbalsa/filter.h: add FILTER_COLOR to FilterActionType enum,
+	and FILTER_N_TYPES sentinel.
+	* libbalsa/filter.c (libbalsa_filter_mailbox_messages): act on
+	it.
+	* libbalsa/libbalsa_private.h: add color members to
+	LibBalsaMailboxIndexEntry.
+	* libbalsa/mailbox.h: new methods to set color; expand
+	LibBalsaMailboxColumn enum.
+	* libbalsa/mailbox.c (lbm_index_entry_populate_from_msg),
+	(mbox_model_init), (mbox_model_get_value), (lbm_set_color),
+	(libbalsa_mailbox_set_foreground),
+	(libbalsa_mailbox_set_background): implement them.
+	* src/balsa-index.c (bndx_instance_init): set color in all
+	columns.
+	* src/filter-edit-callbacks.c (fe_action_selected),
+	(fe_apply_pressed), (fe_filters_list_selection_changed),
+	(fe_color_check_toggled), (fe_color_set):
+	* src/filter-edit-dialog.c (fe_make_color_buttons),
+	(build_action_page): add option to choose colors.
+	* src/filter-edit.h: new callbacks.
+	* src/filter-run-callbacks.c (fr_apply_selected_pressed_func),
+	(fr_add_pressed_func): ditto.
+	* src/save-restore.c (config_filter_load),
+	(config_filters_load): scrap broken pre-2.1 compatibility code.
+
 2009-04-29  Ildar Mulyukov
 
 	* balsa.desktop.in: respect
diff --git a/libbalsa/filter.c b/libbalsa/filter.c
index 5e1c5c7..49f07de 100644
--- a/libbalsa/filter.c
+++ b/libbalsa/filter.c
@@ -249,6 +249,7 @@ libbalsa_filter_mailbox_messages(LibBalsaFilter * filt,
     gboolean result=FALSE;
     LibBalsaMailbox *mbox;
     GError *err = NULL;
+    gchar **parts, **p;
 
     if (msgnos->len == 0)
 	return FALSE;
@@ -301,6 +302,18 @@ libbalsa_filter_mailbox_messages(LibBalsaFilter * filt,
 	else if (mbox == filters_trash_mbox)
 	    result = TRUE;
 	break;
+    case FILTER_COLOR:
+        parts = g_strsplit(filt->action_string, ";", 2);
+        for (p = parts; *p; p++) {
+            if (g_str_has_prefix(*p, "foreground:"))
+                libbalsa_mailbox_set_foreground(mailbox, msgnos,
+                                                (*p) + 11);
+            if (g_str_has_prefix(*p, "background:"))
+                libbalsa_mailbox_set_background(mailbox, msgnos,
+                                                (*p) + 11);
+        }
+        g_strfreev(parts);
+        break;
     case FILTER_PRINT:
 	/* FIXME : to be implemented */
 	break;
@@ -308,6 +321,7 @@ libbalsa_filter_mailbox_messages(LibBalsaFilter * filt,
 	/* FIXME : to be implemented */
 	break;
     case FILTER_NOTHING:
+    case FILTER_N_TYPES:
 	/* Nothing to do */
 	break;
     }
diff --git a/libbalsa/filter.h b/libbalsa/filter.h
index 2700acb..3013023 100644
--- a/libbalsa/filter.h
+++ b/libbalsa/filter.h
@@ -145,7 +145,9 @@ typedef enum {
     FILTER_MOVE,
     FILTER_PRINT,
     FILTER_RUN,
-    FILTER_TRASH              /* Must be the last one */
+    FILTER_TRASH,
+    FILTER_COLOR,
+    FILTER_N_TYPES
 } FilterActionType;
 
 /*
diff --git a/libbalsa/libbalsa_private.h b/libbalsa/libbalsa_private.h
index 82b87e0..467e9b4 100644
--- a/libbalsa/libbalsa_private.h
+++ b/libbalsa/libbalsa_private.h
@@ -30,7 +30,7 @@
 #include <unistd.h>
 
 /* LibBalsaMailboxEntry handling code which is to be used for message
- * intex caching.  Mailbox index entry used for caching (almost) all
+ * index caching.  Mailbox index entry used for caching (almost) all
  * columns provided by GtkTreeModel interface. Size matters. */
 struct LibBalsaMailboxIndexEntry_ {
     gchar *from;
@@ -40,6 +40,10 @@ struct LibBalsaMailboxIndexEntry_ {
     unsigned short status_icon;
     unsigned short attach_icon;
     unsigned long size;
+    gchar *foreground;
+    gchar *background;
+    unsigned foreground_set:1;
+    unsigned background_set:1;
     unsigned unseen:1;
 #ifdef BALSA_USE_THREADS
     unsigned idle_pending:1;
diff --git a/libbalsa/mailbox.c b/libbalsa/mailbox.c
index f1378ef..1073081 100644
--- a/libbalsa/mailbox.c
+++ b/libbalsa/mailbox.c
@@ -356,6 +356,10 @@ lbm_index_entry_populate_from_msg(LibBalsaMailboxIndexEntry * entry,
     entry->status_icon   = libbalsa_get_icon_from_flags(msg->flags);
     entry->attach_icon   = libbalsa_message_get_attach_icon(msg);
     entry->size          = msg->length;
+    entry->foreground     = NULL;
+    entry->background     = NULL;
+    entry->foreground_set = 0;
+    entry->background_set = 0;
     entry->unseen        = LIBBALSA_MESSAGE_IS_UNREAD(msg);
 #ifdef BALSA_USE_THREADS
     entry->idle_pending  = 0;
@@ -2604,6 +2608,11 @@ mbox_model_init(GtkTreeModelIface *iface)
     mbox_model_col_type[LB_MBOX_SIZE_COL]    = G_TYPE_STRING;
     mbox_model_col_type[LB_MBOX_WEIGHT_COL]  = G_TYPE_UINT;
     mbox_model_col_type[LB_MBOX_STYLE_COL]   = G_TYPE_UINT;
+    mbox_model_col_type[LB_MBOX_FOREGROUND_COL]     = G_TYPE_STRING;
+    mbox_model_col_type[LB_MBOX_FOREGROUND_SET_COL] = G_TYPE_UINT;
+    mbox_model_col_type[LB_MBOX_BACKGROUND_COL]     = G_TYPE_STRING;
+    mbox_model_col_type[LB_MBOX_BACKGROUND_SET_COL] = G_TYPE_UINT;
+
 
     libbalsa_mbox_model_signals[ROW_CHANGED] =
         g_signal_lookup("row-changed",           GTK_TYPE_TREE_MODEL);
@@ -2919,6 +2928,24 @@ mbox_model_get_value(GtkTreeModel *tree_model,
 						   (GNode *) iter->user_data)
                          ? PANGO_STYLE_OBLIQUE : PANGO_STYLE_NORMAL);
         break;
+    case LB_MBOX_FOREGROUND_COL:
+        if(msg) {
+            tmp = g_strdup(msg->foreground);
+            g_value_take_string(value, tmp);
+        }
+        break;
+    case LB_MBOX_FOREGROUND_SET_COL:
+        g_value_set_uint(value, msg && msg->foreground_set);
+        break;
+    case LB_MBOX_BACKGROUND_COL:
+        if(msg) {
+            tmp = g_strdup(msg->background);
+            g_value_take_string(value, tmp);
+        }
+        break;
+    case LB_MBOX_BACKGROUND_SET_COL:
+        g_value_set_uint(value, msg && msg->background_set);
+        break;
     }
 }
 
@@ -4250,3 +4277,47 @@ libbalsa_mailbox_cache_message(LibBalsaMailbox * mailbox, guint msgno,
 
     lbm_cache_message(mailbox, msgno, message);
 }
+
+static void
+lbm_set_color(LibBalsaMailbox * mailbox, GArray * msgnos,
+              const gchar * color, gboolean foreground)
+{
+    guint i;
+
+    for (i = 0; i < msgnos->len; i++) {
+        guint msgno = g_array_index(msgnos, guint, i);
+        LibBalsaMailboxIndexEntry *entry;
+
+        if (msgno > mailbox->mindex->len)
+            return;
+
+        entry = g_ptr_array_index(mailbox->mindex, msgno - 1);
+        if (!entry)
+            entry = g_ptr_array_index(mailbox->mindex, msgno - 1) =
+                g_new0(LibBalsaMailboxIndexEntry, 1);
+
+        if (foreground) {
+            g_free(entry->foreground);
+            entry->foreground = g_strdup(color);
+            entry->foreground_set = TRUE;
+        } else {
+            g_free(entry->background);
+            entry->background = g_strdup(color);
+            entry->background_set = TRUE;
+        }
+    }
+}
+
+void
+libbalsa_mailbox_set_foreground(LibBalsaMailbox * mailbox, GArray * msgnos,
+                                const gchar * color)
+{
+    lbm_set_color(mailbox, msgnos, color, TRUE);
+}
+
+void
+libbalsa_mailbox_set_background(LibBalsaMailbox * mailbox, GArray * msgnos,
+                                const gchar * color)
+{
+    lbm_set_color(mailbox, msgnos, color, FALSE);
+}
diff --git a/libbalsa/mailbox.h b/libbalsa/mailbox.h
index 4b3f755..614895a 100644
--- a/libbalsa/mailbox.h
+++ b/libbalsa/mailbox.h
@@ -653,6 +653,12 @@ void libbalsa_mailbox_msgno_update_attach(LibBalsaMailbox * mailbox,
 void libbalsa_mailbox_cache_message(LibBalsaMailbox * mailbox, guint msgno,
                                     LibBalsaMessage * message);
 
+/* Set the foreground and background colors of an array of messages */
+void libbalsa_mailbox_set_foreground(LibBalsaMailbox * mailbox,
+                                     GArray * msgnos, const gchar * color);
+void libbalsa_mailbox_set_background(LibBalsaMailbox * mailbox,
+                                     GArray * msgnos, const gchar * color);
+
 #if BALSA_USE_THREADS
 
 /* Lock and unlock the mail store--currently, a no-op except for mbox.
@@ -678,6 +684,10 @@ typedef enum {
     LB_MBOX_SIZE_COL,
     LB_MBOX_WEIGHT_COL,
     LB_MBOX_STYLE_COL,
+    LB_MBOX_FOREGROUND_COL,
+    LB_MBOX_FOREGROUND_SET_COL,
+    LB_MBOX_BACKGROUND_COL,
+    LB_MBOX_BACKGROUND_SET_COL,
     LB_MBOX_N_COLS
 } LibBalsaMailboxColumn;
 
diff --git a/src/balsa-index.c b/src/balsa-index.c
index bf5ff5b..789d333 100644
--- a/src/balsa-index.c
+++ b/src/balsa-index.c
@@ -291,10 +291,14 @@ bndx_instance_init(BalsaIndex * index)
     
     /* Index column */
     renderer = gtk_cell_renderer_text_new();
-    column =
-        gtk_tree_view_column_new_with_attributes("#", renderer,
-                                                 "text", LB_MBOX_MSGNO_COL,
-                                                 NULL);
+    column = gtk_tree_view_column_new_with_attributes
+        ("#", renderer,
+         "text",           LB_MBOX_MSGNO_COL,
+         "foreground",     LB_MBOX_FOREGROUND_COL,
+         "foreground-set", LB_MBOX_FOREGROUND_SET_COL,
+         "background",     LB_MBOX_BACKGROUND_COL,
+         "background-set", LB_MBOX_BACKGROUND_SET_COL,
+         NULL);
     g_object_set(renderer, "xalign", 1.0, NULL);
     set_sizing(column); gtk_tree_view_append_column(tree_view, column);
     bi_apply_other_column_settings(column, TRUE, LB_MBOX_MSGNO_COL);
@@ -302,31 +306,39 @@ bndx_instance_init(BalsaIndex * index)
     /* Status icon column */
     renderer = gtk_cell_renderer_pixbuf_new();
     gtk_cell_renderer_set_fixed_size(renderer, icon_w, icon_h);
-    column =
-        gtk_tree_view_column_new_with_attributes("S", renderer,
-                                                 "pixbuf", LB_MBOX_MARKED_COL,
-                                                 NULL);
+    column = gtk_tree_view_column_new_with_attributes
+        ("S", renderer,
+         "pixbuf",              LB_MBOX_MARKED_COL,
+         "cell-background",     LB_MBOX_BACKGROUND_COL,
+         "cell-background-set", LB_MBOX_BACKGROUND_SET_COL,
+         NULL);
     set_sizing(column); gtk_tree_view_append_column(tree_view, column);
     bi_apply_other_column_settings(column, FALSE, 0);
 
     /* Attachment icon column */
     renderer = gtk_cell_renderer_pixbuf_new();
     gtk_cell_renderer_set_fixed_size(renderer, icon_w, icon_h);
-    column =
-        gtk_tree_view_column_new_with_attributes("A", renderer,
-                                                 "pixbuf", LB_MBOX_ATTACH_COL,
-                                                 NULL);
+    column = gtk_tree_view_column_new_with_attributes
+        ("A", renderer,
+         "pixbuf",              LB_MBOX_ATTACH_COL,
+         "cell-background",     LB_MBOX_BACKGROUND_COL,
+         "cell-background-set", LB_MBOX_BACKGROUND_SET_COL,
+         NULL);
     set_sizing(column); gtk_tree_view_append_column(tree_view, column);
     bi_apply_other_column_settings(column, FALSE, 0);
 
     /* From/To column */
     renderer = gtk_cell_renderer_text_new();
-    column = 
-        gtk_tree_view_column_new_with_attributes(_("From"), renderer,
-                                                 "text", LB_MBOX_FROM_COL,
-						 "weight", LB_MBOX_WEIGHT_COL,
-						 "style", LB_MBOX_STYLE_COL,
-                                                 NULL);
+    column = gtk_tree_view_column_new_with_attributes
+        (_("From"), renderer,
+         "text",           LB_MBOX_FROM_COL,
+         "weight",         LB_MBOX_WEIGHT_COL,
+         "style",          LB_MBOX_STYLE_COL,
+         "foreground",     LB_MBOX_FOREGROUND_COL,
+         "foreground-set", LB_MBOX_FOREGROUND_SET_COL,
+         "background",     LB_MBOX_BACKGROUND_COL,
+         "background-set", LB_MBOX_BACKGROUND_SET_COL,
+         NULL);
     gtk_tree_view_column_set_resizable(column, TRUE);
     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
     gtk_tree_view_append_column(tree_view, column);
@@ -334,12 +346,16 @@ bndx_instance_init(BalsaIndex * index)
 
     /* Subject column--contains tree expanders */
     renderer = gtk_cell_renderer_text_new();
-    column = 
-        gtk_tree_view_column_new_with_attributes(_("Subject"), renderer,
-                                                 "text", LB_MBOX_SUBJECT_COL,
-						 "weight", LB_MBOX_WEIGHT_COL,
-						 "style", LB_MBOX_STYLE_COL,
-                                                 NULL);
+    column = gtk_tree_view_column_new_with_attributes
+        (_("Subject"), renderer,
+         "text",           LB_MBOX_SUBJECT_COL,
+         "weight",         LB_MBOX_WEIGHT_COL,
+         "style",          LB_MBOX_STYLE_COL,
+         "foreground",     LB_MBOX_FOREGROUND_COL,
+         "foreground-set", LB_MBOX_FOREGROUND_SET_COL,
+         "background",     LB_MBOX_BACKGROUND_COL,
+         "background-set", LB_MBOX_BACKGROUND_SET_COL,
+         NULL);
     gtk_tree_view_column_set_resizable(column, TRUE);
     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
     gtk_tree_view_append_column(tree_view, column);
@@ -348,12 +364,16 @@ bndx_instance_init(BalsaIndex * index)
 
     /* Date column */
     renderer = gtk_cell_renderer_text_new();
-    column = 
-        gtk_tree_view_column_new_with_attributes(_("Date"), renderer,
-                                                 "text", LB_MBOX_DATE_COL,
-						 "weight", LB_MBOX_WEIGHT_COL,
-						 "style", LB_MBOX_STYLE_COL,
-                                                 NULL);
+    column = gtk_tree_view_column_new_with_attributes
+        (_("Date"), renderer,
+         "text",           LB_MBOX_DATE_COL,
+         "weight",         LB_MBOX_WEIGHT_COL,
+         "style",          LB_MBOX_STYLE_COL,
+         "foreground",     LB_MBOX_FOREGROUND_COL,
+         "foreground-set", LB_MBOX_FOREGROUND_SET_COL,
+         "background",     LB_MBOX_BACKGROUND_COL,
+         "background-set", LB_MBOX_BACKGROUND_SET_COL,
+         NULL);
     gtk_tree_view_column_set_resizable(column, TRUE);
     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
     gtk_tree_view_append_column(tree_view, column);
@@ -365,11 +385,16 @@ bndx_instance_init(BalsaIndex * index)
     renderer = gtk_cell_renderer_text_new();
     g_object_set(renderer, "xalign", 1.0, NULL);
     gtk_tree_view_column_pack_start(column, renderer, FALSE);
-    gtk_tree_view_column_set_attributes(column, renderer,
-                                        "text", LB_MBOX_SIZE_COL,
-					"weight", LB_MBOX_WEIGHT_COL,
-					"style", LB_MBOX_STYLE_COL,
-                                        NULL);
+    gtk_tree_view_column_set_attributes
+        (column, renderer,
+         "text",           LB_MBOX_SIZE_COL,
+         "weight",         LB_MBOX_WEIGHT_COL,
+         "style",          LB_MBOX_STYLE_COL,
+         "foreground",     LB_MBOX_FOREGROUND_COL,
+         "foreground-set", LB_MBOX_FOREGROUND_SET_COL,
+         "background",     LB_MBOX_BACKGROUND_COL,
+         "background-set", LB_MBOX_BACKGROUND_SET_COL,
+         NULL);
     set_sizing(column); gtk_tree_view_append_column(tree_view, column);
     bi_apply_other_column_settings(column, TRUE, LB_MBOX_SIZE_COL);
 
diff --git a/src/filter-edit-callbacks.c b/src/filter-edit-callbacks.c
index 6a37312..573d81c 100644
--- a/src/filter-edit-callbacks.c
+++ b/src/filter-edit-callbacks.c
@@ -121,9 +121,19 @@ extern GtkWidget *fe_popup_entry;
 /* action field */
 extern GtkWidget *fe_action_option_menu;
 
+/* action list */
+extern option_list fe_actions[];
+
 /* Mailboxes option menu */
 extern GtkWidget * fe_mailboxes;
 
+/* Colorize widgets */
+extern GtkWidget * fe_color_buttons;
+extern GtkWidget * fe_foreground_set;
+extern GtkWidget * fe_foreground;
+extern GtkWidget * fe_background_set;
+extern GtkWidget * fe_background;
+
 /* Different buttons that need to be greyed or ungreyed */
 extern GtkWidget * fe_new_button;
 extern GtkWidget * fe_delete_button;
@@ -1502,8 +1512,15 @@ fe_action_selected(GtkWidget * widget, gpointer data)
 {
     FilterActionType type =
         (FilterActionType) fe_combo_box_get_value(widget);
-    gtk_widget_set_sensitive(GTK_WIDGET(fe_mailboxes),
-                             type != FILTER_TRASH);
+    if (type == FILTER_COLOR) {
+        gtk_widget_hide(fe_mailboxes);
+        gtk_widget_show_all(fe_color_buttons);
+    } else {
+        gtk_widget_hide(fe_color_buttons);
+        gtk_widget_show(fe_mailboxes);
+        gtk_widget_set_sensitive(GTK_WIDGET(fe_mailboxes),
+                                 type != FILTER_TRASH);
+    }
     set_button_sensitivities(TRUE);
 }                       /* end fe_action_selected() */
 
@@ -1870,7 +1887,36 @@ fe_apply_pressed(GtkWidget * widget, gpointer data)
 
     fil->action=action;
 
-    if (fil->action!=FILTER_TRASH)
+    if (fil->action == FILTER_COLOR) {
+        GdkColor color;
+        GString *string = g_string_new(NULL);
+        GtkToggleButton *toggle_button;
+        gchar *color_string;
+
+        toggle_button = (GTK_TOGGLE_BUTTON(fe_foreground_set));
+        if (gtk_toggle_button_get_active(toggle_button)) {
+            gtk_color_button_get_color(GTK_COLOR_BUTTON(fe_foreground),
+                                       &color);
+            color_string = gdk_color_to_string(&color);
+            g_string_append_printf(string, "foreground:%s", color_string);
+            g_free(color_string);
+            gtk_toggle_button_set_active(toggle_button, FALSE);
+        }
+
+        toggle_button = (GTK_TOGGLE_BUTTON(fe_background_set));
+        if (gtk_toggle_button_get_active(toggle_button)) {
+            gtk_color_button_get_color(GTK_COLOR_BUTTON(fe_background),
+                                       &color);
+            color_string = gdk_color_to_string(&color);
+            if (string->len > 0)
+                g_string_append_c(string, ';');
+            g_string_append_printf(string, "background:%s", color_string);
+            g_free(color_string);
+            gtk_toggle_button_set_active(toggle_button, FALSE);
+        }
+
+        fil->action_string = g_string_free(string, FALSE);
+    } else if (fil->action!=FILTER_TRASH)
         fil->action_string=g_strdup(balsa_mblist_mru_option_menu_get(fe_mailboxes));
     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fe_popup_button))) {
         static gchar defstring[] = N_("Filter has matched");
@@ -1971,7 +2017,7 @@ fe_filters_list_selection_changed(GtkTreeSelection * selection,
     GtkTreeModel *model;
     GtkTreeIter iter;
     LibBalsaFilter* fil;
-    int pos;
+    int pos, i;
 
     if (!gtk_tree_selection_get_selected(selection, &model, &iter)) {
         if (gtk_tree_model_iter_n_children(model, NULL) == 0)
@@ -1994,12 +2040,36 @@ fe_filters_list_selection_changed(GtkTreeSelection * selection,
         gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(fe_sound_entry),
                                       fil->sound);
     
-    gtk_combo_box_set_active(GTK_COMBO_BOX(fe_action_option_menu),
-                             fil->action - 1);
+    for (i = 0; i < FILTER_N_TYPES - 1; i++)
+        if (((FilterActionType) fe_actions[i].value) == fil->action)
+            gtk_combo_box_set_active(GTK_COMBO_BOX(fe_action_option_menu),
+                                     i);
     pos = (fil->condition
            && fil->condition->type == CONDITION_AND) ? 1 : 0;
     gtk_combo_box_set_active(GTK_COMBO_BOX(fe_op_codes_option_menu), pos);
-    if (fil->action!=FILTER_TRASH && fil->action_string)
+    if (fil->action == FILTER_COLOR) {
+        gchar **parts, **p;
+        GdkColor color;
+
+        parts = g_strsplit(fil->action_string, ";", 2);
+        for (p = parts; *p; p++) {
+            if (g_str_has_prefix(*p, "foreground:")) {
+                gdk_color_parse((*p) + 11, &color);
+                gtk_color_button_set_color(GTK_COLOR_BUTTON(fe_foreground),
+                                           &color);
+                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+                                             (fe_foreground_set), TRUE);
+            }
+            if (g_str_has_prefix(*p, "background:")) {
+                gdk_color_parse((*p) + 11, &color);
+                gtk_color_button_set_color(GTK_COLOR_BUTTON(fe_background),
+                                           &color);
+                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+                                             (fe_background_set), TRUE);
+            }
+        }
+        g_strfreev(parts);
+    } else if (fil->action!=FILTER_TRASH && fil->action_string)
         balsa_mblist_mru_option_menu_set(fe_mailboxes,
                                          fil->action_string);
     /* We free the conditions */
@@ -2062,3 +2132,20 @@ fe_sound_response(GtkDialog * dialog, gint response)
     if (response == GTK_RESPONSE_ACCEPT)
         set_button_sensitivities(TRUE);
 }
+
+/* Callback for color check-buttons' "toggled" signal */
+void
+fe_color_check_toggled(GtkToggleButton * check_button, gpointer data)
+{
+    GtkWidget *color_button = GTK_WIDGET(data);
+    gtk_widget_set_sensitive(color_button,
+                             gtk_toggle_button_get_active(check_button));
+    set_button_sensitivities(TRUE);
+}
+
+/* Callback for color buttons' "color-set" signal */
+void
+fe_color_set(GtkColorButton * color_button, gpointer data)
+{
+    set_button_sensitivities(TRUE);
+}
diff --git a/src/filter-edit-dialog.c b/src/filter-edit-dialog.c
index 0b9b058..63f1d05 100644
--- a/src/filter-edit-dialog.c
+++ b/src/filter-edit-dialog.c
@@ -77,6 +77,13 @@ GtkWidget *fe_action_option_menu;
 /* Mailboxes option menu */
 GtkWidget * fe_mailboxes;
 
+/* Select colors */
+GtkWidget * fe_color_buttons;
+GtkWidget * fe_foreground_set;
+GtkWidget * fe_foreground;
+GtkWidget * fe_background_set;
+GtkWidget * fe_background;
+
 GtkWidget* fe_right_page;
 
 /* Different buttons that need to be greyed or ungreyed */
@@ -96,6 +103,7 @@ option_list fe_search_type[] = {
 option_list fe_actions[] = {
     {N_("Copy to folder:"), FILTER_COPY},
     {N_("Move to folder:"), FILTER_MOVE},
+    {N_("Colorize"), FILTER_COLOR},
     {N_("Print on printer:"), FILTER_PRINT},
     {N_("Run program:"), FILTER_RUN},
     {N_("Send to Trash"), FILTER_TRASH}
@@ -335,6 +343,39 @@ build_match_page()
  *
  * Builds the "Action" page of the main notebook
  */
+
+static GtkWidget *
+fe_make_color_buttons(void)
+{
+    GtkWidget *table_widget = gtk_table_new(2, 2, FALSE);
+    GtkTable  *table = GTK_TABLE(table_widget);
+    GdkColor color;
+
+    fe_foreground_set = gtk_check_button_new_with_mnemonic(_("Foreground"));
+    gtk_table_attach_defaults(table, fe_foreground_set, 0, 1, 0, 1);
+    gdk_color_parse("black", &color);
+    fe_foreground = gtk_color_button_new_with_color(&color);
+    gtk_widget_set_sensitive(fe_foreground, FALSE);
+    gtk_table_attach_defaults(table, fe_foreground, 1, 2, 0, 1);
+    g_signal_connect(fe_foreground_set, "toggled",
+                     G_CALLBACK(fe_color_check_toggled), fe_foreground);
+    g_signal_connect(fe_foreground, "color-set",
+                     G_CALLBACK(fe_color_set), NULL);
+
+    fe_background_set = gtk_check_button_new_with_mnemonic(_("Background"));
+    gtk_table_attach_defaults(table, fe_background_set, 0, 1, 1, 2);
+    gdk_color_parse("white", &color);
+    fe_background = gtk_color_button_new_with_color(&color);
+    gtk_widget_set_sensitive(fe_background, FALSE);
+    gtk_table_attach_defaults(table, fe_background, 1, 2, 1, 2);
+    g_signal_connect(fe_background_set, "toggled",
+                     G_CALLBACK(fe_color_check_toggled), fe_background);
+    g_signal_connect(fe_background, "color-set",
+                     G_CALLBACK(fe_color_set), NULL);
+
+    return table_widget;
+}
+
 static GtkWidget *
 build_action_page(GtkWindow * window)
 {
@@ -430,6 +471,8 @@ build_action_page(GtkWindow * window)
                      G_CALLBACK(fe_action_changed), NULL);
     gtk_box_pack_start(GTK_BOX(box), fe_mailboxes, TRUE, FALSE, 1);
 
+    fe_color_buttons = fe_make_color_buttons();
+    gtk_box_pack_start(GTK_BOX(box), fe_color_buttons, TRUE, FALSE, 1);
     return page;
 }				/* end build_action_page() */
 
diff --git a/src/filter-edit.h b/src/filter-edit.h
index 6509f5c..3701122 100644
--- a/src/filter-edit.h
+++ b/src/filter-edit.h
@@ -98,4 +98,9 @@ void fe_enable_right_page(gboolean enabled);
 void fe_sound_response(GtkDialog * dialog, gint response);
 
 void fe_add_new_user_header(const gchar *);
+
+/* Callbacks for color button signals */
+void fe_color_check_toggled(GtkToggleButton * check_button, gpointer data);
+void fe_color_set(GtkColorButton * color_button, gpointer data);
+
 #endif /*__FILTER_EDIT_H__ */
diff --git a/src/filter-run-callbacks.c b/src/filter-run-callbacks.c
index b6c1138..ded857a 100644
--- a/src/filter-run-callbacks.c
+++ b/src/filter-run-callbacks.c
@@ -208,8 +208,10 @@ fr_apply_selected_pressed_func(GtkTreeModel * model, GtkTreePath * path,
 
     gtk_tree_model_get(model, iter, DATA_COLUMN, &fil, -1);
     /* Check for move to self: */
-    if (fil->action == FILTER_RUN || fil->action == FILTER_TRASH ||
-        strcmp(fil->action_string, p->mbox->url) != 0)
+    if (fil->action == FILTER_RUN
+        || fil->action == FILTER_TRASH
+        || (fil->action == FILTER_COLOR && fil->action_string[0])
+        || strcmp(fil->action_string, p->mbox->url) != 0)
         p->filters = g_slist_append(p->filters, fil);
 }
 
@@ -266,8 +268,10 @@ fr_add_pressed_func(GtkTreeModel * model, GtkTreePath * path,
     LibBalsaFilter *fil;
 
     gtk_tree_model_get(model, iter, DATA_COLUMN, &fil, -1);
-    if (fil->action == FILTER_RUN || fil->action == FILTER_TRASH ||
-        strcmp(fil->action_string, p->mbox->url) != 0) {
+    if (fil->action == FILTER_RUN
+        || fil->action == FILTER_TRASH
+        || (fil->action == FILTER_COLOR && fil->action_string[0])
+        || strcmp(fil->action_string, p->mbox->url) != 0) {
         /* Ok we can add the filter to this mailbox, there is no recursion problem */
         LibBalsaMailboxFilter *mf = g_new(LibBalsaMailboxFilter, 1);
         GtkTreeModel *sel_model =
diff --git a/src/save-restore.c b/src/save-restore.c
index 8ae380f..3f012b5 100644
--- a/src/save-restore.c
+++ b/src/save-restore.c
@@ -1912,7 +1912,6 @@ static gboolean
 config_filter_load(const gchar * key, const gchar * value, gpointer data)
 {
     char *endptr;
-    guint *save = data;
     LibBalsaFilter *fil;
     long int dummy;
 
@@ -1926,20 +1925,6 @@ config_filter_load(const gchar * key, const gchar * value, gpointer data)
 
     fil = libbalsa_filter_new_from_config();
     if (!fil->condition) {
-        /* Try pre-2.1 style: */
-        FilterOpType op = libbalsa_conf_get_int("Operation");
-        ConditionMatchType cmt =
-            op == FILTER_OP_OR ? CONDITION_OR : CONDITION_AND;
-        fil->condition = libbalsa_condition_new_2_0(key, cmt);
-        if (fil->condition) {
-            if (fil->action > FILTER_TRASH)
-                /* Some 2.0.x versions had a new action code which
-                 * changed the value of FILTER_TRASH. */
-                fil->action = FILTER_TRASH;
-            ++*save;
-        }
-    }
-    if (!fil->condition) {
         g_idle_add((GSourceFunc) config_warning_idle,
                    _("Filter with no condition was omitted"));
         libbalsa_filter_free(fil, GINT_TO_POINTER(FALSE));
@@ -1956,14 +1941,9 @@ config_filter_load(const gchar * key, const gchar * value, gpointer data)
 static void
 config_filters_load(void)
 {
-    guint save = 0;
-
     filter_errno = FILTER_NOERR;
     libbalsa_conf_foreach_group(FILTER_SECTION_PREFIX,
-                                config_filter_load, &save);
-
-    if (save)
-        config_filters_save();
+                                config_filter_load, NULL);
 }
 
 #define FILTER_SECTION_MAX "9999"



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