[evolution-patches] Another crack at custom headers
- From: grahame angrygoats net (Grahame Bowland)
- To: evolution-patches lists ximian com
- Subject: [evolution-patches] Another crack at custom headers
- Date: Sat, 29 Nov 2003 03:10:20 +0800
Ok, I've tried to merge in as much of dobey and NotZed's feedback as
possible. This new patch:
* uses XML in gconf to store settings, avoiding the two gconf keys
problem of the last patch
* has a revamped user interface with much better feedback. The new
header is typed into the edit field at the top; the Add button is
active only if the entered header is valid and unique.
the check box now selects whether or not the custom header is
displayed in the view
* correctly refreshes the mail view when apply is pressed
* keyboard shortcuts should be correct, and the UI should be more
HIG compliant
* actually attempted to write a complete changelog
Screenshot of the configuration interface:
http://grahame.angrygoats.net/images/custom-mail-headers2.png
Screenshot of the resulting email display:
http://grahame.angrygoats.net/images/custom-mail-headers-view2.png
Patch is attached. It should be pretty clean, and I don't think
it leaks memory or does anything hideous.
dobey was saying on IRC that he'd like this to go into the View
menu somewhere, so that arbitrary custom views can be defined.
I'm really not sure where to start with that, but I can give it
a try. It'd be nice to commit this and then look for a generic
solution - what do people think? I'm a bit scared of bonoboui :)
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 28 Nov 2003 18:57:32 -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,7 @@
EMFV_MARK_SEEN_TIMEOUT,
EMFV_LOAD_HTTP,
EMFV_XMAILER_MASK,
+ EMFV_HEADERS,
EMFV_SETTINGS /* last, for loop count */
};
@@ -1911,6 +1913,7 @@
"mark_seen_timeout",
"load_http_images",
"xmailer_mask",
+ "headers",
};
static GHashTable *emfv_setting_key;
@@ -1974,6 +1977,36 @@
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: {
+ GSList *header_config_list, *p;
+ EMFormat *emf = (EMFormat *)emfv->preview;
+ header_config_list = gconf_client_get_list (gconf, "/apps/evolution/mail/display/headers", GCONF_VALUE_STRING, NULL);
+ em_format_clear_headers((EMFormat *)emfv->preview);
+ em_format_default_headers((EMFormat *)emfv->preview);
+ p = header_config_list;
+ while (p) {
+ struct EMMailerCustomHeader h;
+ gchar *xml = (gchar *)p->data;
+ gint header_flags = 0;
+
+ em_mailer_custom_header_from_xml(&h, xml);
+ if (h.name) {
+ if (h.flags & EM_MAILER_PREFS_FLAGS_ENABLED) {
+ if (h.flags & EM_MAILER_PREFS_FLAGS_BOLD) {
+ header_flags |= EM_FORMAT_HEADER_BOLD;
+ }
+ em_format_add_header(emf, h.name, header_flags);
+ }
+ }
+ p = g_slist_next(p);
+ }
+ g_slist_foreach (header_config_list, (GFunc) g_free, NULL);
+ g_slist_free(header_config_list);
+ /* force a redraw */
+ if (emf->message) {
+ em_format_format_clone(emf, emf->message, emf);
+ }
+ 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 28 Nov 2003 18:57:34 -0000
@@ -31,18 +31,26 @@
#include <gal/util/e-iconv.h>
#include <gtkhtml/gtkhtml-properties.h>
+#include <libxml/tree.h>
#include "widgets/misc/e-charset-picker.h"
#include <bonobo/bonobo-generic-factory.h>
#include "mail-config.h"
-static void em_mailer_prefs_class_init (EMMailerPrefsClass *class);
-static void em_mailer_prefs_init (EMMailerPrefs *dialog);
-static void em_mailer_prefs_finalise (GObject *obj);
+static void em_mailer_prefs_class_init (EMMailerPrefsClass *class);
+static void em_mailer_prefs_init (EMMailerPrefs *dialog);
+static void em_mailer_prefs_finalise (GObject *obj);
+static gchar *em_mailer_custom_header_to_xml (struct EMMailerCustomHeader *h);
static GtkVBoxClass *parent_class = NULL;
+enum {
+ HEADER_LIST_NAME_COLUMN,
+ HEADER_LIST_ENABLED_COLUMN,
+ HEADER_LIST_N_COLUMNS
+};
+
GtkType
em_mailer_prefs_get_type (void)
@@ -203,6 +211,122 @@
}
static void
+header_list_enabled_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_ENABLED_COLUMN, &enabled, -1);
+ enabled = !enabled;
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, HEADER_LIST_ENABLED_COLUMN,
+ enabled, -1);
+ gtk_tree_path_free(path);
+
+ if (prefs->control)
+ evolution_config_control_changed (prefs->control);
+}
+
+static void
+add_header (GtkWidget *widget, gpointer user_data)
+{
+ EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
+ GtkTreeModel *model = GTK_TREE_MODEL(prefs->header_list_store);
+ GtkTreeIter iter;
+
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter,
+ HEADER_LIST_NAME_COLUMN, g_strdup(gtk_entry_get_text(prefs->entry_header)),
+ HEADER_LIST_ENABLED_COLUMN, TRUE,
+ -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);
+ }
+ /* now clear out the text entry, and make the add button insensitive */
+ gtk_entry_set_text(prefs->entry_header, "");
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs->add_header), FALSE);
+ 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 gboolean
+is_valid_header(const gchar *header)
+{
+ const gchar *p = header;
+
+ if (strlen(header) == 0) {
+ return FALSE;
+ }
+ while (*p) {
+ if ((*p == ':') || (*p == ' ')) {
+ return FALSE;
+ }
+ p++;
+ }
+ return TRUE;
+}
+
+static void
+entry_header_changed (GtkWidget *entry, gpointer user_data)
+{
+ EMMailerPrefs *prefs = (EMMailerPrefs *)user_data;
+ const gchar *entry_contents;
+ GtkTreeIter iter;
+ gboolean valid;
+
+ entry_contents = gtk_entry_get_text(GTK_ENTRY(entry));
+ if (!is_valid_header (entry_contents)) {
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs->add_header), FALSE);
+ return;
+ }
+ /* check if this is a duplicate */
+ valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs->header_list_store), &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, entry_contents)) {
+ /* duplicate, not valid */
+ gtk_widget_set_sensitive (GTK_WIDGET(prefs->add_header), FALSE);
+ return;
+ }
+ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(prefs->header_list_store), &iter);
+ }
+ /* if we got here, we are valid and unique */
+ gtk_widget_set_sensitive (GTK_WIDGET(prefs->add_header), TRUE);
+}
+
+static void
em_mailer_prefs_construct (EMMailerPrefs *prefs)
{
GtkWidget *toplevel, *menu;
@@ -212,7 +336,9 @@
char *font;
int i, val;
char *buf;
-
+ GSList *header_config_list, *p;
+ GtkTreeIter iter;
+
gui = glade_xml_new (EVOLUTION_GLADEDIR "/mail-config.glade", "preferences_tab", NULL);
prefs->gui = gui;
@@ -360,6 +486,58 @@
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->entry_header = GTK_ENTRY (glade_xml_get_widget (gui, "txtHeaders"));
+ prefs->header_list = GTK_TREE_VIEW (glade_xml_get_widget (gui, "treeHeaders"));
+ g_signal_connect (prefs->entry_header, "changed",
+ G_CALLBACK (entry_header_changed), prefs);
+ g_signal_connect (prefs->entry_header, "activate",
+ G_CALLBACK (add_header), prefs);
+ /* 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_enabled_renderer = gtk_cell_renderer_toggle_new();
+ g_object_set(prefs->header_list_enabled_renderer, "activatable", TRUE, NULL);
+ g_signal_connect(prefs->header_list_enabled_renderer, "toggled",
+ G_CALLBACK(header_list_enabled_toggled), prefs);
+ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(prefs->header_list), -1,
+ "Enabled", prefs->header_list_enabled_renderer,
+ "active", HEADER_LIST_ENABLED_COLUMN,
+ NULL);
+ prefs->header_list_name_renderer = gtk_cell_renderer_text_new();
+ 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);
+ p = header_config_list;
+ while (p) {
+ gchar *xml = (gchar *)p->data;
+ struct EMMailerCustomHeader h;
+ em_mailer_custom_header_from_xml(&h, xml);
+ if (h.name) {
+ gtk_list_store_append(prefs->header_list_store, &iter);
+ gtk_list_store_set(prefs->header_list_store, &iter,
+ HEADER_LIST_NAME_COLUMN, h.name,
+ HEADER_LIST_ENABLED_COLUMN, (h.flags & EM_MAILER_PREFS_FLAGS_ENABLED),
+ -1);
+ }
+ p = g_slist_next(p);
+ }
+ g_slist_foreach (header_config_list, (GFunc) g_free, NULL);
+ g_slist_free(header_config_list);
+ 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 +562,9 @@
GSList *list, *l, *n;
guint32 rgb;
int i, val;
+ GtkTreeIter iter;
+ gboolean valid;
+ GSList *header_list;
/* General tab */
@@ -444,7 +625,7 @@
gconf_client_set_string (prefs->gconf, "/apps/evolution/mail/display/fonts/monospace",
gnome_font_picker_get_font_name (prefs->font_fixed), NULL);
gconf_client_set_bool (prefs->gconf, "/apps/evolution/mail/display/fonts/use_custom",
- !gtk_toggle_button_get_active (prefs->font_share), NULL);
+ !gtk_toggle_button_get_active (prefs->font_share), NULL);
gconf_client_set_bool (prefs->gconf, "/apps/evolution/mail/display/animate_images",
gtk_toggle_button_get_active (prefs->show_animated), NULL);
@@ -469,6 +650,105 @@
g_slist_free_1 (l);
l = n;
}
-
+
+ /* Headers */
+ header_list = NULL;
+ valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs->header_list_store), &iter);
+ while (valid) {
+ struct EMMailerCustomHeader h;
+ gboolean header_enabled;
+ gchar *xml;
+ /* bold should be on by default */
+ h.flags = EM_MAILER_PREFS_FLAGS_BOLD;
+ gtk_tree_model_get (GTK_TREE_MODEL(prefs->header_list_store), &iter,
+ HEADER_LIST_NAME_COLUMN, &h.name,
+ HEADER_LIST_ENABLED_COLUMN, &header_enabled,
+ -1);
+ if (header_enabled) {
+ h.flags |= EM_MAILER_PREFS_FLAGS_ENABLED;
+ }
+ xml = em_mailer_custom_header_to_xml(&h);
+ if (xml != NULL) {
+ header_list = g_slist_append(header_list, xml);
+ }
+ 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);
+ g_slist_free (header_list);
gconf_client_suggest_sync (prefs->gconf, NULL);
+}
+
+static void
+em_mailer_custom_header_from_xmldoc(struct EMMailerCustomHeader *header, xmlDocPtr doc)
+{
+ xmlNodePtr root;
+ xmlChar *name, *flags;
+
+ if (doc == NULL) {
+ header->name = NULL;
+ return;
+ }
+ root = doc->children;
+ if (strcmp (root->name, "header") != 0) {
+ return;
+ }
+ name = xmlGetProp (root, "name");
+ flags = xmlGetProp (root, "flags");
+ if ((name == NULL) || (flags == NULL)) {
+ return;
+ }
+ header->name = g_strdup(name);
+ header->flags = atoi(flags);
+ xmlFree(name);
+ xmlFree(flags);
+ return;
+}
+
+void
+em_mailer_custom_header_from_xml(struct EMMailerCustomHeader *header, const gchar *xml)
+{
+ xmlDocPtr doc;
+
+ header->name = NULL;
+ doc = xmlParseDoc((char *)xml);
+ if (doc == NULL) {
+ return;
+ }
+ em_mailer_custom_header_from_xmldoc(header, doc);
+ xmlFreeDoc(doc);
+ return;
+}
+
+static gchar *
+em_mailer_custom_header_to_xml(struct EMMailerCustomHeader *header)
+{
+ xmlDocPtr doc;
+ xmlNodePtr root;
+ gchar *flags;
+ xmlChar *xml_buffer;
+ char *returned_buffer;
+ int xml_buffer_size;
+
+ g_return_val_if_fail (header != NULL, NULL);
+ g_return_val_if_fail (header->name != NULL, NULL);
+
+ doc = xmlNewDoc ("1.0");
+
+ root = xmlNewDocNode (doc, NULL, "header", NULL);
+ flags = g_strdup_printf ("%d", header->flags);
+ xmlSetProp (root, "name", header->name);
+ xmlSetProp (root, "flags", flags);
+
+ xmlDocSetRootElement (doc, root);
+
+ xmlDocDumpMemory (doc, &xml_buffer, &xml_buffer_size);
+ xmlFreeDoc (doc);
+
+ returned_buffer = g_malloc (xml_buffer_size + 1);
+ memcpy (returned_buffer, xml_buffer, xml_buffer_size);
+ returned_buffer [xml_buffer_size] = '\0';
+ xmlFree (xml_buffer);
+ g_free (flags);
+
+ return returned_buffer;
}
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 28 Nov 2003 18:57:34 -0000
@@ -49,8 +49,16 @@
typedef struct _EMMailerPrefs EMMailerPrefs;
typedef struct _EMMailerPrefsClass EMMailerPrefsClass;
+#define EM_MAILER_PREFS_FLAGS_BOLD 0x01
+#define EM_MAILER_PREFS_FLAGS_ENABLED 0x02
+
+struct EMMailerCustomHeader {
+ gchar *name;
+ gint flags;
+};
+
struct _EMMailerPrefs {
- GtkVBox parent_object;
+ GtkVBox parent_object;
GNOME_Evolution_Shell shell;
@@ -98,6 +106,15 @@
GnomeColorPicker *color;
} labels[5];
GtkButton *restore_labels;
+
+ /* Headers tab */
+ GtkButton *add_header;
+ GtkButton *remove_header;
+ GtkEntry *entry_header;
+ GtkTreeView *header_list;
+ GtkListStore *header_list_store;
+ GtkCellRenderer *header_list_name_renderer;
+ GtkCellRenderer *header_list_enabled_renderer;
};
struct _EMMailerPrefsClass {
@@ -113,6 +130,11 @@
GtkWidget *em_mailer_prefs_new (void);
void em_mailer_prefs_apply (EMMailerPrefs *prefs);
+
+/* pass a pointer to an allocated struct EMMailerCustomHeader. on error, header.name will
+ be set to NULL
+ */
+void em_mailer_custom_header_from_xml(struct EMMailerCustomHeader *header, const gchar *xml);
/* needed by global config */
#define EM_MAILER_PREFS_CONTROL_ID "OAFIID:GNOME_Evolution_Mail_MailerPrefs_ConfigControl_2"
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 28 Nov 2003 18:57:51 -0000
@@ -4475,6 +4475,177 @@
<property name="type">tab</property>
</packing>
</child>
+
+ <child>
+ <widget class="GtkVBox" id="vboxHeaderTab">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="lblHeaders">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>_Displayed Mail Headers</b></property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">txtHeaders</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hboxTreeButtons">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkVBox" id="vboxEntryTree">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkEntry" id="txtHeaders">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow49">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</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">False</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>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox162">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkButton" id="cmdHeadersAdd">
+ <property name="visible">True</property>
+ <property name="sensitive">False</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">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="cmdHeadersRemove">
+ <property name="visible">True</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">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </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">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>
Index: mail/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog,v
retrieving revision 1.2896
diff -u -r1.2896 ChangeLog
--- mail/ChangeLog 23 Nov 2003 17:02:09 -0000 1.2896
+++ mail/ChangeLog 28 Nov 2003 18:57:58 -0000
@@ -1,3 +1,33 @@
+2003-11-29 Grahame Bowland <grahame angrygoats net>
+
+ * mail-config.glade: add tab to mail configuration
+ dialog to allow custom headers to be specified for
+ display.
+ * em-mailer-prefs.h: modify struct _EMMailerPrefs to
+ add widgets for custom header tab. Add defines for custom
+ header flags. Add struct EMMailerCustomHeader to describe
+ custom headers, and add function
+ em_mailer_custom_headers_from_xml to allow XML from gconf
+ key to be parsed into this structure.
+ * em-folder-view.c (emfv_setting_notify): catch changes to
+ custom header gconf key and update mail view to correspond
+ * em-mailer-prefs.c (em_mailer_prefs_apply): save custom
+ headers to gconf
+ (header_list_enabled_toggled): toggle clicked toggle column
+ (add_header): add header to custom header list if valid
+ (remove_header): remove selected custom header
+ (is_valid_header): return true if passed header is valid,
+ otherwise false
+ (entry_header_changed): set add button sensitive if entered
+ header is valid, otherwise set add button unsensitive
+ (em_mailer_prefs_construct): initialise header selection tab.
+ Load gconf data for header selection dialog.
+ (em_mailer_custom_header_to_xml):
+ load a header structure from XML document structure
+ (em_mailer_custom_header_from_xml): load a header
+ structure from a string containing valid XML. if any failure,
+ the header.name is set to NULL.
+
2003-11-22 Jeffrey Stedfast <fejj ximian com>
* em-folder-tree-model.c (model_drag_data_received)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]