839 lines
20 KiB
C
839 lines
20 KiB
C
/*
|
|
* e-mail-reader-utils.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/>
|
|
*
|
|
*
|
|
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
|
|
*
|
|
*/
|
|
|
|
/* Miscellaneous utility functions used by EMailReader actions. */
|
|
|
|
#include "e-mail-reader-utils.h"
|
|
|
|
#include <glib/gi18n.h>
|
|
#include <libxml/tree.h>
|
|
#include <gtkhtml/gtkhtml.h>
|
|
#include <camel/camel.h>
|
|
|
|
#include "e-util/e-alert-dialog.h"
|
|
#include "filter/e-filter-rule.h"
|
|
#include "misc/e-web-view.h"
|
|
|
|
#include "mail/e-mail-backend.h"
|
|
#include "mail/e-mail-browser.h"
|
|
#include "mail/em-composer-utils.h"
|
|
#include "mail/em-format-html-print.h"
|
|
#include "mail/em-utils.h"
|
|
#include "mail/mail-autofilter.h"
|
|
#include "mail/mail-ops.h"
|
|
#include "mail/mail-tools.h"
|
|
#include "mail/mail-vfolder.h"
|
|
#include "mail/message-list.h"
|
|
|
|
void
|
|
e_mail_reader_activate (EMailReader *reader,
|
|
const gchar *action_name)
|
|
{
|
|
GtkActionGroup *action_group;
|
|
GtkAction *action;
|
|
|
|
g_return_if_fail (E_IS_MAIL_READER (reader));
|
|
g_return_if_fail (action_name != NULL);
|
|
|
|
action_group = e_mail_reader_get_action_group (reader);
|
|
action = gtk_action_group_get_action (action_group, action_name);
|
|
g_return_if_fail (action != NULL);
|
|
|
|
gtk_action_activate (action);
|
|
}
|
|
|
|
gboolean
|
|
e_mail_reader_confirm_delete (EMailReader *reader)
|
|
{
|
|
EShell *shell;
|
|
EMailBackend *backend;
|
|
EShellBackend *shell_backend;
|
|
EShellSettings *shell_settings;
|
|
CamelFolder *folder;
|
|
CamelStore *parent_store;
|
|
GtkWidget *check_button;
|
|
GtkWidget *container;
|
|
GtkWidget *dialog;
|
|
GtkWindow *window;
|
|
const gchar *label;
|
|
gboolean prompt_delete_in_vfolder;
|
|
gint response;
|
|
|
|
/* Remind users what deleting from a search folder does. */
|
|
|
|
g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
|
|
|
|
backend = e_mail_reader_get_backend (reader);
|
|
folder = e_mail_reader_get_folder (reader);
|
|
window = e_mail_reader_get_window (reader);
|
|
|
|
shell_backend = E_SHELL_BACKEND (backend);
|
|
shell = e_shell_backend_get_shell (shell_backend);
|
|
shell_settings = e_shell_get_shell_settings (shell);
|
|
|
|
prompt_delete_in_vfolder = e_shell_settings_get_boolean (
|
|
shell_settings, "mail-prompt-delete-in-vfolder");
|
|
|
|
parent_store = camel_folder_get_parent_store (folder);
|
|
|
|
if (!CAMEL_IS_VEE_STORE (parent_store))
|
|
return TRUE;
|
|
|
|
if (!prompt_delete_in_vfolder)
|
|
return TRUE;
|
|
|
|
dialog = e_alert_dialog_new_for_args (
|
|
window, "mail:ask-delete-vfolder-msg",
|
|
camel_folder_get_full_name (folder), NULL);
|
|
|
|
container = e_alert_dialog_get_content_area (E_ALERT_DIALOG (dialog));
|
|
|
|
label = _("Do not warn me again");
|
|
check_button = gtk_check_button_new_with_label (label);
|
|
gtk_box_pack_start (GTK_BOX (container), check_button, TRUE, TRUE, 6);
|
|
gtk_widget_show (check_button);
|
|
|
|
response = gtk_dialog_run (GTK_DIALOG (dialog));
|
|
|
|
if (response != GTK_RESPONSE_DELETE_EVENT)
|
|
e_shell_settings_set_boolean (
|
|
shell_settings,
|
|
"mail-prompt-delete-in-vfolder",
|
|
!gtk_toggle_button_get_active (
|
|
GTK_TOGGLE_BUTTON (check_button)));
|
|
|
|
gtk_widget_destroy (dialog);
|
|
|
|
return (response == GTK_RESPONSE_OK);
|
|
}
|
|
|
|
void
|
|
e_mail_reader_mark_as_read (EMailReader *reader,
|
|
const gchar *uid)
|
|
{
|
|
EMailBackend *backend;
|
|
EMailSession *session;
|
|
EMFormatHTML *formatter;
|
|
CamelFolder *folder;
|
|
guint32 mask, set;
|
|
guint32 flags;
|
|
|
|
g_return_if_fail (E_IS_MAIL_READER (reader));
|
|
g_return_if_fail (uid != NULL);
|
|
|
|
folder = e_mail_reader_get_folder (reader);
|
|
backend = e_mail_reader_get_backend (reader);
|
|
formatter = e_mail_reader_get_formatter (reader);
|
|
|
|
session = e_mail_backend_get_session (backend);
|
|
|
|
flags = camel_folder_get_message_flags (folder, uid);
|
|
|
|
if (!(flags & CAMEL_MESSAGE_SEEN)) {
|
|
CamelMimeMessage *message;
|
|
|
|
message = EM_FORMAT (formatter)->message;
|
|
em_utils_handle_receipt (session, folder, uid, message);
|
|
}
|
|
|
|
mask = CAMEL_MESSAGE_SEEN;
|
|
set = CAMEL_MESSAGE_SEEN;
|
|
|
|
camel_folder_set_message_flags (folder, uid, mask, set);
|
|
}
|
|
|
|
guint
|
|
e_mail_reader_mark_selected (EMailReader *reader,
|
|
guint32 mask,
|
|
guint32 set)
|
|
{
|
|
CamelFolder *folder;
|
|
GPtrArray *uids;
|
|
guint ii;
|
|
|
|
g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
|
|
|
|
folder = e_mail_reader_get_folder (reader);
|
|
|
|
if (folder == NULL)
|
|
return 0;
|
|
|
|
camel_folder_freeze (folder);
|
|
uids = e_mail_reader_get_selected_uids (reader);
|
|
|
|
for (ii = 0; ii < uids->len; ii++)
|
|
camel_folder_set_message_flags (
|
|
folder, uids->pdata[ii], mask, set);
|
|
|
|
em_utils_uids_free (uids);
|
|
|
|
camel_folder_thaw (folder);
|
|
|
|
return ii;
|
|
}
|
|
static void
|
|
copy_tree_state (EMailReader *src_reader, EMailReader *des_reader)
|
|
{
|
|
GtkWidget *src_mlist, *des_mlist;
|
|
gchar *state;
|
|
|
|
g_return_if_fail (src_reader != NULL);
|
|
g_return_if_fail (des_reader != NULL);
|
|
|
|
src_mlist = e_mail_reader_get_message_list (src_reader);
|
|
if (!src_mlist)
|
|
return;
|
|
|
|
des_mlist = e_mail_reader_get_message_list (des_reader);
|
|
if (!des_mlist)
|
|
return;
|
|
|
|
state = e_tree_get_state (E_TREE (src_mlist));
|
|
if (state)
|
|
e_tree_set_state (E_TREE (des_mlist), state);
|
|
g_free (state);
|
|
}
|
|
|
|
guint
|
|
e_mail_reader_open_selected (EMailReader *reader)
|
|
{
|
|
EShell *shell;
|
|
EMailBackend *backend;
|
|
EShellBackend *shell_backend;
|
|
CamelFolder *folder;
|
|
GtkWindow *window;
|
|
GPtrArray *views;
|
|
GPtrArray *uids;
|
|
const gchar *folder_uri;
|
|
guint ii;
|
|
|
|
g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
|
|
|
|
backend = e_mail_reader_get_backend (reader);
|
|
folder = e_mail_reader_get_folder (reader);
|
|
folder_uri = e_mail_reader_get_folder_uri (reader);
|
|
uids = e_mail_reader_get_selected_uids (reader);
|
|
window = e_mail_reader_get_window (reader);
|
|
|
|
shell_backend = E_SHELL_BACKEND (backend);
|
|
shell = e_shell_backend_get_shell (shell_backend);
|
|
|
|
if (!em_utils_ask_open_many (window, uids->len)) {
|
|
em_utils_uids_free (uids);
|
|
return 0;
|
|
}
|
|
|
|
if (em_utils_folder_is_drafts (folder) ||
|
|
em_utils_folder_is_outbox (folder) ||
|
|
em_utils_folder_is_templates (folder)) {
|
|
em_utils_edit_messages (shell, folder, uids, TRUE);
|
|
return uids->len;
|
|
}
|
|
|
|
views = g_ptr_array_new ();
|
|
|
|
/* For vfolders we need to edit the original, not the vfolder copy. */
|
|
for (ii = 0; ii < uids->len; ii++) {
|
|
const gchar *uid = uids->pdata[ii];
|
|
CamelFolder *real_folder;
|
|
CamelMessageInfo *info;
|
|
const gchar *real_folder_uri;
|
|
gchar *real_uid;
|
|
|
|
if (!CAMEL_IS_VEE_FOLDER (folder)) {
|
|
g_ptr_array_add (views, g_strdup (uid));
|
|
continue;
|
|
}
|
|
|
|
info = camel_folder_get_message_info (folder, uid);
|
|
if (info == NULL)
|
|
continue;
|
|
|
|
real_folder = camel_vee_folder_get_location (
|
|
CAMEL_VEE_FOLDER (folder),
|
|
(CamelVeeMessageInfo *) info, &real_uid);
|
|
real_folder_uri = camel_folder_get_uri (real_folder);
|
|
|
|
if (em_utils_folder_is_drafts (real_folder) ||
|
|
em_utils_folder_is_outbox (real_folder)) {
|
|
GPtrArray *edits;
|
|
|
|
edits = g_ptr_array_new ();
|
|
g_ptr_array_add (edits, real_uid);
|
|
em_utils_edit_messages (
|
|
shell, real_folder, edits, TRUE);
|
|
} else {
|
|
g_free (real_uid);
|
|
g_ptr_array_add (views, g_strdup (uid));
|
|
}
|
|
|
|
camel_folder_free_message_info (folder, info);
|
|
}
|
|
|
|
for (ii = 0; ii < views->len; ii++) {
|
|
const gchar *uid = views->pdata[ii];
|
|
GtkWidget *browser;
|
|
|
|
browser = e_mail_browser_new (backend);
|
|
e_mail_reader_set_folder (
|
|
E_MAIL_READER (browser), folder);
|
|
e_mail_reader_set_message (E_MAIL_READER (browser), uid);
|
|
copy_tree_state (reader, E_MAIL_READER (browser));
|
|
e_mail_reader_set_group_by_threads (
|
|
E_MAIL_READER (browser),
|
|
e_mail_reader_get_group_by_threads (reader));
|
|
gtk_widget_show (browser);
|
|
}
|
|
|
|
g_ptr_array_foreach (views, (GFunc) g_free, NULL);
|
|
g_ptr_array_free (views, TRUE);
|
|
|
|
em_utils_uids_free (uids);
|
|
|
|
return ii;
|
|
}
|
|
|
|
void
|
|
e_mail_reader_print (EMailReader *reader,
|
|
GtkPrintOperationAction action)
|
|
{
|
|
EMFormatHTML *formatter;
|
|
EMFormatHTMLPrint *html_print;
|
|
CamelFolder *folder;
|
|
GPtrArray *uids;
|
|
|
|
g_return_if_fail (E_IS_MAIL_READER (reader));
|
|
|
|
folder = e_mail_reader_get_folder (reader);
|
|
g_return_if_fail (folder != NULL);
|
|
|
|
/* XXX Learn to handle len > 1. */
|
|
uids = e_mail_reader_get_selected_uids (reader);
|
|
if (uids->len != 1)
|
|
goto exit;
|
|
|
|
formatter = e_mail_reader_get_formatter (reader);
|
|
|
|
html_print = em_format_html_print_new (formatter, action);
|
|
em_format_merge_handler (
|
|
EM_FORMAT (html_print), EM_FORMAT (formatter));
|
|
em_format_html_print_message (html_print, folder, uids->pdata[0]);
|
|
g_object_unref (html_print);
|
|
|
|
exit:
|
|
em_utils_uids_free (uids);
|
|
}
|
|
|
|
/* Helper for e_mail_reader_reply_to_message()
|
|
* XXX This function belongs in e-html-utils.c */
|
|
static gboolean
|
|
html_contains_nonwhitespace (const gchar *html,
|
|
gint len)
|
|
{
|
|
const gchar *cp;
|
|
gunichar uc = 0;
|
|
|
|
if (html == NULL || len <= 0)
|
|
return FALSE;
|
|
|
|
cp = html;
|
|
|
|
while (cp != NULL && cp - html < len) {
|
|
uc = g_utf8_get_char (cp);
|
|
if (uc == 0)
|
|
break;
|
|
|
|
if (uc == '<') {
|
|
/* skip until next '>' */
|
|
uc = g_utf8_get_char (cp);
|
|
while (uc != 0 && uc != '>' && cp - html < len) {
|
|
cp = g_utf8_next_char (cp);
|
|
uc = g_utf8_get_char (cp);
|
|
}
|
|
if (uc == 0)
|
|
break;
|
|
} else if (uc == '&') {
|
|
/* sequence ' ' is a space */
|
|
if (g_ascii_strncasecmp (cp, " ", 6) == 0)
|
|
cp = cp + 5;
|
|
else
|
|
break;
|
|
} else if (!g_unichar_isspace (uc))
|
|
break;
|
|
|
|
cp = g_utf8_next_char (cp);
|
|
}
|
|
|
|
return cp - html < len - 1 && uc != 0;
|
|
}
|
|
|
|
void
|
|
e_mail_reader_reply_to_message (EMailReader *reader,
|
|
CamelMimeMessage *src_message,
|
|
EMailReplyType reply_type)
|
|
{
|
|
EShell *shell;
|
|
EMailBackend *backend;
|
|
EShellBackend *shell_backend;
|
|
EMFormatHTML *formatter;
|
|
GtkWidget *message_list;
|
|
CamelMimeMessage *new_message;
|
|
CamelFolder *folder;
|
|
EMailReplyStyle reply_style;
|
|
EWebView *web_view;
|
|
struct _camel_header_raw *header;
|
|
const gchar *uid;
|
|
gchar *selection = NULL;
|
|
gint length;
|
|
|
|
/* This handles quoting only selected text in the reply. If
|
|
* nothing is selected or only whitespace is selected, fall
|
|
* back to the normal em_utils_reply_to_message(). */
|
|
|
|
g_return_if_fail (E_IS_MAIL_READER (reader));
|
|
|
|
backend = e_mail_reader_get_backend (reader);
|
|
folder = e_mail_reader_get_folder (reader);
|
|
formatter = e_mail_reader_get_formatter (reader);
|
|
message_list = e_mail_reader_get_message_list (reader);
|
|
reply_style = e_mail_reader_get_reply_style (reader);
|
|
|
|
shell_backend = E_SHELL_BACKEND (backend);
|
|
shell = e_shell_backend_get_shell (shell_backend);
|
|
|
|
web_view = em_format_html_get_web_view (formatter);
|
|
|
|
uid = MESSAGE_LIST (message_list)->cursor_uid;
|
|
g_return_if_fail (uid != NULL);
|
|
|
|
if (!gtk_widget_get_mapped (GTK_WIDGET (web_view)))
|
|
goto whole_message;
|
|
|
|
if (src_message == NULL) {
|
|
src_message = EM_FORMAT (formatter)->message;
|
|
if (src_message != NULL)
|
|
g_object_ref (src_message);
|
|
}
|
|
|
|
if (!e_web_view_is_selection_active (web_view))
|
|
goto whole_message;
|
|
|
|
selection = gtk_html_get_selection_html (GTK_HTML (web_view), &length);
|
|
if (selection == NULL || *selection == '\0')
|
|
goto whole_message;
|
|
|
|
if (!html_contains_nonwhitespace (selection, length))
|
|
goto whole_message;
|
|
|
|
new_message = camel_mime_message_new ();
|
|
|
|
/* Filter out "content-*" headers. */
|
|
header = CAMEL_MIME_PART (src_message)->headers;
|
|
while (header != NULL) {
|
|
if (g_ascii_strncasecmp (header->name, "content-", 8) != 0)
|
|
camel_medium_add_header (
|
|
CAMEL_MEDIUM (new_message),
|
|
header->name, header->value);
|
|
|
|
header = header->next;
|
|
}
|
|
|
|
camel_mime_part_set_encoding (
|
|
CAMEL_MIME_PART (new_message),
|
|
CAMEL_TRANSFER_ENCODING_8BIT);
|
|
|
|
camel_mime_part_set_content (
|
|
CAMEL_MIME_PART (new_message),
|
|
selection, length, "text/html");
|
|
|
|
g_object_unref (src_message);
|
|
|
|
em_utils_reply_to_message (
|
|
shell, folder, uid, new_message,
|
|
reply_type, reply_style, NULL);
|
|
|
|
g_free (selection);
|
|
|
|
return;
|
|
|
|
whole_message:
|
|
em_utils_reply_to_message (
|
|
shell, folder, uid, src_message,
|
|
reply_type, reply_style, EM_FORMAT (formatter));
|
|
}
|
|
|
|
void
|
|
e_mail_reader_select_next_message (EMailReader *reader,
|
|
gboolean or_else_previous)
|
|
{
|
|
GtkWidget *message_list;
|
|
gboolean hide_deleted;
|
|
gboolean success;
|
|
|
|
g_return_if_fail (E_IS_MAIL_READER (reader));
|
|
|
|
hide_deleted = e_mail_reader_get_hide_deleted (reader);
|
|
message_list = e_mail_reader_get_message_list (reader);
|
|
|
|
success = message_list_select (
|
|
MESSAGE_LIST (message_list),
|
|
MESSAGE_LIST_SELECT_NEXT, 0, 0);
|
|
|
|
if (!success && (hide_deleted || or_else_previous))
|
|
message_list_select (
|
|
MESSAGE_LIST (message_list),
|
|
MESSAGE_LIST_SELECT_PREVIOUS, 0, 0);
|
|
}
|
|
|
|
/* Helper for e_mail_reader_create_filter_from_selected() */
|
|
static void
|
|
mail_reader_create_filter_cb (CamelFolder *folder,
|
|
const gchar *uid,
|
|
CamelMimeMessage *message,
|
|
gpointer user_data)
|
|
{
|
|
struct {
|
|
EMailSession *session;
|
|
const gchar *source;
|
|
gint type;
|
|
} *filter_data = user_data;
|
|
|
|
if (message != NULL)
|
|
filter_gui_add_from_message (
|
|
filter_data->session,
|
|
message,
|
|
filter_data->source,
|
|
filter_data->type);
|
|
|
|
g_object_unref (filter_data->session);
|
|
g_free (filter_data);
|
|
}
|
|
|
|
void
|
|
e_mail_reader_create_filter_from_selected (EMailReader *reader,
|
|
gint filter_type)
|
|
{
|
|
EMailBackend *backend;
|
|
EMailSession *session;
|
|
CamelFolder *folder;
|
|
const gchar *filter_source;
|
|
const gchar *folder_uri;
|
|
GPtrArray *uids;
|
|
|
|
struct {
|
|
EMailSession *session;
|
|
const gchar *source;
|
|
gint type;
|
|
} *filter_data;
|
|
|
|
g_return_if_fail (E_IS_MAIL_READER (reader));
|
|
|
|
backend = e_mail_reader_get_backend (reader);
|
|
session = e_mail_backend_get_session (backend);
|
|
|
|
folder = e_mail_reader_get_folder (reader);
|
|
folder_uri = e_mail_reader_get_folder_uri (reader);
|
|
|
|
if (em_utils_folder_is_sent (folder))
|
|
filter_source = E_FILTER_SOURCE_OUTGOING;
|
|
else if (em_utils_folder_is_outbox (folder))
|
|
filter_source = E_FILTER_SOURCE_OUTGOING;
|
|
else
|
|
filter_source = E_FILTER_SOURCE_INCOMING;
|
|
|
|
uids = e_mail_reader_get_selected_uids (reader);
|
|
|
|
if (uids->len == 1) {
|
|
filter_data = g_malloc (sizeof (*filter_data));
|
|
filter_data->session = g_object_ref (session);
|
|
filter_data->source = filter_source;
|
|
filter_data->type = filter_type;
|
|
|
|
mail_get_message (
|
|
folder, uids->pdata[0],
|
|
mail_reader_create_filter_cb,
|
|
filter_data, mail_msg_unordered_push);
|
|
}
|
|
|
|
em_utils_uids_free (uids);
|
|
}
|
|
|
|
/* Helper for e_mail_reader_create_vfolder_from_selected() */
|
|
static void
|
|
mail_reader_create_vfolder_cb (CamelFolder *folder,
|
|
const gchar *uid,
|
|
CamelMimeMessage *message,
|
|
gpointer user_data)
|
|
{
|
|
struct {
|
|
EMailSession *session;
|
|
gchar *uri;
|
|
gint type;
|
|
} *vfolder_data = user_data;
|
|
|
|
if (message != NULL)
|
|
vfolder_gui_add_from_message (
|
|
vfolder_data->session, message,
|
|
vfolder_data->type, vfolder_data->uri);
|
|
|
|
g_object_unref (vfolder_data->session);
|
|
g_free (vfolder_data->uri);
|
|
g_free (vfolder_data);
|
|
}
|
|
|
|
void
|
|
e_mail_reader_create_vfolder_from_selected (EMailReader *reader,
|
|
gint vfolder_type)
|
|
{
|
|
EMailBackend *backend;
|
|
EMailSession *session;
|
|
CamelFolder *folder;
|
|
const gchar *folder_uri;
|
|
GPtrArray *uids;
|
|
|
|
struct {
|
|
EMailSession *session;
|
|
gchar *uri;
|
|
gint type;
|
|
} *vfolder_data;
|
|
|
|
g_return_if_fail (E_IS_MAIL_READER (reader));
|
|
|
|
backend = e_mail_reader_get_backend (reader);
|
|
session = e_mail_backend_get_session (backend);
|
|
|
|
folder = e_mail_reader_get_folder (reader);
|
|
folder_uri = e_mail_reader_get_folder_uri (reader);
|
|
uids = e_mail_reader_get_selected_uids (reader);
|
|
|
|
if (uids->len == 1) {
|
|
vfolder_data = g_malloc (sizeof (*vfolder_data));
|
|
vfolder_data->session = g_object_ref (session);
|
|
vfolder_data->uri = g_strdup (folder_uri);
|
|
vfolder_data->type = vfolder_type;
|
|
|
|
mail_get_message (
|
|
folder, uids->pdata[0],
|
|
mail_reader_create_vfolder_cb,
|
|
vfolder_data, mail_msg_unordered_push);
|
|
}
|
|
|
|
em_utils_uids_free (uids);
|
|
}
|
|
|
|
static EMailReaderHeader *
|
|
emr_header_from_xmldoc (xmlDocPtr doc)
|
|
{
|
|
EMailReaderHeader *h;
|
|
xmlNodePtr root;
|
|
xmlChar *name;
|
|
|
|
if (doc == NULL)
|
|
return NULL;
|
|
|
|
root = doc->children;
|
|
if (strcmp ((gchar *)root->name, "header") != 0)
|
|
return NULL;
|
|
|
|
name = xmlGetProp (root, (const guchar *)"name");
|
|
if (name == NULL)
|
|
return NULL;
|
|
|
|
h = g_malloc0 (sizeof (EMailReaderHeader));
|
|
h->name = g_strdup ((gchar *)name);
|
|
xmlFree (name);
|
|
|
|
if (xmlHasProp (root, (const guchar *)"enabled"))
|
|
h->enabled = 1;
|
|
else
|
|
h->enabled = 0;
|
|
|
|
return h;
|
|
}
|
|
|
|
/**
|
|
* e_mail_reader_header_from_xml
|
|
* @xml: XML configuration data
|
|
*
|
|
* Parses passed XML data, which should be of
|
|
* the format <header name="foo" enabled />, and
|
|
* returns a EMailReaderHeader structure, or NULL if there
|
|
* is an error.
|
|
**/
|
|
EMailReaderHeader *
|
|
e_mail_reader_header_from_xml (const gchar *xml)
|
|
{
|
|
EMailReaderHeader *header;
|
|
xmlDocPtr doc;
|
|
|
|
if (!(doc = xmlParseDoc ((guchar *) xml)))
|
|
return NULL;
|
|
|
|
header = emr_header_from_xmldoc (doc);
|
|
xmlFreeDoc (doc);
|
|
|
|
return header;
|
|
}
|
|
|
|
/**
|
|
* e_mail_reader_header_to_xml
|
|
* @header: header from which to generate XML
|
|
*
|
|
* Returns the passed header as a XML structure,
|
|
* or NULL on error
|
|
*/
|
|
gchar *
|
|
e_mail_reader_header_to_xml (EMailReaderHeader *header)
|
|
{
|
|
xmlDocPtr doc;
|
|
xmlNodePtr root;
|
|
xmlChar *xml;
|
|
gchar *out;
|
|
gint size;
|
|
|
|
g_return_val_if_fail (header != NULL, NULL);
|
|
g_return_val_if_fail (header->name != NULL, NULL);
|
|
|
|
doc = xmlNewDoc ((const guchar *)"1.0");
|
|
|
|
root = xmlNewDocNode (doc, NULL, (const guchar *)"header", NULL);
|
|
xmlSetProp (root, (const guchar *)"name", (guchar *)header->name);
|
|
if (header->enabled)
|
|
xmlSetProp (root, (const guchar *)"enabled", NULL);
|
|
|
|
xmlDocSetRootElement (doc, root);
|
|
xmlDocDumpMemory (doc, &xml, &size);
|
|
xmlFreeDoc (doc);
|
|
|
|
out = g_malloc (size + 1);
|
|
memcpy (out, xml, size);
|
|
out[size] = '\0';
|
|
xmlFree (xml);
|
|
|
|
return out;
|
|
}
|
|
|
|
/**
|
|
* e_mail_reader_header_free
|
|
* @header: header to free
|
|
*
|
|
* Frees the memory associated with the passed header
|
|
* structure.
|
|
*/
|
|
void
|
|
e_mail_reader_header_free (EMailReaderHeader *header)
|
|
{
|
|
if (header == NULL)
|
|
return;
|
|
|
|
g_free (header->name);
|
|
g_free (header);
|
|
}
|
|
|
|
static void
|
|
headers_changed_cb (GConfClient *client,
|
|
guint cnxn_id,
|
|
GConfEntry *entry,
|
|
EMailReader *reader)
|
|
{
|
|
EMFormatHTML *formatter;
|
|
GSList *header_config_list, *p;
|
|
|
|
g_return_if_fail (client != NULL);
|
|
g_return_if_fail (reader != NULL);
|
|
|
|
formatter = e_mail_reader_get_formatter (reader);
|
|
|
|
header_config_list = gconf_client_get_list (
|
|
client, "/apps/evolution/mail/display/headers",
|
|
GCONF_VALUE_STRING, NULL);
|
|
em_format_clear_headers (EM_FORMAT (formatter));
|
|
for (p = header_config_list; p; p = g_slist_next (p)) {
|
|
EMailReaderHeader *h;
|
|
gchar *xml = (gchar *)p->data;
|
|
|
|
h = e_mail_reader_header_from_xml (xml);
|
|
if (h && h->enabled)
|
|
em_format_add_header (
|
|
EM_FORMAT (formatter),
|
|
h->name, EM_FORMAT_HEADER_BOLD);
|
|
|
|
e_mail_reader_header_free (h);
|
|
}
|
|
|
|
if (!header_config_list)
|
|
em_format_default_headers (EM_FORMAT (formatter));
|
|
|
|
g_slist_foreach (header_config_list, (GFunc) g_free, NULL);
|
|
g_slist_free (header_config_list);
|
|
|
|
/* force a redraw */
|
|
if (EM_FORMAT (formatter)->message)
|
|
em_format_queue_redraw (EM_FORMAT (formatter));
|
|
}
|
|
|
|
static void
|
|
remove_header_notify_cb (gpointer data)
|
|
{
|
|
GConfClient *client;
|
|
guint notify_id;
|
|
|
|
notify_id = GPOINTER_TO_INT (data);
|
|
g_return_if_fail (notify_id != 0);
|
|
|
|
client = gconf_client_get_default ();
|
|
gconf_client_notify_remove (client, notify_id);
|
|
gconf_client_remove_dir (client, "/apps/evolution/mail/display", NULL);
|
|
g_object_unref (client);
|
|
}
|
|
|
|
/**
|
|
* e_mail_reader_connect_headers
|
|
* @reader: an #EMailReader
|
|
*
|
|
* Connects @reader to listening for changes in headers and
|
|
* updates the EMFormat whenever it changes and on this call too.
|
|
**/
|
|
void
|
|
e_mail_reader_connect_headers (EMailReader *reader)
|
|
{
|
|
GConfClient *client;
|
|
guint notify_id;
|
|
|
|
client = gconf_client_get_default ();
|
|
|
|
gconf_client_add_dir (
|
|
client, "/apps/evolution/mail/display",
|
|
GCONF_CLIENT_PRELOAD_NONE, NULL);
|
|
notify_id = gconf_client_notify_add (
|
|
client, "/apps/evolution/mail/display/headers",
|
|
(GConfClientNotifyFunc) headers_changed_cb,
|
|
reader, NULL, NULL);
|
|
|
|
g_object_set_data_full (
|
|
G_OBJECT (reader), "reader-header-notify-id",
|
|
GINT_TO_POINTER (notify_id), remove_header_notify_cb);
|
|
|
|
headers_changed_cb (client, 0, NULL, reader);
|
|
|
|
g_object_unref (client);
|
|
}
|