Files
evolution/plugins/email-custom-header/email-custom-header.c
Jonathon Jongsma c2ee0afbc8 Rename EError to EAlert to match general use better
The EError mechanism is used both for error dialogs as well as basic alerts or
user prompts, so we should give it a more general name which matches this use.

This patch also cleans up a few includes of e-alert.h (formerly e-error.h) that
were not actually being used.

https://bugzilla.gnome.org/show_bug.cgi?id=602963
2009-11-30 13:33:04 -06:00

1033 lines
32 KiB
C

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
* Authors:
* Ashish Shrivastava <shashish@novell.com>
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <glib/gi18n.h>
#include <gconf/gconf-client.h>
#include "mail/em-utils.h"
#include "mail/em-event.h"
#include "composer/e-msg-composer.h"
#include "libedataserver/e-account.h"
#include "e-util/e-config.h"
#include "e-util/e-util.h"
#include "email-custom-header.h"
#define d(x)
#define GCONF_KEY_CUSTOM_HEADER "/apps/evolution/eplugin/email_custom_header/customHeader"
typedef struct {
GConfClient *gconf;
GtkWidget *treeview;
GtkWidget *header_add;
GtkWidget *header_edit;
GtkWidget *header_remove;
GtkListStore *store;
} ConfigData;
enum {
HEADER_KEY_COLUMN,
HEADER_VALUE_COLUMN,
HEADER_N_COLUMNS
};
struct _EmailCustomHeaderOptionsDialogPrivate {
GtkBuilder *builder;
/*Widgets*/
GtkWidget *main;
GtkWidget *page;
GtkWidget *header_table;
GtkWidget *header_type_name_label;
GArray *combo_box_header_value;
GArray *email_custom_header_details;
GArray *header_index_type;
gint flag;
gchar *help_section;
};
/* epech - e-plugin email custom header*/
static void epech_dialog_class_init (GObjectClass *object_class);
static void epech_dialog_finalize (GObject *object);
static void epech_dialog_init (GObject *object);
static void epech_dialog_dispose (GObject *object);
static void epech_setup_widgets (CustomHeaderOptionsDialog *mch);
static gint epech_check_existing_composer_window(gconstpointer a, gconstpointer b);
static void commit_changes (ConfigData *cd);
gint e_plugin_lib_enable (EPlugin *ep, gint enable);
GtkWidget *e_plugin_lib_get_configure_widget (EPlugin *epl);
gboolean e_plugin_ui_init(GtkUIManager *ui_manager, EMsgComposer *composer);
GtkWidget *org_gnome_email_custom_header_config_option (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data);
gint
e_plugin_lib_enable (EPlugin *ep, gint enable)
{
return 0;
}
static void
epech_get_widgets_data (CustomHeaderOptionsDialog *mch)
{
EmailCustomHeaderOptionsDialogPrivate *priv;
HeaderValueComboBox *sub_combo_box_get;
gint selected_item;
gint index_row,index_column;
priv = mch->priv;
priv->header_index_type = g_array_new (FALSE, FALSE, sizeof (gint));
priv->flag++;
for (index_row = 0,index_column = 0;
index_column < priv->email_custom_header_details->len; index_column++) {
sub_combo_box_get = &g_array_index(priv->combo_box_header_value, HeaderValueComboBox,index_column);
selected_item = gtk_combo_box_get_active((GtkComboBox *)sub_combo_box_get->header_value_combo_box);
g_array_append_val (priv->header_index_type, selected_item);
}
return;
}
static gboolean
epech_get_widgets (CustomHeaderOptionsDialog *mch)
{
EmailCustomHeaderOptionsDialogPrivate *priv;
priv = mch->priv;
#define EMAIL_CUSTOM_HEADER(name) e_builder_get_widget (priv->builder, name)
priv->main = EMAIL_CUSTOM_HEADER ("email-custom-header-dialog");
if (!priv->main)
return FALSE;
priv->page = EMAIL_CUSTOM_HEADER ("email-custom-header-vbox");
priv->header_table = EMAIL_CUSTOM_HEADER ("email-custom-header-options");
#undef EMAIL_CUSTOM_HEADER
return (priv->page
&&priv->header_table);
}
static void
epech_fill_widgets_with_data (CustomHeaderOptionsDialog *mch)
{
EmailCustomHeaderOptionsDialogPrivate *priv;
HeaderValueComboBox *sub_combo_box_fill;
gint set_index_row,set_index_column;
priv = mch->priv;
priv->help_section = g_strdup ("usage-mail");
for (set_index_row = 0,set_index_column = 0;
set_index_column < priv->email_custom_header_details->len;set_index_column++) {
sub_combo_box_fill = &g_array_index(priv->combo_box_header_value, HeaderValueComboBox,set_index_column);
if (priv->flag == 0) {
gtk_combo_box_set_active ((GtkComboBox *)sub_combo_box_fill->header_value_combo_box,0);
} else {
gtk_combo_box_set_active ((GtkComboBox *)sub_combo_box_fill->header_value_combo_box,
g_array_index(priv->header_index_type, gint, set_index_column));
}
}
}
CustomHeaderOptionsDialog *
epech_dialog_new (void)
{
CustomHeaderOptionsDialog *mch;
mch = g_object_new (EMAIL_CUSTOM_HEADER_OPTIONS_DIALOG, NULL);
return mch;
}
GType
epech_dialog_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GTypeInfo info = {
sizeof (CustomHeaderOptionsDialogClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) epech_dialog_class_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (CustomHeaderOptionsDialog),
0, /* n_preallocs */
(GInstanceInitFunc) epech_dialog_init,
NULL /* instance_init */
};
type = g_type_register_static (G_TYPE_OBJECT,
"CustomHeaderOptionsDialogType",
&info, 0);
}
return type;
}
static void
epech_header_options_cb (GtkDialog *dialog, gint state, gpointer func_data)
{
EmailCustomHeaderOptionsDialogPrivate *priv;
CustomHeaderOptionsDialog *mch;
mch = func_data;
priv = mch->priv;
switch (state) {
case GTK_RESPONSE_OK:
epech_get_widgets_data (mch);
case GTK_RESPONSE_CANCEL:
gtk_widget_hide (priv->main);
gtk_widget_destroy (priv->main);
g_object_unref (priv->builder);
break;
case GTK_RESPONSE_HELP:
e_display_help (
GTK_WINDOW (priv->main),
priv->help_section);
break;
}
g_signal_emit (G_OBJECT (func_data), signals[MCH_RESPONSE], 0, state);
}
static gboolean
epech_dialog_run (CustomHeaderOptionsDialog *mch, GtkWidget *parent)
{
EmailCustomHeaderOptionsDialogPrivate *priv;
GtkWidget *toplevel;
g_return_val_if_fail (mch != NULL || EMAIL_CUSTOM_HEADER_OPTIONS_IS_DIALOG (mch), FALSE);
priv = mch->priv;
epech_get_header_list (mch);
priv->builder = gtk_builder_new ();
e_load_ui_builder_definition (
priv->builder, "org-gnome-email-custom-header.ui");
if (!epech_get_widgets(mch)) {
g_object_unref (priv->builder);
d (printf ("\n Could not get the Widgets\n"));
}
epech_setup_widgets (mch);
toplevel = gtk_widget_get_toplevel (priv->main);
if (parent)
gtk_window_set_transient_for (GTK_WINDOW (toplevel),GTK_WINDOW (parent));
epech_fill_widgets_with_data (mch);
g_signal_connect (GTK_DIALOG (priv->main), "response", G_CALLBACK(epech_header_options_cb), mch);
gtk_widget_show (priv->main);
return TRUE;
}
static void
epech_get_header_list (CustomHeaderOptionsDialog *mch)
{
GConfClient *client;
client = gconf_client_get_default ();
g_return_if_fail (GCONF_IS_CLIENT (client));
gconf_client_add_dir (client, GCONF_KEY_CUSTOM_HEADER, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
epech_load_from_gconf (client, "/apps/evolution/eplugin/email_custom_header/customHeader", mch);
return;
}
static void
epech_load_from_gconf (GConfClient *client,const gchar *path,CustomHeaderOptionsDialog *mch)
{
EmailCustomHeaderOptionsDialogPrivate *priv;
EmailCustomHeaderDetails temp_header_details= {-1, -1, NULL, NULL};
CustomSubHeader temp_header_value_details = {NULL};
GSList *header_list,*q;
gchar *buffer;
gint index,pos;
priv = mch->priv;
priv->email_custom_header_details = g_array_new (TRUE, TRUE, sizeof (EmailCustomHeaderDetails));
header_list = gconf_client_get_list (client,path,GCONF_VALUE_STRING, NULL);
for (q = header_list,pos = 0; q != NULL; q = q->next,pos++) {
gchar **parse_header_list;
memset(&temp_header_value_details,0,sizeof(CustomSubHeader));
temp_header_details.sub_header_type_value = g_array_new (TRUE, TRUE, sizeof (CustomSubHeader));
buffer = q->data;
parse_header_list = g_strsplit_set (buffer, "=;,", -1);
temp_header_details.header_type_value = g_string_new("");
if (temp_header_details.header_type_value) {
g_string_assign(temp_header_details.header_type_value, parse_header_list[0]);
}
for (index = 0; parse_header_list[index+1] ; ++index) {
temp_header_value_details.sub_header_string_value = g_string_new("");
if (temp_header_value_details.sub_header_string_value) {
g_string_assign(temp_header_value_details.sub_header_string_value, parse_header_list[index+1]);
}
g_array_append_val(temp_header_details.sub_header_type_value, temp_header_value_details);
}
temp_header_details.number_of_subtype_header = index;
g_array_append_val(priv->email_custom_header_details, temp_header_details);
}
temp_header_details.number_of_header = pos;
}
static void
epech_setup_widgets (CustomHeaderOptionsDialog *mch)
{
EmailCustomHeaderOptionsDialogPrivate *priv;
EmailCustomHeaderDetails *temp_header_ptr,*temp;
CustomSubHeader *temp_header_value_ptr;
HeaderValueComboBox sub_combo_box = {NULL};
HeaderValueComboBox *sub_combo_box_ptr;
gint sub_index,row_combo,column_combo;
gint header_section_id,sub_type_index,row,column,label_row;
gint i;
gchar *str;
static const gchar *security_field = N_("Security:");
static struct _security_values {
const gchar *value, *str;
} security_values[] = {
{ "Personal", N_("Personal") } ,
{ "Unclassified", N_("Unclassified") },
{ "Protected", N_("Protected") },
{ "InConfidence", N_("Confidential") },
{ "Secret", N_("Secret") },
{ "Topsecret", N_("Top secret") },
{ NULL, NULL }
};
priv = mch->priv;
priv->combo_box_header_value = g_array_new (TRUE, FALSE, sizeof (HeaderValueComboBox));
for (header_section_id = 0,label_row = 0,row = 0,column = 1;
header_section_id < priv->email_custom_header_details->len; header_section_id++,row++,column++) {
/* To create an empty label widget. Text will be added dynamically. */
priv->header_type_name_label = gtk_label_new ("");
temp_header_ptr = &g_array_index(priv->email_custom_header_details, EmailCustomHeaderDetails,header_section_id);
str = (temp_header_ptr->header_type_value)->str;
if (strcmp (str, security_field) == 0) {
str = _(security_field);
}
gtk_label_set_markup (GTK_LABEL (priv->header_type_name_label), str);
gtk_table_attach (GTK_TABLE (priv->header_table), priv->header_type_name_label, 0, 1, row, column,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_misc_set_alignment (GTK_MISC (priv->header_type_name_label), 0, 0.5);
gtk_widget_show (priv->header_type_name_label);
sub_combo_box.header_value_combo_box = gtk_combo_box_new_text ();
g_array_append_val(priv->combo_box_header_value, sub_combo_box);
}
for (sub_index = 0,row_combo = 0,column_combo = 1; sub_index < priv->combo_box_header_value->len;
sub_index++,row_combo++,column_combo++) {
temp = &g_array_index(priv->email_custom_header_details, EmailCustomHeaderDetails,sub_index);
sub_combo_box_ptr = &g_array_index(priv->combo_box_header_value, HeaderValueComboBox,sub_index);
gtk_table_attach (GTK_TABLE (priv->header_table),
sub_combo_box_ptr->header_value_combo_box, 1, 2, row_combo, column_combo,
(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
(GtkAttachOptions) (GTK_FILL), 0, 0);
for (sub_type_index = 0; sub_type_index < temp->number_of_subtype_header; sub_type_index++) {
temp_header_value_ptr = &g_array_index(temp->sub_header_type_value, CustomSubHeader,sub_type_index);
str = (temp_header_value_ptr->sub_header_string_value)->str;
for (i = 0; security_values[i].value != NULL; i++) {
if (strcmp (str, security_values[i].value) == 0) {
str = _(security_values[i].str);
break;
}
}
gtk_combo_box_append_text (GTK_COMBO_BOX (sub_combo_box_ptr->header_value_combo_box),
str);
}
gtk_combo_box_append_text (GTK_COMBO_BOX (sub_combo_box_ptr->header_value_combo_box), _("None"));
gtk_widget_show (sub_combo_box_ptr->header_value_combo_box);
}
}
static void
epech_dialog_class_init (GObjectClass *object)
{
CustomHeaderOptionsDialogClass *klass;
GObjectClass *object_class;
klass = EMAIL_CUSTOM_HEADEROPTIONS_DIALOG_CLASS (object);
parent_class = g_type_class_peek_parent (klass);
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = epech_dialog_finalize;
object_class->dispose = epech_dialog_dispose;
signals[MCH_RESPONSE] = g_signal_new ("emch_response",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (CustomHeaderOptionsDialogClass, emch_response),
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1,
G_TYPE_INT);
}
static void
epech_dialog_init (GObject *object)
{
CustomHeaderOptionsDialog *mch;
EmailCustomHeaderOptionsDialogPrivate *priv;
mch = EMAIL_CUSTOM_HEADEROPTIONS_DIALOG (object);
priv = g_new0 (EmailCustomHeaderOptionsDialogPrivate, 1);
mch->priv = priv;
priv->builder = NULL;
priv->main = NULL;
priv->page = NULL;
priv->header_table = NULL;
}
static void
epech_dialog_finalize (GObject *object)
{
CustomHeaderOptionsDialog *mch = (CustomHeaderOptionsDialog *)object;
EmailCustomHeaderOptionsDialogPrivate *priv;
g_return_if_fail (EMAIL_CUSTOM_HEADER_OPTIONS_IS_DIALOG (mch));
priv = mch->priv;
g_free (priv->help_section);
if (mch->priv) {
g_free (mch->priv);
mch->priv = NULL;
}
if (parent_class->finalize)
(* parent_class->finalize) (object);
}
static void
epech_dialog_dispose (GObject *object)
{
CustomHeaderOptionsDialog *mch = (CustomHeaderOptionsDialog *) object;
g_return_if_fail (EMAIL_CUSTOM_HEADER_OPTIONS_IS_DIALOG (mch));
if (parent_class->dispose)
(* parent_class->dispose) (object);
}
static void
epech_append_to_custom_header (CustomHeaderOptionsDialog *dialog, gint state, gpointer data)
{
EMsgComposer *composer;
EmailCustomHeaderOptionsDialogPrivate *priv;
EmailCustomHeaderDetails *temp_header_ptr;
CustomSubHeader *temp_header_value_ptr;
gint index, index_subtype,sub_type_index;
composer = (EMsgComposer *)data;
priv = dialog->priv;
if (state == GTK_RESPONSE_OK) {
for (index = 0,index_subtype = 0; index_subtype < priv->email_custom_header_details->len; index_subtype++) {
temp_header_ptr = &g_array_index(priv->email_custom_header_details, EmailCustomHeaderDetails,index_subtype);
for (sub_type_index = 0; sub_type_index < temp_header_ptr->number_of_subtype_header; sub_type_index++) {
temp_header_value_ptr = &g_array_index(temp_header_ptr->sub_header_type_value, CustomSubHeader,sub_type_index);
if (sub_type_index == g_array_index(priv->header_index_type, gint, index_subtype)) {
e_msg_composer_modify_header (composer, (temp_header_ptr->header_type_value)->str,
(temp_header_value_ptr->sub_header_string_value)->str);
}
}
}
}
}
static void
epech_custom_header_options_commit (EMsgComposer *comp, gpointer user_data)
{
EMsgComposer *composer;
EmailCustomHeaderWindow *new_email_custom_header_window = NULL;
CustomHeaderOptionsDialog *current_dialog = NULL;
composer = (EMsgComposer *) user_data;
if (!user_data || !EMAIL_CUSTOM_HEADER_OPTIONS_IS_DIALOG (user_data))
return;
new_email_custom_header_window = g_object_get_data ((GObject *) composer, "compowindow");
if (new_email_custom_header_window) {
current_dialog = new_email_custom_header_window->epech_dialog;
}
if (current_dialog) {
g_free (current_dialog);
current_dialog = NULL;
}
if (new_email_custom_header_window) {
g_free (new_email_custom_header_window);
new_email_custom_header_window = NULL;
}
}
static gint
epech_check_existing_composer_window(gconstpointer compowindow, gconstpointer other_compowindow)
{
if ((compowindow) && (other_compowindow)) {
if (((EmailCustomHeaderWindow *)compowindow)->epech_window == (GdkWindow *)other_compowindow) {
return 0;
}
}
return -1;
}
static void
destroy_compo_data (gpointer data)
{
EmailCustomHeaderWindow *compo_data = (EmailCustomHeaderWindow *) data;
if (!compo_data)
return;
g_free (compo_data);
}
static void action_email_custom_header_cb (GtkAction *action, EMsgComposer *composer)
{
GtkUIManager *ui_manager;
GtkWidget *menuitem;
CustomHeaderOptionsDialog *dialog = NULL;
EmailCustomHeaderWindow *new_email_custom_header_window = NULL;
ui_manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (composer));
menuitem = gtk_ui_manager_get_widget (ui_manager, "/main-menu/insert-menu/insert-menu-top/Custom Header");
new_email_custom_header_window = g_object_get_data ((GObject *) composer, "compowindow");
if (epech_check_existing_composer_window(new_email_custom_header_window,menuitem->window) == 0) {
dialog = new_email_custom_header_window->epech_dialog;
} else {
dialog = epech_dialog_new ();
if (dialog) {
EmailCustomHeaderWindow *new_email_custom_header_window;
new_email_custom_header_window = g_new0(EmailCustomHeaderWindow, 1);
new_email_custom_header_window->epech_window = menuitem->window;
new_email_custom_header_window->epech_dialog = dialog;
g_object_set_data_full ((GObject *) composer, "compowindow", new_email_custom_header_window, destroy_compo_data);
}
}
epech_dialog_run (dialog, GTK_WIDGET (composer));
g_signal_connect (dialog, "emch_response", G_CALLBACK (epech_append_to_custom_header), GTK_WIDGET (composer));
g_signal_connect (GTK_WIDGET (composer), "destroy", G_CALLBACK (epech_custom_header_options_commit), composer);
}
static GtkActionEntry entries[] = {
{ "Custom Header",
NULL,
N_("_Custom Header"),
NULL,
NULL,
G_CALLBACK (action_email_custom_header_cb) }
};
gboolean
e_plugin_ui_init (GtkUIManager *ui_manager,
EMsgComposer *composer)
{
GtkhtmlEditor *editor;
editor = GTKHTML_EDITOR (composer);
/* Add actions to the "composer" action group. */
gtk_action_group_add_actions (
gtkhtml_editor_get_action_group (editor, "composer"),
entries, G_N_ELEMENTS (entries), composer);
return TRUE;
}
static void
commit_changes (ConfigData *cd)
{
GtkTreeModel *model = NULL;
GSList *header_config_list = NULL;
GtkTreeIter iter;
gboolean valid;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (cd->treeview));
valid = gtk_tree_model_get_iter_first (model, &iter);
while (valid) {
gchar *keyword = NULL, *value = NULL;
gtk_tree_model_get (model, &iter,
HEADER_KEY_COLUMN, &keyword,
HEADER_VALUE_COLUMN, &value,
-1);
/* Check if the keyword is not empty */
if ((keyword) && (g_utf8_strlen(g_strstrip(keyword), -1) > 0)) {
if ((value) && (g_utf8_strlen(g_strstrip(value), -1) > 0)) {
keyword = g_strconcat (keyword, "=", value, NULL);
}
header_config_list = g_slist_append (header_config_list, g_strdup(keyword));
}
g_free (keyword);
g_free (value);
valid = gtk_tree_model_iter_next (model, &iter);
}
gconf_client_set_list (cd->gconf, GCONF_KEY_CUSTOM_HEADER, GCONF_VALUE_STRING, header_config_list, NULL);
g_slist_foreach (header_config_list, (GFunc) g_free, NULL);
g_slist_free (header_config_list);
}
static void
header_isempty (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, ConfigData *cd)
{
GtkTreeSelection *selection;
gchar *keyword = NULL;
gchar *value = NULL;
gboolean valid;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cd->treeview));
/* move to the previous node */
valid = gtk_tree_path_prev (path);
gtk_tree_model_get (model, iter, HEADER_KEY_COLUMN, &keyword, -1);
if ((keyword) && !(g_utf8_strlen (g_strstrip (keyword), -1) > 0))
gtk_list_store_remove (cd->store, iter);
/* Check if we have a valid row to select. If not, then select
* the previous row */
if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (model), iter)) {
gtk_tree_selection_select_iter (selection, iter);
} else {
if (path && valid) {
gtk_tree_model_get_iter (model, iter, path);
gtk_tree_selection_select_iter (selection, iter);
}
}
gtk_widget_grab_focus (cd->treeview);
g_free (keyword);
g_free (value);
}
static gboolean
header_foreach_check_isempty (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, ConfigData *cd)
{
gboolean valid;
valid = gtk_tree_model_get_iter_first (model, iter);
while (valid && gtk_list_store_iter_is_valid (cd->store, iter)) {
gchar *keyword = NULL;
gchar *value = NULL;
gtk_tree_model_get (model, iter, HEADER_KEY_COLUMN, &keyword, -1);
/* Check if the keyword is not empty and then emit the row-changed
signal (if we delete the row, then the iter gets corrupted) */
if ((keyword) && !(g_utf8_strlen (g_strstrip (keyword), -1) > 0))
gtk_tree_model_row_changed (model, path, iter);
else {
gtk_tree_model_get (model, iter, HEADER_VALUE_COLUMN, &value, -1);
/* Check if the keyword is not empty and then emit the row-changed
signal (if we delete the row, then the iter gets corrupted) */
if ((value) && !(g_utf8_strlen (g_strstrip (value), -1) > 0))
gtk_tree_model_row_changed (model, path, iter);
}
g_free (keyword);
g_free (value);
valid = gtk_tree_model_iter_next (model, iter);
}
return FALSE;
}
static void
cell_edited_callback (GtkCellRendererText *cell,
gchar *path_string,
gchar *new_text,
ConfigData *cd)
{
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (cd->treeview));
gtk_tree_model_get_iter_from_string (model, &iter, path_string);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
HEADER_KEY_COLUMN, new_text, -1);
commit_changes (cd);
}
static void
cell_value_edited_callback (GtkCellRendererText *cell,
gchar *path_string,
gchar *new_text,
ConfigData *cd)
{
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (cd->treeview));
gtk_tree_model_get_iter_from_string (model, &iter, path_string);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
HEADER_VALUE_COLUMN, new_text, -1);
commit_changes (cd);
}
static void
header_add_clicked (GtkButton *button, ConfigData *cd)
{
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeViewColumn *focus_col;
GtkTreePath *path;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (cd->treeview));
gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) header_foreach_check_isempty, cd);
/* Disconnect from signal so that we can create an empty row */
g_signal_handlers_disconnect_matched(G_OBJECT(model), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, header_isempty, cd);
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
HEADER_KEY_COLUMN, "", -1);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
HEADER_VALUE_COLUMN, "", -1);
focus_col = gtk_tree_view_get_column (GTK_TREE_VIEW (cd->treeview), HEADER_KEY_COLUMN);
path = gtk_tree_model_get_path (model, &iter);
if (path) {
gtk_tree_view_set_cursor (GTK_TREE_VIEW (cd->treeview), path, focus_col, TRUE);
gtk_tree_view_row_activated(GTK_TREE_VIEW(cd->treeview), path, focus_col);
gtk_tree_path_free (path);
}
/* We have done our job, connect back to the signal */
g_signal_connect(G_OBJECT(model), "row-changed", G_CALLBACK(header_isempty), cd);
}
static void
header_remove_clicked (GtkButton *button, ConfigData *cd)
{
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreePath *path;
gboolean valid;
gint len;
valid = FALSE;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cd->treeview));
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
return;
/* Get the path and move to the previous node :) */
path = gtk_tree_model_get_path (model, &iter);
if (path)
valid = gtk_tree_path_prev(path);
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
len = gtk_tree_model_iter_n_children (model, NULL);
if (len > 0) {
if (gtk_list_store_iter_is_valid (GTK_LIST_STORE(model), &iter)) {
gtk_tree_selection_select_iter (selection, &iter);
} else {
if (path && valid) {
gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_selection_select_iter (selection, &iter);
}
}
} else {
gtk_widget_set_sensitive (cd->header_edit, FALSE);
gtk_widget_set_sensitive (cd->header_remove, FALSE);
}
gtk_widget_grab_focus(cd->treeview);
gtk_tree_path_free (path);
commit_changes (cd);
}
static void
header_edit_clicked (GtkButton *button, ConfigData *cd)
{
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreePath *path;
GtkTreeIter iter;
GtkTreeViewColumn *focus_col;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cd->treeview));
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
return;
focus_col = gtk_tree_view_get_column (GTK_TREE_VIEW (cd->treeview), HEADER_KEY_COLUMN);
path = gtk_tree_model_get_path (model, &iter);
if (path) {
gtk_tree_view_set_cursor (GTK_TREE_VIEW (cd->treeview), path, focus_col, TRUE);
gtk_tree_path_free (path);
}
}
static void
selection_changed (GtkTreeSelection *selection, ConfigData *cd)
{
GtkTreeModel *model;
GtkTreeIter iter;
if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
gtk_widget_set_sensitive (cd->header_edit, TRUE);
gtk_widget_set_sensitive (cd->header_remove, TRUE);
} else {
gtk_widget_set_sensitive (cd->header_edit, FALSE);
gtk_widget_set_sensitive (cd->header_remove, FALSE);
}
}
static void
destroy_cd_data (gpointer data)
{
ConfigData *cd = (ConfigData *) data;
if (!cd)
return;
g_object_unref (cd->gconf);
g_free (cd);
}
GtkWidget *
e_plugin_lib_get_configure_widget (EPlugin *epl)
{
GtkCellRenderer *renderer;
GtkTreeSelection *selection;
GtkTreeIter iter;
GtkWidget *hbox;
GSList *list;
GSList *header_list = NULL;
GtkTreeModel *model;
gint index;
gchar *buffer;
GtkTreeViewColumn *col;
gint col_pos;
GConfClient *client = gconf_client_get_default();
ConfigData *cd = g_new0 (ConfigData, 1);
GtkWidget *ech_configuration_box;
GtkWidget *vbox2;
GtkWidget *label1;
GtkWidget *header_configuration_box;
GtkWidget *header_container;
GtkWidget *scrolledwindow1;
GtkWidget *header_treeview;
GtkWidget *vbuttonbox1;
GtkWidget *header_add;
GtkWidget *header_edit;
GtkWidget *header_remove;
ech_configuration_box = gtk_vbox_new (FALSE, 0);
gtk_widget_show (ech_configuration_box);
vbox2 = gtk_vbox_new (FALSE, 0);
gtk_widget_show (vbox2);
gtk_box_pack_start (GTK_BOX (ech_configuration_box), vbox2, FALSE, FALSE, 0);
/* To translators: This string is used while adding a new message header to configuration, to specifying the format of the key values */
label1 = gtk_label_new (_("The format for specifying a Custom Header key value is:\nName of the Custom Header key values separated by \";\"."));
gtk_widget_show (label1);
gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, TRUE, 0);
gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_CENTER);
gtk_label_set_line_wrap (GTK_LABEL (label1), TRUE);
header_configuration_box = gtk_vbox_new (FALSE, 5);
gtk_widget_show (header_configuration_box);
gtk_box_pack_start (GTK_BOX (ech_configuration_box), header_configuration_box, TRUE, TRUE, 0);
header_container = gtk_hbox_new (FALSE, 6);
gtk_widget_show (header_container);
gtk_box_pack_start (GTK_BOX (header_configuration_box), header_container, TRUE, TRUE, 0);
scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (scrolledwindow1);
gtk_box_pack_start (GTK_BOX (header_container), scrolledwindow1, TRUE, TRUE, 0);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
header_treeview = gtk_tree_view_new ();
gtk_widget_show (header_treeview);
gtk_container_add (GTK_CONTAINER (scrolledwindow1), header_treeview);
gtk_container_set_border_width (GTK_CONTAINER (header_treeview), 1);
vbuttonbox1 = gtk_vbutton_box_new ();
gtk_widget_show (vbuttonbox1);
gtk_box_pack_start (GTK_BOX (header_container), vbuttonbox1, FALSE, TRUE, 0);
gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_START);
gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 6);
header_add = gtk_button_new_from_stock ("gtk-add");
gtk_widget_show (header_add);
gtk_container_add (GTK_CONTAINER (vbuttonbox1), header_add);
GTK_WIDGET_SET_FLAGS (header_add, GTK_CAN_DEFAULT);
header_edit = gtk_button_new_from_stock ("gtk-edit");
gtk_widget_show (header_edit);
gtk_container_add (GTK_CONTAINER (vbuttonbox1), header_edit);
GTK_WIDGET_SET_FLAGS (header_edit, GTK_CAN_DEFAULT);
header_remove = gtk_button_new_from_stock ("gtk-remove");
gtk_widget_show (header_remove);
gtk_container_add (GTK_CONTAINER (vbuttonbox1), header_remove);
GTK_WIDGET_SET_FLAGS (header_remove, GTK_CAN_DEFAULT);
cd->gconf = gconf_client_get_default ();
cd->treeview = header_treeview;
cd->store = gtk_list_store_new (HEADER_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
gtk_tree_view_set_model (GTK_TREE_VIEW (cd->treeview), GTK_TREE_MODEL (cd->store));
renderer = gtk_cell_renderer_text_new ();
col_pos = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (cd->treeview), -1, _("Key"),
renderer, "text", HEADER_KEY_COLUMN, NULL);
col = gtk_tree_view_get_column (GTK_TREE_VIEW (cd->treeview), col_pos -1);
gtk_tree_view_column_set_resizable (col, TRUE);
gtk_tree_view_column_set_reorderable(col, TRUE);
g_object_set (col, "min-width", 50, NULL);
g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
g_signal_connect(renderer, "edited", (GCallback) cell_edited_callback, cd);
renderer = gtk_cell_renderer_text_new ();
col_pos = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (cd->treeview), -1, _("Values"),
renderer, "text", HEADER_VALUE_COLUMN, NULL);
col = gtk_tree_view_get_column (GTK_TREE_VIEW (cd->treeview), col_pos -1);
gtk_tree_view_column_set_resizable (col, TRUE);
gtk_tree_view_column_set_reorderable(col, TRUE);
g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
g_signal_connect(renderer, "edited", (GCallback) cell_value_edited_callback, cd);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cd->treeview));
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (selection_changed), cd);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (cd->treeview), TRUE);
cd->header_add = header_add;
g_signal_connect (G_OBJECT (cd->header_add), "clicked", G_CALLBACK (header_add_clicked), cd);
cd->header_remove = header_remove;
g_signal_connect (G_OBJECT (cd->header_remove), "clicked", G_CALLBACK (header_remove_clicked), cd);
gtk_widget_set_sensitive (cd->header_remove, FALSE);
cd->header_edit = header_edit;
g_signal_connect (G_OBJECT (cd->header_edit), "clicked", G_CALLBACK (header_edit_clicked), cd);
gtk_widget_set_sensitive (cd->header_edit, FALSE);
model = gtk_tree_view_get_model (GTK_TREE_VIEW (cd->treeview));
g_signal_connect(G_OBJECT(model), "row-changed", G_CALLBACK(header_isempty), cd);
/* Populate tree view with values from gconf */
header_list = gconf_client_get_list (client,GCONF_KEY_CUSTOM_HEADER,GCONF_VALUE_STRING, NULL);
for (list = header_list; list; list = g_slist_next (list)) {
gchar **parse_header_list;
buffer = list->data;
gtk_list_store_append (cd->store, &iter);
parse_header_list = g_strsplit_set (buffer, "=,", -1);
gtk_list_store_set (cd->store, &iter, HEADER_KEY_COLUMN, parse_header_list[0], -1);
for (index = 0; parse_header_list[index+1] ; ++index) {
gtk_list_store_set (cd->store, &iter, HEADER_VALUE_COLUMN, parse_header_list[index+1], -1);
}
}
if (header_list) {
g_slist_foreach (header_list, (GFunc) g_free, NULL);
g_slist_free (header_list);
}
/* Add the list here */
hbox = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), ech_configuration_box, TRUE, TRUE, 0);
/* to let free data properly on destroy of configuration widget */
g_object_set_data_full (G_OBJECT (hbox), "mycd-data", cd, destroy_cd_data);
return hbox;
}
/* Configuration in Mail Prefs Page goes here */
GtkWidget *
org_gnome_email_custom_header_config_option (struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data)
{
/* This function and the hook needs to be removed,
once the configure code is thoroughly tested */
return NULL;
}