[evolution-patches] Patch for custom mail headers
- From: grahame angrygoats net (Grahame Bowland)
- To: evolution-patches ximian com
- Subject: [evolution-patches] Patch for custom mail headers
- Date: Fri, 28 Nov 2003 03:09:02 +0800
Hi all
I sent an older version of this to NotZed and fejj yesterday, but
haven't heard back - I'm being impatient :-) The patch does
seems to work, could I have some feedback?
Config dialog screenshot:
http://grahame.angrygoats.net/images/custom-mail-headers.png
Viewing a mail:
http://grahame.angrygoats.net/images/custom-mail-headers-view.png
Patch attached, it should apply to the current CVS version of
evolution.
Oh, the patch is for Ximian Bug #1186 and #127523 in Gnome
bugzilla.
Cheers
Grahame
Index: mail/em-folder-view.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-folder-view.c,v
retrieving revision 1.14
diff -u -r1.14 em-folder-view.c
--- mail/em-folder-view.c 14 Nov 2003 16:20:17 -0000 1.14
+++ mail/em-folder-view.c 27 Nov 2003 18:53:12 -0000
@@ -62,6 +62,7 @@
#include "em-format-html-print.h"
#include "em-folder-selection.h"
#include "em-folder-view.h"
+#include "em-mailer-prefs.h"
#include "em-message-browser.h"
#include "message-list.h"
#include "em-utils.h"
@@ -1896,6 +1897,8 @@
EMFV_MARK_SEEN_TIMEOUT,
EMFV_LOAD_HTTP,
EMFV_XMAILER_MASK,
+ EMFV_HEADERS,
+ EMFV_HEADERS_FLAGS,
EMFV_SETTINGS /* last, for loop count */
};
@@ -1911,6 +1914,8 @@
"mark_seen_timeout",
"load_http_images",
"xmailer_mask",
+ "headers",
+ "headers_flags",
};
static GHashTable *emfv_setting_key;
@@ -1974,6 +1979,27 @@
case EMFV_XMAILER_MASK:
em_format_html_set_xmailer_mask((EMFormatHTML *)emfv->preview, gconf_value_get_int(gconf_entry_get_value(entry)));
break;
+ case EMFV_HEADERS:
+ case EMFV_HEADERS_FLAGS: {
+ GSList *header_config_list, *header_flags_config_list, *p, *q;
+ header_config_list = gconf_client_get_list (gconf, "/apps/evolution/mail/display/headers", GCONF_VALUE_STRING, NULL);
+ header_flags_config_list = gconf_client_get_list (gconf, "/apps/evolution/mail/display/headers_flags", GCONF_VALUE_INT, NULL);
+ em_format_clear_headers((EMFormat *)emfv->preview);
+ em_format_default_headers((EMFormat *)emfv->preview);
+ p = header_config_list;
+ q = header_flags_config_list;
+ while (p && q) {
+ gint header_flags = 0;
+ if (GPOINTER_TO_INT(q->data) & EM_MAILER_PREFS_FLAGS_BOLD) {
+ header_flags |= EM_FORMAT_HEADER_BOLD;
+ }
+ em_format_add_header((EMFormat *)emfv->preview, (gchar *)p->data, header_flags);
+ p = g_slist_next(p);
+ q = g_slist_next(q);
+ }
+ g_slist_free(header_config_list);
+ g_slist_free(header_flags_config_list);
+ break; }
}
}
Index: mail/em-mailer-prefs.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-mailer-prefs.c,v
retrieving revision 1.1
diff -u -r1.1 em-mailer-prefs.c
--- mail/em-mailer-prefs.c 24 Oct 2003 19:31:22 -0000 1.1
+++ mail/em-mailer-prefs.c 27 Nov 2003 18:53:14 -0000
@@ -43,6 +43,12 @@
static GtkVBoxClass *parent_class = NULL;
+enum {
+ HEADER_LIST_NAME_COLUMN,
+ HEADER_LIST_BOLD_COLUMN,
+ HEADER_LIST_N_COLUMNS
+};
+
GtkType
em_mailer_prefs_get_type (void)
@@ -203,6 +209,172 @@
}
static void
+header_sanitize_name(gchar *header)
+{
+ gchar *p = header;
+ while (*p) {
+ if (*p == ' ') {
+ *p = '-';
+ }
+ p++;
+ }
+ if (p == header) {
+ return;
+ }
+ p--;
+ /* back up removing trailing colon characters.. */
+ while ((p >= header) && (*p == ':')) {
+ *p = '\0';
+ p--;
+ }
+}
+
+static void
+header_list_cell_edited (GtkCellRendererText *cell, const gchar *path_string, const gchar *new_text, gpointer user_data)
+{
+ EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
+ GtkTreeModel *model = GTK_TREE_MODEL(prefs->header_list_store);
+ GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
+ GtkTreeIter iter;
+ gchar *old_text, *new_header;
+ gint i;
+ gboolean valid;
+
+ /* we want to make sure this is a valid header */
+ new_header = g_strdup(new_text);
+ header_sanitize_name(new_header);
+ /* no zero length headers */
+ if (strlen(new_header) == 0) {
+ g_free(new_header);
+ return;
+ }
+
+ /* check that the header isn't a duplicate.. */
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+ i = 0;
+ while (valid) {
+ gchar *header_name;
+ gtk_tree_model_get (GTK_TREE_MODEL(prefs->header_list_store), &iter,
+ HEADER_LIST_NAME_COLUMN, &header_name,
+ -1);
+ if (!strcasecmp(header_name, new_header)) {
+ i++;
+ }
+ g_free(header_name);
+ valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs->header_list_store), &iter);
+ }
+ if (i > 0) {
+ /* duplicate... reject the edit */
+ g_free(new_header);
+ return;
+ }
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, HEADER_LIST_NAME_COLUMN, &old_text, -1);
+ g_free (old_text);
+
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, HEADER_LIST_NAME_COLUMN,
+ new_header, -1);
+ gtk_tree_path_free(path);
+
+ if (prefs->control)
+ evolution_config_control_changed (prefs->control);
+}
+
+static void
+header_list_bold_toggled (GtkCellRendererToggle *cell, const char *path_string, gpointer user_data)
+{
+ EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
+ GtkTreeModel *model = GTK_TREE_MODEL(prefs->header_list_store);
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
+ GtkTreeIter iter;
+ gint enabled;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, HEADER_LIST_BOLD_COLUMN, &enabled, -1);
+ enabled = !enabled;
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, HEADER_LIST_BOLD_COLUMN,
+ enabled, -1);
+ gtk_tree_path_free(path);
+
+ if (prefs->control)
+ evolution_config_control_changed (prefs->control);
+}
+
+static void
+add_header (GtkWidget *button, gpointer user_data)
+{
+ EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
+ GtkTreeModel *model = GTK_TREE_MODEL(prefs->header_list_store);
+ GtkTreeIter iter;
+ gint loops = 0;
+ gint matches;
+ gchar *new_header_name = NULL;
+
+ /* find an initial name for the header */
+ do {
+ gboolean valid;
+ if (new_header_name) {
+ g_free(new_header_name);
+ }
+ if (loops == 0) {
+ new_header_name = g_strdup("New-header");
+ } else {
+ new_header_name = g_strdup_printf("New-header-%d", loops);
+ }
+ matches = 0;
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+ while (valid) {
+ gchar *header_name;
+ gtk_tree_model_get (GTK_TREE_MODEL(prefs->header_list_store), &iter,
+ HEADER_LIST_NAME_COLUMN, &header_name,
+ -1);
+ if (!strcasecmp(header_name, new_header_name)) {
+ matches++;
+ }
+ g_free(header_name);
+ valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs->header_list_store), &iter);
+ }
+ loops++;
+ } while (matches > 0);
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter,
+ HEADER_LIST_NAME_COLUMN, new_header_name,
+ HEADER_LIST_BOLD_COLUMN, FALSE,
+ -1);
+ if (!GTK_WIDGET_SENSITIVE(GTK_WIDGET(prefs->remove_header))) {
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (prefs->header_list);
+ gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs->remove_header), TRUE);
+ gtk_tree_selection_select_iter(selection, &iter);
+ }
+ if (prefs->control)
+ evolution_config_control_changed (prefs->control);
+}
+
+static void
+remove_header (GtkWidget *button, gpointer user_data)
+{
+ EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
+ GtkTreeView *treeview = prefs->header_list;
+ GtkTreeModel *model = GTK_TREE_MODEL(prefs->header_list_store);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
+ GtkTreeIter iter;
+
+ if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
+ gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+ if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) {
+ /* list is empty - disable the remove button*/
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs->remove_header), FALSE);
+ } else {
+ /* select the first entry */
+ gtk_tree_selection_select_iter(selection, &iter);
+ }
+ if (prefs->control)
+ evolution_config_control_changed (prefs->control);
+ }
+}
+
+static void
em_mailer_prefs_construct (EMMailerPrefs *prefs)
{
GtkWidget *toplevel, *menu;
@@ -212,7 +384,9 @@
char *font;
int i, val;
char *buf;
-
+ GSList *header_config_list, *bold_config_list, *p, *q;
+ GtkTreeIter iter;
+
gui = glade_xml_new (EVOLUTION_GLADEDIR "/mail-config.glade", "preferences_tab", NULL);
prefs->gui = gui;
@@ -360,6 +534,60 @@
prefs->restore_labels = GTK_BUTTON (glade_xml_get_widget (gui, "cmdRestoreLabels"));
g_signal_connect (prefs->restore_labels, "clicked", G_CALLBACK (restore_labels_clicked), prefs);
+
+ /* headers */
+ prefs->add_header = GTK_BUTTON (glade_xml_get_widget (gui, "cmdHeadersAdd"));
+ prefs->remove_header = GTK_BUTTON (glade_xml_get_widget (gui, "cmdHeadersRemove"));
+
+ prefs->header_list = GTK_TREE_VIEW (glade_xml_get_widget (gui, "treeHeaders"));
+ /* initialise the tree with appropriate headings */
+ prefs->header_list_store = gtk_list_store_new(HEADER_LIST_N_COLUMNS, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
+ g_signal_connect (prefs->add_header, "clicked",
+ G_CALLBACK (add_header), prefs);
+ g_signal_connect (prefs->remove_header, "clicked",
+ G_CALLBACK (remove_header), prefs);
+ gtk_tree_view_set_model(prefs->header_list, GTK_TREE_MODEL (prefs->header_list_store));
+ prefs->header_list_bold_renderer = gtk_cell_renderer_toggle_new();
+ g_object_set(prefs->header_list_bold_renderer, "activatable", TRUE, NULL);
+ g_signal_connect(prefs->header_list_bold_renderer, "toggled",
+ G_CALLBACK(header_list_bold_toggled), prefs);
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(prefs->header_list), -1,
+ "Bold", prefs->header_list_bold_renderer,
+ "active", HEADER_LIST_BOLD_COLUMN,
+ NULL);
+ prefs->header_list_name_renderer = gtk_cell_renderer_text_new();
+ g_object_set(prefs->header_list_name_renderer, "editable", TRUE, NULL);
+ g_signal_connect(prefs->header_list_name_renderer, "edited",
+ G_CALLBACK(header_list_cell_edited), prefs);
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(prefs->header_list), -1,
+ "Name", prefs->header_list_name_renderer,
+ "text", HEADER_LIST_NAME_COLUMN,
+ NULL);
+ /* read stored values from gconf */
+ header_config_list = gconf_client_get_list (prefs->gconf, "/apps/evolution/mail/display/headers", GCONF_VALUE_STRING, NULL);
+ bold_config_list = gconf_client_get_list (prefs->gconf, "/apps/evolution/mail/display/headers_flags", GCONF_VALUE_INT, NULL);
+ p = header_config_list;
+ q = bold_config_list;
+ /* iterate over both of these, stopping when either ends
+ if the data is corrupt, we'll output as many valid entries as possible
+ */
+ while (p && q) {
+ gint flags = (gboolean)q->data;
+ gchar *name = (gchar *)p->data;
+ gtk_list_store_append(prefs->header_list_store, &iter);
+ gtk_list_store_set(prefs->header_list_store, &iter,
+ HEADER_LIST_NAME_COLUMN, name,
+ HEADER_LIST_BOLD_COLUMN, (flags & EM_MAILER_PREFS_FLAGS_BOLD),
+ -1);
+ p = g_slist_next(p);
+ q = g_slist_next(q);
+ }
+ g_slist_free(p);
+ g_slist_free(q);
+ if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs->header_list_store), &iter)) {
+ /* list is empty - disable the remove button*/
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs->remove_header), FALSE);
+ }
}
@@ -384,6 +612,9 @@
GSList *list, *l, *n;
guint32 rgb;
int i, val;
+ GtkTreeIter iter;
+ gboolean valid;
+ GSList *header_list, *header_flags_list;
/* General tab */
@@ -469,6 +700,29 @@
g_slist_free_1 (l);
l = n;
}
-
+
+ /* Headers */
+ header_list = NULL;
+ header_flags_list = NULL;
+ valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs->header_list_store), &iter);
+ while (valid) {
+ gchar *header_name;
+ gboolean header_bold;
+ gint flags = 0;
+ gtk_tree_model_get (GTK_TREE_MODEL(prefs->header_list_store), &iter,
+ HEADER_LIST_NAME_COLUMN, &header_name,
+ HEADER_LIST_BOLD_COLUMN, &header_bold,
+ -1);
+ header_list = g_slist_append(header_list, header_name);
+ if (header_bold) {
+ flags |= EM_MAILER_PREFS_FLAGS_BOLD;
+ }
+ header_flags_list = g_slist_append(header_flags_list, GINT_TO_POINTER(flags));
+ valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs->header_list_store), &iter);
+ }
+ gconf_client_set_list (prefs->gconf, "/apps/evolution/mail/display/headers", GCONF_VALUE_STRING, header_list, NULL);
+ gconf_client_set_list (prefs->gconf, "/apps/evolution/mail/display/headers_flags", GCONF_VALUE_INT, header_flags_list, NULL);
+ g_slist_free(header_list);
+ g_slist_free(header_flags_list);
gconf_client_suggest_sync (prefs->gconf, NULL);
}
Index: mail/em-mailer-prefs.h
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-mailer-prefs.h,v
retrieving revision 1.2
diff -u -r1.2 em-mailer-prefs.h
--- mail/em-mailer-prefs.h 29 Oct 2003 17:49:55 -0000 1.2
+++ mail/em-mailer-prefs.h 27 Nov 2003 18:53:14 -0000
@@ -49,8 +49,10 @@
typedef struct _EMMailerPrefs EMMailerPrefs;
typedef struct _EMMailerPrefsClass EMMailerPrefsClass;
+#define EM_MAILER_PREFS_FLAGS_BOLD 0x01
+
struct _EMMailerPrefs {
- GtkVBox parent_object;
+ GtkVBox parent_object;
GNOME_Evolution_Shell shell;
@@ -98,6 +100,14 @@
GnomeColorPicker *color;
} labels[5];
GtkButton *restore_labels;
+
+ /* Headers tab */
+ GtkButton *add_header;
+ GtkButton *remove_header;
+ GtkTreeView *header_list;
+ GtkListStore *header_list_store;
+ GtkCellRenderer *header_list_name_renderer;
+ GtkCellRenderer *header_list_bold_renderer;
};
struct _EMMailerPrefsClass {
Index: mail/mail-config.glade
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-config.glade,v
retrieving revision 1.124
diff -u -r1.124 mail-config.glade
--- mail/mail-config.glade 11 Nov 2003 02:38:01 -0000 1.124
+++ mail/mail-config.glade 27 Nov 2003 18:53:31 -0000
@@ -4475,6 +4475,152 @@
<property name="type">tab</property>
</packing>
</child>
+
+ <child>
+ <widget class="GtkVBox" id="vboxHeaders">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkFrame" id="frameHeaders">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox161">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow49">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="treeHeaders">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox177">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkButton" id="cmdHeadersAdd">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Add a header to be shown in mail view</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ </widget>
+ <packing>
+ <property name="padding">6</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="cmdHeadersRemove">
+ <property name="visible">True</property>
+ <property name="tooltip" translatable="yes">Remove selected header</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-remove</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ </widget>
+ <packing>
+ <property name="padding">6</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="lblHeadersFrame">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Display Custom Mail Headers</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="lblHeaders">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">H_eaders</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
</widget>
</child>
</widget>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]