aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/Makefile.am378
-rw-r--r--mail/e-attachment-handler-mail.c524
-rw-r--r--mail/e-attachment-handler-mail.h65
-rw-r--r--mail/e-mail-attachment-bar.c3
-rw-r--r--mail/e-mail-browser.c749
-rw-r--r--mail/e-mail-browser.h72
-rw-r--r--mail/e-mail-display.c1072
-rw-r--r--mail/e-mail-display.h99
-rw-r--r--mail/e-mail-label-dialog.c323
-rw-r--r--mail/e-mail-label-dialog.h77
-rw-r--r--mail/e-mail-label-list-store.c513
-rw-r--r--mail/e-mail-label-list-store.h85
-rw-r--r--mail/e-mail-label-manager.c479
-rw-r--r--mail/e-mail-label-manager.h81
-rw-r--r--mail/e-mail-label-tree-view.c136
-rw-r--r--mail/e-mail-label-tree-view.h66
-rw-r--r--mail/e-mail-local.c130
-rw-r--r--mail/e-mail-local.h (renamed from mail/em-migrate.h)32
-rw-r--r--mail/e-mail-reader-utils.c588
-rw-r--r--mail/e-mail-reader-utils.h56
-rw-r--r--mail/e-mail-reader.c2744
-rw-r--r--mail/e-mail-reader.h134
-rw-r--r--mail/e-mail-store.c423
-rw-r--r--mail/e-mail-store.h (renamed from mail/mail-config-factory.h)31
-rw-r--r--mail/e-searching-tokenizer.c629
-rw-r--r--mail/e-searching-tokenizer.h81
-rw-r--r--mail/em-account-editor.c626
-rw-r--r--mail/em-account-editor.h85
-rw-r--r--mail/em-account-prefs.c571
-rw-r--r--mail/em-account-prefs.h84
-rw-r--r--mail/em-composer-prefs.c1066
-rw-r--r--mail/em-composer-prefs.h106
-rw-r--r--mail/em-composer-utils.c341
-rw-r--r--mail/em-composer-utils.h12
-rw-r--r--mail/em-event.c16
-rw-r--r--mail/em-event.h16
-rw-r--r--mail/em-filter-folder-element.c8
-rw-r--r--mail/em-folder-browser.c1580
-rw-r--r--mail/em-folder-properties.c65
-rw-r--r--mail/em-folder-properties.h6
-rw-r--r--mail/em-folder-selection-button.c528
-rw-r--r--mail/em-folder-selection-button.h82
-rw-r--r--mail/em-folder-selection.c65
-rw-r--r--mail/em-folder-selection.h13
-rw-r--r--mail/em-folder-selector.c137
-rw-r--r--mail/em-folder-selector.h27
-rw-r--r--mail/em-folder-tree-model.c1371
-rw-r--r--mail/em-folder-tree-model.h151
-rw-r--r--mail/em-folder-tree.c1938
-rw-r--r--mail/em-folder-tree.h65
-rw-r--r--mail/em-folder-utils.c112
-rw-r--r--mail/em-folder-utils.h10
-rw-r--r--mail/em-folder-view.c2612
-rw-r--r--mail/em-folder-view.h3
-rw-r--r--mail/em-format-hook.h2
-rw-r--r--mail/em-format-html-display.c992
-rw-r--r--mail/em-format-html-display.h54
-rw-r--r--mail/em-format-html-print.c24
-rw-r--r--mail/em-format-html.c1461
-rw-r--r--mail/em-format-html.h64
-rw-r--r--mail/em-format-quote.c571
-rw-r--r--mail/em-format-quote.h81
-rw-r--r--mail/em-format.c1839
-rw-r--r--mail/em-format.h348
-rw-r--r--mail/em-html-stream.c147
-rw-r--r--mail/em-html-stream.h42
-rw-r--r--mail/em-inline-filter.c3
-rw-r--r--mail/em-mailer-prefs.c1618
-rw-r--r--mail/em-mailer-prefs.h147
-rw-r--r--mail/em-message-browser.c421
-rw-r--r--mail/em-message-browser.h74
-rw-r--r--mail/em-migrate.c3046
-rw-r--r--mail/em-network-prefs.c499
-rw-r--r--mail/em-network-prefs.h107
-rw-r--r--mail/em-popup.c416
-rw-r--r--mail/em-search-context.c84
-rw-r--r--mail/em-search-context.h41
-rw-r--r--mail/em-stripsig-filter.c164
-rw-r--r--mail/em-stripsig-filter.h57
-rw-r--r--mail/em-subscribe-editor.c10
-rw-r--r--mail/em-subscribe-editor.h2
-rw-r--r--mail/em-utils.c534
-rw-r--r--mail/em-utils.h42
-rw-r--r--mail/em-vfolder-editor.c4
-rw-r--r--mail/em-vfolder-editor.h2
-rw-r--r--mail/em-vfolder-rule.c6
-rw-r--r--mail/evolution-mail.schemas.in63
-rw-r--r--mail/filtertypes.xml4
-rw-r--r--mail/importers/Makefile.am3
-rw-r--r--mail/importers/evolution-mbox-importer.c14
-rw-r--r--mail/importers/mail-importer.c18
-rw-r--r--mail/mail-autofilter.c14
-rw-r--r--mail/mail-component-factory.c125
-rw-r--r--mail/mail-component.c1254
-rw-r--r--mail/mail-component.h2
-rw-r--r--mail/mail-config-factory.c63
-rw-r--r--mail/mail-config.c505
-rw-r--r--mail/mail-config.glade7392
-rw-r--r--mail/mail-config.h45
-rw-r--r--mail/mail-crypto.c53
-rw-r--r--mail/mail-crypto.h33
-rw-r--r--mail/mail-folder-cache.c91
-rw-r--r--mail/mail-mt.c85
-rw-r--r--mail/mail-ops.c46
-rw-r--r--mail/mail-ops.h3
-rw-r--r--mail/mail-send-recv.c81
-rw-r--r--mail/mail-send-recv.h8
-rw-r--r--mail/mail-session.c37
-rw-r--r--mail/mail-session.h8
-rw-r--r--mail/mail-signature-editor.c498
-rw-r--r--mail/mail-signature-editor.h72
-rw-r--r--mail/mail-tools.c6
-rw-r--r--mail/mail-types.h34
-rw-r--r--mail/mail-vfolder.c136
-rw-r--r--mail/mail-vfolder.h3
-rw-r--r--mail/message-list.c257
-rw-r--r--mail/message-list.h14
-rw-r--r--mail/message-tag-followup.c5
-rw-r--r--mail/searchtypes.xml36
-rw-r--r--mail/vfoldertypes.xml2
120 files changed, 19887 insertions, 25291 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am
index f8277aa9e0..5f8372f691 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = default importers
+SUBDIRS = . default importers
mailincludedir = $(privincludedir)/mail
@@ -6,6 +6,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/widgets \
-I$(top_srcdir)/widgets/misc \
-I$(top_srcdir) \
+ -I$(top_srcdir)/em-format \
-I$(top_srcdir)/mail \
-I$(top_srcdir)/composer \
-I$(top_builddir)/composer \
@@ -30,257 +31,149 @@ AM_CPPFLAGS = \
-DPREFIX=\""$(prefix)"\" \
-DG_LOG_DOMAIN=\"evolution-mail\"
-privsolib_LTLIBRARIES = libevolution-mail-shared.la
-component_LTLIBRARIES = libevolution-mail.la
-
-# Mail.idl
-MAIL_IDL = Evolution-Mail.idl
-MAIL_IDL_GENERATED_H = \
- Evolution-Mail.h
-MAIL_IDL_GENERATED_C = \
- Evolution-Mail-common.c \
- Evolution-Mail-skels.c \
- Evolution-Mail-stubs.c
-MAIL_IDL_GENERATED = $(MAIL_IDL_GENERATED_C) $(MAIL_IDL_GENERATED_H)
-
-$(MAIL_IDL_GENERATED_H): $(MAIL_IDL)
- $(ORBIT_IDL) -I $(top_srcdir) -I $(datadir)/idl $(IDL_INCLUDES) $^
-$(MAIL_IDL_GENERATED_C): $(MAIL_IDL_GENERATED_H)
-
-# IDL install
-
-idl_DATA = $(MAIL_IDL)
-
-# plugin mail api
-mailinclude_HEADERS = \
- $(MAIL_IDL_GENERATED_H) \
- e-mail-attachment-bar.h \
- e-searching-tokenizer.h \
- em-account-editor.h \
- e-mail-search-bar.h \
- em-composer-utils.h \
- em-config.h \
- em-event.h \
- em-filter-context.h \
- em-filter-editor.h \
- em-filter-folder-element.h \
- em-filter-rule.h \
- em-filter-source-element.h \
- em-folder-browser.h \
- em-folder-tree-model.h \
- em-folder-tree.h \
- em-folder-utils.h \
- em-folder-view.h \
- em-format-hook.h \
- em-format-html-display.h \
- em-format-html-print.h \
- em-format-html.h \
- em-format-quote.h \
- em-format.h \
- em-html-stream.h \
- em-icon-stream.h \
- em-inline-filter.h \
- em-junk-hook.h \
- em-menu.h \
- em-message-browser.h \
- em-popup.h \
- em-search-context.h \
- em-stripsig-filter.h \
- em-sync-stream.h \
- em-utils.h \
- mail-autofilter.h \
- mail-component.h \
- mail-config.h \
- mail-folder-cache.h \
- mail-mt.h \
- mail-ops.h \
- mail-send-recv.h \
- mail-session.h \
- mail-tools.h \
- message-list.h \
- mail-vfolder.h
+privsolib_LTLIBRARIES = libevolution-mail.la
+
+mailinclude_HEADERS = \
+ e-mail-attachment-bar.h \
+ e-mail-browser.h \
+ e-mail-display.h \
+ e-mail-label-dialog.h \
+ e-mail-label-list-store.h \
+ e-mail-label-manager.h \
+ e-mail-label-tree-view.h \
+ e-mail-local.h \
+ e-mail-reader.h \
+ e-mail-reader-utils.h \
+ e-mail-search-bar.h \
+ e-mail-store.h \
+ e-searching-tokenizer.h \
+ em-account-editor.h \
+ em-composer-utils.h \
+ em-config.h \
+ em-event.h \
+ em-filter-context.h \
+ em-filter-editor.h \
+ em-filter-folder-element.h \
+ em-filter-rule.h \
+ em-filter-source-element.h \
+ em-folder-properties.h \
+ em-folder-selection.h \
+ em-folder-selector.h \
+ em-folder-selection-button.h \
+ em-folder-tree.h \
+ em-folder-tree-model.h \
+ em-folder-utils.h \
+ em-format-hook.h \
+ em-format-html.h \
+ em-format-html-display.h \
+ em-format-html-print.h \
+ em-html-stream.h \
+ em-icon-stream.h \
+ em-inline-filter.h \
+ em-junk-hook.h \
+ em-menu.h \
+ em-popup.h \
+ em-search-context.h \
+ em-subscribe-editor.h \
+ em-sync-stream.h \
+ em-utils.h \
+ em-vfolder-context.h \
+ em-vfolder-editor.h \
+ em-vfolder-rule.h \
+ mail-autofilter.h \
+ mail-config.h \
+ mail-folder-cache.h \
+ mail-mt.h \
+ mail-ops.h \
+ mail-send-recv.h \
+ mail-session.h \
+ mail-tools.h \
+ mail-vfolder.h \
+ message-list.h \
+ message-tag-editor.h \
+ message-tag-followup.h
-# libevolution-mail
+libevolution_mail_la_SOURCES = \
+ e-mail-attachment-bar.c \
+ e-mail-browser.c \
+ e-mail-display.c \
+ e-mail-label-dialog.c \
+ e-mail-label-list-store.c \
+ e-mail-label-manager.c \
+ e-mail-label-tree-view.c \
+ e-mail-local.c \
+ e-mail-reader.c \
+ e-mail-reader-utils.c \
+ e-mail-search-bar.c \
+ e-mail-store.c \
+ e-searching-tokenizer.c \
+ em-account-editor.c \
+ em-composer-utils.c \
+ em-config.c \
+ em-event.c \
+ em-filter-context.c \
+ em-filter-editor.c \
+ em-filter-folder-element.c \
+ em-filter-rule.c \
+ em-filter-source-element.c \
+ em-folder-properties.c \
+ em-folder-selection.c \
+ em-folder-selector.c \
+ em-folder-selection-button.c \
+ em-folder-tree.c \
+ em-folder-tree-model.c \
+ em-folder-utils.c \
+ em-format-hook.c \
+ em-format-html.c \
+ em-format-html-display.c \
+ em-format-html-print.c \
+ em-html-stream.c \
+ em-icon-stream.c \
+ em-inline-filter.c \
+ em-junk-hook.c \
+ em-menu.c \
+ em-popup.c \
+ em-search-context.c \
+ em-subscribe-editor.c \
+ em-sync-stream.c \
+ em-utils.c \
+ em-vfolder-context.c \
+ em-vfolder-editor.c \
+ em-vfolder-rule.c \
+ mail-autofilter.c \
+ mail-config.c \
+ mail-folder-cache.c \
+ mail-mt.c \
+ mail-ops.c \
+ mail-send-recv.c \
+ mail-session.c \
+ mail-tools.c \
+ mail-vfolder.c \
+ message-list.c \
+ message-tag-editor.c \
+ message-tag-followup.c
-libevolution_mail_la_SOURCES = \
- $(MAIL_IDL_GENERATED) \
- $(mailinclude_HEADERS) \
- e-searching-tokenizer.c \
- em-account-prefs.c \
- em-account-prefs.h \
- em-composer-prefs.c \
- em-composer-prefs.h \
- em-folder-browser.c \
- em-folder-view.c \
- em-format-hook.c \
- em-format-html-display.c \
- em-format-html-print.c \
- em-format-html.c \
- em-html-stream.c \
- em-junk-hook.c \
- em-mailer-prefs.c \
- em-mailer-prefs.h \
- em-menu.c \
- em-message-browser.c \
- em-migrate.c \
- em-migrate.h \
- em-network-prefs.c \
- em-network-prefs.h \
- em-subscribe-editor.c \
- em-subscribe-editor.h \
- mail-component-factory.c \
- mail-component.c \
- mail-config-factory.c \
- mail-config-factory.h \
- mail-signature-editor.c \
- mail-signature-editor.h \
- mail-types.h \
- message-list.c
if ENABLE_SMIME
-SMIME_LIBS = \
+SMIME_LIBS = \
$(top_builddir)/smime/lib/libessmime.la \
$(top_builddir)/smime/gui/libevolution-smime.la
endif
-libevolution_mail_la_LIBADD = \
- $(top_builddir)/mail/libevolution-mail-shared.la \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/shell/libeshell.la \
- $(top_builddir)/widgets/table/libetable.la \
- $(top_builddir)/widgets/text/libetext.la \
- $(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/widgets/misc/libefilterbar.la \
- $(top_builddir)/filter/libfilter.la \
- $(top_builddir)/widgets/menus/libmenus.la \
- $(top_builddir)/addressbook/util/libeabutil.la \
+libevolution_mail_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/shell/libeshell.la \
+ $(top_builddir)/composer/libcomposer.la \
+ $(top_builddir)/widgets/table/libetable.la \
+ $(top_builddir)/widgets/text/libetext.la \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
$(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
$(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
- $(top_builddir)/mail/importers/libevolution-mail-importers.la \
- $(SMIME_LIBS) \
- $(EVOLUTION_MAIL_LIBS) \
- $(GTKHTML_LIBS) \
- $(REGEX_LIBS) \
- $(THREADS_LIBS)
-
-libevolution_mail_la_LDFLAGS = \
- -avoid-version -module $(NO_UNDEFINED)
-
-libevolution_mail_la_DEPENDENCIES = \
- em-filter-i18n.h \
- libevolution-mail-shared.la
-
-libevolution_mail_shared_la_SOURCES = \
- e-attachment-handler-mail.c \
- e-attachment-handler-mail.h \
- e-mail-attachment-bar.c \
- e-mail-search-bar.c \
- em-account-editor.c \
- em-account-editor.h \
- em-event.c \
- em-config.c \
- em-composer-utils.c \
- em-composer-utils.h \
- em-filter-context.c \
- em-filter-context.h \
- em-filter-editor.c \
- em-filter-editor.h \
- em-filter-folder-element.c \
- em-filter-folder-element.h \
- em-filter-rule.c \
- em-filter-rule.h \
- em-filter-source-element.c \
- em-filter-source-element.h \
- em-folder-tree-model.c \
- em-folder-tree.c \
- em-folder-properties.c \
- em-folder-properties.h \
- em-folder-selection-button.c \
- em-folder-selection-button.h \
- em-folder-selection.c \
- em-folder-selection.h \
- em-folder-selector.c \
- em-folder-selector.h \
- em-folder-utils.c \
- em-format-quote.c \
- em-format.c \
- em-icon-stream.c \
- em-inline-filter.c \
- em-popup.c \
- em-search-context.c \
- em-search-context.h \
- em-stripsig-filter.c \
- em-sync-stream.c \
- em-utils.c \
- em-vfolder-context.c \
- em-vfolder-context.h \
- em-vfolder-editor.c \
- em-vfolder-editor.h \
- em-vfolder-rule.c \
- em-vfolder-rule.h \
- mail-autofilter.c \
- mail-config.c \
- mail-crypto.c \
- mail-crypto.h \
- mail-folder-cache.c \
- mail-folder-cache.h \
- mail-ops.c \
- mail-mt.c \
- mail-send-recv.c \
- mail-send-recv.h \
- mail-session.c \
- mail-tools.c \
- mail-vfolder.c \
- message-tag-editor.c \
- message-tag-editor.h \
- message-tag-followup.c \
- message-tag-followup.h
-
-if OS_WIN32
-LIBEVOMAIL=$(top_builddir)/win32/libevolution-mail.la
-endif
-
-libevolution_mail_shared_la_LIBADD = \
- $(LIBEVOMAIL) \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/composer/libcomposer.la \
- $(top_builddir)/filter/libfilter.la \
- $(top_builddir)/widgets/menus/libmenus.la \
- $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
- $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
- $(SMIME_LIBS) \
- $(EVOLUTION_MAIL_LIBS) \
- $(THREADS_LIBS)
-
-libevolution_mail_shared_la_LDFLAGS = $(NO_UNDEFINED)
-
-# --- BIG NASTY AUTOMAKE HACK ---
-#
-# Automake apparently sorts Makefile.am rules alphabetically. And
-# since component_LTLIBRARIES < privsolib_LTLIBRARIES, it tries to
-# install libevolution-mail.la before libevolution-mail-shared.la,
-# which fails when libtool tries to relink libevolution-mail.la
-# against the not-yet-installed libevolution-mail-shared.la.
-install-data-am: \
- install-privsolibLTLIBRARIES \
- install-componentLTLIBRARIES \
- install-data-local \
- install-errorDATA \
- install-etspecDATA \
- install-filterDATA \
- install-gladeDATA \
- install-idlDATA \
- install-mailincludeHEADERS \
- install-schemaDATA \
- install-serverDATA
-
-# .server files
+ $(GTKHTML_LIBS) \
+ $(SMIME_LIBS)
-server_in_files = GNOME_Evolution_Mail.server.in.in
-server_DATA = $(server_in_files:.server.in.in=.server)
+libevolution_mail_la_LDFLAGS = $(NO_UNDEFINED)
-@EVO_SERVER_RULE@
-@INTLTOOL_SERVER_RULE@
+libevolution_mail_la_DEPENDENCIES = em-filter-i18n.h
# Misc data to install
filterdir = $(privdatadir)
@@ -304,7 +197,6 @@ etspec_DATA = message-list.etspec
EXTRA_DIST = \
ChangeLog.pre-1-4 \
README.async \
- $(MAIL_IDL) \
mail.error.xml \
$(glade_DATA) \
$(schema_in_files) \
@@ -360,7 +252,7 @@ endif
dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)
-BUILT_SOURCES = $(MAIL_IDL_GENERATED) $(server_DATA) $(error_DATA)
+BUILT_SOURCES = $(error_DATA)
CLEANFILES = $(BUILT_SOURCES)
diff --git a/mail/e-attachment-handler-mail.c b/mail/e-attachment-handler-mail.c
deleted file mode 100644
index c17c97d8ca..0000000000
--- a/mail/e-attachment-handler-mail.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * e-attachment-handler-mail.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)
- *
- */
-
-#include "e-attachment-handler-mail.h"
-
-#include <glib/gi18n.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-stream-mem.h>
-
-#include "e-util/e-error.h"
-#include "mail/em-composer-utils.h"
-#include "mail/mail-tools.h"
-
-#define E_ATTACHMENT_HANDLER_MAIL_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMailPrivate))
-
-struct _EAttachmentHandlerMailPrivate {
- gint placeholder;
-};
-
-static gpointer parent_class;
-
-static const gchar *ui =
-"<ui>"
-" <popup name='context'>"
-" <placeholder name='custom-actions'>"
-" <menuitem action='mail-reply-sender'/>"
-" <menuitem action='mail-reply-all'/>"
-" <menuitem action='mail-forward'/>"
-" </placeholder>"
-" </popup>"
-"</ui>";
-
-/* Note: Do not use the info field. */
-static GtkTargetEntry target_table[] = {
- { (gchar *) "message/rfc822", 0, 0 },
- { (gchar *) "x-uid-list", 0, 0 }
-};
-
-static void
-attachment_handler_mail_forward (GtkAction *action,
- EAttachmentView *view)
-{
- EAttachment *attachment;
- CamelMimePart *mime_part;
- CamelDataWrapper *wrapper;
- GList *selected;
-
- selected = e_attachment_view_get_selected_attachments (view);
- g_return_if_fail (g_list_length (selected) == 1);
-
- attachment = E_ATTACHMENT (selected->data);
- mime_part = e_attachment_get_mime_part (attachment);
- wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part));
-
- em_utils_forward_message (CAMEL_MIME_MESSAGE (wrapper), NULL);
-
- g_list_foreach (selected, (GFunc) g_object_unref, NULL);
- g_list_free (selected);
-}
-
-static void
-attachment_handler_mail_reply_all (GtkAction *action,
- EAttachmentView *view)
-{
- EAttachment *attachment;
- CamelMimePart *mime_part;
- CamelDataWrapper *wrapper;
- GList *selected;
-
- selected = e_attachment_view_get_selected_attachments (view);
- g_return_if_fail (g_list_length (selected) == 1);
-
- attachment = E_ATTACHMENT (selected->data);
- mime_part = e_attachment_get_mime_part (attachment);
- wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part));
-
- em_utils_reply_to_message (
- NULL, NULL, CAMEL_MIME_MESSAGE (wrapper),
- REPLY_MODE_ALL, NULL);
-
- g_list_foreach (selected, (GFunc) g_object_unref, NULL);
- g_list_free (selected);
-}
-
-static void
-attachment_handler_mail_reply_sender (GtkAction *action,
- EAttachmentView *view)
-{
- EAttachment *attachment;
- CamelMimePart *mime_part;
- CamelDataWrapper *wrapper;
- GList *selected;
-
- selected = e_attachment_view_get_selected_attachments (view);
- g_return_if_fail (g_list_length (selected) == 1);
-
- attachment = E_ATTACHMENT (selected->data);
- mime_part = e_attachment_get_mime_part (attachment);
- wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part));
-
- em_utils_reply_to_message (
- NULL, NULL, CAMEL_MIME_MESSAGE (wrapper),
- REPLY_MODE_SENDER, NULL);
-
- g_list_foreach (selected, (GFunc) g_object_unref, NULL);
- g_list_free (selected);
-}
-
-static GtkActionEntry standard_entries[] = {
-
- { "mail-forward",
- "mail-forward",
- N_("_Forward"),
- NULL,
- NULL, /* XXX Add a tooltip! */
- G_CALLBACK (attachment_handler_mail_forward) },
-
- { "mail-reply-all",
- "mail-reply-all",
- N_("Reply to _All"),
- NULL,
- NULL, /* XXX Add a tooltip! */
- G_CALLBACK (attachment_handler_mail_reply_all) },
-
- { "mail-reply-sender",
- "mail-reply-sender",
- N_("_Reply to Sender"),
- NULL,
- NULL, /* XXX Add a tooltip! */
- G_CALLBACK (attachment_handler_mail_reply_sender) }
-};
-
-static void
-attachment_handler_mail_message_rfc822 (EAttachmentView *view,
- GdkDragContext *drag_context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint time)
-{
- static GdkAtom atom = GDK_NONE;
- EAttachmentStore *store;
- EAttachment *attachment;
- CamelMimeMessage *message;
- CamelDataWrapper *wrapper;
- CamelStream *stream;
- const gchar *data;
- gboolean success = FALSE;
- gpointer parent;
- gint length;
-
- if (G_UNLIKELY (atom == GDK_NONE))
- atom = gdk_atom_intern_static_string ("message/rfc822");
-
- if (gtk_selection_data_get_target (selection_data) != atom)
- return;
-
- g_signal_stop_emission_by_name (view, "drag-data-received");
-
- data = (const gchar *) gtk_selection_data_get_data (selection_data);
- length = gtk_selection_data_get_length (selection_data);
-
- stream = camel_stream_mem_new ();
- camel_stream_write (stream, data, length);
- camel_stream_reset (stream);
-
- message = camel_mime_message_new ();
- wrapper = CAMEL_DATA_WRAPPER (message);
-
- if (camel_data_wrapper_construct_from_stream (wrapper, stream) == -1)
- goto exit;
-
- store = e_attachment_view_get_store (view);
-
- parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
- parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
-
- attachment = e_attachment_new_for_message (message);
- e_attachment_store_add_attachment (store, attachment);
- e_attachment_load_async (
- attachment, (GAsyncReadyCallback)
- e_attachment_load_handle_error, parent);
- g_object_unref (attachment);
-
- success = TRUE;
-
-exit:
- camel_object_unref (message);
- camel_object_unref (stream);
-
- gtk_drag_finish (drag_context, success, FALSE, time);
-}
-
-static void
-attachment_handler_mail_x_uid_list (EAttachmentView *view,
- GdkDragContext *drag_context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint time)
-{
- static GdkAtom atom = GDK_NONE;
- CamelException ex = CAMEL_EXCEPTION_INITIALISER;
- CamelDataWrapper *wrapper;
- CamelMimeMessage *message;
- CamelMultipart *multipart;
- CamelMimePart *mime_part;
- CamelFolder *folder = NULL;
- EAttachment *attachment;
- EAttachmentStore *store;
- GPtrArray *uids;
- const gchar *data;
- const gchar *cp, *end;
- gchar *description;
- gpointer parent;
- gint length;
- guint ii;
-
- if (G_UNLIKELY (atom == GDK_NONE))
- atom = gdk_atom_intern_static_string ("x-uid-list");
-
- if (gtk_selection_data_get_target (selection_data) != atom)
- return;
-
- store = e_attachment_view_get_store (view);
-
- parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
- parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
-
- uids = g_ptr_array_new ();
-
- data = (const gchar *) gtk_selection_data_get_data (selection_data);
- length = gtk_selection_data_get_length (selection_data);
-
- /* The UID list is delimited by NUL characters.
- * Brilliant. So we can't use g_strsplit(). */
-
- cp = data;
- end = data + length;
-
- while (cp < end) {
- const gchar *start = cp;
-
- while (cp < end && *cp != '\0')
- cp++;
-
- /* Skip the first string. */
- if (start > data)
- g_ptr_array_add (uids, g_strndup (start, cp - start));
-
- cp++;
- }
-
- if (uids->len == 0)
- goto exit;
-
- /* The first string is the folder URI. */
- folder = mail_tool_uri_to_folder (data, 0, &ex);
- if (folder == NULL)
- goto exit;
-
- /* Handle one message. */
- if (uids->len == 1) {
- message = camel_folder_get_message (
- folder, uids->pdata[0], &ex);
- if (message == NULL)
- goto exit;
-
- attachment = e_attachment_new_for_message (message);
- e_attachment_store_add_attachment (store, attachment);
- e_attachment_load_async (
- attachment, (GAsyncReadyCallback)
- e_attachment_load_handle_error, parent);
- g_object_unref (attachment);
-
- camel_object_unref (message);
- goto exit;
- }
-
- /* Build a multipart/digest message out of the UIDs. */
-
- multipart = camel_multipart_new ();
- wrapper = CAMEL_DATA_WRAPPER (multipart);
- camel_data_wrapper_set_mime_type (wrapper, "multipart/digest");
- camel_multipart_set_boundary (multipart, NULL);
-
- for (ii = 0; ii < uids->len; ii++) {
- message = camel_folder_get_message (
- folder, uids->pdata[ii], &ex);
- if (message == NULL) {
- camel_object_unref (multipart);
- goto exit;
- }
-
- mime_part = camel_mime_part_new ();
- wrapper = CAMEL_DATA_WRAPPER (message);
- camel_mime_part_set_disposition (mime_part, "inline");
- camel_medium_set_content_object (
- CAMEL_MEDIUM (mime_part), wrapper);
- camel_mime_part_set_content_type (mime_part, "message/rfc822");
- camel_multipart_add_part (multipart, mime_part);
- camel_object_unref (mime_part);
-
- camel_object_unref (message);
- }
-
- mime_part = camel_mime_part_new ();
- wrapper = CAMEL_DATA_WRAPPER (multipart);
- camel_medium_set_content_object (CAMEL_MEDIUM (mime_part), wrapper);
-
- /* Translators: This is only for multiple messages. */
- description = g_strdup_printf (_("%d attached messages"), uids->len);
- camel_mime_part_set_description (mime_part, description);
- g_free (description);
-
- attachment = e_attachment_new ();
- e_attachment_set_mime_part (attachment, mime_part);
- e_attachment_store_add_attachment (store, attachment);
- e_attachment_load_async (
- attachment, (GAsyncReadyCallback)
- e_attachment_load_handle_error, parent);
- g_object_unref (attachment);
-
- camel_object_unref (mime_part);
- camel_object_unref (multipart);
-
-exit:
- if (camel_exception_is_set (&ex)) {
- gchar *folder_name;
-
- if (folder != NULL)
- camel_object_get (
- folder, NULL, CAMEL_FOLDER_NAME,
- &folder_name, NULL);
- else
- folder_name = g_strdup (data);
-
- e_error_run (
- parent, "mail-composer:attach-nomessages",
- folder_name, camel_exception_get_description (&ex),
- NULL);
-
- if (folder != NULL)
- camel_object_free (
- folder, CAMEL_FOLDER_NAME, folder_name);
- else
- g_free (folder_name);
-
- camel_exception_clear (&ex);
- }
-
- if (folder != NULL)
- camel_object_unref (folder);
-
- g_ptr_array_free (uids, TRUE);
-
- g_signal_stop_emission_by_name (view, "drag-data-received");
-}
-
-static void
-attachment_handler_mail_update_actions (EAttachmentView *view)
-{
- EAttachment *attachment;
- CamelMimePart *mime_part;
- CamelDataWrapper *wrapper;
- GtkActionGroup *action_group;
- GList *selected;
- gboolean visible = FALSE;
-
- selected = e_attachment_view_get_selected_attachments (view);
-
- if (g_list_length (selected) != 1)
- goto exit;
-
- attachment = E_ATTACHMENT (selected->data);
- mime_part = e_attachment_get_mime_part (attachment);
-
- if (!CAMEL_IS_MIME_PART (mime_part))
- goto exit;
-
- wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part));
-
- visible = CAMEL_IS_MIME_MESSAGE (wrapper);
-
-exit:
- action_group = e_attachment_view_get_action_group (view, "mail");
- gtk_action_group_set_visible (action_group, visible);
-
- g_list_foreach (selected, (GFunc) g_object_unref, NULL);
- g_list_free (selected);
-}
-
-static void
-attachment_handler_mail_constructed (GObject *object)
-{
- EAttachmentHandler *handler;
- EAttachmentView *view;
- GtkActionGroup *action_group;
- GtkUIManager *ui_manager;
- GError *error = NULL;
-
- handler = E_ATTACHMENT_HANDLER (object);
-
- /* Chain up to parent's constructed() method. */
- G_OBJECT_CLASS (parent_class)->constructed (object);
-
- view = e_attachment_handler_get_view (handler);
-
- action_group = e_attachment_view_add_action_group (view, "mail");
- gtk_action_group_add_actions (
- action_group, standard_entries,
- G_N_ELEMENTS (standard_entries), view);
-
- ui_manager = e_attachment_view_get_ui_manager (view);
- gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
-
- if (error != NULL) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- g_signal_connect (
- view, "update-actions",
- G_CALLBACK (attachment_handler_mail_update_actions),
- NULL);
-
- g_signal_connect (
- view, "drag-data-received",
- G_CALLBACK (attachment_handler_mail_message_rfc822),
- NULL);
-
- g_signal_connect (
- view, "drag-data-received",
- G_CALLBACK (attachment_handler_mail_x_uid_list),
- NULL);
-}
-
-static GdkDragAction
-attachment_handler_mail_get_drag_actions (EAttachmentHandler *handler)
-{
- return GDK_ACTION_COPY;
-}
-
-static const GtkTargetEntry *
-attachment_handler_mail_get_target_table (EAttachmentHandler *handler,
- guint *n_targets)
-{
- if (n_targets != NULL)
- *n_targets = G_N_ELEMENTS (target_table);
-
- return target_table;
-}
-
-static void
-attachment_handler_mail_class_init (EAttachmentHandlerMailClass *class)
-{
- GObjectClass *object_class;
- EAttachmentHandlerClass *handler_class;
-
- parent_class = g_type_class_peek_parent (class);
- g_type_class_add_private (class, sizeof (EAttachmentHandlerMailPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->constructed = attachment_handler_mail_constructed;
-
- handler_class = E_ATTACHMENT_HANDLER_CLASS (class);
- handler_class->get_drag_actions = attachment_handler_mail_get_drag_actions;
- handler_class->get_target_table = attachment_handler_mail_get_target_table;
-}
-
-static void
-attachment_handler_mail_init (EAttachmentHandlerMail *handler)
-{
- handler->priv = E_ATTACHMENT_HANDLER_MAIL_GET_PRIVATE (handler);
-}
-
-GType
-e_attachment_handler_mail_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EAttachmentHandlerMailClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) attachment_handler_mail_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EAttachmentHandlerMail),
- 0, /* n_preallocs */
- (GInstanceInitFunc) attachment_handler_mail_init,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- E_TYPE_ATTACHMENT_HANDLER,
- "EAttachmentHandlerMail", &type_info, 0);
- }
-
- return type;
-}
diff --git a/mail/e-attachment-handler-mail.h b/mail/e-attachment-handler-mail.h
deleted file mode 100644
index c62ea99cab..0000000000
--- a/mail/e-attachment-handler-mail.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * e-attachment-handler-mail.h
- *
- * 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)
- *
- */
-
-#ifndef E_ATTACHMENT_HANDLER_MAIL_H
-#define E_ATTACHMENT_HANDLER_MAIL_H
-
-#include <widgets/misc/e-attachment-handler.h>
-
-/* Standard GObject macros */
-#define E_TYPE_ATTACHMENT_HANDLER_MAIL \
- (e_attachment_handler_mail_get_type ())
-#define E_ATTACHMENT_HANDLER_MAIL(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMail))
-#define E_ATTACHMENT_HANDLER_MAIL_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMailClass))
-#define E_IS_ATTACHMENT_HANDLER_MAIL(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL))
-#define E_IS_ATTACHMENT_HANDLER_MAIL_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_ATTACHMENT_HANDLER_MAIL))
-#define E_ATTACHMENT_HANDLER_MAIL_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_MAIL, EAttachmentHandlerMailClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EAttachmentHandlerMail EAttachmentHandlerMail;
-typedef struct _EAttachmentHandlerMailClass EAttachmentHandlerMailClass;
-typedef struct _EAttachmentHandlerMailPrivate EAttachmentHandlerMailPrivate;
-
-struct _EAttachmentHandlerMail {
- EAttachmentHandler parent;
- EAttachmentHandlerMailPrivate *priv;
-};
-
-struct _EAttachmentHandlerMailClass {
- EAttachmentHandlerClass parent_class;
-};
-
-GType e_attachment_handler_mail_get_type (void);
-
-G_END_DECLS
-
-#endif /* E_ATTACHMENT_HANDLER_MAIL_H */
diff --git a/mail/e-mail-attachment-bar.c b/mail/e-mail-attachment-bar.c
index e3656e1223..fd53292610 100644
--- a/mail/e-mail-attachment-bar.c
+++ b/mail/e-mail-attachment-bar.c
@@ -98,6 +98,7 @@ mail_attachment_bar_update_status (EMailAttachmentBar *bar)
{
EAttachmentView *view;
EAttachmentStore *store;
+ GtkActivatable *activatable;
GtkExpander *expander;
GtkAction *action;
GtkLabel *label;
@@ -106,8 +107,6 @@ mail_attachment_bar_update_status (EMailAttachmentBar *bar)
gchar *display_size;
gchar *markup;
- GtkActivatable *activatable;
-
view = E_ATTACHMENT_VIEW (bar);
store = e_attachment_view_get_store (view);
expander = GTK_EXPANDER (bar->priv->expander);
diff --git a/mail/e-mail-browser.c b/mail/e-mail-browser.c
new file mode 100644
index 0000000000..1dd3fae587
--- /dev/null
+++ b/mail/e-mail-browser.c
@@ -0,0 +1,749 @@
+/*
+ * e-mail-browser.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)
+ *
+ */
+
+#include "e-mail-browser.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <camel/camel-folder.h>
+
+#include "e-util/e-util.h"
+#include "e-util/gconf-bridge.h"
+#include "shell/e-shell.h"
+
+#include "mail/e-mail-reader.h"
+#include "mail/e-mail-reader-utils.h"
+#include "mail/e-mail-search-bar.h"
+#include "mail/em-folder-tree-model.h"
+#include "mail/em-format-html-display.h"
+#include "mail/message-list.h"
+
+#define E_MAIL_BROWSER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_BROWSER, EMailBrowserPrivate))
+
+#define MAIL_BROWSER_GCONF_PREFIX "/apps/evolution/mail/mail_browser"
+
+struct _EMailBrowserPrivate {
+ GtkUIManager *ui_manager;
+ EShellBackend *shell_backend;
+ GtkActionGroup *action_group;
+ EMFormatHTMLDisplay *html_display;
+
+ GtkWidget *main_menu;
+ GtkWidget *main_toolbar;
+ GtkWidget *message_list;
+ GtkWidget *search_bar;
+ GtkWidget *statusbar;
+
+ guint show_deleted : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_SHELL_BACKEND,
+ PROP_SHOW_DELETED,
+ PROP_UI_MANAGER
+};
+
+static gpointer parent_class;
+
+/* This is too trivial to put in a file.
+ * It gets merged with the EMailReader UI. */
+static const gchar *ui =
+"<ui>"
+" <menubar name='main-menu'>"
+" <menu action='file-menu'>"
+" <placeholder name='file-actions'/>"
+" <placeholder name='print-actions'/>"
+" <separator/>"
+" <menuitem action='close'/>"
+" </menu>"
+" </menubar>"
+"</ui>";
+
+static void
+action_close_cb (GtkAction *action,
+ EMailBrowser *browser)
+{
+ e_mail_browser_close (browser);
+}
+
+static GtkActionEntry mail_browser_entries[] = {
+
+ { "close",
+ GTK_STOCK_CLOSE,
+ NULL,
+ NULL,
+ N_("Close this window"),
+ G_CALLBACK (action_close_cb) },
+
+ /*** Menus ***/
+
+ { "file-menu",
+ NULL,
+ N_("_File"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "edit-menu",
+ NULL,
+ N_("_Edit"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "view-menu",
+ NULL,
+ N_("_View"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static void
+mail_browser_menu_item_select_cb (EMailBrowser *browser,
+ GtkWidget *menu_item)
+{
+ GtkAction *action;
+ GtkStatusbar *statusbar;
+ gchar *tooltip = NULL;
+ guint context_id;
+ gpointer data;
+
+ action = g_object_get_data (G_OBJECT (menu_item), "action");
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ data = g_object_get_data (G_OBJECT (menu_item), "context-id");
+ context_id = GPOINTER_TO_UINT (data);
+
+ g_object_get (action, "tooltip", &tooltip, NULL);
+
+ if (tooltip == NULL)
+ return;
+
+ statusbar = GTK_STATUSBAR (browser->priv->statusbar);
+ gtk_statusbar_push (statusbar, context_id, tooltip);
+}
+
+static void
+mail_browser_menu_item_deselect_cb (EMailBrowser *browser,
+ GtkWidget *menu_item)
+{
+ GtkStatusbar *statusbar;
+ guint context_id;
+ gpointer data;
+
+ data = g_object_get_data (G_OBJECT (menu_item), "context-id");
+ context_id = GPOINTER_TO_UINT (data);
+
+ statusbar = GTK_STATUSBAR (browser->priv->statusbar);
+ gtk_statusbar_pop (statusbar, context_id);
+}
+
+static void
+mail_browser_connect_proxy_cb (EMailBrowser *browser,
+ GtkAction *action,
+ GtkWidget *proxy)
+{
+ GtkStatusbar *statusbar;
+ guint context_id;
+
+ if (!GTK_IS_MENU_ITEM (proxy))
+ return;
+
+ statusbar = GTK_STATUSBAR (browser->priv->statusbar);
+ context_id = gtk_statusbar_get_context_id (statusbar, G_STRFUNC);
+
+ g_object_set_data_full (
+ G_OBJECT (proxy),
+ "action", g_object_ref (action),
+ (GDestroyNotify) g_object_unref);
+
+ g_object_set_data (
+ G_OBJECT (proxy), "context-id",
+ GUINT_TO_POINTER (context_id));
+
+ g_signal_connect_swapped (
+ proxy, "select",
+ G_CALLBACK (mail_browser_menu_item_select_cb), browser);
+
+ g_signal_connect_swapped (
+ proxy, "deselect",
+ G_CALLBACK (mail_browser_menu_item_deselect_cb), browser);
+}
+
+static void
+mail_browser_message_selected_cb (EMailBrowser *browser,
+ const gchar *uid)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ CamelMessageInfo *info;
+ EMailReader *reader;
+
+ if (uid == NULL)
+ return;
+
+ reader = E_MAIL_READER (browser);
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+ info = camel_folder_get_message_info (message_list->folder, uid);
+
+ if (info == NULL)
+ return;
+
+ gtk_window_set_title (
+ GTK_WINDOW (browser),
+ camel_message_info_subject (info));
+ gtk_widget_grab_focus (
+ GTK_WIDGET (((EMFormatHTML *) html_display)->html));
+
+ camel_folder_free_message_info (message_list->folder, info);
+}
+
+static void
+mail_browser_status_message_cb (EMailBrowser *browser,
+ const gchar *status_message)
+{
+ GtkStatusbar *statusbar;
+ guint context_id;
+
+ statusbar = GTK_STATUSBAR (browser->priv->statusbar);
+ context_id = gtk_statusbar_get_context_id (statusbar, G_STRFUNC);
+
+ /* Always pop first. This prevents messages from piling up. */
+ gtk_statusbar_pop (statusbar, context_id);
+
+ if (status_message != NULL && *status_message != '\0')
+ gtk_statusbar_push (statusbar, context_id, status_message);
+}
+
+static void
+mail_browser_set_shell_backend (EMailBrowser *browser,
+ EShellBackend *shell_backend)
+{
+ g_return_if_fail (browser->priv->shell_backend == NULL);
+
+ browser->priv->shell_backend = g_object_ref (shell_backend);
+}
+
+static void
+mail_browser_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_BACKEND:
+ mail_browser_set_shell_backend (
+ E_MAIL_BROWSER (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SHOW_DELETED:
+ e_mail_browser_set_show_deleted (
+ E_MAIL_BROWSER (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_browser_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_BACKEND:
+ g_value_set_object (
+ value, e_mail_reader_get_shell_backend (
+ E_MAIL_READER (object)));
+ return;
+
+ case PROP_SHOW_DELETED:
+ g_value_set_boolean (
+ value, e_mail_browser_get_show_deleted (
+ E_MAIL_BROWSER (object)));
+ return;
+
+ case PROP_UI_MANAGER:
+ g_value_set_object (
+ value, e_mail_browser_get_ui_manager (
+ E_MAIL_BROWSER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_browser_dispose (GObject *object)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (object);
+
+ if (priv->ui_manager != NULL) {
+ g_object_unref (priv->ui_manager);
+ priv->ui_manager = NULL;
+ }
+
+ if (priv->shell_backend != NULL) {
+ g_object_unref (priv->shell_backend);
+ priv->shell_backend = NULL;
+ }
+
+ if (priv->action_group != NULL) {
+ g_object_unref (priv->action_group);
+ priv->action_group = NULL;
+ }
+
+ if (priv->html_display != NULL) {
+ g_object_unref (priv->html_display);
+ priv->html_display = NULL;
+ }
+
+ if (priv->main_menu != NULL) {
+ g_object_unref (priv->main_menu);
+ priv->main_menu = NULL;
+ }
+
+ if (priv->main_toolbar != NULL) {
+ g_object_unref (priv->main_toolbar);
+ priv->main_toolbar = NULL;
+ }
+
+ if (priv->message_list != NULL) {
+ g_object_unref (priv->message_list);
+ priv->message_list = NULL;
+ }
+
+ if (priv->search_bar != NULL) {
+ g_object_unref (priv->search_bar);
+ priv->search_bar = NULL;
+ }
+
+ if (priv->statusbar != NULL) {
+ g_object_unref (priv->statusbar);
+ priv->statusbar = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_browser_constructed (GObject *object)
+{
+ EMFormatHTMLDisplay *html_display;
+ EMailBrowserPrivate *priv;
+ EMailReader *reader;
+ EShellBackend *shell_backend;
+ EShell *shell;
+ GConfBridge *bridge;
+ GtkAccelGroup *accel_group;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ GtkWidget *container;
+ GtkWidget *widget;
+ GtkHTML *html;
+ const gchar *domain;
+ const gchar *key;
+ guint merge_id;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (object);
+
+ reader = E_MAIL_READER (object);
+ ui_manager = priv->ui_manager;
+ domain = GETTEXT_PACKAGE;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ e_shell_watch_window (shell, GTK_WINDOW (object));
+
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ /* The message list is a widget, but it is not shown in the browser.
+ * Unfortunately, the widget is inseparable from its model, and the
+ * model is all we need. */
+ priv->message_list = message_list_new (shell_backend);
+ g_object_ref_sink (priv->message_list);
+
+ g_signal_connect_swapped (
+ priv->message_list, "message-selected",
+ G_CALLBACK (mail_browser_message_selected_cb), object);
+
+ g_signal_connect_swapped (
+ html, "status-message",
+ G_CALLBACK (mail_browser_status_message_cb), object);
+
+ e_mail_reader_init (reader);
+
+ action_group = priv->action_group;
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_action_group_add_actions (
+ action_group, mail_browser_entries,
+ G_N_ELEMENTS (mail_browser_entries), object);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+
+ e_load_ui_definition (ui_manager, E_MAIL_READER_UI_DEFINITION);
+ gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, NULL);
+
+ merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+ e_mail_reader_create_charset_menu (reader, ui_manager, merge_id);
+
+ accel_group = gtk_ui_manager_get_accel_group (ui_manager);
+ gtk_window_add_accel_group (GTK_WINDOW (object), accel_group);
+
+ g_signal_connect_swapped (
+ ui_manager, "connect-proxy",
+ G_CALLBACK (mail_browser_connect_proxy_cb), object);
+
+ /* Construct window widgets. */
+
+ widget = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (object), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ /* Create the status bar before connecting proxy widgets. */
+ widget = gtk_statusbar_new ();
+ gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->statusbar = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = e_mail_search_bar_new (EM_FORMAT_HTML (html_display)->html);
+ gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->search_bar = g_object_ref (widget);
+ gtk_widget_hide (widget);
+
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (em_format_redraw), html_display);
+
+ widget = gtk_ui_manager_get_widget (ui_manager, "/main-menu");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->main_menu = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_ui_manager_get_widget (ui_manager, "/main-toolbar");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ priv->main_toolbar = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = GTK_WIDGET (EM_FORMAT_HTML (html_display)->html);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ object = G_OBJECT (reader);
+ key = "/apps/evolution/mail/display/show_deleted";
+ gconf_bridge_bind_property (bridge, key, object, "show-deleted");
+}
+
+static gboolean
+mail_browser_key_press_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ if (event->keyval == GDK_Escape) {
+ e_mail_browser_close (E_MAIL_BROWSER (widget));
+ return TRUE;
+ }
+
+ /* Chain up to parent's key_press_event() method. */
+ return GTK_WIDGET_CLASS (parent_class)->
+ key_press_event (widget, event);
+}
+
+static GtkActionGroup *
+mail_browser_get_action_group (EMailReader *reader)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
+
+ return priv->action_group;
+}
+
+static gboolean
+mail_browser_get_hide_deleted (EMailReader *reader)
+{
+ EMailBrowser *browser;
+
+ browser = E_MAIL_BROWSER (reader);
+
+ return !e_mail_browser_get_show_deleted (browser);
+}
+
+static EMFormatHTMLDisplay *
+mail_browser_get_html_display (EMailReader *reader)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
+
+ return priv->html_display;
+}
+
+static MessageList *
+mail_browser_get_message_list (EMailReader *reader)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
+
+ return MESSAGE_LIST (priv->message_list);
+}
+
+static EShellBackend *
+mail_browser_get_shell_backend (EMailReader *reader)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
+
+ return priv->shell_backend;
+}
+
+static GtkWindow *
+mail_browser_get_window (EMailReader *reader)
+{
+ return GTK_WINDOW (reader);
+}
+
+static void
+mail_browser_set_message (EMailReader *reader,
+ const gchar *uid,
+ gboolean mark_read)
+{
+ EMailReaderIface *iface;
+ MessageList *message_list;
+ CamelMessageInfo *info;
+ CamelFolder *folder;
+
+ /* Chain up to parent's set_message() method. */
+ iface = g_type_default_interface_peek (E_TYPE_MAIL_READER);
+ iface->set_message (reader, uid, mark_read);
+
+ if (uid == NULL) {
+ e_mail_browser_close (E_MAIL_BROWSER (reader));
+ return;
+ }
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ info = camel_folder_get_message_info (folder, uid);
+
+ if (info != NULL) {
+ gtk_window_set_title (
+ GTK_WINDOW (reader),
+ camel_message_info_subject (info));
+ camel_folder_free_message_info (folder, info);
+ }
+
+ if (mark_read)
+ e_mail_reader_mark_as_read (reader, uid);
+}
+
+static void
+mail_browser_show_search_bar (EMailReader *reader)
+{
+ EMailBrowserPrivate *priv;
+
+ priv = E_MAIL_BROWSER_GET_PRIVATE (reader);
+
+ gtk_widget_show (priv->search_bar);
+}
+
+static void
+mail_browser_class_init (EMailBrowserClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailBrowserPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_browser_set_property;
+ object_class->get_property = mail_browser_get_property;
+ object_class->dispose = mail_browser_dispose;
+ object_class->constructed = mail_browser_constructed;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->key_press_event = mail_browser_key_press_event;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_BACKEND,
+ g_param_spec_object (
+ "shell-backend",
+ _("Shell Module"),
+ _("The mail shell backend"),
+ E_TYPE_SHELL_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_DELETED,
+ g_param_spec_boolean (
+ "show-deleted",
+ _("Show Deleted"),
+ _("Show deleted messages"),
+ FALSE,
+ G_PARAM_READWRITE));
+}
+
+static void
+mail_browser_iface_init (EMailReaderIface *iface)
+{
+ iface->get_action_group = mail_browser_get_action_group;
+ iface->get_hide_deleted = mail_browser_get_hide_deleted;
+ iface->get_html_display = mail_browser_get_html_display;
+ iface->get_message_list = mail_browser_get_message_list;
+ iface->get_shell_backend = mail_browser_get_shell_backend;
+ iface->get_window = mail_browser_get_window;
+ iface->set_message = mail_browser_set_message;
+ iface->show_search_bar = mail_browser_show_search_bar;
+}
+
+static void
+mail_browser_init (EMailBrowser *browser)
+{
+ GConfBridge *bridge;
+ const gchar *prefix;
+
+ browser->priv = E_MAIL_BROWSER_GET_PRIVATE (browser);
+
+ browser->priv->ui_manager = gtk_ui_manager_new ();
+ browser->priv->action_group = gtk_action_group_new ("mail-browser");
+ browser->priv->html_display = em_format_html_display_new ();
+
+ bridge = gconf_bridge_get ();
+ prefix = "/apps/evolution/mail/mail_browser";
+ gconf_bridge_bind_window_size (bridge, prefix, GTK_WINDOW (browser));
+
+ gtk_window_set_title (GTK_WINDOW (browser), _("Evolution"));
+}
+
+GType
+e_mail_browser_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailBrowserClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_browser_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailBrowser),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_browser_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo iface_info = {
+ (GInterfaceInitFunc) mail_browser_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_WINDOW, "EMailBrowser", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, E_TYPE_MAIL_READER, &iface_info);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_mail_browser_new (EShellBackend *shell_backend)
+{
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_BROWSER,
+ "shell-backend", shell_backend, NULL);
+}
+
+void
+e_mail_browser_close (EMailBrowser *browser)
+{
+ g_return_if_fail (E_IS_MAIL_BROWSER (browser));
+
+ gtk_widget_destroy (GTK_WIDGET (browser));
+}
+
+gboolean
+e_mail_browser_get_show_deleted (EMailBrowser *browser)
+{
+ g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), FALSE);
+
+ return browser->priv->show_deleted;
+}
+
+void
+e_mail_browser_set_show_deleted (EMailBrowser *browser,
+ gboolean show_deleted)
+{
+ g_return_if_fail (E_IS_MAIL_BROWSER (browser));
+
+ browser->priv->show_deleted = show_deleted;
+
+ g_object_notify (G_OBJECT (browser), "show-deleted");
+}
+
+GtkUIManager *
+e_mail_browser_get_ui_manager (EMailBrowser *browser)
+{
+ g_return_val_if_fail (E_IS_MAIL_BROWSER (browser), NULL);
+
+ return browser->priv->ui_manager;
+}
diff --git a/mail/e-mail-browser.h b/mail/e-mail-browser.h
new file mode 100644
index 0000000000..f2fd4d9131
--- /dev/null
+++ b/mail/e-mail-browser.h
@@ -0,0 +1,72 @@
+/*
+ * e-mail-browser.h
+ *
+ * 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)
+ *
+ */
+
+#ifndef E_MAIL_BROWSER_H
+#define E_MAIL_BROWSER_H
+
+#include <gtk/gtk.h>
+#include <shell/e-shell-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_BROWSER \
+ (e_mail_browser_get_type ())
+#define E_MAIL_BROWSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_BROWSER, EMailBrowser))
+#define E_MAIL_BROWSER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_BROWSER, EMailBrowserClass))
+#define E_IS_MAIL_BROWSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_BROWSER))
+#define E_IS_MAIL_BROWSER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_BROWSER))
+#define E_MAIL_BROWSER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_BROWSER, EMailBrowserClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailBrowser EMailBrowser;
+typedef struct _EMailBrowserClass EMailBrowserClass;
+typedef struct _EMailBrowserPrivate EMailBrowserPrivate;
+
+struct _EMailBrowser {
+ GtkWindow parent;
+ EMailBrowserPrivate *priv;
+};
+
+struct _EMailBrowserClass {
+ GtkWindowClass parent_class;
+};
+
+GType e_mail_browser_get_type (void);
+GtkWidget * e_mail_browser_new (EShellBackend *shell_backend);
+void e_mail_browser_close (EMailBrowser *browser);
+gboolean e_mail_browser_get_show_deleted (EMailBrowser *browser);
+void e_mail_browser_set_show_deleted (EMailBrowser *browser,
+ gboolean show_deleted);
+GtkUIManager * e_mail_browser_get_ui_manager (EMailBrowser *browser);
+
+G_END_DECLS
+
+#endif /* E_MAIL_BROWSER_H */
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
new file mode 100644
index 0000000000..3719dc09f1
--- /dev/null
+++ b/mail/e-mail-display.c
@@ -0,0 +1,1072 @@
+/*
+ * e-mail-display.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)
+ *
+ */
+
+#include "e-mail-display.h"
+
+#include <config.h>
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-util.h"
+#include "e-util/e-plugin-ui.h"
+#include "mail/em-composer-utils.h"
+#include "mail/em-utils.h"
+
+#define E_MAIL_DISPLAY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_DISPLAY, EMailDisplayPrivate))
+
+struct _EMailDisplayPrivate {
+ EMFormatHTML *formatter;
+ GtkUIManager *ui_manager;
+ gchar *selected_uri;
+};
+
+enum {
+ PROP_0,
+ PROP_ANIMATE,
+ PROP_CARET_MODE,
+ PROP_FORMATTER,
+ PROP_SELECTED_URI
+};
+
+enum {
+ POPUP_EVENT,
+ STATUS_MESSAGE,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static const gchar *ui =
+"<ui>"
+" <popup name='context'>"
+" <menuitem action='http-open'/>"
+" <menuitem action='send-message'/>"
+" <menuitem action='uri-copy'/>"
+" <menuitem action='add-to-address-book'/>"
+" <menuitem action='mailto-copy'/>"
+" <menu action='search-folder-menu'>"
+" <menuitem action='search-folder-sender'/>"
+" <menuitem action='search-folder-recipient'/>"
+" </menu>"
+" </popup>"
+"</ui>";
+
+static void
+action_add_to_address_book_cb (GtkAction *action,
+ EMailDisplay *display)
+{
+ CamelURL *curl;
+ const gchar *uri;
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (display));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ /* This should work because we checked it in update_actions(). */
+ curl = camel_url_new (uri, NULL);
+ g_return_if_fail (curl != NULL);
+
+ if (curl->path != NULL && *curl->path != '\0')
+ em_utils_add_address (parent, curl->path);
+
+ camel_url_free (curl);
+}
+
+static void
+action_http_open_cb (GtkAction *action,
+ EMailDisplay *display)
+{
+ const gchar *uri;
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (display));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ e_show_uri (parent, uri);
+}
+
+static void
+action_mailto_copy_cb (GtkAction *action,
+ EMailDisplay *display)
+{
+ CamelURL *curl;
+ CamelInternetAddress *inet_addr;
+ GtkClipboard *clipboard;
+ const gchar *uri;
+ gchar *text;
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ /* This should work because we checked it in update_actions(). */
+ curl = camel_url_new (uri, NULL);
+ g_return_if_fail (curl != NULL);
+
+ inet_addr = camel_internet_address_new ();
+ camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
+ text = camel_address_encode (CAMEL_ADDRESS (inet_addr));
+ if (text == NULL || *text == '\0')
+ text = g_strdup (uri + strlen ("mailto:"));
+
+ camel_object_unref (inet_addr);
+ camel_url_free (curl);
+
+ gtk_clipboard_set_text (clipboard, text, -1);
+ gtk_clipboard_store (clipboard);
+
+ g_free (text);
+}
+
+static void
+action_send_message_cb (GtkAction *action,
+ EMailDisplay *display)
+{
+ const gchar *uri;
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ em_utils_compose_new_message_with_mailto (uri, NULL);
+}
+
+static void
+action_uri_copy_cb (GtkAction *action,
+ EMailDisplay *display)
+{
+ GtkClipboard *clipboard;
+ const gchar *uri;
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ gtk_clipboard_set_text (clipboard, uri, -1);
+ gtk_clipboard_store (clipboard);
+}
+
+static GtkActionEntry uri_entries[] = {
+
+ { "uri-copy",
+ GTK_STOCK_COPY,
+ N_("_Copy Link Location"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_uri_copy_cb) },
+};
+
+static GtkActionEntry http_entries[] = {
+
+ { "http-open",
+ "emblem-web",
+ N_("_Open Link in Browser"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_http_open_cb) },
+};
+
+static GtkActionEntry mailto_entries[] = {
+
+ { "add-to-address-book",
+ "contact-new",
+ N_("_Add to Address Book"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_add_to_address_book_cb) },
+
+ { "mailto-copy",
+ GTK_STOCK_COPY,
+ N_("_Copy Email Address"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_mailto_copy_cb) },
+
+ { "search-folder-recipient",
+ NULL,
+ N_("_To This Address"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ NULL /* Handled by EMailReader */ },
+
+ { "search-folder-sender",
+ NULL,
+ N_("_From This Address"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ NULL /* Handled by EMailReader */ },
+
+ { "send-message",
+ "mail-message-new",
+ N_("_Send New Message To..."),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_send_message_cb) },
+
+ /*** Menus ***/
+
+ { "search-folder-menu",
+ "folder-saved-search",
+ N_("Create Search _Folder"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static gboolean
+mail_display_emit_popup_event (EMailDisplay *display,
+ GdkEventButton *event,
+ const gchar *uri,
+ EMFormatPURI *puri)
+{
+ CamelMimePart *mime_part;
+ gboolean stop_handlers = FALSE;
+
+ mime_part = (puri != NULL) ? puri->part : NULL;
+
+ g_signal_emit (
+ display, signals[POPUP_EVENT], 0,
+ event, uri, mime_part, &stop_handlers);
+
+ return stop_handlers;
+}
+
+static void
+mail_display_emit_status_message (EMailDisplay *display,
+ const gchar *status_message)
+{
+ g_signal_emit (display, signals[STATUS_MESSAGE], 0, status_message);
+}
+
+static void
+mail_display_get_uri_puri (EMailDisplay *display,
+ GdkEventButton *event,
+ GtkHTML *html,
+ gchar **uri,
+ EMFormatPURI **puri)
+{
+ EMFormat *formatter;
+ gchar *text_uri;
+ gchar *image_uri;
+ gboolean is_cid;
+
+ formatter = EM_FORMAT (display->priv->formatter);
+
+ if (event != NULL) {
+ text_uri = gtk_html_get_url_at (html, event->x, event->y);
+ image_uri = gtk_html_get_image_src_at (html, event->x, event->y);
+ } else {
+ text_uri = gtk_html_get_cursor_url (html);
+ image_uri = gtk_html_get_cursor_image_src (html);
+ }
+
+ is_cid = (image_uri != NULL) &&
+ (g_ascii_strncasecmp (image_uri, "cid:", 4) == 0);
+
+ if (image_uri != NULL) {
+ if (strstr (image_uri, "://") == NULL && !is_cid) {
+ gchar *temp;
+
+ temp = g_strconcat ("file://", image_uri, NULL);
+ g_free (image_uri);
+ image_uri = temp;
+ }
+ }
+
+ if (puri != NULL) {
+ if (text_uri != NULL)
+ *puri = em_format_find_puri (formatter, text_uri);
+
+ if (*puri == NULL && image_uri != NULL)
+ *puri = em_format_find_puri (formatter, image_uri);
+ }
+
+ if (uri != NULL) {
+ *uri = NULL;
+ if (is_cid) {
+ if (text_uri != NULL)
+ *uri = g_strdup_printf (
+ "%s\n%s", text_uri, image_uri);
+ else {
+ *uri = image_uri;
+ image_uri = NULL;
+ }
+ } else {
+ *uri = text_uri;
+ text_uri = NULL;
+ }
+ }
+
+ g_free (text_uri);
+ g_free (image_uri);
+}
+
+static gboolean
+mail_display_button_press_event_cb (EMailDisplay *display,
+ GdkEventButton *event,
+ GtkHTML *html)
+{
+ EMFormatPURI *puri = NULL;
+ gboolean finished = TRUE;
+ gchar *uri = NULL;
+
+ /* The GtkHTML object may be the EMailDisplay itself
+ * or an inner iframe. */
+
+ if (event->button != 3)
+ return FALSE;
+
+ mail_display_get_uri_puri (display, event, html, &uri, &puri);
+
+ if (uri == NULL || g_str_has_prefix (uri, "##")) {
+ g_free (uri);
+ return FALSE;
+ }
+
+ finished = mail_display_emit_popup_event (display, event, uri, puri);
+
+ g_free (uri);
+
+ return finished;
+}
+
+static void
+mail_display_update_formatter_colors (EMailDisplay *display)
+{
+ EMFormatHTMLColorType type;
+ EMFormatHTML *formatter;
+ GdkColor *color;
+ GtkStyle *style;
+ gint state;
+
+ state = GTK_WIDGET_STATE (display);
+ formatter = display->priv->formatter;
+
+ style = gtk_widget_get_style (GTK_WIDGET (display));
+ if (style == NULL)
+ return;
+
+ g_object_freeze_notify (G_OBJECT (formatter));
+
+ color = &style->bg[state];
+ type = EM_FORMAT_HTML_COLOR_BODY;
+ em_format_html_set_color (formatter, type, color);
+
+ color = &style->base[GTK_STATE_NORMAL];
+ type = EM_FORMAT_HTML_COLOR_CONTENT;
+ em_format_html_set_color (formatter, type, color);
+
+ color = &style->dark[state];
+ type = EM_FORMAT_HTML_COLOR_FRAME;
+ em_format_html_set_color (formatter, type, color);
+
+ color = &style->fg[state];
+ type = EM_FORMAT_HTML_COLOR_HEADER;
+ em_format_html_set_color (formatter, type, color);
+
+ color = &style->text[state];
+ type = EM_FORMAT_HTML_COLOR_TEXT;
+ em_format_html_set_color (formatter, type, color);
+
+ g_object_thaw_notify (G_OBJECT (formatter));
+}
+
+static void
+mail_display_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ANIMATE:
+ e_mail_display_set_animate (
+ E_MAIL_DISPLAY (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_CARET_MODE:
+ e_mail_display_set_caret_mode (
+ E_MAIL_DISPLAY (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_FORMATTER:
+ e_mail_display_set_formatter (
+ E_MAIL_DISPLAY (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SELECTED_URI:
+ e_mail_display_set_selected_uri (
+ E_MAIL_DISPLAY (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_display_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ANIMATE:
+ g_value_set_boolean (
+ value, e_mail_display_get_animate (
+ E_MAIL_DISPLAY (object)));
+ return;
+
+ case PROP_CARET_MODE:
+ g_value_set_boolean (
+ value, e_mail_display_get_caret_mode (
+ E_MAIL_DISPLAY (object)));
+ return;
+
+ case PROP_FORMATTER:
+ g_value_set_object (
+ value, e_mail_display_get_formatter (
+ E_MAIL_DISPLAY (object)));
+ return;
+
+ case PROP_SELECTED_URI:
+ g_value_set_string (
+ value, e_mail_display_get_selected_uri (
+ E_MAIL_DISPLAY (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_display_dispose (GObject *object)
+{
+ EMailDisplayPrivate *priv;
+
+ priv = E_MAIL_DISPLAY_GET_PRIVATE (object);
+
+ if (priv->formatter) {
+ g_object_unref (priv->formatter);
+ priv->formatter = NULL;
+ }
+
+ if (priv->ui_manager) {
+ g_object_unref (priv->ui_manager);
+ priv->ui_manager = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_display_realize (GtkWidget *widget)
+{
+ /* Chain up to parent's realize() method. */
+ GTK_WIDGET_CLASS (parent_class)->realize (widget);
+
+ mail_display_update_formatter_colors (E_MAIL_DISPLAY (widget));
+}
+
+static void
+mail_display_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ EMailDisplayPrivate *priv;
+
+ priv = E_MAIL_DISPLAY_GET_PRIVATE (widget);
+
+ /* Chain up to parent's style_set() method. */
+ GTK_WIDGET_CLASS (parent_class)->style_set (widget, previous_style);
+
+ mail_display_update_formatter_colors (E_MAIL_DISPLAY (widget));
+ em_format_redraw (EM_FORMAT (priv->formatter));
+}
+
+static gboolean
+mail_display_button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ EMailDisplay *display = E_MAIL_DISPLAY (widget);
+ GtkHTML *html = GTK_HTML (widget);
+
+ if (mail_display_button_press_event_cb (display, event, html))
+ return TRUE;
+
+ /* Chain up to parent's button_press_event() method. */
+ return GTK_WIDGET_CLASS (parent_class)->
+ button_press_event (widget, event);
+}
+
+static gboolean
+mail_display_scroll_event (GtkWidget *widget,
+ GdkEventScroll *event)
+{
+ if (event->state & GDK_CONTROL_MASK) {
+ switch (event->direction) {
+ case GDK_SCROLL_UP:
+ gtk_html_zoom_in (GTK_HTML (widget));
+ return TRUE;
+ case GDK_SCROLL_DOWN:
+ gtk_html_zoom_out (GTK_HTML (widget));
+ return TRUE;
+ default:
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+mail_display_link_clicked (GtkHTML *html,
+ const gchar *uri)
+{
+ EMailDisplayPrivate *priv;
+
+ priv = E_MAIL_DISPLAY_GET_PRIVATE (html);
+ g_return_if_fail (priv->formatter != NULL);
+
+ if (g_str_has_prefix (uri, "##")) {
+ guint32 flags;
+
+ flags = priv->formatter->header_wrap_flags;
+
+ if (strcmp (uri, "##TO##") == 0) {
+ if (!(flags & EM_FORMAT_HTML_HEADER_TO))
+ flags |= EM_FORMAT_HTML_HEADER_TO;
+ else
+ flags &= ~EM_FORMAT_HTML_HEADER_TO;
+ } else if (strcmp (uri, "##CC##") == 0) {
+ if (!(flags & EM_FORMAT_HTML_HEADER_CC))
+ flags |= EM_FORMAT_HTML_HEADER_CC;
+ else
+ flags |= EM_FORMAT_HTML_HEADER_CC;
+ } else if (strcmp (uri, "##BCC##") == 0) {
+ if (!(flags & EM_FORMAT_HTML_HEADER_BCC))
+ flags |= EM_FORMAT_HTML_HEADER_BCC;
+ else
+ flags |= EM_FORMAT_HTML_HEADER_BCC;
+ }
+
+ priv->formatter->header_wrap_flags = flags;
+ em_format_redraw (EM_FORMAT (priv->formatter));
+
+ } else if (*uri == '#')
+ gtk_html_jump_to_anchor (html, uri + 1);
+
+ else if (g_ascii_strncasecmp (uri, "thismessage:", 12) == 0)
+ /* ignore */ ;
+
+ else if (g_ascii_strncasecmp (uri, "cid:", 4) == 0)
+ /* ignore */ ;
+
+ else {
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (html));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ e_show_uri (parent, uri);
+ }
+}
+
+static void
+mail_display_on_url (GtkHTML *html,
+ const gchar *uri)
+{
+ EMailDisplay *display;
+ CamelInternetAddress *address;
+ CamelURL *curl;
+ const gchar *format = NULL;
+ gchar *message = NULL;
+ gchar *who;
+
+ display = E_MAIL_DISPLAY (html);
+
+ if (uri == NULL || *uri == '\0')
+ goto exit;
+
+ if (g_str_has_prefix (uri, "mailto:"))
+ format = _("Click to mail %s");
+ else if (g_str_has_prefix (uri, "callto:"))
+ format = _("Click to call %s");
+ else if (g_str_has_prefix (uri, "h323:"))
+ format = _("Click to call %s");
+ else if (g_str_has_prefix (uri, "sip:"))
+ format = _("Click to call %s");
+ else if (g_str_has_prefix (uri, "##"))
+ message = g_strdup (_("Click to hide/unhide addresses"));
+ else
+ message = g_strdup_printf (_("Click to open %s"), uri);
+
+ if (format == NULL)
+ goto exit;
+
+ curl = camel_url_new (uri, NULL);
+ address = camel_internet_address_new ();
+ camel_address_decode (CAMEL_ADDRESS (address), curl->path);
+ who = camel_address_format (CAMEL_ADDRESS (address));
+ camel_object_unref (address);
+ camel_url_free (curl);
+
+ if (who == NULL)
+ who = g_strdup (strchr (uri, ':') + 1);
+
+ message = g_strdup_printf (format, who);
+
+ g_free (who);
+
+exit:
+ mail_display_emit_status_message (display, message);
+
+ g_free (message);
+}
+
+static void
+mail_display_iframe_created (GtkHTML *html,
+ GtkHTML *iframe)
+{
+ g_signal_connect_swapped (
+ iframe, "button-press-event",
+ G_CALLBACK (mail_display_button_press_event_cb), html);
+}
+
+static gboolean
+mail_display_popup_event (EMailDisplay *display,
+ GdkEventButton *event,
+ const gchar *uri,
+ EMFormatPURI *puri)
+{
+ e_mail_display_set_selected_uri (display, uri);
+ e_mail_display_show_popup_menu (display, event, NULL, NULL);
+
+ return TRUE;
+}
+
+static void
+mail_display_class_init (EMailDisplayClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkHTMLClass *html_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailDisplayPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_display_set_property;
+ object_class->get_property = mail_display_get_property;
+ object_class->dispose = mail_display_dispose;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->realize = mail_display_realize;
+ widget_class->style_set = mail_display_style_set;
+ widget_class->button_press_event = mail_display_button_press_event;
+ widget_class->scroll_event = mail_display_scroll_event;
+
+ html_class = GTK_HTML_CLASS (class);
+ html_class->link_clicked = mail_display_link_clicked;
+ html_class->on_url = mail_display_on_url;
+ html_class->iframe_created = mail_display_iframe_created;
+
+ class->popup_event = mail_display_popup_event;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ANIMATE,
+ g_param_spec_boolean (
+ "animate",
+ "Animate Images",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CARET_MODE,
+ g_param_spec_boolean (
+ "caret-mode",
+ "Caret Mode",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FORMATTER,
+ g_param_spec_object (
+ "formatter",
+ "HTML Formatter",
+ NULL,
+ EM_TYPE_FORMAT_HTML,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTED_URI,
+ g_param_spec_string (
+ "selected-uri",
+ "Selected URI",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailDisplayClass, popup_event),
+ g_signal_accumulator_true_handled, NULL,
+ e_marshal_BOOLEAN__BOXED_POINTER_POINTER,
+ G_TYPE_BOOLEAN, 3,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
+ signals[STATUS_MESSAGE] = g_signal_new (
+ "status-message",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMailDisplayClass, status_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+}
+
+static void
+mail_display_init (EMailDisplay *display)
+{
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ const gchar *id;
+ GError *error = NULL;
+
+ display->priv = E_MAIL_DISPLAY_GET_PRIVATE (display);
+
+ ui_manager = gtk_ui_manager_new ();
+ display->priv->ui_manager = ui_manager;
+
+ action_group = e_mail_display_add_action_group (display, "uri");
+
+ gtk_action_group_add_actions (
+ action_group, uri_entries,
+ G_N_ELEMENTS (uri_entries), display);
+
+ action_group = e_mail_display_add_action_group (display, "http");
+
+ gtk_action_group_add_actions (
+ action_group, http_entries,
+ G_N_ELEMENTS (http_entries), display);
+
+ action_group = e_mail_display_add_action_group (display, "mailto");
+
+ gtk_action_group_add_actions (
+ action_group, mailto_entries,
+ G_N_ELEMENTS (mailto_entries), display);
+
+ /* Because we are loading from a hard-coded string, there is
+ * no chance of I/O errors. Failure here implies a malformed
+ * UI definition. Full stop. */
+ gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
+ if (error != NULL)
+ g_error ("%s", error->message);
+
+ id = "org.gnome.evolution.mail.display";
+ e_plugin_ui_register_manager (ui_manager, id, display);
+ e_plugin_ui_enable_manager (ui_manager, id);
+}
+
+GType
+e_mail_display_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailDisplayClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_display_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailDisplay),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_display_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_HTML, "EMailDisplay", &type_info, 0);
+ }
+
+ return type;
+}
+
+gboolean
+e_mail_display_get_animate (EMailDisplay *display)
+{
+ /* XXX This is just here to maintain symmetry
+ * with e_mail_display_set_animate(). */
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), FALSE);
+
+ return gtk_html_get_animate (GTK_HTML (display));
+}
+
+void
+e_mail_display_set_animate (EMailDisplay *display,
+ gboolean animate)
+{
+ /* XXX GtkHTML does not utilize GObject properties as well
+ * as it could. This just wraps gtk_html_set_animate()
+ * so we can get a "notify::animate" signal. */
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ gtk_html_set_animate (GTK_HTML (display), animate);
+
+ g_object_notify (G_OBJECT (display), "animate");
+}
+
+gboolean
+e_mail_display_get_caret_mode (EMailDisplay *display)
+{
+ /* XXX This is just here to maintain symmetry
+ * with e_mail_display_set_caret_mode(). */
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), FALSE);
+
+ return gtk_html_get_caret_mode (GTK_HTML (display));
+}
+
+void
+e_mail_display_set_caret_mode (EMailDisplay *display,
+ gboolean caret_mode)
+{
+ /* XXX GtkHTML does not utilize GObject properties as well
+ * as it could. This just wraps gtk_html_set_caret_mode()
+ * so we can get a "notify::caret-mode" signal. */
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ gtk_html_set_caret_mode (GTK_HTML (display), caret_mode);
+
+ g_object_notify (G_OBJECT (display), "caret-mode");
+}
+
+EMFormatHTML *
+e_mail_display_get_formatter (EMailDisplay *display)
+{
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ return display->priv->formatter;
+}
+
+void
+e_mail_display_set_formatter (EMailDisplay *display,
+ EMFormatHTML *formatter)
+{
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+ g_return_if_fail (EM_IS_FORMAT_HTML (formatter));
+
+ if (display->priv->formatter != NULL)
+ g_object_unref (display->priv->formatter);
+
+ display->priv->formatter = g_object_ref (formatter);
+
+ g_object_notify (G_OBJECT (display), "formatter");
+}
+
+const gchar *
+e_mail_display_get_selected_uri (EMailDisplay *display)
+{
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ return display->priv->selected_uri;
+}
+
+void
+e_mail_display_set_selected_uri (EMailDisplay *display,
+ const gchar *selected_uri)
+{
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ g_free (display->priv->selected_uri);
+ display->priv->selected_uri = g_strdup (selected_uri);
+
+ g_object_notify (G_OBJECT (display), "selected-uri");
+}
+
+GtkAction *
+e_mail_display_get_action (EMailDisplay *display,
+ const gchar *action_name)
+{
+ GtkUIManager *ui_manager;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+ g_return_val_if_fail (action_name != NULL, NULL);
+
+ ui_manager = e_mail_display_get_ui_manager (display);
+
+ return e_lookup_action (ui_manager, action_name);
+}
+
+GtkActionGroup *
+e_mail_display_add_action_group (EMailDisplay *display,
+ const gchar *group_name)
+{
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ const gchar *domain;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+
+ ui_manager = e_mail_display_get_ui_manager (display);
+ domain = GETTEXT_PACKAGE;
+
+ action_group = gtk_action_group_new (group_name);
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ return action_group;
+}
+
+GtkActionGroup *
+e_mail_display_get_action_group (EMailDisplay *display,
+ const gchar *group_name)
+{
+ GtkUIManager *ui_manager;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+
+ ui_manager = e_mail_display_get_ui_manager (display);
+
+ return e_lookup_action_group (ui_manager, group_name);
+}
+
+GtkWidget *
+e_mail_display_get_popup_menu (EMailDisplay *display)
+{
+ GtkUIManager *ui_manager;
+ GtkWidget *menu;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ ui_manager = e_mail_display_get_ui_manager (display);
+ menu = gtk_ui_manager_get_widget (ui_manager, "/context");
+ g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
+
+ return menu;
+}
+
+GtkUIManager *
+e_mail_display_get_ui_manager (EMailDisplay *display)
+{
+ EMailDisplayPrivate *priv;
+
+ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
+
+ priv = E_MAIL_DISPLAY_GET_PRIVATE (display);
+
+ return priv->ui_manager;
+}
+
+void
+e_mail_display_show_popup_menu (EMailDisplay *display,
+ GdkEventButton *event,
+ GtkMenuPositionFunc func,
+ gpointer user_data)
+{
+ GtkWidget *menu;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ e_mail_display_update_actions (display);
+
+ menu = e_mail_display_get_popup_menu (display);
+
+ if (event != NULL)
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, func,
+ user_data, event->button, event->time);
+ else
+ gtk_menu_popup (
+ GTK_MENU (menu), NULL, NULL, func,
+ user_data, 0, gtk_get_current_event_time ());
+}
+
+void
+e_mail_display_update_actions (EMailDisplay *display)
+{
+ CamelURL *curl;
+ GtkActionGroup *action_group;
+ gboolean scheme_is_http;
+ gboolean scheme_is_mailto;
+ gboolean uri_is_valid;
+ gboolean visible;
+ const gchar *uri;
+
+ g_return_if_fail (E_IS_MAIL_DISPLAY (display));
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ /* Parse the URI early so we know if the actions will work. */
+ curl = camel_url_new (uri, NULL);
+ uri_is_valid = (curl != NULL);
+ camel_url_free (curl);
+
+ scheme_is_http =
+ (g_ascii_strncasecmp (uri, "http:", 5) == 0) ||
+ (g_ascii_strncasecmp (uri, "https:", 6) == 0);
+
+ scheme_is_mailto =
+ (g_ascii_strncasecmp (uri, "mailto:", 7) == 0);
+
+ /* Allow copying the URI even if it's malformed. */
+ visible = !scheme_is_mailto;
+ action_group = e_mail_display_get_action_group (display, "uri");
+ gtk_action_group_set_visible (action_group, visible);
+
+ visible = uri_is_valid && scheme_is_http;
+ action_group = e_mail_display_get_action_group (display, "http");
+ gtk_action_group_set_visible (action_group, visible);
+
+ visible = uri_is_valid && scheme_is_mailto;
+ action_group = e_mail_display_get_action_group (display, "mailto");
+ gtk_action_group_set_visible (action_group, visible);
+}
diff --git a/mail/e-mail-display.h b/mail/e-mail-display.h
new file mode 100644
index 0000000000..9f273fb26f
--- /dev/null
+++ b/mail/e-mail-display.h
@@ -0,0 +1,99 @@
+/*
+ * e-mail-display.h
+ *
+ * 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)
+ *
+ */
+
+#ifndef E_MAIL_DISPLAY_H
+#define E_MAIL_DISPLAY_H
+
+#include <gtkhtml/gtkhtml.h>
+#include <mail/em-format-html.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_DISPLAY \
+ (e_mail_display_get_type ())
+#define E_MAIL_DISPLAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_DISPLAY, EMailDisplay))
+#define E_MAIL_DISPLAY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_DISPLAY, EMailDisplayClass))
+#define E_IS_MAIL_DISPLAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_DISPLAY))
+#define E_IS_MAIL_DISPLAY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_DISPLAY))
+#define E_MAIL_DISPLAY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_DISPLAY, EMailDisplayClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailDisplay EMailDisplay;
+typedef struct _EMailDisplayClass EMailDisplayClass;
+typedef struct _EMailDisplayPrivate EMailDisplayPrivate;
+
+struct _EMailDisplay {
+ GtkHTML parent;
+ EMailDisplayPrivate *priv;
+};
+
+struct _EMailDisplayClass {
+ GtkHTMLClass parent_class;
+
+ /* Signals */
+ gboolean (*popup_event) (EMailDisplay *display,
+ GdkEventButton *event,
+ const gchar *uri,
+ EMFormatPURI *puri);
+ void (*status_message) (EMailDisplay *display,
+ const gchar *status_message);
+};
+
+GType e_mail_display_get_type (void);
+gboolean e_mail_display_get_animate (EMailDisplay *display);
+void e_mail_display_set_animate (EMailDisplay *display,
+ gboolean animate);
+gboolean e_mail_display_get_caret_mode (EMailDisplay *display);
+void e_mail_display_set_caret_mode (EMailDisplay *display,
+ gboolean caret_mode);
+EMFormatHTML * e_mail_display_get_formatter (EMailDisplay *display);
+void e_mail_display_set_formatter (EMailDisplay *display,
+ EMFormatHTML *formatter);
+const gchar * e_mail_display_get_selected_uri (EMailDisplay *display);
+void e_mail_display_set_selected_uri (EMailDisplay *display,
+ const gchar *uri);
+GtkAction * e_mail_display_get_action (EMailDisplay *display,
+ const gchar *action_name);
+GtkActionGroup *e_mail_display_add_action_group (EMailDisplay *display,
+ const gchar *group_name);
+GtkActionGroup *e_mail_display_get_action_group (EMailDisplay *display,
+ const gchar *group_name);
+GtkWidget * e_mail_display_get_popup_menu (EMailDisplay *display);
+GtkUIManager * e_mail_display_get_ui_manager (EMailDisplay *display);
+void e_mail_display_show_popup_menu (EMailDisplay *display,
+ GdkEventButton *event,
+ GtkMenuPositionFunc func,
+ gpointer user_data);
+void e_mail_display_update_actions (EMailDisplay *display);
+
+G_END_DECLS
+
+#endif /* E_MAIL_DISPLAY_H */
diff --git a/mail/e-mail-label-dialog.c b/mail/e-mail-label-dialog.c
new file mode 100644
index 0000000000..bebe0e69fb
--- /dev/null
+++ b/mail/e-mail-label-dialog.c
@@ -0,0 +1,323 @@
+/*
+ * e-mail-label-dialog.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)
+ *
+ */
+
+#include "e-mail-label-dialog.h"
+
+#include <glib/gi18n.h>
+
+#define E_MAIL_LABEL_DIALOG_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_LABEL_DIALOG, EMailLabelDialogPrivate))
+
+struct _EMailLabelDialogPrivate {
+ GtkWidget *entry;
+ GtkWidget *colorsel;
+};
+
+enum {
+ PROP_0,
+ PROP_LABEL_COLOR,
+ PROP_LABEL_NAME
+};
+
+static gpointer parent_class;
+
+static void
+mail_label_dialog_entry_changed_cb (EMailLabelDialog *dialog)
+{
+ const gchar *text;
+ gboolean sensitive;
+
+ text = gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry));
+ sensitive = (text != NULL && *text != '\0');
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive);
+}
+
+static void
+mail_label_dialog_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_LABEL_COLOR:
+ e_mail_label_dialog_set_label_color (
+ E_MAIL_LABEL_DIALOG (object),
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_LABEL_NAME:
+ e_mail_label_dialog_set_label_name (
+ E_MAIL_LABEL_DIALOG (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_label_dialog_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdkColor color;
+
+ switch (property_id) {
+ case PROP_LABEL_COLOR:
+ e_mail_label_dialog_get_label_color (
+ E_MAIL_LABEL_DIALOG (object), &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_LABEL_NAME:
+ g_value_set_string (
+ value, e_mail_label_dialog_get_label_name (
+ E_MAIL_LABEL_DIALOG (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_label_dialog_dispose (GObject *object)
+{
+ EMailLabelDialogPrivate *priv;
+
+ priv = E_MAIL_LABEL_DIALOG_GET_PRIVATE (object);
+
+ if (priv->entry != NULL) {
+ g_object_unref (priv->entry);
+ priv->entry = NULL;
+ }
+
+ if (priv->colorsel != NULL) {
+ g_object_unref (priv->colorsel);
+ priv->colorsel = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_label_dialog_constructed (GObject *object)
+{
+ GtkWidget *action_area;
+ GtkWidget *content_area;
+
+ /* XXX Override GTK's style property defaults for GtkDialog.
+ * Hopefully GTK+ 3.0 will fix the broken defaults. */
+
+ action_area = gtk_dialog_get_action_area (GTK_DIALOG (object));
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (object));
+
+ gtk_box_set_spacing (GTK_BOX (content_area), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (object), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (action_area), 0);
+ gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
+}
+
+static void
+mail_label_dialog_class_init (EMailLabelDialogClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailLabelDialogPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_label_dialog_set_property;
+ object_class->get_property = mail_label_dialog_get_property;
+ object_class->dispose = mail_label_dialog_dispose;
+ object_class->constructed = mail_label_dialog_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_LABEL_COLOR,
+ g_param_spec_boxed (
+ "label-color",
+ "Label Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_LABEL_NAME,
+ g_param_spec_string (
+ "label-name",
+ "Label Name",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+}
+
+static void
+mail_label_dialog_init (EMailLabelDialog *dialog)
+{
+ GtkWidget *content_area;
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ dialog->priv = E_MAIL_LABEL_DIALOG_GET_PRIVATE (dialog);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ gtk_dialog_add_button (
+ GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+
+ gtk_dialog_add_button (
+ GTK_DIALOG (dialog),
+ GTK_STOCK_OK, GTK_RESPONSE_OK);
+
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ container = content_area;
+
+ widget = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
+ gtk_box_pack_end (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ dialog->priv->entry = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (mail_label_dialog_entry_changed_cb), dialog);
+
+ mail_label_dialog_entry_changed_cb (dialog);
+
+ widget = gtk_label_new_with_mnemonic (_("_Label name:"));
+ gtk_label_set_mnemonic_widget (
+ GTK_LABEL (widget), dialog->priv->entry);
+ gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = content_area;
+
+ widget = gtk_color_selection_new ();
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ dialog->priv->colorsel = g_object_ref (widget);
+ gtk_widget_show (widget);
+}
+
+GType
+e_mail_label_dialog_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailLabelDialogClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_label_dialog_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailLabelDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_label_dialog_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_DIALOG, "EMailLabelDialog", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_mail_label_dialog_new (GtkWindow *parent)
+{
+ return g_object_new (
+ E_TYPE_MAIL_LABEL_DIALOG,
+ "transient-for", parent, NULL);
+}
+
+const gchar *
+e_mail_label_dialog_get_label_name (EMailLabelDialog *dialog)
+{
+ GtkEntry *entry;
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_DIALOG (dialog), NULL);
+
+ entry = GTK_ENTRY (dialog->priv->entry);
+
+ return gtk_entry_get_text (entry);
+}
+
+void
+e_mail_label_dialog_set_label_name (EMailLabelDialog *dialog,
+ const gchar *label_name)
+{
+ GtkEntry *entry;
+
+ g_return_if_fail (E_IS_MAIL_LABEL_DIALOG (dialog));
+
+ entry = GTK_ENTRY (dialog->priv->entry);
+
+ gtk_entry_set_text (entry, label_name);
+
+ g_object_notify (G_OBJECT (dialog), "label-name");
+}
+
+void
+e_mail_label_dialog_get_label_color (EMailLabelDialog *dialog,
+ GdkColor *label_color)
+{
+ GtkColorSelection *colorsel;
+
+ g_return_if_fail (E_IS_MAIL_LABEL_DIALOG (dialog));
+ g_return_if_fail (label_color != NULL);
+
+ colorsel = GTK_COLOR_SELECTION (dialog->priv->colorsel);
+
+ gtk_color_selection_get_current_color (colorsel, label_color);
+}
+
+void
+e_mail_label_dialog_set_label_color (EMailLabelDialog *dialog,
+ const GdkColor *label_color)
+{
+ GtkColorSelection *colorsel;
+
+ g_return_if_fail (E_IS_MAIL_LABEL_DIALOG (dialog));
+ g_return_if_fail (label_color != NULL);
+
+ colorsel = GTK_COLOR_SELECTION (dialog->priv->colorsel);
+
+ gtk_color_selection_set_current_color (colorsel, label_color);
+
+ g_object_notify (G_OBJECT (dialog), "label-color");
+}
diff --git a/mail/e-mail-label-dialog.h b/mail/e-mail-label-dialog.h
new file mode 100644
index 0000000000..17430c3607
--- /dev/null
+++ b/mail/e-mail-label-dialog.h
@@ -0,0 +1,77 @@
+/*
+ * e-mail-label-dialog.h
+ *
+ * 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)
+ *
+ */
+
+#ifndef E_MAIL_LABEL_DIALOG_H
+#define E_MAIL_LABEL_DIALOG_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_LABEL_DIALOG \
+ (e_mail_label_dialog_get_type ())
+#define E_MAIL_LABEL_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_LABEL_DIALOG, EMailLabelDialog))
+#define E_MAIL_LABEL_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_LABEL_DIALOG, EMailLabelDialogClass))
+#define E_IS_MAIL_LABEL_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_LABEL_DIALOG))
+#define E_IS_MAIL_LABEL_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_LABEL_DIALOG))
+#define E_MAIL_LABEL_DIALOG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_LABEL_DIALOG, EMailLabelDialogClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailLabelDialog EMailLabelDialog;
+typedef struct _EMailLabelDialogClass EMailLabelDialogClass;
+typedef struct _EMailLabelDialogPrivate EMailLabelDialogPrivate;
+
+struct _EMailLabelDialog {
+ GtkDialog parent;
+ EMailLabelDialogPrivate *priv;
+};
+
+struct _EMailLabelDialogClass {
+ GtkDialogClass parent_class;
+};
+
+GType e_mail_label_dialog_get_type (void);
+GtkWidget * e_mail_label_dialog_new (GtkWindow *parent);
+const gchar * e_mail_label_dialog_get_label_name
+ (EMailLabelDialog *dialog);
+void e_mail_label_dialog_set_label_name
+ (EMailLabelDialog *dialog,
+ const gchar *label_name);
+void e_mail_label_dialog_get_label_color
+ (EMailLabelDialog *dialog,
+ GdkColor *label_color);
+void e_mail_label_dialog_set_label_color
+ (EMailLabelDialog *dialog,
+ const GdkColor *label_color);
+
+G_END_DECLS
+
+#endif /* E_MAIL_LABEL_DIALOG_H */
diff --git a/mail/e-mail-label-list-store.c b/mail/e-mail-label-list-store.c
new file mode 100644
index 0000000000..1cbe927cb6
--- /dev/null
+++ b/mail/e-mail-label-list-store.c
@@ -0,0 +1,513 @@
+/*
+ * e-mail-label-list-store.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)
+ *
+ */
+
+#include "e-mail-label-list-store.h"
+
+#include <glib/gi18n.h>
+#include <camel/camel-utf8.h>
+#include "e-util/gconf-bridge.h"
+
+#define E_MAIL_LABEL_LIST_STORE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_LABEL_LIST_STORE, EMailLabelListStorePrivate))
+
+struct _EMailLabelListStorePrivate {
+ GHashTable *tag_index;
+};
+
+static struct {
+ const gchar *label_name;
+ const gchar *label_color;
+ const gchar *label_tag;
+} label_defaults[] = {
+ { N_("I_mportant"), "#EF2929", "$Labelimportant" }, /* red */
+ { N_("_Work"), "#F57900", "$Labelwork" }, /* orange */
+ { N_("_Personal"), "#4E9A06", "$Labelpersonal" }, /* green */
+ { N_("_To Do"), "#3465A4", "$Labeltodo" }, /* blue */
+ { N_("_Later"), "#75507B", "$Labellater" } /* purple */
+};
+
+static gpointer parent_class;
+
+static gchar *
+mail_label_list_store_tag_from_name (const gchar *label_name)
+{
+ gchar *label_tag;
+ gchar *temp;
+
+ /* Thunderbird compatible */
+ temp = g_ascii_strdown (label_name, -1);
+ g_strdelimit (temp, " ()/{%*<>\\\"", '_');
+ label_tag = camel_utf8_utf7 (temp);
+ g_free (temp);
+
+ return label_tag;
+}
+
+static gchar *
+mail_label_list_store_encode_label (const gchar *label_name,
+ const gchar *label_color,
+ const gchar *label_tag)
+{
+ GString *string;
+
+ /* Encoded Form: <name> ':' <color> [ '|' <tag> ] */
+
+ string = g_string_new (label_name);
+ g_string_append_printf (string, ":%s", label_color);
+
+ if (label_tag != NULL)
+ g_string_append_printf (string, "|%s", label_tag);
+
+ return g_string_free (string, FALSE);
+}
+
+static void
+mail_label_list_store_ensure_defaults (EMailLabelListStore *store)
+{
+ gint ii;
+
+ for (ii = 0; ii < G_N_ELEMENTS (label_defaults); ii++) {
+ GtkTreeIter iter;
+ const gchar *label_name;
+ const gchar *label_color;
+ const gchar *label_tag;
+ gchar *encoded;
+
+ label_name = gettext (label_defaults[ii].label_name);
+ label_color = label_defaults[ii].label_color;
+ label_tag = label_defaults[ii].label_tag;
+
+ encoded = mail_label_list_store_encode_label (
+ label_name, label_color, label_tag);
+
+ if (e_mail_label_list_store_lookup (store, label_tag, &iter))
+ gtk_list_store_set (
+ GTK_LIST_STORE (store),
+ &iter, 0, encoded, -1);
+ else
+ gtk_list_store_insert_with_values (
+ GTK_LIST_STORE (store),
+ NULL, -1, 0, encoded, -1);
+
+ g_free (encoded);
+ }
+}
+
+static gchar *
+mail_label_list_store_get_stock_id (EMailLabelListStore *store,
+ const gchar *color_spec)
+{
+ EMailLabelListStoreClass *class;
+ GtkIconFactory *icon_factory;
+ GdkColor color;
+ gchar *stock_id;
+
+ class = E_MAIL_LABEL_LIST_STORE_GET_CLASS (store);
+ icon_factory = class->icon_factory;
+
+ if (!gdk_color_parse (color_spec, &color))
+ return NULL;
+
+ stock_id = g_strdup_printf ("evolution-label-%s", color_spec);
+
+ /* Themes need not be taken into account here.
+ * It's just a solid block of a user-chosen color. */
+ if (gtk_icon_factory_lookup (icon_factory, stock_id) == NULL) {
+ GtkIconSet *icon_set;
+ GdkPixbuf *pixbuf;
+ guint32 pixel;
+
+ pixel = ((color.red & 0xFF00) << 16) +
+ ((color.green & 0xFF00) << 8) +
+ (color.blue & 0xFF00);
+
+ pixbuf = gdk_pixbuf_new (
+ GDK_COLORSPACE_RGB, FALSE, 8, 16, 16);
+ gdk_pixbuf_fill (pixbuf, pixel);
+
+ icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
+ gtk_icon_factory_add (icon_factory, stock_id, icon_set);
+ gtk_icon_set_unref (icon_set);
+
+ g_object_unref (pixbuf);
+ }
+
+ return stock_id;
+}
+
+static void
+mail_label_list_store_finalize (GObject *object)
+{
+ EMailLabelListStorePrivate *priv;
+
+ priv = E_MAIL_LABEL_LIST_STORE_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->tag_index);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+mail_label_list_store_constructed (GObject *object)
+{
+ EMailLabelListStore *store;
+ GtkTreeModel *model;
+ GConfBridge *bridge;
+ const gchar *key;
+
+ model = GTK_TREE_MODEL (object);
+ store = E_MAIL_LABEL_LIST_STORE (object);
+
+ bridge = gconf_bridge_get ();
+ key = "/apps/evolution/mail/labels";
+ gconf_bridge_bind_string_list_store (
+ bridge, key, GTK_LIST_STORE (store));
+
+ mail_label_list_store_ensure_defaults (store);
+}
+
+static void
+mail_label_list_store_row_inserted (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter)
+{
+ EMailLabelListStore *store;
+ GtkTreeRowReference *reference;
+ GHashTable *tag_index;
+ gchar *tag;
+
+ store = E_MAIL_LABEL_LIST_STORE (model);
+
+ /* Hash table takes ownership of both tag and reference. */
+ tag_index = store->priv->tag_index;
+ tag = e_mail_label_list_store_get_tag (store, iter);
+ reference = gtk_tree_row_reference_new (model, path);
+ g_hash_table_insert (tag_index, tag, reference);
+
+ /* We don't need to do anything special for row deletion.
+ * The reference will automatically become invalid (that's
+ * why we're storing references and not iterators or paths),
+ * so garbage collection is not important. We'll do it
+ * lazily. */
+}
+
+static void
+mail_label_list_store_class_init (EMailLabelListStoreClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailLabelListStorePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = mail_label_list_store_finalize;
+ object_class->constructed = mail_label_list_store_constructed;
+
+ class->icon_factory = gtk_icon_factory_new ();
+ gtk_icon_factory_add_default (class->icon_factory);
+}
+
+static void
+mail_label_list_store_init (EMailLabelListStore *store)
+{
+ GHashTable *tag_index;
+ GType type = G_TYPE_STRING;
+
+ tag_index = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) gtk_tree_row_reference_free);
+
+ store->priv = E_MAIL_LABEL_LIST_STORE_GET_PRIVATE (store);
+ store->priv->tag_index = tag_index;
+
+ /* XXX While it may seem awkward to cram the label name and color
+ * into a single string column, we do it for the benefit of
+ * letting GConfBridge keep the model in sync with GConf.
+ *
+ * XXX There's a valid argument to be made that this information
+ * doesn't belong in GConf in the first place. A key file
+ * under $(user_data_dir)/mail would work better. */
+ gtk_list_store_set_column_types (GTK_LIST_STORE (store), 1, &type);
+}
+
+static void
+mail_label_list_store_iface_init (GtkTreeModelIface *iface)
+{
+ iface->row_inserted = mail_label_list_store_row_inserted;
+}
+
+GType
+e_mail_label_list_store_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailLabelListStoreClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_label_list_store_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailLabelListStore),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_label_list_store_init,
+ NULL /* vaule_table */
+ };
+
+ static const GInterfaceInfo iface_info = {
+ (GInterfaceInitFunc) mail_label_list_store_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_LIST_STORE, "EMailLabelListStore",
+ &type_info, 0);
+
+ g_type_add_interface_static (
+ type, GTK_TYPE_TREE_MODEL, &iface_info);
+ }
+
+ return type;
+}
+
+EMailLabelListStore *
+e_mail_label_list_store_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_LABEL_LIST_STORE, NULL);
+}
+
+gchar *
+e_mail_label_list_store_get_name (EMailLabelListStore *store,
+ GtkTreeIter *iter)
+{
+ gchar *encoded;
+ gchar *result;
+ gchar **strv;
+
+ /* Encoded Form: <name> ':' <color> [ '|' <tag> ] */
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), NULL);
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (store), iter, 0, &encoded, -1);
+
+ strv = g_strsplit_set (encoded, ":|", 3);
+
+ if (g_strv_length (strv) >= 2)
+ result = g_strdup (gettext (strv[0]));
+ else
+ result = NULL;
+
+ g_strfreev (strv);
+
+ return result;
+}
+
+gboolean
+e_mail_label_list_store_get_color (EMailLabelListStore *store,
+ GtkTreeIter *iter,
+ GdkColor *color)
+{
+ gchar *encoded;
+ gchar **strv;
+ gboolean valid;
+
+ /* Encoded Form: <name> ':' <color> [ '|' <tag> ] */
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+ g_return_val_if_fail (color != NULL, FALSE);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (store), iter, 0, &encoded, -1);
+
+ strv = g_strsplit_set (encoded, ":|", 3);
+
+ if (g_strv_length (strv) >= 2)
+ valid = gdk_color_parse (strv[1], color);
+ else
+ valid = FALSE;
+
+ g_strfreev (strv);
+
+ return valid;
+}
+
+gchar *
+e_mail_label_list_store_get_stock_id (EMailLabelListStore *store,
+ GtkTreeIter *iter)
+{
+ gchar *encoded;
+ gchar *result;
+ gchar **strv;
+
+ /* Encoded Form: <name> ':' <color> [ '|' <tag> ] */
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), NULL);
+ g_return_val_if_fail (iter != NULL, NULL);
+ gtk_tree_model_get (GTK_TREE_MODEL (store), iter, 0, &encoded, -1);
+
+ strv = g_strsplit_set (encoded, ":|", 3);
+
+ if (g_strv_length (strv) >= 2)
+ result = mail_label_list_store_get_stock_id (store, strv[1]);
+ else
+ result = NULL;
+
+ g_strfreev (strv);
+
+ return result;
+}
+
+gchar *
+e_mail_label_list_store_get_tag (EMailLabelListStore *store,
+ GtkTreeIter *iter)
+{
+ gchar *encoded;
+ gchar *result;
+ gchar **strv;
+
+ /* Encoded Form: <name> ':' <color> [ '|' <tag> ] */
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), NULL);
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ gtk_tree_model_get (GTK_TREE_MODEL (store), iter, 0, &encoded, -1);
+
+ strv = g_strsplit_set (encoded, ":|", 3);
+
+ /* XXX I guess for historical reasons the default label tags have
+ * a "$Label" prefix, but the default list in GConf doesn't
+ * include tags. That's why the <tag> part is optional.
+ * So if we're missing the <tag> part, look it up in the
+ * hard-coded default list above.
+ *
+ * Not sure I got my facts straight here. Double check. */
+ if (g_strv_length (strv) >= 3)
+ result = g_strdup (strv[2]);
+ else {
+ gint ii;
+
+ result = NULL;
+
+ for (ii = 0; ii < G_N_ELEMENTS (label_defaults); ii++) {
+ const gchar *label_name;
+ const gchar *label_tag;
+
+ label_name = label_defaults[ii].label_name;
+ label_tag = label_defaults[ii].label_tag;
+
+ if (strcmp (strv[0], label_name) == 0) {
+ result = g_strdup (label_tag);
+ break;
+ }
+ }
+ }
+
+ g_strfreev (strv);
+
+ return result;
+}
+
+void
+e_mail_label_list_store_set (EMailLabelListStore *store,
+ GtkTreeIter *iter,
+ const gchar *name,
+ const GdkColor *color)
+{
+ gchar *encoded;
+ gchar *label_color;
+ gchar *label_tag = NULL;
+
+ g_return_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store));
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (color != NULL);
+
+ label_color = gdk_color_to_string (color);
+
+ if (iter != NULL)
+ label_tag = e_mail_label_list_store_get_tag (store, iter);
+ if (label_tag == NULL)
+ label_tag = mail_label_list_store_tag_from_name (name);
+
+ encoded = mail_label_list_store_encode_label (
+ name, label_color, label_tag);
+
+ /* We use gtk_list_store_insert_with_values() so the data is
+ * in place when the 'row-inserted' signal is emitted and our
+ * row_inserted() method executes. */
+ if (iter != NULL)
+ gtk_list_store_set (
+ GTK_LIST_STORE (store), iter, 0, encoded, -1);
+ else
+ gtk_list_store_insert_with_values (
+ GTK_LIST_STORE (store), NULL, -1, 0, encoded, -1);
+
+ g_free (label_color);
+ g_free (label_tag);
+ g_free (encoded);
+}
+
+gboolean
+e_mail_label_list_store_lookup (EMailLabelListStore *store,
+ const gchar *tag,
+ GtkTreeIter *iter)
+{
+ GtkTreeRowReference *reference;
+ GHashTable *tag_index;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_LIST_STORE (store), FALSE);
+ g_return_val_if_fail (tag != NULL, FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ tag_index = store->priv->tag_index;
+ reference = g_hash_table_lookup (tag_index, tag);
+
+ if (reference == NULL)
+ return FALSE;
+
+ if (!gtk_tree_row_reference_valid (reference)) {
+ /* Garbage collect the dead reference. */
+ g_hash_table_remove (tag_index, tag);
+ return FALSE;
+ }
+
+ model = gtk_tree_row_reference_get_model (reference);
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (model, iter, path);
+ gtk_tree_path_free (path);
+
+ return TRUE;
+}
+
+gboolean
+e_mail_label_tag_is_default (const gchar *tag)
+{
+ g_return_val_if_fail (tag != NULL, FALSE);
+
+ return g_str_has_prefix (tag, "$Label");
+}
diff --git a/mail/e-mail-label-list-store.h b/mail/e-mail-label-list-store.h
new file mode 100644
index 0000000000..a9093eaa08
--- /dev/null
+++ b/mail/e-mail-label-list-store.h
@@ -0,0 +1,85 @@
+/*
+ * e-mail-label-list-store.h
+ *
+ * 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)
+ *
+ */
+
+#ifndef E_MAIL_LABEL_LIST_STORE_H
+#define E_MAIL_LABEL_LIST_STORE_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_LABEL_LIST_STORE \
+ (e_mail_label_list_store_get_type ())
+#define E_MAIL_LABEL_LIST_STORE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_LABEL_LIST_STORE, EMailLabelListStore))
+#define E_MAIL_LABEL_LIST_STORE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_LABEL_LIST_STORE, EMailLabelListStoreClass))
+#define E_IS_MAIL_LABEL_LIST_STORE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_LABEL_LIST_STORE))
+#define E_IS_MAIL_LABEL_LIST_STORE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_LABEL_LIST_STORE))
+#define E_MAIL_LABEL_LIST_STORE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_LABEL_LIST_STORE, EMailLabelListStoreClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailLabelListStore EMailLabelListStore;
+typedef struct _EMailLabelListStoreClass EMailLabelListStoreClass;
+typedef struct _EMailLabelListStorePrivate EMailLabelListStorePrivate;
+
+struct _EMailLabelListStore {
+ GtkListStore parent;
+ EMailLabelListStorePrivate *priv;
+};
+
+struct _EMailLabelListStoreClass {
+ GtkListStoreClass parent_class;
+ GtkIconFactory *icon_factory;
+};
+
+GType e_mail_label_list_store_get_type (void);
+EMailLabelListStore *
+ e_mail_label_list_store_new (void);
+gchar * e_mail_label_list_store_get_name (EMailLabelListStore *store,
+ GtkTreeIter *iter);
+gboolean e_mail_label_list_store_get_color (EMailLabelListStore *store,
+ GtkTreeIter *iter,
+ GdkColor *color);
+gchar * e_mail_label_list_store_get_stock_id (EMailLabelListStore *store,
+ GtkTreeIter *iter);
+gchar * e_mail_label_list_store_get_tag (EMailLabelListStore *store,
+ GtkTreeIter *iter);
+void e_mail_label_list_store_set (EMailLabelListStore *store,
+ GtkTreeIter *iter,
+ const gchar *name,
+ const GdkColor *color);
+gboolean e_mail_label_list_store_lookup (EMailLabelListStore *store,
+ const gchar *tag,
+ GtkTreeIter *iter);
+gboolean e_mail_label_tag_is_default (const gchar *tag);
+
+G_END_DECLS
+
+#endif /* E_MAIL_LABEL_LIST_STORE_H */
diff --git a/mail/e-mail-label-manager.c b/mail/e-mail-label-manager.c
new file mode 100644
index 0000000000..212a0507ad
--- /dev/null
+++ b/mail/e-mail-label-manager.c
@@ -0,0 +1,479 @@
+/*
+ * e-mail-label-manager.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)
+ *
+ */
+
+#include "e-mail-label-manager.h"
+
+#include <glib/gi18n.h>
+#include "e-mail-label-dialog.h"
+#include "e-mail-label-tree-view.h"
+
+#define E_MAIL_LABEL_MANAGER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_LABEL_MANAGER, EMailLabelManagerPrivate))
+
+struct _EMailLabelManagerPrivate {
+ GtkWidget *tree_view;
+ GtkWidget *add_button;
+ GtkWidget *edit_button;
+ GtkWidget *remove_button;
+};
+
+enum {
+ PROP_0,
+ PROP_LIST_STORE
+};
+
+enum {
+ ADD_LABEL,
+ EDIT_LABEL,
+ REMOVE_LABEL,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+mail_label_manager_selection_changed_cb (EMailLabelManager *manager,
+ GtkTreeSelection *selection)
+{
+ GtkWidget *edit_button;
+ GtkWidget *remove_button;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ edit_button = manager->priv->edit_button;
+ remove_button = manager->priv->remove_button;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ EMailLabelListStore *store;
+ gboolean sensitive;
+ gchar *label_tag;
+
+ store = E_MAIL_LABEL_LIST_STORE (model);
+ label_tag = e_mail_label_list_store_get_tag (store, &iter);
+ sensitive = !e_mail_label_tag_is_default (label_tag);
+ g_free (label_tag);
+
+ /* Disallow removing default labels. */
+ gtk_widget_set_sensitive (edit_button, TRUE);
+ gtk_widget_set_sensitive (remove_button, sensitive);
+ } else {
+ gtk_widget_set_sensitive (edit_button, FALSE);
+ gtk_widget_set_sensitive (remove_button, FALSE);
+ }
+}
+
+static void
+mail_label_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_LIST_STORE:
+ e_mail_label_manager_set_list_store (
+ E_MAIL_LABEL_MANAGER (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_label_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_LIST_STORE:
+ g_value_set_object (
+ value, e_mail_label_manager_get_list_store (
+ E_MAIL_LABEL_MANAGER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_label_manager_dispose (GObject *object)
+{
+ EMailLabelManagerPrivate *priv;
+
+ priv = E_MAIL_LABEL_MANAGER_GET_PRIVATE (object);
+
+ if (priv->tree_view != NULL) {
+ g_object_unref (priv->tree_view);
+ priv->tree_view = NULL;
+ }
+
+ if (priv->add_button != NULL) {
+ g_object_unref (priv->add_button);
+ priv->add_button = NULL;
+ }
+
+ if (priv->edit_button != NULL) {
+ g_object_unref (priv->edit_button);
+ priv->edit_button = NULL;
+ }
+
+ if (priv->remove_button != NULL) {
+ g_object_unref (priv->remove_button);
+ priv->remove_button = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_label_manager_add_label (EMailLabelManager *manager)
+{
+ EMailLabelDialog *label_dialog;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkWidget *dialog;
+ gpointer parent;
+ GdkColor label_color;
+ const gchar *label_name;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+ dialog = e_mail_label_dialog_new (parent);
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Add Label"));
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ label_dialog = E_MAIL_LABEL_DIALOG (dialog);
+ label_name = e_mail_label_dialog_get_label_name (label_dialog);
+ e_mail_label_dialog_get_label_color (label_dialog, &label_color);
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ model = gtk_tree_view_get_model (tree_view);
+
+ e_mail_label_list_store_set (
+ E_MAIL_LABEL_LIST_STORE (model),
+ NULL, label_name, &label_color);
+
+exit:
+ gtk_widget_destroy (dialog);
+}
+
+static void
+mail_label_manager_edit_label (EMailLabelManager *manager)
+{
+ EMailLabelDialog *label_dialog;
+ EMailLabelListStore *label_store;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkWidget *dialog;
+ GtkWidget *parent;
+ GdkColor label_color;
+ const gchar *new_name;
+ gchar *label_name;
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ label_store = E_MAIL_LABEL_LIST_STORE (model);
+ label_name = e_mail_label_list_store_get_name (label_store, &iter);
+ e_mail_label_list_store_get_color (label_store, &iter, &label_color);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
+ dialog = e_mail_label_dialog_new (GTK_WINDOW (parent));
+ label_dialog = E_MAIL_LABEL_DIALOG (dialog);
+
+ e_mail_label_dialog_set_label_name (label_dialog, label_name);
+ e_mail_label_dialog_set_label_color (label_dialog, &label_color);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Label"));
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ new_name = e_mail_label_dialog_get_label_name (label_dialog);
+ e_mail_label_dialog_get_label_color (label_dialog, &label_color);
+
+ e_mail_label_list_store_set (
+ label_store, &iter, new_name, &label_color);
+
+exit:
+ gtk_widget_destroy (dialog);
+
+ g_free (label_name);
+}
+
+static void
+mail_label_manager_remove_label (EMailLabelManager *manager)
+{
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+}
+
+static void
+mail_label_manager_class_init (EMailLabelManagerClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailLabelManagerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_label_manager_set_property;
+ object_class->get_property = mail_label_manager_get_property;
+ object_class->dispose = mail_label_manager_dispose;
+
+ class->add_label = mail_label_manager_add_label;
+ class->edit_label = mail_label_manager_edit_label;
+ class->remove_label = mail_label_manager_remove_label;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_LIST_STORE,
+ g_param_spec_object (
+ "list-store",
+ "List Store",
+ NULL,
+ E_TYPE_MAIL_LABEL_LIST_STORE,
+ G_PARAM_READWRITE));
+
+ signals[ADD_LABEL] = g_signal_new (
+ "add-label",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMailLabelManagerClass, add_label),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[EDIT_LABEL] = g_signal_new (
+ "edit-label",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMailLabelManagerClass, edit_label),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[REMOVE_LABEL] = g_signal_new (
+ "remove-label",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMailLabelManagerClass, remove_label),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+mail_label_manager_init (EMailLabelManager *manager)
+{
+ GtkTreeSelection *selection;
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ manager->priv = E_MAIL_LABEL_MANAGER_GET_PRIVATE (manager);
+
+ gtk_table_resize (GTK_TABLE (manager), 2, 2);
+ gtk_table_set_col_spacings (GTK_TABLE (manager), 6);
+ gtk_table_set_row_spacings (GTK_TABLE (manager), 12);
+
+ container = GTK_WIDGET (manager);
+
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_table_attach (
+ GTK_TABLE (container), widget, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_mail_label_tree_view_new ();
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ manager->priv->tree_view = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (mail_label_manager_selection_changed_cb),
+ manager);
+
+ container = GTK_WIDGET (manager);
+
+ /* FIXME Clarify this. What menu? */
+ widget = gtk_label_new (
+ _("Note: Underscore in the label name is used\n"
+ "as mnemonic identifier in menu."));
+ gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_CENTER);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 0, 1, 1, 2, 0, 0, 0, 0);
+ gtk_widget_show (widget);
+
+ widget = gtk_vbutton_box_new ();
+ gtk_button_box_set_layout (
+ GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START);
+ gtk_box_set_spacing (GTK_BOX (widget), 6);
+ gtk_table_attach (
+ GTK_TABLE (container), widget,
+ 1, 2, 0, 2, 0, GTK_FILL, 0, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_ADD);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->add_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_mail_label_manager_add_label), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->edit_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_mail_label_manager_edit_label), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->remove_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_mail_label_manager_remove_label), manager);
+}
+
+GType
+e_mail_label_manager_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailLabelManagerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_label_manager_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailLabelManager),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_label_manager_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TABLE, "EMailLabelManager", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_mail_label_manager_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_LABEL_MANAGER, NULL);
+}
+
+void
+e_mail_label_manager_add_label (EMailLabelManager *manager)
+{
+ g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
+
+ g_signal_emit (manager, signals[ADD_LABEL], 0);
+}
+
+void
+e_mail_label_manager_edit_label (EMailLabelManager *manager)
+{
+ g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
+
+ g_signal_emit (manager, signals[EDIT_LABEL], 0);
+}
+
+void
+e_mail_label_manager_remove_label (EMailLabelManager *manager)
+{
+ g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
+
+ g_signal_emit (manager, signals[REMOVE_LABEL], 0);
+}
+
+EMailLabelListStore *
+e_mail_label_manager_get_list_store (EMailLabelManager *manager)
+{
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+
+ g_return_val_if_fail (E_IS_MAIL_LABEL_MANAGER (manager), NULL);
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ model = gtk_tree_view_get_model (tree_view);
+
+ return E_MAIL_LABEL_LIST_STORE (model);
+}
+
+void
+e_mail_label_manager_set_list_store (EMailLabelManager *manager,
+ EMailLabelListStore *list_store)
+{
+ GtkTreeView *tree_view;
+
+ g_return_if_fail (E_IS_MAIL_LABEL_MANAGER (manager));
+ g_return_if_fail (E_IS_MAIL_LABEL_LIST_STORE (list_store));
+
+ tree_view = GTK_TREE_VIEW (manager->priv->tree_view);
+ gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (list_store));
+
+ g_object_notify (G_OBJECT (manager), "list-store");
+}
diff --git a/mail/e-mail-label-manager.h b/mail/e-mail-label-manager.h
new file mode 100644
index 0000000000..20d375efc0
--- /dev/null
+++ b/mail/e-mail-label-manager.h
@@ -0,0 +1,81 @@
+/*
+ * e-mail-label-manager.h
+ *
+ * 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)
+ *
+ */
+
+#ifndef E_MAIL_LABEL_MANAGER_H
+#define E_MAIL_LABEL_MANAGER_H
+
+#include <gtk/gtk.h>
+#include <mail/e-mail-label-list-store.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_LABEL_MANAGER \
+ (e_mail_label_manager_get_type ())
+#define E_MAIL_LABEL_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_LABEL_MANAGER, EMailLabelManager))
+#define E_MAIL_LABEL_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_LABEL_MANAGER, EMailLabelManagerClass))
+#define E_IS_MAIL_LABEL_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_LABEL_MANAGER))
+#define E_IS_MAIL_LABEL_MANAGER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_LABEL_MANAGER))
+#define E_MAIL_LABEL_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_LABEL_MANAGER, EMailLabelManagerClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailLabelManager EMailLabelManager;
+typedef struct _EMailLabelManagerClass EMailLabelManagerClass;
+typedef struct _EMailLabelManagerPrivate EMailLabelManagerPrivate;
+
+struct _EMailLabelManager {
+ GtkTable parent;
+ EMailLabelManagerPrivate *priv;
+};
+
+struct _EMailLabelManagerClass {
+ GtkTableClass parent_class;
+
+ void (*add_label) (EMailLabelManager *manager);
+ void (*edit_label) (EMailLabelManager *manager);
+ void (*remove_label) (EMailLabelManager *manager);
+};
+
+GType e_mail_label_manager_get_type (void);
+GtkWidget * e_mail_label_manager_new (void);
+void e_mail_label_manager_add_label (EMailLabelManager *manager);
+void e_mail_label_manager_edit_label (EMailLabelManager *manager);
+void e_mail_label_manager_remove_label
+ (EMailLabelManager *manager);
+EMailLabelListStore *
+ e_mail_label_manager_get_list_store
+ (EMailLabelManager *manager);
+void e_mail_label_manager_set_list_store
+ (EMailLabelManager *manager,
+ EMailLabelListStore *list_store);
+
+G_END_DECLS
+
+#endif /* E_MAIL_LABEL_MANAGER_H */
diff --git a/mail/e-mail-label-tree-view.c b/mail/e-mail-label-tree-view.c
new file mode 100644
index 0000000000..808d8d060a
--- /dev/null
+++ b/mail/e-mail-label-tree-view.c
@@ -0,0 +1,136 @@
+/*
+ * e-mail-label-tree-view.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)
+ *
+ */
+
+#include "e-mail-label-tree-view.h"
+
+#include <glib/gi18n.h>
+#include "e-mail-label-list-store.h"
+
+#define E_MAIL_LABEL_TREE_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_LABEL_TREE_VIEW, EMailLabelTreeViewPrivate))
+
+struct _EMailLabelTreeViewPrivate {
+ gint placeholder;
+};
+
+static gpointer parent_class;
+
+static void
+mail_label_tree_view_render_pixbuf (GtkTreeViewColumn *column,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ EMailLabelTreeView *tree_view)
+{
+ EMailLabelListStore *store;
+ gchar *stock_id;
+
+ store = E_MAIL_LABEL_LIST_STORE (model);
+ stock_id = e_mail_label_list_store_get_stock_id (store, iter);
+ g_object_set (renderer, "stock-id", stock_id, NULL);
+ g_free (stock_id);
+}
+
+static void
+mail_label_tree_view_render_text (GtkTreeViewColumn *column,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ EMailLabelTreeView *tree_view)
+{
+ EMailLabelListStore *store;
+ gchar *name;
+
+ store = E_MAIL_LABEL_LIST_STORE (model);
+ name = e_mail_label_list_store_get_name (store, iter);
+ g_object_set (renderer, "text", name, NULL);
+ g_free (name);
+}
+
+static void
+mail_label_tree_view_class_init (EMailLabelTreeViewClass *class)
+{
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMailLabelTreeViewPrivate));
+}
+
+static void
+mail_label_tree_view_init (EMailLabelTreeView *tree_view)
+{
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+
+ tree_view->priv = E_MAIL_LABEL_TREE_VIEW_GET_PRIVATE (tree_view);
+
+ column = gtk_tree_view_column_new ();
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_set_title (column, _("Color"));
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+
+ gtk_tree_view_column_set_cell_data_func (
+ column, renderer, (GtkTreeCellDataFunc)
+ mail_label_tree_view_render_pixbuf, tree_view, NULL);
+
+ column = gtk_tree_view_column_new ();
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_set_title (column, _("Name"));
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+
+ gtk_tree_view_column_set_cell_data_func (
+ column, renderer, (GtkTreeCellDataFunc)
+ mail_label_tree_view_render_text, tree_view, NULL);
+}
+
+GType
+e_mail_label_tree_view_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailLabelTreeViewClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_label_tree_view_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMailLabelTreeView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) mail_label_tree_view_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TREE_VIEW, "EMailLabelTreeView",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_mail_label_tree_view_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_LABEL_TREE_VIEW, NULL);
+}
diff --git a/mail/e-mail-label-tree-view.h b/mail/e-mail-label-tree-view.h
new file mode 100644
index 0000000000..0dd58f2152
--- /dev/null
+++ b/mail/e-mail-label-tree-view.h
@@ -0,0 +1,66 @@
+/*
+ * e-mail-label-tree-view.h
+ *
+ * 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)
+ *
+ */
+
+#ifndef E_MAIL_LABEL_TREE_VIEW_H
+#define E_MAIL_LABEL_TREE_VIEW_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_LABEL_TREE_VIEW \
+ (e_mail_label_tree_view_get_type ())
+#define E_MAIL_LABEL_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_LABEL_TREE_VIEW, EMailLabelTreeView))
+#define E_MAIL_LABEL_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_LABEL_TREE_VIEW, EMailLabelTreeViewClass))
+#define E_IS_MAIL_LABEL_TREE_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_LABEL_TREE_VIEW))
+#define E_IS_MAIL_LABEL_TREE_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_LABEL_TREE_VIEW))
+#define E_MAIL_LABEL_TREE_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_LABEL_TREE_VIEW, EMailLabelTreeViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailLabelTreeView EMailLabelTreeView;
+typedef struct _EMailLabelTreeViewClass EMailLabelTreeViewClass;
+typedef struct _EMailLabelTreeViewPrivate EMailLabelTreeViewPrivate;
+
+struct _EMailLabelTreeView {
+ GtkTreeView parent;
+ EMailLabelTreeViewPrivate *priv;
+};
+
+struct _EMailLabelTreeViewClass {
+ GtkTreeViewClass parent_class;
+};
+
+GType e_mail_label_tree_view_get_type (void);
+GtkWidget * e_mail_label_tree_view_new (void);
+
+G_END_DECLS
+
+#endif /* E_MAIL_LABEL_TREE_VIEW_H */
diff --git a/mail/e-mail-local.c b/mail/e-mail-local.c
new file mode 100644
index 0000000000..0944c7da95
--- /dev/null
+++ b/mail/e-mail-local.c
@@ -0,0 +1,130 @@
+/*
+ * e-mail-local.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)
+ *
+ */
+
+#include "e-mail-local.h"
+
+#include <glib/gi18n.h>
+
+#include "mail/mail-session.h"
+
+#define CHECK_LOCAL_FOLDER_TYPE(type) \
+ ((type) < G_N_ELEMENTS (default_local_folders))
+
+/* The array elements correspond to EMailLocalFolder. */
+static struct {
+ const gchar *display_name;
+ CamelFolder *folder;
+ gchar *folder_uri;
+} default_local_folders[] = {
+ { N_("Inbox") },
+ { N_("Drafts") },
+ { N_("Outbox") },
+ { N_("Sent") },
+ { N_("Templates") },
+ { "Inbox" } /* "always local" inbox */
+};
+
+static CamelStore *local_store;
+
+void
+e_mail_local_init (const gchar *data_dir)
+{
+ static gboolean initialized = FALSE;
+ CamelException ex;
+ CamelService *service;
+ CamelURL *url;
+ gchar *temp;
+ gint ii;
+
+ g_return_if_fail (!initialized);
+ g_return_if_fail (data_dir != NULL);
+
+ camel_exception_init (&ex);
+
+ url = camel_url_new ("mbox:", NULL);
+ temp = g_build_filename (data_dir, "local", NULL);
+ camel_url_set_path (url, temp);
+ g_free (temp);
+
+ temp = camel_url_to_string (url, 0);
+ service = camel_session_get_service (
+ session, temp, CAMEL_PROVIDER_STORE, &ex);
+ g_free (temp);
+
+ if (camel_exception_is_set (&ex))
+ goto fail;
+
+ /* Populate the rest of the default_local_folders array. */
+ for (ii = 0; ii < G_N_ELEMENTS (default_local_folders); ii++) {
+ const gchar *display_name;
+ gchar *folder_uri;
+
+ display_name = default_local_folders[ii].display_name;
+
+ /* XXX Should this URI be account relative? */
+ camel_url_set_fragment (url, display_name);
+ folder_uri = camel_url_to_string (url, 0);
+
+ default_local_folders[ii].folder_uri = folder_uri;
+ default_local_folders[ii].folder = camel_store_get_folder (
+ CAMEL_STORE (service), display_name,
+ CAMEL_STORE_FOLDER_CREATE, &ex);
+
+ camel_exception_clear (&ex);
+ }
+
+ camel_url_free (url);
+
+ camel_object_ref (service);
+ local_store = CAMEL_STORE (service);
+
+ return;
+
+fail:
+ g_warning ("Could not initialize local store/folder: %s", ex.desc);
+
+ camel_exception_clear (&ex);
+ camel_url_free (url);
+}
+
+CamelFolder *
+e_mail_local_get_folder (EMailLocalFolder type)
+{
+ g_return_val_if_fail (CHECK_LOCAL_FOLDER_TYPE (type), NULL);
+
+ return default_local_folders[type].folder;
+}
+
+const gchar *
+e_mail_local_get_folder_uri (EMailLocalFolder type)
+{
+ g_return_val_if_fail (CHECK_LOCAL_FOLDER_TYPE (type), NULL);
+
+ return default_local_folders[type].folder_uri;
+}
+
+CamelStore *
+e_mail_local_get_store (void)
+{
+ g_return_val_if_fail (CAMEL_IS_STORE (local_store), NULL);
+
+ return local_store;
+}
diff --git a/mail/em-migrate.h b/mail/e-mail-local.h
index 89896d4aec..1bd34e4273 100644
--- a/mail/em-migrate.h
+++ b/mail/e-mail-local.h
@@ -1,4 +1,6 @@
/*
+ * e-mail-local.h
+ *
* 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
@@ -13,22 +15,36 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef __EM_MIGRATE_H__
-#define __EM_MIGRATE_H__
+#ifndef E_MAIL_LOCAL_H
+#define E_MAIL_LOCAL_H
-#include <camel/camel-exception.h>
+#include <glib.h>
+#include <camel/camel-folder.h>
+#include <camel/camel-store.h>
G_BEGIN_DECLS
-gint em_migrate (const gchar *evolution_dir, gint major, gint minor, gint revision, CamelException *ex);
+/* XXX E_MAIL_FOLDER_TEMPLATES is a prime example of why
+ * templates should be a core feature, not a plugin. */
+typedef enum {
+ E_MAIL_FOLDER_INBOX,
+ E_MAIL_FOLDER_DRAFTS,
+ E_MAIL_FOLDER_OUTBOX,
+ E_MAIL_FOLDER_SENT,
+ E_MAIL_FOLDER_TEMPLATES,
+ E_MAIL_FOLDER_LOCAL_INBOX,
+ E_MAIL_NUM_LOCAL_FOLDERS
+} EMailLocalFolder;
+
+void e_mail_local_init (const gchar *data_dir);
+CamelFolder * e_mail_local_get_folder (EMailLocalFolder type);
+const gchar * e_mail_local_get_folder_uri (EMailLocalFolder type);
+CamelStore * e_mail_local_get_store (void);
G_END_DECLS
-#endif /* __EM_MIGRATE_H__ */
+#endif /* E_MAIL_LOCAL_H */
diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c
new file mode 100644
index 0000000000..b9bde5b370
--- /dev/null
+++ b/mail/e-mail-reader-utils.c
@@ -0,0 +1,588 @@
+/*
+ * 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 <gtkhtml/gtkhtml.h>
+#include <camel/camel-mime-message.h>
+#include <camel/camel-vee-folder.h>
+#include <camel/camel-vee-store.h>
+
+#include "e-util/e-error.h"
+#include "filter/filter-rule.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"
+
+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;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWidget *check_button;
+ GtkWidget *content_area;
+ 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);
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ folder = message_list->folder;
+
+ prompt_delete_in_vfolder = e_shell_settings_get_boolean (
+ shell_settings, "mail-prompt-delete-in-vfolder");
+
+ if (!CAMEL_IS_VEE_STORE (folder->parent_store))
+ return TRUE;
+
+ if (!prompt_delete_in_vfolder)
+ return TRUE;
+
+ dialog = e_error_new (
+ window, "mail:ask-delete-vfolder-msg",
+ folder->full_name, NULL);
+
+ /* XXX e-error should provide a widget layout and API suitable
+ * for packing additional widgets to the right of the alert
+ * icon. But for now, screw it. */
+
+ label = _("Do not ask me again");
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ check_button = gtk_check_button_new_with_label (label);
+ gtk_box_pack_start (
+ GTK_BOX (content_area), check_button, TRUE, TRUE, 6);
+ gtk_widget_show (check_button);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_OK)
+ 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)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ CamelFolder *folder;
+ guint32 mask, set;
+ guint32 flags;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+ g_return_if_fail (uid != NULL);
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ flags = camel_folder_get_message_flags (folder, uid);
+
+ if (!(flags & CAMEL_MESSAGE_SEEN)) {
+ CamelMimeMessage *message;
+
+ message = ((EMFormat *) html_display)->message;
+ em_utils_handle_receipt (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)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GPtrArray *uids;
+ guint ii;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ if (folder == NULL)
+ return 0;
+
+ camel_folder_freeze (folder);
+ uids = message_list_get_selected (message_list);
+
+ for (ii = 0; ii < uids->len; ii++)
+ camel_folder_set_message_flags (
+ folder, uids->pdata[ii], mask, set);
+
+ message_list_free_uids (message_list, uids);
+ camel_folder_thaw (folder);
+
+ return ii;
+}
+
+guint
+e_mail_reader_open_selected (EMailReader *reader)
+{
+ EShellBackend *shell_backend;
+ MessageList *message_list;
+ 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);
+
+ message_list = e_mail_reader_get_message_list (reader);
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len >= 10) {
+ gchar *len_str;
+ gboolean proceed;
+
+ len_str = g_strdup_printf ("%d", uids->len);
+
+ proceed = em_utils_prompt_user (
+ window, "/apps/evolution/mail/prompts/open_many",
+ "mail:ask-open-many", len_str, NULL);
+
+ g_free (len_str);
+
+ if (!proceed) {
+ message_list_free_uids (message_list, uids);
+ return 0;
+ }
+ }
+
+ if (em_utils_folder_is_drafts (folder, folder_uri) ||
+ em_utils_folder_is_outbox (folder, folder_uri) ||
+ em_utils_folder_is_templates (folder, folder_uri)) {
+ em_utils_edit_messages (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;
+ 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 = mail_tools_folder_to_url (real_folder);
+
+ if (em_utils_folder_is_drafts (real_folder, real_folder_uri) ||
+ em_utils_folder_is_outbox (real_folder, real_folder_uri)) {
+ GPtrArray *edits;
+
+ edits = g_ptr_array_new ();
+ g_ptr_array_add (edits, real_uid);
+ em_utils_edit_messages (real_folder, edits, TRUE);
+ } else {
+ g_free (real_uid);
+ g_ptr_array_add (views, g_strdup (uid));
+ }
+
+ g_free (real_folder_uri);
+ }
+
+ for (ii = 0; ii < views->len; ii++) {
+ const gchar *uid = views->pdata[ii];
+ GtkWidget *browser;
+
+ browser = e_mail_browser_new (shell_backend);
+ e_mail_reader_set_folder (
+ E_MAIL_READER (browser), folder, folder_uri);
+ e_mail_reader_set_message (
+ E_MAIL_READER (browser), uid, FALSE);
+ gtk_widget_show (browser);
+ }
+
+ g_ptr_array_free (views, TRUE);
+
+ message_list_free_uids (message_list, uids);
+
+ return ii;
+}
+
+void
+e_mail_reader_print (EMailReader *reader,
+ GtkPrintOperationAction action)
+{
+ MessageList *message_list;
+ EMFormatHTMLDisplay *html_display;
+ EMFormatHTMLPrint *html_print;
+ CamelFolder *folder;
+ GPtrArray *uids;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ g_return_if_fail (folder != NULL);
+
+ /* XXX Learn to handle len > 1. */
+ uids = message_list_get_selected (message_list);
+ if (uids->len != 1)
+ goto exit;
+
+ html_print = em_format_html_print_new (
+ (EMFormatHTML *) html_display, action);
+ em_format_merge_handler (
+ (EMFormat *) html_print,
+ (EMFormat *) html_display);
+ em_format_html_print_message (html_print, folder, uids->pdata[0]);
+ g_object_unref (html_print);
+
+exit:
+ message_list_free_uids (message_list, 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 '&nbsp;' is a space */
+ if (g_ascii_strncasecmp (cp, "&nbsp;", 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,
+ gint reply_mode)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ CamelMimeMessage *new_message;
+ CamelMimeMessage *src_message;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GtkHTML *html;
+ 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));
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = ((EMFormatHTML *) html_display)->html;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uid = message_list->cursor_uid;
+ g_return_if_fail (uid != NULL);
+
+ if (!gtk_html_command (html, "is-selection-active"))
+ goto whole_message;
+
+ selection = gtk_html_get_selection_html (html, &length);
+ if (selection == NULL || *selection == '\0')
+ goto whole_message;
+
+ if (!html_contains_nonwhitespace (selection, length))
+ goto whole_message;
+
+ src_message =
+ CAMEL_MIME_MESSAGE (((EMFormat *) html_display)->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);
+ }
+
+ 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");
+
+ em_utils_reply_to_message (
+ folder, uid, new_message, reply_mode, NULL);
+
+ g_free (selection);
+
+ return;
+
+whole_message:
+ em_utils_reply_to_message (
+ folder, uid, NULL, reply_mode, (EMFormat *) html_display);
+}
+
+void
+e_mail_reader_select_next_message (EMailReader *reader,
+ gboolean or_else_previous)
+{
+ MessageList *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_SELECT_NEXT, 0, 0);
+
+ if (!success && (hide_deleted || or_else_previous))
+ message_list_select (
+ 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 {
+ const gchar *source;
+ gint type;
+ } *filter_data = user_data;
+
+ if (message != NULL)
+ filter_gui_add_from_message (
+ message, filter_data->source, filter_data->type);
+
+ g_free (filter_data);
+}
+
+void
+e_mail_reader_create_filter_from_selected (EMailReader *reader,
+ gint filter_type)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ const gchar *filter_source;
+ const gchar *folder_uri;
+ GPtrArray *uids;
+
+ struct {
+ const gchar *source;
+ gint type;
+ } *filter_data;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+
+ if (em_utils_folder_is_sent (folder, folder_uri))
+ filter_source = FILTER_SOURCE_OUTGOING;
+ else if (em_utils_folder_is_outbox (folder, folder_uri))
+ filter_source = FILTER_SOURCE_OUTGOING;
+ else
+ filter_source = FILTER_SOURCE_INCOMING;
+
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len == 1) {
+ filter_data = g_malloc (sizeof (*filter_data));
+ 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 {
+ gchar *uri;
+ gint type;
+ } *vfolder_data = user_data;
+
+ if (message != NULL)
+ vfolder_gui_add_from_message (
+ message, vfolder_data->type, vfolder_data->uri);
+
+ g_free (vfolder_data->uri);
+ g_free (vfolder_data);
+}
+
+void
+e_mail_reader_create_vfolder_from_selected (EMailReader *reader,
+ gint vfolder_type)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ const gchar *folder_uri;
+ GPtrArray *uids;
+
+ struct {
+ gchar *uri;
+ gint type;
+ } *vfolder_data;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len == 1) {
+ vfolder_data = g_malloc (sizeof (*vfolder_data));
+ 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);
+}
diff --git a/mail/e-mail-reader-utils.h b/mail/e-mail-reader-utils.h
new file mode 100644
index 0000000000..46c3ea7345
--- /dev/null
+++ b/mail/e-mail-reader-utils.h
@@ -0,0 +1,56 @@
+/*
+ * e-mail-reader-utils.h
+ *
+ * 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. */
+
+#ifndef E_MAIL_READER_UTILS_H
+#define E_MAIL_READER_UTILS_H
+
+#include <mail/e-mail-reader.h>
+
+G_BEGIN_DECLS
+
+void e_mail_reader_activate (EMailReader *reader,
+ const gchar *action_name);
+gboolean e_mail_reader_confirm_delete (EMailReader *reader);
+void e_mail_reader_mark_as_read (EMailReader *reader,
+ const gchar *uid);
+guint e_mail_reader_mark_selected (EMailReader *reader,
+ guint32 mask,
+ guint32 set);
+guint e_mail_reader_open_selected (EMailReader *reader);
+void e_mail_reader_print (EMailReader *reader,
+ GtkPrintOperationAction action);
+void e_mail_reader_reply_to_message (EMailReader *reader,
+ gint reply_mode);
+void e_mail_reader_select_next_message
+ (EMailReader *reader,
+ gboolean or_else_previous);
+void e_mail_reader_create_filter_from_selected
+ (EMailReader *reader,
+ gint filter_type);
+void e_mail_reader_create_vfolder_from_selected
+ (EMailReader *reader,
+ gint filter_type);
+
+G_END_DECLS
+
+#endif /* E_MAIL_READER_UTILS_H */
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
new file mode 100644
index 0000000000..0e20dbb043
--- /dev/null
+++ b/mail/e-mail-reader.c
@@ -0,0 +1,2744 @@
+/*
+ * e-mail-reader.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)
+ *
+ */
+
+#include "e-mail-reader.h"
+
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-stream.h>
+
+#ifdef HAVE_XFREE
+#include <X11/XF86keysym.h>
+#endif
+
+#include "e-util/e-binding.h"
+#include "e-util/e-charset.h"
+#include "e-util/e-util.h"
+#include "e-util/gconf-bridge.h"
+#include "shell/e-shell.h"
+#include "widgets/misc/e-popup-action.h"
+
+#include "mail/e-mail-browser.h"
+#include "mail/e-mail-display.h"
+#include "mail/e-mail-reader-utils.h"
+#include "mail/em-composer-utils.h"
+#include "mail/em-event.h"
+#include "mail/em-folder-selector.h"
+#include "mail/em-folder-tree.h"
+#include "mail/em-utils.h"
+#include "mail/mail-autofilter.h"
+#include "mail/mail-config.h"
+#include "mail/mail-ops.h"
+#include "mail/mail-vfolder.h"
+
+enum {
+ CHANGED,
+ FOLDER_LOADED,
+ SHOW_SEARCH_BAR,
+ LAST_SIGNAL
+};
+
+/* Remembers the previously selected folder when transferring messages. */
+static gchar *default_xfer_messages_uri;
+
+static guint signals[LAST_SIGNAL];
+
+static void
+action_mail_add_sender_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelMessageInfo *info;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+ const gchar *address;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ if (uids->len != 1)
+ goto exit;
+
+ info = camel_folder_get_message_info (folder, uids->pdata[0]);
+ if (info == NULL)
+ goto exit;
+
+ address = camel_message_info_from (info);
+ if (address == NULL || *address == '\0')
+ goto exit;
+
+ em_utils_add_address (window, address);
+
+exit:
+ em_utils_uids_free (uids);
+}
+
+static void
+action_mail_charset_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ const gchar *charset;
+
+ if (action != current)
+ return;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ charset = g_object_get_data (G_OBJECT (action), "charset");
+
+ /* Charset for "Default" action will be NULL. */
+ em_format_set_charset (EM_FORMAT (html_display), charset);
+}
+
+static void
+action_mail_check_for_junk_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GPtrArray *uids;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ mail_filter_junk (folder, uids);
+}
+
+static void
+action_mail_clipboard_copy_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ gtk_html_copy (html);
+}
+
+static void
+action_mail_copy_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWidget *folder_tree;
+ GtkWidget *dialog;
+ GPtrArray *selected;
+ const gchar *uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder_tree = em_folder_tree_new ();
+ selected = message_list_get_selected (message_list);
+
+ folder = message_list->folder;
+
+ em_folder_tree_set_excluded (
+ EM_FOLDER_TREE (folder_tree),
+ EMFT_EXCLUDE_NOSELECT | EMFT_EXCLUDE_VIRTUAL |
+ EMFT_EXCLUDE_VTRASH);
+
+ dialog = em_folder_selector_new (
+ EM_FOLDER_TREE (folder_tree),
+ EM_FOLDER_SELECTOR_CAN_CREATE,
+ _("Select Folder"), NULL, _("C_opy"));
+
+ if (default_xfer_messages_uri != NULL)
+ em_folder_selector_set_selected (
+ EM_FOLDER_SELECTOR (dialog),
+ default_xfer_messages_uri);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ uri = em_folder_selector_get_selected_uri (
+ EM_FOLDER_SELECTOR (dialog));
+
+ g_free (default_xfer_messages_uri);
+ default_xfer_messages_uri = g_strdup (uri);
+
+ if (uri != NULL) {
+ mail_transfer_messages (
+ folder, selected, FALSE, uri, 0, NULL, NULL);
+ selected = NULL;
+ }
+
+exit:
+ if (selected != NULL)
+ em_utils_uids_free (selected);
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+action_mail_delete_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
+ guint32 set = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
+
+ if (!e_mail_reader_confirm_delete (reader))
+ return;
+
+ /* FIXME Verify all selected messages are deletable.
+ * But handle it by disabling this action. */
+
+ if (e_mail_reader_mark_selected (reader, mask, set) == 1)
+ e_mail_reader_select_next_message (reader, FALSE);
+}
+
+static void
+action_mail_filter_on_mailing_list_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_filter_from_selected (reader, AUTO_MLIST);
+}
+
+static void
+action_mail_filter_on_recipients_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_filter_from_selected (reader, AUTO_TO);
+}
+
+static void
+action_mail_filter_on_sender_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_filter_from_selected (reader, AUTO_FROM);
+}
+
+static void
+action_mail_filter_on_subject_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_filter_from_selected (reader, AUTO_SUBJECT);
+}
+
+static void
+action_mail_filters_apply_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GPtrArray *uids;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ mail_filter_on_demand (folder, uids);
+}
+
+static void
+action_mail_find_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_show_search_bar (reader);
+}
+
+static void
+action_mail_flag_clear_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_flag_for_followup_clear (window, folder, uids);
+
+ em_format_redraw (EM_FORMAT (html_display));
+}
+
+static void
+action_mail_flag_completed_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_flag_for_followup_completed (window, folder, uids);
+
+ em_format_redraw (EM_FORMAT (html_display));
+}
+
+static void
+action_mail_flag_for_followup_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_flag_for_followup (reader, folder, uids);
+}
+
+static void
+action_mail_forward_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_forward_messages (folder, uids, folder_uri);
+}
+
+static void
+action_mail_forward_attached_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_forward_attached (folder, uids, folder_uri);
+}
+
+static void
+action_mail_forward_inline_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_forward_inline (folder, uids, folder_uri);
+}
+
+static void
+action_mail_forward_quoted_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_forward_quoted (folder, uids, folder_uri);
+}
+
+static void
+action_mail_load_images_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+
+ html_display = e_mail_reader_get_html_display (reader);
+
+ em_format_html_load_images (EM_FORMAT_HTML (html_display));
+}
+
+static void
+action_mail_mark_important_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_DELETED;
+ guint32 set = CAMEL_MESSAGE_FLAGGED;
+
+ e_mail_reader_mark_selected (reader, mask, set);
+}
+
+static void
+action_mail_mark_junk_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_JUNK |
+ CAMEL_MESSAGE_NOTJUNK | CAMEL_MESSAGE_JUNK_LEARN;
+ guint32 set = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_JUNK |
+ CAMEL_MESSAGE_JUNK_LEARN;
+
+ if (e_mail_reader_mark_selected (reader, mask, set) == 1)
+ e_mail_reader_select_next_message (reader, TRUE);
+}
+
+static void
+action_mail_mark_notjunk_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_NOTJUNK |
+ CAMEL_MESSAGE_JUNK_LEARN;
+ guint32 set = CAMEL_MESSAGE_NOTJUNK | CAMEL_MESSAGE_JUNK_LEARN;
+
+ if (e_mail_reader_mark_selected (reader, mask, set) == 1)
+ e_mail_reader_select_next_message (reader, TRUE);
+}
+
+static void
+action_mail_mark_read_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_SEEN;
+ guint32 set = CAMEL_MESSAGE_SEEN;
+
+ e_mail_reader_mark_selected (reader, mask, set);
+}
+
+static void
+action_mail_mark_unimportant_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_FLAGGED;
+ guint32 set = 0;
+
+ e_mail_reader_mark_selected (reader, mask, set);
+}
+
+static void
+action_mail_mark_unread_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ guint32 mask = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DELETED;
+ guint32 set = 0;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ e_mail_reader_mark_selected (reader, mask, set);
+
+ if (message_list->seen_id != 0) {
+ g_source_remove (message_list->seen_id);
+ message_list->seen_id = 0;
+ }
+}
+
+static void
+action_mail_message_edit_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+
+ window = e_mail_reader_get_window (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_edit_messages (folder, uids, FALSE);
+}
+
+static void
+action_mail_message_new_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ GtkWindow *window;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ em_utils_compose_new_message (message_list->folder_uri);
+}
+
+static void
+action_mail_message_open_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_open_selected (reader);
+}
+
+static void
+action_mail_move_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWidget *folder_tree;
+ GtkWidget *dialog;
+ GPtrArray *selected;
+ const gchar *uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder_tree = em_folder_tree_new ();
+ selected = message_list_get_selected (message_list);
+
+ folder = message_list->folder;
+
+ em_folder_tree_set_excluded (
+ EM_FOLDER_TREE (folder_tree),
+ EMFT_EXCLUDE_NOSELECT | EMFT_EXCLUDE_VIRTUAL |
+ EMFT_EXCLUDE_VTRASH);
+
+ dialog = em_folder_selector_new (
+ EM_FOLDER_TREE (folder_tree),
+ EM_FOLDER_SELECTOR_CAN_CREATE,
+ _("Select Folder"), NULL, _("_Move"));
+
+ if (default_xfer_messages_uri != NULL)
+ em_folder_selector_set_selected (
+ EM_FOLDER_SELECTOR (dialog),
+ default_xfer_messages_uri);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ uri = em_folder_selector_get_selected_uri (
+ EM_FOLDER_SELECTOR (dialog));
+
+ g_free (default_xfer_messages_uri);
+ default_xfer_messages_uri = g_strdup (uri);
+
+ if (uri != NULL) {
+ mail_transfer_messages (
+ folder, selected, TRUE, uri, 0, NULL, NULL);
+ selected = NULL;
+ }
+
+exit:
+ if (selected != NULL)
+ em_utils_uids_free (selected);
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+action_mail_next_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_NEXT;
+ flags = 0;
+ mask = 0;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_next_important_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP;
+ flags = CAMEL_MESSAGE_FLAGGED;
+ mask = CAMEL_MESSAGE_FLAGGED;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_next_thread_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select_next_thread (message_list);
+}
+
+static void
+action_mail_next_unread_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP;
+ flags = 0;
+ mask = CAMEL_MESSAGE_SEEN;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_previous_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_PREVIOUS;
+ flags = 0;
+ mask = 0;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_previous_important_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP;
+ flags = CAMEL_MESSAGE_FLAGGED;
+ mask = CAMEL_MESSAGE_FLAGGED;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_previous_unread_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ MessageListSelectDirection direction;
+ guint32 flags, mask;
+
+ direction = MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP;
+ flags = 0;
+ mask = CAMEL_MESSAGE_SEEN;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select (message_list, direction, flags, mask);
+}
+
+static void
+action_mail_print_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ GtkPrintOperationAction print_action;
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
+ e_mail_reader_print (reader, print_action);
+}
+
+static void
+action_mail_print_preview_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ GtkPrintOperationAction print_action;
+
+ print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
+ e_mail_reader_print (reader, print_action);
+}
+
+static void
+action_mail_redirect_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ const gchar *uid;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uid = message_list->cursor_uid;
+ g_return_if_fail (uid != NULL);
+
+ em_utils_redirect_message_by_uid (folder, uid);
+}
+
+static void
+action_mail_reply_all_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_reply_to_message (reader, REPLY_MODE_ALL);
+}
+
+static void
+action_mail_reply_list_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_reply_to_message (reader, REPLY_MODE_LIST);
+}
+
+static void
+action_mail_reply_sender_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_reply_to_message (reader, REPLY_MODE_SENDER);
+}
+
+static void
+action_mail_save_as_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWindow *window;
+ GPtrArray *uids;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ window = e_mail_reader_get_window (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ em_utils_save_messages (window, folder, uids);
+}
+
+static void
+action_mail_search_folder_from_mailing_list_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_vfolder_from_selected (reader, AUTO_MLIST);
+}
+
+static void
+action_mail_search_folder_from_recipients_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_vfolder_from_selected (reader, AUTO_TO);
+}
+
+static void
+action_mail_search_folder_from_sender_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_vfolder_from_selected (reader, AUTO_FROM);
+}
+
+static void
+action_mail_search_folder_from_subject_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ e_mail_reader_create_vfolder_from_selected (reader, AUTO_SUBJECT);
+}
+
+static void
+action_mail_select_all_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
+ const gchar *action_name;
+ gboolean selection_active;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ gtk_html_select_all (html);
+
+ action_name = "mail-clipboard-copy";
+ action = e_mail_reader_get_action (reader, action_name);
+ selection_active = gtk_html_command (html, "is-selection-active");
+ gtk_action_set_sensitive (action, selection_active);
+}
+
+static void
+action_mail_show_all_headers_cb (GtkToggleAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ em_format_mode_t mode;
+
+ html_display = e_mail_reader_get_html_display (reader);
+
+ if (gtk_toggle_action_get_active (action))
+ mode = EM_FORMAT_ALLHEADERS;
+ else
+ mode = EM_FORMAT_NORMAL;
+
+ em_format_set_mode (EM_FORMAT (html_display), mode);
+}
+
+static void
+action_mail_show_source_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ EShellBackend *shell_backend;
+ MessageList *message_list;
+ CamelFolder *folder;
+ GtkWidget *browser;
+ GPtrArray *uids;
+ const gchar *folder_uri;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+
+ folder = message_list->folder;
+ folder_uri = message_list->folder_uri;
+ uids = message_list_get_selected (message_list);
+ g_return_if_fail (uids->len > 0);
+
+ browser = e_mail_browser_new (shell_backend);
+ reader = E_MAIL_READER (browser);
+ html_display = e_mail_reader_get_html_display (reader);
+ em_format_set_mode (EM_FORMAT (html_display), EM_FORMAT_SOURCE);
+ e_mail_reader_set_folder (reader, folder, folder_uri);
+ e_mail_reader_set_message (reader, uids->pdata[0], FALSE);
+ gtk_widget_show (browser);
+
+ message_list_free_uids (message_list, uids);
+}
+
+static void
+action_mail_toggle_important_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ MessageList *message_list;
+ CamelFolder *folder;
+ GPtrArray *uids;
+ guint ii;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ folder = message_list->folder;
+ uids = message_list_get_selected (message_list);
+
+ camel_folder_freeze (folder);
+
+ for (ii = 0; ii < uids->len; ii++) {
+ guint32 flags;
+
+ flags = camel_folder_get_message_flags (
+ folder, uids->pdata[ii]);
+ flags ^= CAMEL_MESSAGE_FLAGGED;
+ if (flags & CAMEL_MESSAGE_FLAGGED)
+ flags &= ~CAMEL_MESSAGE_DELETED;
+ camel_folder_set_message_flags (
+ folder, uids->pdata[ii], CAMEL_MESSAGE_FLAGGED |
+ CAMEL_MESSAGE_DELETED, flags);
+ }
+
+ camel_folder_thaw (folder);
+
+ message_list_free_uids (message_list, uids);
+}
+
+static void
+action_mail_undelete_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ guint32 mask = CAMEL_MESSAGE_DELETED;
+ guint32 set = 0;
+
+ e_mail_reader_mark_selected (reader, mask, set);
+}
+
+static void
+action_mail_zoom_100_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ gtk_html_zoom_reset (html);
+}
+
+static void
+action_mail_zoom_in_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ gtk_html_zoom_out (html);
+}
+
+static void
+action_mail_zoom_out_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ GtkHTML *html;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ html = EM_FORMAT_HTML (html_display)->html;
+
+ gtk_html_zoom_out (html);
+}
+
+static void
+action_search_folder_recipient_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ EMailDisplay *display;
+ CamelURL *curl;
+ const gchar *uri;
+
+ /* This action is defined in EMailDisplay. */
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ display = E_MAIL_DISPLAY (EM_FORMAT_HTML (html_display)->html);
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ curl = camel_url_new (uri, NULL);
+ g_return_if_fail (curl != NULL);
+
+ if (curl->path != NULL && *curl->path != '\0') {
+ CamelInternetAddress *inet_addr;
+ const gchar *folder_uri;
+
+ /* Ensure vfolder is running. */
+ vfolder_load_storage ();
+
+ folder_uri = message_list->folder_uri;
+
+ inet_addr = camel_internet_address_new ();
+ camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
+ vfolder_gui_add_from_address (inet_addr, AUTO_TO, folder_uri);
+ camel_object_unref (inet_addr);
+ }
+
+ camel_url_free (curl);
+}
+
+static void
+action_search_folder_sender_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ EMailDisplay *display;
+ CamelURL *curl;
+ const gchar *uri;
+
+ /* This action is defined in EMailDisplay. */
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ display = E_MAIL_DISPLAY (EM_FORMAT_HTML (html_display)->html);
+
+ uri = e_mail_display_get_selected_uri (display);
+ g_return_if_fail (uri != NULL);
+
+ curl = camel_url_new (uri, NULL);
+ g_return_if_fail (curl != NULL);
+
+ if (curl->path != NULL && *curl->path != '\0') {
+ CamelInternetAddress *inet_addr;
+ const gchar *folder_uri;
+
+ /* Ensure vfolder is running. */
+ vfolder_load_storage ();
+
+ folder_uri = message_list->folder_uri;
+
+ inet_addr = camel_internet_address_new ();
+ camel_address_decode (CAMEL_ADDRESS (inet_addr), curl->path);
+ vfolder_gui_add_from_address (inet_addr, AUTO_FROM, folder_uri);
+ camel_object_unref (inet_addr);
+ }
+
+ camel_url_free (curl);
+}
+
+static GtkActionEntry mail_reader_entries[] = {
+
+ { "mail-add-sender",
+ NULL,
+ N_("A_dd Sender to Address Book"),
+ NULL,
+ N_("Add sender to address book"),
+ G_CALLBACK (action_mail_add_sender_cb) },
+
+ { "mail-check-for-junk",
+ "mail-mark-junk",
+ N_("Check for _Junk"),
+ NULL,
+ N_("Filter the selected messages for junk status"),
+ G_CALLBACK (action_mail_check_for_junk_cb) },
+
+ { "mail-clipboard-copy",
+ GTK_STOCK_COPY,
+ NULL,
+ NULL,
+ N_("Copy selected messages to the clipboard"),
+ G_CALLBACK (action_mail_clipboard_copy_cb) },
+
+ { "mail-copy",
+ "mail-copy",
+ N_("_Copy to Folder..."),
+ "<Shift><Control>y",
+ N_("Copy selected messages to another folder"),
+ G_CALLBACK (action_mail_copy_cb) },
+
+ { "mail-delete",
+ "user-trash",
+ N_("_Delete Message"),
+ "<Control>d",
+ N_("Mark the selected messages for deletion"),
+ G_CALLBACK (action_mail_delete_cb) },
+
+ { "mail-filter-on-mailing-list",
+ NULL,
+ N_("Filter on Mailing _List..."),
+ NULL,
+ N_("Create a rule to filter messages to this mailing list"),
+ G_CALLBACK (action_mail_filter_on_mailing_list_cb) },
+
+ { "mail-filter-on-recipients",
+ NULL,
+ N_("Filter on _Recipients..."),
+ NULL,
+ N_("Create a rule to filter messages to these recipients"),
+ G_CALLBACK (action_mail_filter_on_recipients_cb) },
+
+ { "mail-filter-on-sender",
+ NULL,
+ N_("Filter on Se_nder..."),
+ NULL,
+ N_("Create a rule to filter messages from this sender"),
+ G_CALLBACK (action_mail_filter_on_sender_cb) },
+
+ { "mail-filter-on-subject",
+ NULL,
+ N_("Filter on _Subject..."),
+ NULL,
+ N_("Create a rule to filter messages with this subject"),
+ G_CALLBACK (action_mail_filter_on_subject_cb) },
+
+ { "mail-filters-apply",
+ "stock_mail-filters-apply",
+ N_("A_pply Filters"),
+ "<Control>y",
+ N_("Apply filter rules to the selected messages"),
+ G_CALLBACK (action_mail_filters_apply_cb) },
+
+ { "mail-find",
+ GTK_STOCK_FIND,
+ N_("_Find in Message..."),
+ "<Shift><Control>f",
+ N_("Search for text in the body of the displayed message"),
+ G_CALLBACK (action_mail_find_cb) },
+
+ { "mail-flag-clear",
+ NULL,
+ N_("_Clear Flag"),
+ NULL,
+ N_("Remove the follow-up flag from the selected messages"),
+ G_CALLBACK (action_mail_flag_clear_cb) },
+
+ { "mail-flag-completed",
+ NULL,
+ N_("_Flag Completed"),
+ NULL,
+ N_("Set the follow-up flag to completed on the selected messages"),
+ G_CALLBACK (action_mail_flag_completed_cb) },
+
+ { "mail-flag-for-followup",
+ "stock_mail-flag-for-followup",
+ N_("Follow _Up..."),
+ "<Shift><Control>g",
+ N_("Flag the selected messages for follow-up"),
+ G_CALLBACK (action_mail_flag_for_followup_cb) },
+
+ { "mail-forward",
+ "mail-forward",
+ N_("_Forward"),
+ "<Control>f",
+ N_("Forward the selected message to someone"),
+ G_CALLBACK (action_mail_forward_cb) },
+
+ { "mail-forward-attached",
+ NULL,
+ N_("_Attached"),
+ NULL,
+ N_("Forward the selected message to someone as an attachment"),
+ G_CALLBACK (action_mail_forward_attached_cb) },
+
+ { "mail-forward-inline",
+ NULL,
+ N_("_Inline"),
+ NULL,
+ N_("Forward the selected message in the body of a new message"),
+ G_CALLBACK (action_mail_forward_inline_cb) },
+
+ { "mail-forward-quoted",
+ NULL,
+ N_("_Quoted"),
+ NULL,
+ N_("Forward the selected message quoted like a reply"),
+ G_CALLBACK (action_mail_forward_quoted_cb) },
+
+ { "mail-load-images",
+ "image-x-generic",
+ N_("_Load Images"),
+ "<Control>i",
+ N_("Force images in HTML mail to be loaded"),
+ G_CALLBACK (action_mail_load_images_cb) },
+
+ { "mail-mark-important",
+ "mail-mark-important",
+ N_("_Important"),
+ NULL,
+ N_("Mark the selected messages as important"),
+ G_CALLBACK (action_mail_mark_important_cb) },
+
+ { "mail-mark-junk",
+ "mail-mark-junk",
+ N_("_Junk"),
+ "<Control>j",
+ N_("Mark the selected messages as junk"),
+ G_CALLBACK (action_mail_mark_junk_cb) },
+
+ { "mail-mark-notjunk",
+ "mail-mark-notjunk",
+ N_("_Not Junk"),
+ "<Shift><Control>j",
+ N_("Mark the selected messasges as not being junk"),
+ G_CALLBACK (action_mail_mark_notjunk_cb) },
+
+ { "mail-mark-read",
+ "mail-mark-read",
+ N_("_Read"),
+ "<Control>k",
+ N_("Mark the selected messages as having been read"),
+ G_CALLBACK (action_mail_mark_read_cb) },
+
+ { "mail-mark-unimportant",
+ NULL,
+ N_("Uni_mportant"),
+ NULL,
+ N_("Mark the selected messages as unimportant"),
+ G_CALLBACK (action_mail_mark_unimportant_cb) },
+
+ { "mail-mark-unread",
+ "mail-mark-unread",
+ N_("_Unread"),
+ "<Shift><Control>k",
+ N_("Mark the selected messages as not having been read"),
+ G_CALLBACK (action_mail_mark_unread_cb) },
+
+ { "mail-message-edit",
+ NULL,
+ N_("_Edit as New Message..."),
+ NULL,
+ N_("Open the selected messages in the composer for editing"),
+ G_CALLBACK (action_mail_message_edit_cb) },
+
+ { "mail-message-new",
+ "mail-message-new",
+ N_("Compose _New Message"),
+ "<Shift><Control>m",
+ N_("Open a window for composing a mail message"),
+ G_CALLBACK (action_mail_message_new_cb) },
+
+ { "mail-message-open",
+ NULL,
+ N_("_Open in New Window"),
+ "<Control>o",
+ N_("Open the selected messages in a new window"),
+ G_CALLBACK (action_mail_message_open_cb) },
+
+ { "mail-move",
+ "mail-move",
+ N_("_Move to Folder..."),
+ "<Shift><Control>v",
+ N_("Move selected messages to another folder"),
+ G_CALLBACK (action_mail_move_cb) },
+
+ { "mail-next",
+ GTK_STOCK_GO_FORWARD,
+ N_("_Next Message"),
+ "<Control>Page_Down",
+ N_("Display the next message"),
+ G_CALLBACK (action_mail_next_cb) },
+
+ { "mail-next-important",
+ NULL,
+ N_("Next _Important Message"),
+ NULL,
+ N_("Display the next important message"),
+ G_CALLBACK (action_mail_next_important_cb) },
+
+ { "mail-next-thread",
+ NULL,
+ N_("Next _Thread"),
+ NULL,
+ N_("Display the next thread"),
+ G_CALLBACK (action_mail_next_thread_cb) },
+
+ { "mail-next-unread",
+ NULL,
+ N_("Next _Unread Message"),
+ "<Control>bracketright",
+ N_("Display the next unread message"),
+ G_CALLBACK (action_mail_next_unread_cb) },
+
+ { "mail-previous",
+ GTK_STOCK_GO_BACK,
+ N_("_Previous Message"),
+ "<Control>Page_Up",
+ N_("Display the previous message"),
+ G_CALLBACK (action_mail_previous_cb) },
+
+ { "mail-previous-important",
+ NULL,
+ N_("Pr_evious Important Message"),
+ NULL,
+ N_("Display the previous important message"),
+ G_CALLBACK (action_mail_previous_important_cb) },
+
+ { "mail-previous-unread",
+ NULL,
+ N_("P_revious Unread Message"),
+ "<Control>bracketleft",
+ N_("Display the previous unread message"),
+ G_CALLBACK (action_mail_previous_unread_cb) },
+
+ { "mail-print",
+ GTK_STOCK_PRINT,
+ NULL,
+ "<Control>p",
+ N_("Print this message"),
+ G_CALLBACK (action_mail_print_cb) },
+
+ { "mail-print-preview",
+ GTK_STOCK_PRINT_PREVIEW,
+ NULL,
+ NULL,
+ N_("Preview the message to be printed"),
+ G_CALLBACK (action_mail_print_preview_cb) },
+
+ { "mail-redirect",
+ NULL,
+ N_("Re_direct"),
+ NULL,
+ N_("Redirect (bounce) the selected message to someone"),
+ G_CALLBACK (action_mail_redirect_cb) },
+
+ { "mail-reply-all",
+ "mail-reply-all",
+ N_("Reply to _All"),
+ "<Shift><Control>r",
+ N_("Compose a reply to all the recipients of the selected message"),
+ G_CALLBACK (action_mail_reply_all_cb) },
+
+ { "mail-reply-list",
+ NULL,
+ N_("Reply to _List"),
+ "<Control>l",
+ N_("Compose a reply to the mailing list of the selected message"),
+ G_CALLBACK (action_mail_reply_list_cb) },
+
+ { "mail-reply-sender",
+ "mail-reply-sender",
+ N_("_Reply to Sender"),
+ "<Control>r",
+ N_("Compose a reply to the sender of the selected message"),
+ G_CALLBACK (action_mail_reply_sender_cb) },
+
+ { "mail-save-as",
+ GTK_STOCK_SAVE_AS,
+ N_("_Save as mbox..."),
+ NULL,
+ N_("Save selected messages as an mbox file"),
+ G_CALLBACK (action_mail_save_as_cb) },
+
+ { "mail-search-folder-from-mailing-list",
+ NULL,
+ N_("Search Folder from Mailing _List..."),
+ NULL,
+ N_("Create a search folder for this mailing list"),
+ G_CALLBACK (action_mail_search_folder_from_mailing_list_cb) },
+
+ { "mail-search-folder-from-recipients",
+ NULL,
+ N_("Search Folder from Recipien_ts..."),
+ NULL,
+ N_("Create a search folder for these recipients"),
+ G_CALLBACK (action_mail_search_folder_from_recipients_cb) },
+
+ { "mail-search-folder-from-sender",
+ NULL,
+ N_("Search Folder from Sen_der..."),
+ NULL,
+ N_("Create a search folder for this sender"),
+ G_CALLBACK (action_mail_search_folder_from_sender_cb) },
+
+ { "mail-search-folder-from-subject",
+ NULL,
+ N_("Search Folder from S_ubject..."),
+ NULL,
+ N_("Create a search folder for this subject"),
+ G_CALLBACK (action_mail_search_folder_from_subject_cb) },
+
+ { "mail-select-all",
+ NULL,
+ N_("Select _All Text"),
+ "<Shift><Control>x",
+ N_("Select all the text in a message"),
+ G_CALLBACK (action_mail_select_all_cb) },
+
+ { "mail-show-source",
+ NULL,
+ N_("_Message Source"),
+ "<Control>u",
+ N_("Show the raw email source of the message"),
+ G_CALLBACK (action_mail_show_source_cb) },
+
+ { "mail-toggle-important",
+ NULL,
+ NULL, /* No menu item; key press only */
+ NULL,
+ NULL,
+ G_CALLBACK (action_mail_toggle_important_cb) },
+
+ { "mail-undelete",
+ NULL,
+ N_("_Undelete Message"),
+ "<Shift><Control>d",
+ N_("Undelete the selected messages"),
+ G_CALLBACK (action_mail_undelete_cb) },
+
+ { "mail-zoom-100",
+ GTK_STOCK_ZOOM_100,
+ N_("_Normal Size"),
+ "<Control>0",
+ N_("Reset the text to its original size"),
+ G_CALLBACK (action_mail_zoom_100_cb) },
+
+ { "mail-zoom-in",
+ GTK_STOCK_ZOOM_IN,
+ N_("_Zoom In"),
+ "<Control>plus",
+ N_("Increase the text size"),
+ G_CALLBACK (action_mail_zoom_in_cb) },
+
+ { "mail-zoom-out",
+ GTK_STOCK_ZOOM_OUT,
+ N_("Zoom _Out"),
+ "<Control>minus",
+ N_("Decrease the text size"),
+ G_CALLBACK (action_mail_zoom_out_cb) },
+
+ /*** Menus ***/
+
+ { "mail-create-rule-menu",
+ NULL,
+ N_("Create R_ule"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-encoding-menu",
+ NULL,
+ N_("Ch_aracter Encoding"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-forward-as-menu",
+ NULL,
+ N_("F_orward As..."),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-goto-menu",
+ GTK_STOCK_JUMP_TO,
+ N_("_Go To"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-mark-as-menu",
+ NULL,
+ N_("Mar_k As"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-message-menu",
+ NULL,
+ N_("_Message"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "mail-zoom-menu",
+ NULL,
+ N_("_Zoom"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static EPopupActionEntry mail_reader_popup_entries[] = {
+
+ { "mail-popup-copy",
+ NULL,
+ "mail-copy" },
+
+ { "mail-popup-delete",
+ NULL,
+ "mail-delete" },
+
+ { "mail-popup-flag-for-followup",
+ N_("Mark for Follo_w Up..."),
+ "mail-flag-for-followup" },
+
+ { "mail-popup-forward",
+ NULL,
+ "mail-forward" },
+
+ { "mail-popup-mark-important",
+ N_("Mark as _Important"),
+ "mail-mark-important" },
+
+ { "mail-popup-mark-junk",
+ N_("Mark as _Junk"),
+ "mail-mark-junk" },
+
+ { "mail-popup-mark-notjunk",
+ N_("Mark as _Not Junk"),
+ "mail-mark-notjunk" },
+
+ { "mail-popup-mark-read",
+ N_("Mark as _Read"),
+ "mail-mark-read" },
+
+ { "mail-popup-mark-unimportant",
+ N_("Mark as Uni_mportant"),
+ "mail-mark-unimportant" },
+
+ { "mail-popup-mark-unread",
+ N_("Mark as _Unread"),
+ "mail-mark-unread" },
+
+ { "mail-popup-message-edit",
+ NULL,
+ "mail-message-edit" },
+
+ { "mail-popup-move",
+ NULL,
+ "mail-move" },
+
+ { "mail-popup-print",
+ NULL,
+ "mail-print" },
+
+ { "mail-popup-reply-all",
+ NULL,
+ "mail-reply-all" },
+
+ { "mail-popup-reply-sender",
+ NULL,
+ "mail-reply-sender" },
+
+ { "mail-popup-save-as",
+ NULL,
+ "mail-save-as" },
+
+ { "mail-popup-undelete",
+ NULL,
+ "mail-undelete" }
+};
+
+static GtkToggleActionEntry mail_reader_toggle_entries[] = {
+
+ { "mail-caret-mode",
+ NULL,
+ N_("_Caret Mode"),
+ "F7",
+ N_("Show a blinking cursor in the body of displayed messages"),
+ NULL, /* No callback required */
+ FALSE },
+
+ { "mail-show-all-headers",
+ NULL,
+ N_("All Message _Headers"),
+ NULL,
+ N_("Show messages with all email headers"),
+ G_CALLBACK (action_mail_show_all_headers_cb),
+ FALSE }
+};
+
+static gboolean
+mail_reader_button_release_event_cb (EMailReader *reader,
+ GdkEventButton *button,
+ GtkHTML *html)
+{
+ GtkAction *action;
+ const gchar *action_name;
+ gboolean selection_active;
+
+ action_name = "mail-clipboard-copy";
+ action = e_mail_reader_get_action (reader, action_name);
+ selection_active = gtk_html_command (html, "is-selection-active");
+ gtk_action_set_sensitive (action, selection_active);
+
+ return FALSE;
+}
+
+static void
+mail_reader_double_click_cb (EMailReader *reader,
+ gint row,
+ ETreePath path,
+ gint col,
+ GdkEvent *event)
+{
+ /* Ignore double clicks on columns that handle their own state. */
+ if (MESSAGE_LIST_COLUMN_IS_ACTIVE (col))
+ return;
+
+ e_mail_reader_activate (reader, "mail-message-open");
+}
+
+static gboolean
+mail_reader_key_press_event_cb (EMailReader *reader,
+ GdkEventKey *event)
+{
+ const gchar *action_name;
+
+ if ((event->state & GDK_CONTROL_MASK) != 0)
+ goto ctrl;
+
+ /* <keyval> alone */
+ switch (event->keyval) {
+ case GDK_Delete:
+ case GDK_KP_Delete:
+ action_name = "mail-delete";
+ break;
+
+ case GDK_Return:
+ case GDK_KP_Enter:
+ case GDK_ISO_Enter:
+ action_name = "mail-message-open";
+ break;
+
+ case GDK_period:
+ case GDK_bracketleft:
+ action_name = "mail-next-unread";
+ break;
+
+ case GDK_comma:
+ case GDK_bracketright:
+ action_name = "mail-previous-unread";
+ break;
+
+#ifdef HAVE_XFREE
+ case XF86XK_Reply:
+ action_name = "mail-reply-all";
+ break;
+
+ case XF86XK_MailForward:
+ action_name = "mail-forward";
+ break;
+#endif
+
+ case GDK_exclam:
+ action_name = "mail-toggle-important";
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ goto exit;
+
+ctrl:
+
+ /* Ctrl + <keyval> */
+ switch (event->keyval) {
+ case GDK_period:
+ action_name = "mail-next-unread";
+ break;
+
+ case GDK_comma:
+ action_name = "mail-previous-unread";
+ break;
+
+ default:
+ return FALSE;
+ }
+
+exit:
+ e_mail_reader_activate (reader, action_name);
+
+ return TRUE;
+}
+
+static gint
+mail_reader_key_press_cb (EMailReader *reader,
+ gint row,
+ ETreePath path,
+ gint col,
+ GdkEvent *event)
+{
+ return mail_reader_key_press_event_cb (reader, &event->key);
+}
+
+static gboolean
+mail_reader_message_read_cb (EMailReader *reader)
+{
+ MessageList *message_list;
+ const gchar *uid;
+
+ message_list = e_mail_reader_get_message_list (reader);
+
+ uid = g_object_get_data (G_OBJECT (reader), "mark-read-uid");
+ g_return_val_if_fail (uid != NULL, FALSE);
+
+ if (g_strcmp0 (message_list->cursor_uid, uid) == 0)
+ e_mail_reader_mark_as_read (reader, uid);
+
+ return FALSE;
+}
+
+static void
+mail_reader_message_loaded_cb (CamelFolder *folder,
+ const gchar *message_uid,
+ CamelMimeMessage *message,
+ gpointer user_data,
+ CamelException *ex)
+{
+ EMailReader *reader = user_data;
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EShell *shell;
+ EMEvent *event;
+ EMEventTargetMessage *target;
+ gboolean mark_read;
+ gint timeout_interval;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ /* If the user picked a different message in the time it took
+ * to fetch this message, then don't bother rendering it. */
+ if (g_strcmp0 (message_list->cursor_uid, message_uid) != 0)
+ return;
+
+ /** @Event: message.reading
+ * @Title: Viewing a message
+ * @Target: EMEventTargetMessage
+ *
+ * message.reading is emitted whenever a user views a message.
+ */
+ event = em_event_peek ();
+ target = em_event_target_new_message (
+ event, folder, message, message_uid, 0);
+ e_event_emit (
+ (EEvent *) event, "message.reading",
+ (EEventTarget *) target);
+
+ em_format_format (
+ EM_FORMAT (html_display), folder, message_uid, message);
+
+ /* Reset the shell view icon. */
+ e_shell_event (shell, "mail-icon", (gpointer) "evolution-mail");
+
+ /* Determine whether to mark the message as read. */
+ mark_read = e_shell_settings_get_boolean (
+ shell_settings, "mail-mark-seen");
+ timeout_interval = e_shell_settings_get_int (
+ shell_settings, "mail-mark-seen-timeout");
+
+ g_object_set_data_full (
+ G_OBJECT (reader), "mark-read-uid",
+ g_strdup (message_uid), (GDestroyNotify) g_free);
+
+ if (message_list->seen_id > 0)
+ g_source_remove (message_list->seen_id);
+
+ if (mark_read) {
+ message_list->seen_id = g_timeout_add (
+ timeout_interval, (GSourceFunc)
+ mail_reader_message_read_cb, reader);
+
+ } else if (camel_exception_is_set (ex)) {
+ GtkHTMLStream *stream;
+
+ /* Display the error inline and clear the exception. */
+ stream = gtk_html_begin (
+ EM_FORMAT_HTML (html_display)->html);
+ gtk_html_stream_printf (
+ stream, "<h2>%s</h2><p>%s</p>",
+ _("Unable to retrieve message"),
+ ex->desc);
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
+ camel_exception_clear (ex);
+ }
+
+ e_mail_reader_update_actions (reader);
+
+ /* We referenced this in the call to mail_get_messagex(). */
+ g_object_unref (reader);
+}
+
+static gboolean
+mail_reader_message_selected_timeout_cb (EMailReader *reader)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ const gchar *cursor_uid;
+ const gchar *format_uid;
+ const gchar *key;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ cursor_uid = message_list->cursor_uid;
+ format_uid = EM_FORMAT (html_display)->uid;
+
+ if (message_list->last_sel_single) {
+ if (g_strcmp0 (cursor_uid, format_uid) != 0)
+ mail_get_messagex (
+ message_list->folder, cursor_uid,
+ mail_reader_message_loaded_cb,
+ g_object_ref (reader),
+ mail_msg_fast_ordered_push);
+ } else
+ em_format_format (EM_FORMAT (html_display), NULL, NULL, NULL);
+
+ key = "message-selected-timeout";
+ g_object_set_data (G_OBJECT (reader), key, NULL);
+
+ return FALSE;
+}
+
+static void
+mail_reader_message_selected_cb (EMailReader *reader,
+ const gchar *uid)
+{
+ const gchar *key;
+ guint source_id;
+ gpointer data;
+
+ /* XXX This is kludgy, but we have no other place to store
+ * timeout state information. */
+
+ key = "message-selected-timeout";
+ data = g_object_get_data (G_OBJECT (reader), key);
+ source_id = GPOINTER_TO_UINT (data);
+
+ if (source_id > 0)
+ g_source_remove (source_id);
+
+ source_id = g_timeout_add (
+ 100, (GSourceFunc)
+ mail_reader_message_selected_timeout_cb, reader);
+
+ data = GUINT_TO_POINTER (source_id);
+ g_object_set_data (G_OBJECT (reader), key, data);
+
+ e_mail_reader_changed (reader);
+}
+
+static void
+mail_reader_emit_folder_loaded (EMailReader *reader)
+{
+ g_signal_emit (reader, signals[FOLDER_LOADED], 0);
+}
+
+static void
+mail_reader_set_folder (EMailReader *reader,
+ CamelFolder *folder,
+ const gchar *folder_uri)
+{
+ EMFormatHTMLDisplay *html_display;
+ MessageList *message_list;
+ gboolean outgoing;
+
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+
+ outgoing = folder != NULL && folder_uri != NULL && (
+ em_utils_folder_is_drafts (folder, folder_uri) ||
+ em_utils_folder_is_outbox (folder, folder_uri) ||
+ em_utils_folder_is_sent (folder, folder_uri));
+
+ if (message_list->folder != NULL)
+ mail_sync_folder (message_list->folder, NULL, NULL);
+
+ em_format_format (EM_FORMAT (html_display), NULL, NULL, NULL);
+ message_list_set_folder (message_list, folder, folder_uri, outgoing);
+
+ mail_reader_emit_folder_loaded (reader);
+}
+
+static void
+mail_reader_set_message (EMailReader *reader,
+ const gchar *uid,
+ gboolean mark_read)
+{
+ MessageList *message_list;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ message_list_select_uid (message_list, uid);
+}
+
+static void
+mail_reader_init_charset_actions (EMailReader *reader)
+{
+ GtkActionGroup *action_group;
+ GtkRadioAction *default_action;
+ GSList *radio_group;
+
+ action_group = e_mail_reader_get_action_group (reader);
+
+ radio_group = e_charset_add_radio_actions (
+ action_group, "mail-charset-", NULL,
+ G_CALLBACK (action_mail_charset_cb), reader);
+
+ /* XXX Add a tooltip! */
+ default_action = gtk_radio_action_new (
+ "mail-charset-default", _("Default"), NULL, NULL, -1);
+
+ gtk_radio_action_set_group (default_action, radio_group);
+
+ g_signal_connect (
+ default_action, "changed",
+ G_CALLBACK (action_mail_charset_cb), reader);
+
+ gtk_action_group_add_action (
+ action_group, GTK_ACTION (default_action));
+
+ gtk_radio_action_set_current_value (default_action, -1);
+}
+
+static void
+mail_reader_class_init (EMailReaderIface *iface)
+{
+ iface->set_folder = mail_reader_set_folder;
+ iface->set_message = mail_reader_set_message;
+
+ signals[CHANGED] = g_signal_new (
+ "changed",
+ G_OBJECT_CLASS_TYPE (iface),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[FOLDER_LOADED] = g_signal_new (
+ "folder-loaded",
+ G_OBJECT_CLASS_TYPE (iface),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SHOW_SEARCH_BAR] = g_signal_new (
+ "show-search-bar",
+ G_OBJECT_CLASS_TYPE (iface),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMailReaderIface, show_search_bar),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+GType
+e_mail_reader_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMailReaderIface),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) mail_reader_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ 0, /* instance_size */
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ G_TYPE_INTERFACE, "EMailReader", &type_info, 0);
+
+ g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+ }
+
+ return type;
+}
+
+void
+e_mail_reader_init (EMailReader *reader)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EMFormatHTMLDisplay *html_display;
+ EMailDisplay *display;
+ GtkActionGroup *action_group;
+ MessageList *message_list;
+ GConfBridge *bridge;
+ GtkAction *action;
+ const gchar *action_name;
+ const gchar *key;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ action_group = e_mail_reader_get_action_group (reader);
+ html_display = e_mail_reader_get_html_display (reader);
+ message_list = e_mail_reader_get_message_list (reader);
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ display = E_MAIL_DISPLAY (EM_FORMAT_HTML (html_display)->html);
+
+ gtk_action_group_add_actions (
+ action_group, mail_reader_entries,
+ G_N_ELEMENTS (mail_reader_entries), reader);
+ e_action_group_add_popup_actions (
+ action_group, mail_reader_popup_entries,
+ G_N_ELEMENTS (mail_reader_popup_entries));
+ gtk_action_group_add_toggle_actions (
+ action_group, mail_reader_toggle_entries,
+ G_N_ELEMENTS (mail_reader_toggle_entries), reader);
+
+ mail_reader_init_charset_actions (reader);
+
+ /* Bind GObject properties to GConf keys. */
+
+ bridge = gconf_bridge_get ();
+
+ action_name = "mail-caret-mode";
+ key = "/apps/evolution/mail/display/caret_mode";
+ action = e_mail_reader_get_action (reader, action_name);
+ gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active");
+
+ action_name = "mail-show-all-headers";
+ key = "/apps/evolution/mail/display/show_all_headers";
+ action = e_mail_reader_get_action (reader, action_name);
+ gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active");
+
+ /* Fine tuning. */
+
+ action_name = "mail-clipboard-copy";
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, FALSE);
+
+ action_name = "mail-delete";
+ action = e_mail_reader_get_action (reader, action_name);
+ g_object_set (action, "short-label", _("Delete"), NULL);
+
+ action_name = "mail-next";
+ action = e_mail_reader_get_action (reader, action_name);
+ g_object_set (action, "short-label", _("Next"), NULL);
+
+ action_name = "mail-previous";
+ action = e_mail_reader_get_action (reader, action_name);
+ g_object_set (action, "short-label", _("Previous"), NULL);
+
+ action_name = "mail-reply-sender";
+ action = e_mail_reader_get_action (reader, action_name);
+ g_object_set (action, "short-label", _("Reply"), NULL);
+
+ action_name = "search-folder-recipient";
+ action = e_mail_display_get_action (display, action_name);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_search_folder_recipient_cb), reader);
+
+ action_name = "search-folder-sender";
+ action = e_mail_display_get_action (display, action_name);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_search_folder_sender_cb), reader);
+
+ /* Bind properties. */
+
+ e_binding_new_full (
+ G_OBJECT (shell_settings), "mail-citation-color",
+ G_OBJECT (html_display), "citation-color",
+ e_binding_transform_string_to_color,
+ NULL, NULL);
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "mail-image-loading-policy",
+ G_OBJECT (html_display), "image-loading-policy");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "mail-only-local-photos",
+ G_OBJECT (html_display), "only-local-photos");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "mail-show-animated-images",
+ G_OBJECT (display), "animate");
+
+ e_binding_new (
+ G_OBJECT (shell_settings), "mail-show-sender-photo",
+ G_OBJECT (html_display), "show-sender-photo");
+
+ action_name = "mail-caret-mode";
+ action = e_mail_reader_get_action (reader, action_name);
+
+ e_mutual_binding_new (
+ G_OBJECT (action), "active",
+ G_OBJECT (display), "caret-mode");
+
+ /* Connect signals. */
+
+ g_signal_connect_swapped (
+ display, "button-release-event",
+ G_CALLBACK (mail_reader_button_release_event_cb), reader);
+
+ g_signal_connect_swapped (
+ display, "key-press-event",
+ G_CALLBACK (mail_reader_key_press_event_cb), reader);
+
+ g_signal_connect_swapped (
+ message_list, "message-selected",
+ G_CALLBACK (mail_reader_message_selected_cb), reader);
+
+ g_signal_connect_swapped (
+ message_list, "message-list-built",
+ G_CALLBACK (mail_reader_emit_folder_loaded), reader);
+
+ g_signal_connect_swapped (
+ message_list->tree, "double-click",
+ G_CALLBACK (mail_reader_double_click_cb), reader);
+
+ g_signal_connect_swapped (
+ message_list->tree, "key-press",
+ G_CALLBACK (mail_reader_key_press_cb), reader);
+
+ g_signal_connect_swapped (
+ message_list->tree, "selection-change",
+ G_CALLBACK (e_mail_reader_changed), reader);
+}
+
+void
+e_mail_reader_changed (EMailReader *reader)
+{
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ g_signal_emit (reader, signals[CHANGED], 0);
+}
+
+guint32
+e_mail_reader_check_state (EMailReader *reader)
+{
+ MessageList *message_list;
+ GPtrArray *uids;
+ CamelFolder *folder;
+ CamelStore *store = NULL;
+ const gchar *folder_uri;
+ const gchar *tag;
+ gboolean can_clear_flags = FALSE;
+ gboolean can_flag_completed = FALSE;
+ gboolean can_flag_for_followup = FALSE;
+ gboolean has_deleted = FALSE;
+ gboolean has_important = FALSE;
+ gboolean has_junk = FALSE;
+ gboolean has_not_junk = FALSE;
+ gboolean has_read = FALSE;
+ gboolean has_undeleted = FALSE;
+ gboolean has_unimportant = FALSE;
+ gboolean has_unread = FALSE;
+ gboolean drafts_or_outbox;
+ gboolean store_supports_vjunk = FALSE;
+ guint32 state = 0;
+ guint ii;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
+
+ message_list = e_mail_reader_get_message_list (reader);
+ uids = message_list_get_selected (message_list);
+ folder_uri = message_list->folder_uri;
+ folder = message_list->folder;
+
+ if (folder != NULL) {
+ store = CAMEL_STORE (folder->parent_store);
+ store_supports_vjunk = (store->flags & CAMEL_STORE_VJUNK);
+ }
+
+ drafts_or_outbox =
+ em_utils_folder_is_drafts (folder, folder_uri) ||
+ em_utils_folder_is_outbox (folder, folder_uri);
+
+ for (ii = 0; ii < uids->len; ii++) {
+ CamelMessageInfo *info;
+ guint32 flags;
+
+ info = camel_folder_get_message_info (
+ folder, uids->pdata[ii]);
+ if (info == NULL)
+ continue;
+
+ flags = camel_message_info_flags (info);
+
+ if (flags & CAMEL_MESSAGE_SEEN)
+ has_read = TRUE;
+ else
+ has_unread = TRUE;
+
+ if (drafts_or_outbox) {
+ has_junk = FALSE;
+ has_not_junk = FALSE;
+ } else if (store_supports_vjunk) {
+ guint32 bitmask;
+
+ /* XXX Strictly speaking, this logic is correct.
+ * Problem is there's nothing in the message
+ * list that indicates whether a message is
+ * already marked "Not Junk". So the user may
+ * think the "Not Junk" button is enabling and
+ * disabling itself randomly as he reads mail. */
+
+ if (flags & CAMEL_MESSAGE_JUNK)
+ has_junk = TRUE;
+ if (flags & CAMEL_MESSAGE_NOTJUNK)
+ has_not_junk = TRUE;
+
+ bitmask = CAMEL_MESSAGE_JUNK | CAMEL_MESSAGE_NOTJUNK;
+
+ /* If neither junk flag is set, the
+ * message can be marked either way. */
+ if ((flags & bitmask) == 0) {
+ has_junk = TRUE;
+ has_not_junk = TRUE;
+ }
+
+ } else {
+ has_junk = TRUE;
+ has_not_junk = TRUE;
+ }
+
+ if (flags & CAMEL_MESSAGE_DELETED)
+ has_deleted = TRUE;
+ else
+ has_undeleted = TRUE;
+
+ if (flags & CAMEL_MESSAGE_FLAGGED)
+ has_important = TRUE;
+ else
+ has_unimportant = TRUE;
+
+ tag = camel_message_info_user_tag (info, "follow-up");
+ if (tag != NULL && *tag != '\0') {
+ can_clear_flags = TRUE;
+ tag = camel_message_info_user_tag (
+ info, "completed-on");
+ if (tag != NULL && *tag != '\0')
+ can_flag_completed = TRUE;
+ } else
+ can_flag_for_followup = TRUE;
+ }
+
+ if (em_utils_check_user_can_send_mail ())
+ state |= E_MAIL_READER_HAVE_ACCOUNT;
+ if (uids->len == 1)
+ state |= E_MAIL_READER_SELECTION_SINGLE;
+ if (uids->len > 1)
+ state |= E_MAIL_READER_SELECTION_MULTIPLE;
+ if (!drafts_or_outbox && uids->len == 1)
+ state |= E_MAIL_READER_SELECTION_CAN_ADD_SENDER;
+#if 0 /* FIXME */
+ if (can_edit)
+ state |= E_MAIL_READER_SELECTION_CAN_EDIT;
+#endif
+ if (can_clear_flags)
+ state |= E_MAIL_READER_SELECTION_FLAG_CLEAR;
+ if (can_flag_completed)
+ state |= E_MAIL_READER_SELECTION_FLAG_COMPLETED;
+ if (can_flag_for_followup)
+ state |= E_MAIL_READER_SELECTION_FLAG_FOLLOWUP;
+ if (has_deleted)
+ state |= E_MAIL_READER_SELECTION_HAS_DELETED;
+ if (has_important)
+ state |= E_MAIL_READER_SELECTION_HAS_IMPORTANT;
+ if (has_junk)
+ state |= E_MAIL_READER_SELECTION_HAS_JUNK;
+ if (has_not_junk)
+ state |= E_MAIL_READER_SELECTION_HAS_NOT_JUNK;
+ if (has_read)
+ state |= E_MAIL_READER_SELECTION_HAS_READ;
+ if (has_undeleted)
+ state |= E_MAIL_READER_SELECTION_HAS_UNDELETED;
+ if (has_unimportant)
+ state |= E_MAIL_READER_SELECTION_HAS_UNIMPORTANT;
+ if (has_unread)
+ state |= E_MAIL_READER_SELECTION_HAS_UNREAD;
+#if 0 /* FIXME */
+ if (has_http_uri)
+ state |= E_MAIL_READER_SELECTION_HAS_URI_HTTP;
+ if (has_mailto_uri)
+ state |= E_MAIL_READER_SELECTION_HAS_URI_MAILTO;
+ if (is_mailing_list)
+ state |= E_MAIL_READER_SELECTION_IS_MAILING_LIST;
+#endif
+
+ em_utils_uids_free (uids);
+
+ return state;
+
+}
+
+void
+e_mail_reader_update_actions (EMailReader *reader)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ GtkAction *action;
+ GtkActionGroup *action_group;
+ const gchar *action_name;
+ gboolean sensitive;
+ guint32 state;
+
+ /* Be descriptive. */
+ gboolean any_messages_selected;
+ gboolean disable_printing;
+ gboolean enable_flag_clear;
+ gboolean enable_flag_completed;
+ gboolean enable_flag_for_followup;
+ gboolean have_an_account;
+ gboolean multiple_messages_selected;
+ gboolean selection_has_deleted_messages;
+ gboolean selection_has_important_messages;
+ gboolean selection_has_junk_messages;
+ gboolean selection_has_not_junk_messages;
+ gboolean selection_has_read_messages;
+ gboolean selection_has_undeleted_messages;
+ gboolean selection_has_unimportant_messages;
+ gboolean selection_has_unread_messages;
+ gboolean selection_is_mailing_list;
+ gboolean single_message_selected;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ action_group = e_mail_reader_get_action_group (reader);
+ state = e_mail_reader_check_state (reader);
+
+ shell_backend = e_mail_reader_get_shell_backend (reader);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ disable_printing = e_shell_settings_get_boolean (
+ shell_settings, "disable-printing");
+
+ have_an_account =
+ (state & E_MAIL_READER_HAVE_ACCOUNT);
+ single_message_selected =
+ (state & E_MAIL_READER_SELECTION_SINGLE);
+ multiple_messages_selected =
+ (state & E_MAIL_READER_SELECTION_MULTIPLE);
+ /* FIXME Missing booleans */
+ enable_flag_clear =
+ (state & E_MAIL_READER_SELECTION_FLAG_CLEAR);
+ enable_flag_completed =
+ (state & E_MAIL_READER_SELECTION_FLAG_COMPLETED);
+ enable_flag_for_followup =
+ (state & E_MAIL_READER_SELECTION_FLAG_FOLLOWUP);
+ selection_has_deleted_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_DELETED);
+ selection_has_important_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_IMPORTANT);
+ selection_has_junk_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_JUNK);
+ selection_has_not_junk_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_NOT_JUNK);
+ selection_has_read_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_READ);
+ selection_has_undeleted_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_UNDELETED);
+ selection_has_unimportant_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_UNIMPORTANT);
+ selection_has_unread_messages =
+ (state & E_MAIL_READER_SELECTION_HAS_UNREAD);
+ /* FIXME Missing booleans */
+ selection_is_mailing_list =
+ (state & E_MAIL_READER_SELECTION_IS_MAILING_LIST);
+
+ any_messages_selected =
+ (single_message_selected || multiple_messages_selected);
+
+ action_name = "mail-check-for-junk";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-copy";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-delete";
+ sensitive = selection_has_undeleted_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-filters-apply";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-forward";
+ sensitive = have_an_account && any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-forward-attached";
+ sensitive = have_an_account && any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-forward-inline";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-forward-quoted";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-load-images";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-important";
+ sensitive = selection_has_unimportant_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-junk";
+ sensitive = selection_has_not_junk_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-notjunk";
+ sensitive = selection_has_junk_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-read";
+ sensitive = selection_has_unread_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-unimportant";
+ sensitive = selection_has_important_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-mark-unread";
+ sensitive = selection_has_read_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-message-edit";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-message-new";
+ sensitive = have_an_account;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-message-open";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-move";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-next-important";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-next-thread";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-next-unread";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-previous-important";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-previous-unread";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-print";
+ sensitive = single_message_selected && !disable_printing;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-print-preview";
+ sensitive = single_message_selected && !disable_printing;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-redirect";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-reply-all";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-reply-list";
+ sensitive = have_an_account && single_message_selected &&
+ selection_is_mailing_list;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-reply-sender";
+ sensitive = have_an_account && single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-save-as";
+ sensitive = any_messages_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-select-all";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-show-source";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-undelete";
+ sensitive = selection_has_deleted_messages;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-zoom-100";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-zoom-in";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+
+ action_name = "mail-zoom-out";
+ sensitive = single_message_selected;
+ action = e_mail_reader_get_action (reader, action_name);
+ gtk_action_set_sensitive (action, sensitive);
+}
+
+GtkAction *
+e_mail_reader_get_action (EMailReader *reader,
+ const gchar *action_name)
+{
+ GtkActionGroup *action_group;
+ GtkAction *action;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+ g_return_val_if_fail (action_name != NULL, NULL);
+
+ action_group = e_mail_reader_get_action_group (reader);
+ action = gtk_action_group_get_action (action_group, action_name);
+
+ if (action == NULL)
+ g_critical (
+ "%s: action `%s' not found", G_STRFUNC, action_name);
+
+ return action;
+}
+
+GtkActionGroup *
+e_mail_reader_get_action_group (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_action_group != NULL, NULL);
+
+ return iface->get_action_group (reader);
+}
+
+gboolean
+e_mail_reader_get_hide_deleted (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), FALSE);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_hide_deleted != NULL, FALSE);
+
+ return iface->get_hide_deleted (reader);
+}
+
+EMFormatHTMLDisplay *
+e_mail_reader_get_html_display (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_html_display != NULL, NULL);
+
+ return iface->get_html_display (reader);
+}
+
+MessageList *
+e_mail_reader_get_message_list (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_message_list != NULL, NULL);
+
+ return iface->get_message_list (reader);
+}
+
+EShellBackend *
+e_mail_reader_get_shell_backend (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_shell_backend != NULL, NULL);
+
+ return iface->get_shell_backend (reader);
+}
+
+GtkWindow *
+e_mail_reader_get_window (EMailReader *reader)
+{
+ EMailReaderIface *iface;
+
+ g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_val_if_fail (iface->get_window != NULL, NULL);
+
+ return iface->get_window (reader);
+}
+
+void
+e_mail_reader_set_folder (EMailReader *reader,
+ CamelFolder *folder,
+ const gchar *folder_uri)
+{
+ EMailReaderIface *iface;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_if_fail (iface->set_folder != NULL);
+
+ iface->set_folder (reader, folder, folder_uri);
+}
+
+/* Helper for e_mail_reader_set_folder_uri() */
+static void
+mail_reader_got_folder_cb (gchar *folder_uri,
+ CamelFolder *folder,
+ gpointer user_data)
+{
+ EMailReader *reader = user_data;
+
+ e_mail_reader_set_folder (reader, folder, folder_uri);
+}
+
+void
+e_mail_reader_set_folder_uri (EMailReader *reader,
+ const gchar *folder_uri)
+{
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+ g_return_if_fail (folder_uri != NULL);
+
+ /* Fetch the CamelFolder asynchronously. */
+ mail_get_folder (
+ folder_uri, 0, mail_reader_got_folder_cb,
+ reader, mail_msg_fast_ordered_push);
+}
+
+void
+e_mail_reader_set_message (EMailReader *reader,
+ const gchar *uid,
+ gboolean mark_read)
+{
+ EMailReaderIface *iface;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ iface = E_MAIL_READER_GET_IFACE (reader);
+ g_return_if_fail (iface->set_message != NULL);
+
+ iface->set_message (reader, uid, mark_read);
+}
+
+void
+e_mail_reader_create_charset_menu (EMailReader *reader,
+ GtkUIManager *ui_manager,
+ guint merge_id)
+{
+ GtkAction *action;
+ const gchar *action_name;
+ const gchar *path;
+ GSList *list;
+
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+ g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
+
+ action_name = "mail-charset-default";
+ action = e_mail_reader_get_action (reader, action_name);
+ g_return_if_fail (action != NULL);
+
+ list = gtk_radio_action_get_group (GTK_RADIO_ACTION (action));
+ list = g_slist_copy (list);
+ list = g_slist_remove (list, action);
+ list = g_slist_sort (list, (GCompareFunc) e_action_compare_by_label);
+
+ path = "/main-menu/view-menu/mail-message-view-actions/mail-encoding-menu";
+
+ while (list != NULL) {
+ action = list->data;
+
+ gtk_ui_manager_add_ui (
+ ui_manager, merge_id, path,
+ gtk_action_get_name (action),
+ gtk_action_get_name (action),
+ GTK_UI_MANAGER_AUTO, FALSE);
+
+ list = g_slist_delete_link (list, list);
+ }
+
+ gtk_ui_manager_ensure_update (ui_manager);
+}
+
+void
+e_mail_reader_show_search_bar (EMailReader *reader)
+{
+ g_return_if_fail (E_IS_MAIL_READER (reader));
+
+ g_signal_emit (reader, signals[SHOW_SEARCH_BAR], 0);
+}
diff --git a/mail/e-mail-reader.h b/mail/e-mail-reader.h
new file mode 100644
index 0000000000..08d6f23e51
--- /dev/null
+++ b/mail/e-mail-reader.h
@@ -0,0 +1,134 @@
+/*
+ * e-mail-reader.h
+ *
+ * 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)
+ *
+ */
+
+#ifndef E_MAIL_READER_H
+#define E_MAIL_READER_H
+
+#include <gtk/gtk.h>
+#include <camel/camel-folder.h>
+#include <mail/em-format-html-display.h>
+#include <mail/message-list.h>
+#include <shell/e-shell-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_READER \
+ (e_mail_reader_get_type ())
+#define E_MAIL_READER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_READER, EMailReader))
+#define E_MAIL_READER_IFACE(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_READER, EMailReaderIface))
+#define E_IS_MAIL_READER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_READER))
+#define E_IS_MAIL_READER_IFACE(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_READER))
+#define E_MAIL_READER_GET_IFACE(obj) \
+ (G_TYPE_INSTANCE_GET_INTERFACE \
+ ((obj), E_TYPE_MAIL_READER, EMailReaderIface))
+
+/* Basename of the UI definition file. */
+#define E_MAIL_READER_UI_DEFINITION "evolution-mail-reader.ui"
+
+G_BEGIN_DECLS
+
+typedef struct _EMailReader EMailReader;
+typedef struct _EMailReaderIface EMailReaderIface;
+
+enum {
+ E_MAIL_READER_HAVE_ACCOUNT = 1 << 0,
+ E_MAIL_READER_SELECTION_SINGLE = 1 << 1,
+ E_MAIL_READER_SELECTION_MULTIPLE = 1 << 2,
+ E_MAIL_READER_SELECTION_CAN_ADD_SENDER = 1 << 3,
+ E_MAIL_READER_SELECTION_CAN_EDIT = 1 << 4,
+ E_MAIL_READER_SELECTION_FLAG_CLEAR = 1 << 5,
+ E_MAIL_READER_SELECTION_FLAG_COMPLETED = 1 << 6,
+ E_MAIL_READER_SELECTION_FLAG_FOLLOWUP = 1 << 7,
+ E_MAIL_READER_SELECTION_HAS_DELETED = 1 << 8,
+ E_MAIL_READER_SELECTION_HAS_IMPORTANT = 1 << 9,
+ E_MAIL_READER_SELECTION_HAS_JUNK = 1 << 10,
+ E_MAIL_READER_SELECTION_HAS_NOT_JUNK = 1 << 11,
+ E_MAIL_READER_SELECTION_HAS_READ = 1 << 12,
+ E_MAIL_READER_SELECTION_HAS_UNDELETED = 1 << 13,
+ E_MAIL_READER_SELECTION_HAS_UNIMPORTANT = 1 << 14,
+ E_MAIL_READER_SELECTION_HAS_UNREAD = 1 << 15,
+ E_MAIL_READER_SELECTION_HAS_URI_HTTP = 1 << 16,
+ E_MAIL_READER_SELECTION_HAS_URI_MAILTO = 1 << 17,
+ E_MAIL_READER_SELECTION_IS_MAILING_LIST = 1 << 18
+};
+
+struct _EMailReaderIface {
+ GTypeInterface parent_iface;
+
+ GtkActionGroup *
+ (*get_action_group) (EMailReader *reader);
+ gboolean (*get_hide_deleted) (EMailReader *reader);
+ EMFormatHTMLDisplay *
+ (*get_html_display) (EMailReader *reader);
+ MessageList * (*get_message_list) (EMailReader *reader);
+ EShellBackend * (*get_shell_backend) (EMailReader *reader);
+ GtkWindow * (*get_window) (EMailReader *reader);
+
+ void (*set_folder) (EMailReader *reader,
+ CamelFolder *folder,
+ const gchar *folder_uri);
+ void (*set_message) (EMailReader *reader,
+ const gchar *uid,
+ gboolean mark_read);
+
+ /* Signals */
+ void (*show_search_bar) (EMailReader *reader);
+};
+
+GType e_mail_reader_get_type (void);
+void e_mail_reader_init (EMailReader *reader);
+void e_mail_reader_changed (EMailReader *reader);
+guint32 e_mail_reader_check_state (EMailReader *reader);
+void e_mail_reader_update_actions (EMailReader *reader);
+GtkAction * e_mail_reader_get_action (EMailReader *reader,
+ const gchar *action_name);
+GtkActionGroup *
+ e_mail_reader_get_action_group (EMailReader *reader);
+gboolean e_mail_reader_get_hide_deleted (EMailReader *reader);
+EMFormatHTMLDisplay *
+ e_mail_reader_get_html_display (EMailReader *reader);
+MessageList * e_mail_reader_get_message_list (EMailReader *reader);
+EShellBackend * e_mail_reader_get_shell_backend (EMailReader *reader);
+GtkWindow * e_mail_reader_get_window (EMailReader *reader);
+void e_mail_reader_set_folder (EMailReader *reader,
+ CamelFolder *folder,
+ const gchar *folder_uri);
+void e_mail_reader_set_folder_uri (EMailReader *reader,
+ const gchar *folder_uri);
+void e_mail_reader_set_message (EMailReader *reader,
+ const gchar *uid,
+ gboolean mark_read);
+void e_mail_reader_create_charset_menu
+ (EMailReader *reader,
+ GtkUIManager *ui_manager,
+ guint merge_id);
+void e_mail_reader_show_search_bar (EMailReader *reader);
+
+G_END_DECLS
+
+#endif /* E_MAIL_READER_H */
diff --git a/mail/e-mail-store.c b/mail/e-mail-store.c
new file mode 100644
index 0000000000..1fc3eb5b25
--- /dev/null
+++ b/mail/e-mail-store.c
@@ -0,0 +1,423 @@
+/*
+ * e-mail-store.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)
+ *
+ */
+
+#include "e-mail-store.h"
+
+#include <glib/gi18n.h>
+#include <camel/camel-service.h>
+#include <camel/camel-session.h>
+#include <camel/camel-url.h>
+#include <libedataserver/e-account.h>
+#include <libedataserver/e-account-list.h>
+
+#include "e-util/e-account-utils.h"
+
+#include "mail/e-mail-local.h"
+#include "mail/em-folder-tree-model.h"
+#include "mail/mail-folder-cache.h"
+#include "mail/mail-mt.h"
+#include "mail/mail-session.h"
+
+typedef struct _StoreInfo StoreInfo;
+
+typedef void (*AddStoreCallback) (CamelStore *store,
+ CamelFolderInfo *info,
+ StoreInfo *store_info);
+
+struct _StoreInfo {
+ gint ref_count;
+
+ CamelStore *store;
+ gchar *display_name;
+
+ /* Hold a reference to keep them alive. */
+ CamelFolder *vtrash;
+ CamelFolder *vjunk;
+
+ AddStoreCallback callback;
+
+ guint removed : 1;
+};
+
+CamelStore *vfolder_store; /* XXX write a get() function for this */
+static GHashTable *store_table;
+
+static MailAsyncEvent *async_event;
+
+static StoreInfo *
+store_info_new (CamelStore *store,
+ const gchar *display_name)
+{
+ CamelService *service;
+ StoreInfo *store_info;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+ service = CAMEL_SERVICE (store);
+
+ store_info = g_slice_new0 (StoreInfo);
+ store_info->ref_count = 1;
+
+ camel_object_ref (store);
+ store_info->store = store;
+
+ if (display_name == NULL)
+ store_info->display_name =
+ camel_service_get_name (service, TRUE);
+ else
+ store_info->display_name = g_strdup (display_name);
+
+ /* If these are vfolders then they need to be opened now,
+ * otherwise they won't keep track of all folders. */
+ if (store->flags & CAMEL_STORE_VTRASH)
+ store_info->vtrash = camel_store_get_trash (store, NULL);
+ if (store->flags & CAMEL_STORE_VJUNK)
+ store_info->vjunk = camel_store_get_junk (store, NULL);
+
+ return store_info;
+}
+
+static StoreInfo *
+store_info_ref (StoreInfo *store_info)
+{
+ g_return_val_if_fail (store_info != NULL, store_info);
+ g_return_val_if_fail (store_info->ref_count > 0, store_info);
+
+ g_atomic_int_add (&store_info->ref_count, 1);
+
+ return store_info;
+}
+
+static void
+store_info_unref (StoreInfo *store_info)
+{
+ g_return_if_fail (store_info != NULL);
+ g_return_if_fail (store_info->ref_count > 0);
+
+ if (g_atomic_int_exchange_and_add (&store_info->ref_count, -1) > 1)
+ return;
+
+ camel_object_unref (store_info->store);
+ g_free (store_info->display_name);
+
+ if (store_info->vtrash != NULL)
+ camel_object_unref (store_info->vtrash);
+
+ if (store_info->vjunk != NULL)
+ camel_object_unref (store_info->vjunk);
+
+ g_slice_free (StoreInfo, store_info);
+}
+
+static void
+store_table_free (StoreInfo *store_info)
+{
+ store_info->removed = 1;
+ store_info_unref (store_info);
+}
+
+static gboolean
+mail_store_note_store_cb (CamelStore *store,
+ CamelFolderInfo *info,
+ gpointer user_data)
+{
+ StoreInfo *store_info = user_data;
+
+ if (store_info->callback != NULL)
+ store_info->callback (store, info, store_info);
+
+ if (!store_info->removed) {
+ /* This keeps message counters up-to-date. */
+ if (store_info->vtrash != NULL)
+ mail_note_folder (store_info->vtrash);
+ if (store_info->vjunk != NULL)
+ mail_note_folder (store_info->vjunk);
+ }
+
+ store_info_unref (store_info);
+
+ return TRUE;
+}
+
+static void
+mail_store_add (CamelStore *store,
+ const gchar *display_name,
+ AddStoreCallback callback)
+{
+ EMFolderTreeModel *default_model;
+ StoreInfo *store_info;
+
+ g_return_if_fail (store_table != NULL);
+
+ default_model = em_folder_tree_model_get_default ();
+
+ store_info = store_info_new (store, display_name);
+ store_info->callback = callback;
+
+ g_hash_table_insert (store_table, store, store_info);
+
+ em_folder_tree_model_add_store (
+ default_model, store, store_info->display_name);
+
+ mail_note_store (
+ store, NULL,
+ mail_store_note_store_cb,
+ store_info_ref (store_info));
+}
+
+static void
+mail_store_add_local_done_cb (CamelStore *store,
+ CamelFolderInfo *info,
+ StoreInfo *store_info)
+{
+ CamelFolder *folder;
+ gint ii;
+
+ for (ii = 0; ii < E_MAIL_NUM_LOCAL_FOLDERS; ii++) {
+ folder = e_mail_local_get_folder (ii);
+ if (folder != NULL)
+ mail_note_folder (folder);
+ }
+}
+
+static void
+mail_store_add_local_cb (CamelStore *local_store,
+ const gchar *display_name)
+{
+ mail_store_add (
+ local_store, display_name,
+ (AddStoreCallback) mail_store_add_local_done_cb);
+}
+
+static void
+mail_store_load_accounts (const gchar *data_dir)
+{
+ CamelStore *local_store;
+ EAccountList *account_list;
+ EIterator *iter;
+
+ /* Set up the local store. */
+
+ e_mail_local_init (data_dir);
+ local_store = e_mail_local_get_store ();
+
+ mail_async_event_emit (
+ async_event, MAIL_ASYNC_GUI,
+ (MailAsyncFunc) mail_store_add_local_cb,
+ local_store, _("On This Computer"), NULL);
+
+ /* Set up remote stores. */
+
+ account_list = e_get_account_list ();
+
+ for (iter = e_list_get_iterator ((EList *) account_list);
+ e_iterator_is_valid (iter); e_iterator_next (iter)) {
+
+ EAccountService *service;
+ EAccount *account;
+ const gchar *display_name;
+ const gchar *uri;
+
+ account = (EAccount *) e_iterator_get (iter);
+ display_name = account->name;
+ service = account->source;
+ uri = service->url;
+
+ if (!account->enabled)
+ continue;
+
+ if (uri == NULL || *uri == '\0')
+ continue;
+
+ /* HACK: mbox URI's are handled by the local store setup
+ * above. Any that come through as account sources
+ * are really movemail sources! */
+ if (g_str_has_prefix (uri, "mbox:"))
+ continue;
+
+ e_mail_store_add_by_uri (uri, display_name);
+ }
+
+ g_object_unref (iter);
+}
+
+void
+e_mail_store_init (const gchar *data_dir)
+{
+ static gboolean initialized = FALSE;
+
+ g_return_if_fail (!initialized);
+ g_return_if_fail (data_dir != NULL);
+
+ /* Initialize global variables. */
+
+ store_table = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) store_table_free);
+
+ async_event = mail_async_event_new ();
+
+ mail_store_load_accounts (data_dir);
+
+ initialized = TRUE;
+}
+
+void
+e_mail_store_add (CamelStore *store,
+ const gchar *display_name)
+{
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (display_name != NULL);
+
+ mail_store_add (store, display_name, NULL);
+}
+
+CamelStore *
+e_mail_store_add_by_uri (const gchar *uri,
+ const gchar *display_name)
+{
+ CamelService *service;
+ CamelProvider *provider;
+ CamelException ex;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+ g_return_val_if_fail (display_name != NULL, NULL);
+
+ camel_exception_init (&ex);
+
+ /* Load the service, but don't connect. Check its provider,
+ * and if this belongs in the folder tree model, add it. */
+
+ provider = camel_provider_get (uri, &ex);
+ if (provider == NULL)
+ goto fail;
+
+ if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
+ return NULL;
+
+ service = camel_session_get_service (
+ session, uri, CAMEL_PROVIDER_STORE, &ex);
+ if (service == NULL)
+ goto fail;
+
+ e_mail_store_add (CAMEL_STORE (service), display_name);
+
+ camel_object_unref (service);
+
+ return CAMEL_STORE (service);
+
+fail:
+ /* FIXME: Show an error dialog. */
+ g_warning (
+ "Couldn't get service: %s: %s", uri,
+ camel_exception_get_description (&ex));
+ camel_exception_clear (&ex);
+
+ return NULL;
+}
+
+/* Helper for e_mail_store_remove() */
+static void
+mail_store_remove_cb (CamelStore *store)
+{
+ camel_service_disconnect (CAMEL_SERVICE (store), TRUE, NULL);
+ camel_object_unref (store);
+}
+
+void
+e_mail_store_remove (CamelStore *store)
+{
+ EMFolderTreeModel *default_model;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (store_table != NULL);
+ g_return_if_fail (async_event != NULL);
+
+ /* Because the store table holds a reference to each store used
+ * as a key in it, none of them will ever be gc'ed, meaning any
+ * call to camel_session_get_{service,store} with the same URL
+ * will always return the same object. So this works. */
+
+ if (g_hash_table_lookup (store_table, store) == NULL)
+ return;
+
+ camel_object_ref (store);
+
+ g_hash_table_remove (store_table, store);
+ mail_note_store_remove (store);
+
+ default_model = em_folder_tree_model_get_default ();
+ em_folder_tree_model_remove_store (default_model, store);
+
+ mail_async_event_emit (
+ async_event, MAIL_ASYNC_THREAD,
+ (MailAsyncFunc) mail_store_remove_cb,
+ store, NULL, NULL);
+}
+
+void
+e_mail_store_remove_by_uri (const gchar *uri)
+{
+ CamelService *service;
+ CamelProvider *provider;
+
+ g_return_if_fail (uri != NULL);
+
+ provider = camel_provider_get (uri, NULL);
+ if (provider == NULL)
+ return;
+
+ if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
+ return;
+
+ service = camel_session_get_service (
+ session, uri, CAMEL_PROVIDER_STORE, NULL);
+ if (service == NULL)
+ return;
+
+ e_mail_store_remove (CAMEL_STORE (service));
+
+ camel_object_unref (service);
+}
+
+void
+e_mail_store_foreach (GHFunc func,
+ gpointer user_data)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_return_if_fail (func != NULL);
+ g_return_if_fail (store_table != NULL);
+
+ g_hash_table_iter_init (&iter, store_table);
+
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ StoreInfo *store_info = value;
+
+ /* Just being paranoid. */
+ g_return_if_fail (CAMEL_IS_STORE (key));
+ g_return_if_fail (store_info != NULL);
+
+ func (key, store_info->display_name, user_data);
+ }
+}
diff --git a/mail/mail-config-factory.h b/mail/e-mail-store.h
index e32d730089..bfd1ab47c8 100644
--- a/mail/mail-config-factory.h
+++ b/mail/e-mail-store.h
@@ -1,4 +1,6 @@
/*
+ * e-mail-store.h
+ *
* 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
@@ -13,27 +15,28 @@
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
-#ifndef __MAIL_CONFIG_FACTORY_H__
-#define __MAIL_CONFIG_FACTORY_H__
-
-G_BEGIN_DECLS
-
-#include <bonobo/bonobo-generic-factory.h>
-#include "evolution-config-control.h"
+#ifndef E_MAIL_STORE_H
+#define E_MAIL_STORE_H
-#include <shell/Evolution.h>
+#include <glib.h>
+#include <camel/camel-store.h>
-gboolean mail_config_register_factory (GNOME_Evolution_Shell shell);
+G_BEGIN_DECLS
-BonoboObject *mail_config_control_factory_cb (BonoboGenericFactory *factory, const gchar *component_id, gpointer user_data);
+void e_mail_store_init (const gchar *data_dir);
+void e_mail_store_add (CamelStore *store,
+ const gchar *display_name);
+CamelStore * e_mail_store_add_by_uri (const gchar *uri,
+ const gchar *display_name);
+void e_mail_store_remove (CamelStore *store);
+void e_mail_store_remove_by_uri (const gchar *uri);
+void e_mail_store_foreach (GHFunc func,
+ gpointer user_data);
G_END_DECLS
-#endif /* __MAIL_CONFIG_FACTORY_H__ */
+#endif /* E_MAIL_STORE_H */
diff --git a/mail/e-searching-tokenizer.c b/mail/e-searching-tokenizer.c
index 32a2d6ccd3..b9a00cddf3 100644
--- a/mail/e-searching-tokenizer.c
+++ b/mail/e-searching-tokenizer.c
@@ -38,76 +38,17 @@
#define d(x)
+#define E_SEARCHING_TOKENIZER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerPrivate))
+
enum {
MATCH_SIGNAL,
LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL] = { 0, };
-
-static void e_searching_tokenizer_begin (HTMLTokenizer *, const gchar *);
-static void e_searching_tokenizer_end (HTMLTokenizer *);
-static gchar *e_searching_tokenizer_peek_token (HTMLTokenizer *);
-static gchar *e_searching_tokenizer_next_token (HTMLTokenizer *);
-static gboolean e_searching_tokenizer_has_more (HTMLTokenizer *);
-
-static HTMLTokenizer *e_searching_tokenizer_clone (HTMLTokenizer *);
-
-/*
- static const gchar *space_tags[] = { "br", NULL };*/
-
-static HTMLTokenizerClass *parent_class = NULL;
-
-/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
-
-/* ???
-typedef struct _SharedState SharedState;
-struct _SharedState {
- gint refs;
- gchar *str_primary;
- gchar *str_secondary;
- gboolean case_sensitive_primary;
- gboolean case_sensitive_secondary;
-};
-*/
-
-/* ********************************************************************** */
-
-#if 0
-static SharedState *
-shared_state_new (void)
-{
- SharedState *shared = g_new0 (SharedState, 1);
- shared->refs = 1;
- return shared;
-}
-
-static void
-shared_state_ref (SharedState *shared)
-{
- g_return_if_fail (shared != NULL);
- g_return_if_fail (shared->refs > 0);
- ++shared->refs;
-}
-
-static void
-shared_state_unref (SharedState *shared)
-{
- if (shared) {
- g_return_if_fail (shared->refs > 0);
- --shared->refs;
- if (shared->refs == 0) {
- g_free (shared->str_primary);
- g_free (shared->str_secondary);
- g_free (shared);
- }
- }
-}
-#endif
-
-/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
-
-/* ********************************************************************** */
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
/* Utility functions */
@@ -183,7 +124,7 @@ ignore_tag (const gchar *tag)
*out = 0;
for (i=0;i<sizeof(ignored_tags)/sizeof(ignored_tags[0]);i++) {
- if (strcmp(t, ignored_tags[i]) == 0)
+ if (strcmp (t, ignored_tags[i]) == 0)
return 1;
}
@@ -221,7 +162,7 @@ struct _trie {
/* will be enabled only if debug is enabled */
#if d(1) -1 != -1
static void
-dump_trie(struct _state *s, gint d)
+dump_trie (struct _state *s, gint d)
{
gchar *p = alloca(d*2+1);
struct _match *m;
@@ -234,7 +175,7 @@ dump_trie(struct _state *s, gint d)
while (m) {
printf(" %s'%c' -> %p\n", p, m->ch, m->match);
if (m->match)
- dump_trie(m->match, d+1);
+ dump_trie (m->match, d+1);
m = m->next;
}
}
@@ -246,7 +187,7 @@ dump_trie(struct _state *s, gint d)
for a neat demo */
static inline struct _match *
-g(struct _state *q, guint32 c)
+g (struct _state *q, guint32 c)
{
struct _match *m = q->matches;
@@ -257,7 +198,7 @@ g(struct _state *q, guint32 c)
}
static struct _trie *
-build_trie(gint nocase, gint len, guchar **words)
+build_trie (gint nocase, gint len, guchar **words)
{
struct _state *q, *qt, *r;
const guchar *word;
@@ -274,8 +215,8 @@ build_trie(gint nocase, gint len, guchar **words)
trie->root.fail = NULL;
trie->root.next = NULL;
- trie->state_chunks = e_memchunk_new(8, sizeof(struct _state));
- trie->match_chunks = e_memchunk_new(8, sizeof(struct _match));
+ trie->state_chunks = e_memchunk_new (8, sizeof(struct _state));
+ trie->match_chunks = e_memchunk_new (8, sizeof(struct _match));
/* This will correspond to the length of the longest pattern */
state_depth_size = 0;
@@ -293,8 +234,8 @@ build_trie(gint nocase, gint len, guchar **words)
depth = 0;
while ((c = camel_utf8_getc (&word))) {
if (nocase)
- c = g_unichar_tolower(c);
- m = g(q, c);
+ c = g_unichar_tolower (c);
+ m = g (q, c);
if (m == NULL) {
m = e_memchunk_alloc(trie->match_chunks);
m->ch = c;
@@ -323,7 +264,7 @@ build_trie(gint nocase, gint len, guchar **words)
}
d(printf("Dumping trie:\n"));
- d(dump_trie(&trie->root, 0));
+ d(dump_trie (&trie->root, 0));
/* Step 2: Build failure graph */
@@ -339,14 +280,14 @@ build_trie(gint nocase, gint len, guchar **words)
c = m->ch;
qt = m->match;
r = q->fail;
- while (r && (n = g(r, c)) == NULL)
+ while (r && (n = g (r, c)) == NULL)
r = r->fail;
if (r != NULL) {
qt->fail = n->match;
if (qt->fail->final > qt->final)
qt->final = qt->fail->final;
} else {
- if ((n = g(&trie->root, c)))
+ if ((n = g (&trie->root, c)))
qt->fail = n->match;
else
qt->fail = &trie->root;
@@ -357,10 +298,10 @@ build_trie(gint nocase, gint len, guchar **words)
}
}
- d(printf("After failure analysis\n"));
- d(dump_trie(&trie->root, 0));
+ d (printf("After failure analysis\n"));
+ d (dump_trie (&trie->root, 0));
- g_free(state_depth);
+ g_free (state_depth);
trie->max_depth = state_depth_size;
@@ -368,12 +309,12 @@ build_trie(gint nocase, gint len, guchar **words)
}
static void
-free_trie(struct _trie *t)
+free_trie (struct _trie *t)
{
e_memchunk_destroy(t->match_chunks);
e_memchunk_destroy(t->state_chunks);
- g_free(t);
+ g_free (t);
}
/* ********************************************************************** */
@@ -443,10 +384,10 @@ searcher_new (gint flags, gint argc, guchar **argv, const gchar *tags, const gch
s = g_malloc(sizeof(*s));
- s->t = build_trie((flags&SEARCH_CASE) == 0, argc, argv);
+ s->t = build_trie ((flags&SEARCH_CASE) == 0, argc, argv);
s->words = argc;
- s->tags = g_strdup(tags);
- s->tage = g_strdup(tage);
+ s->tags = g_strdup (tags);
+ s->tage = g_strdup (tage);
s->flags = flags;
s->state = &s->t->root;
s->matchcount = 0;
@@ -475,20 +416,20 @@ searcher_new (gint flags, gint argc, guchar **argv, const gchar *tags, const gch
}
static void
-searcher_free(struct _searcher *s)
+searcher_free (struct _searcher *s)
{
struct _token *t;
- while ((t = (struct _token *)e_dlist_remhead(&s->input)))
- g_free(t);
- while ((t = (struct _token *)e_dlist_remhead(&s->output)))
- g_free(t);
- g_free(s->tags);
- g_free(s->tage);
- g_free(s->last);
- g_free(s->submatches);
- free_trie(s->t);
- g_free(s);
+ while ((t = (struct _token *)e_dlist_remhead (&s->input)))
+ g_free (t);
+ while ((t = (struct _token *)e_dlist_remhead (&s->output)))
+ g_free (t);
+ g_free (s->tags);
+ g_free (s->tage);
+ g_free (s->last);
+ g_free (s->submatches);
+ free_trie (s->t);
+ g_free (s);
}
static struct _token *
append_token(EDList *list, const gchar *tok, gint len)
@@ -506,7 +447,7 @@ append_token(EDList *list, const gchar *tok, gint len)
return token;
}
-#define free_token(x) (g_free(x))
+#define free_token(x) (g_free (x))
static void
output_token(struct _searcher *s, struct _token *token)
@@ -516,10 +457,10 @@ output_token(struct _searcher *s, struct _token *token)
if (token->tok[0] == TAG_ESCAPE) {
if (token->offset >= s->offout) {
- d(printf("moving tag token '%s' from input to output\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("moving tag token '%s' from input to output\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
e_dlist_addtail(&s->output, (EDListNode *)token);
} else {
- d(printf("discarding tag token '%s' from input\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("discarding tag token '%s' from input\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
free_token(token);
}
} else {
@@ -528,12 +469,12 @@ output_token(struct _searcher *s, struct _token *token)
if (left > 0) {
pre = s->offout - token->offset;
if (pre>0)
- memmove(token->tok, token->tok+pre, left+1);
- d(printf("adding partial remaining/failed '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ memmove (token->tok, token->tok+pre, left+1);
+ d (printf("adding partial remaining/failed '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
s->offout = offend;
e_dlist_addtail(&s->output, (EDListNode *)token);
} else {
- d(printf("discarding whole token '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("discarding whole token '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
free_token(token);
}
}
@@ -562,30 +503,30 @@ output_match(struct _searcher *s, guint start, guint end)
struct _token *starttoken, *endtoken;
gchar b[8];
- d(printf("output match: %d-%d at %d\n", start, end, s->offout));
+ d (printf("output match: %d-%d at %d\n", start, end, s->offout));
starttoken = find_token(s, start);
endtoken = find_token(s, end);
if (starttoken == NULL || endtoken == NULL) {
- d(printf("Cannot find match history for match %d-%d\n", start, end));
+ d (printf("Cannot find match history for match %d-%d\n", start, end));
return;
}
- d(printf("start in token '%s'\n", starttoken->tok[0]==TAG_ESCAPE?starttoken->tok+1:starttoken->tok));
- d(printf("end in token '%s'\n", endtoken->tok[0]==TAG_ESCAPE?endtoken->tok+1:endtoken->tok));
+ d (printf("start in token '%s'\n", starttoken->tok[0]==TAG_ESCAPE?starttoken->tok+1:starttoken->tok));
+ d (printf("end in token '%s'\n", endtoken->tok[0]==TAG_ESCAPE?endtoken->tok+1:endtoken->tok));
/* output pending stuff that didn't match afterall */
while ((struct _token *)s->input.head != starttoken) {
- token = (struct _token *)e_dlist_remhead(&s->input);
- d(printf("appending failed match '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ token = (struct _token *)e_dlist_remhead (&s->input);
+ d (printf("appending failed match '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
output_token(s, token);
}
/* output any pre-match text */
if (s->offout < start) {
token = append_token(&s->output, starttoken->tok + (s->offout-starttoken->offset), start-s->offout);
- d(printf("adding pre-match text '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("adding pre-match text '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
s->offout = start;
}
@@ -597,11 +538,11 @@ output_match(struct _searcher *s, guint start, guint end)
if (s->tags)
append_token(&s->output, s->tags, -1);
- /* output match node(s) */
+ /* output match node (s) */
if (starttoken != endtoken) {
while ((struct _token *)s->input.head != endtoken) {
- token = (struct _token *)e_dlist_remhead(&s->input);
- d(printf("appending (partial) match node (head) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ token = (struct _token *)e_dlist_remhead (&s->input);
+ d (printf("appending (partial) match node (head) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
output_token(s, token);
}
}
@@ -609,7 +550,7 @@ output_match(struct _searcher *s, guint start, guint end)
/* any remaining partial content */
if (s->offout < end) {
token = append_token(&s->output, endtoken->tok+(s->offout-endtoken->offset), end-s->offout);
- d(printf("appending (partial) match node (tail) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("appending (partial) match node (tail) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
s->offout = end;
}
@@ -626,7 +567,7 @@ output_match(struct _searcher *s, guint start, guint end)
/* output any sub-pending blocks */
static void
-output_subpending(struct _searcher *s)
+output_subpending (struct _searcher *s)
{
gint i;
@@ -637,7 +578,7 @@ output_subpending(struct _searcher *s)
/* returns true if a merge took place */
static gint
-merge_subpending(struct _searcher *s, gint offstart, gint offend)
+merge_subpending (struct _searcher *s, gint offstart, gint offend)
{
gint i;
@@ -662,11 +603,11 @@ merge_subpending(struct _searcher *s, gint offstart, gint offend)
}
static void
-push_subpending(struct _searcher *s, gint offstart, gint offend)
+push_subpending (struct _searcher *s, gint offstart, gint offend)
{
/* This is really an assertion, we just ignore the last pending match instead of crashing though */
if (s->submatchp >= s->words) {
- d(printf("ERROR: submatch pending stack overflow\n"));
+ d (printf("ERROR: submatch pending stack overflow\n"));
s->submatchp = s->words-1;
}
@@ -677,11 +618,11 @@ push_subpending(struct _searcher *s, gint offstart, gint offend)
/* move any (partial) tokens from input to output if they are beyond the current output position */
static void
-output_pending(struct _searcher *s)
+output_pending (struct _searcher *s)
{
struct _token *token;
- while ( (token = (struct _token *)e_dlist_remhead(&s->input)) )
+ while ( (token = (struct _token *)e_dlist_remhead (&s->input)) )
output_token(s, token);
}
@@ -705,7 +646,7 @@ flush_extra(struct _searcher *s)
return;
while ((struct _token *)s->input.head != starttoken) {
- token = (struct _token *)e_dlist_remhead(&s->input);
+ token = (struct _token *)e_dlist_remhead (&s->input);
output_token(s, token);
}
}
@@ -725,8 +666,8 @@ searcher_next_token(struct _searcher *s)
/* get next token */
tok = (guchar *)s->next_token(s->next_data);
if (tok == NULL) {
- output_subpending(s);
- output_pending(s);
+ output_subpending (s);
+ output_pending (s);
break;
}
@@ -735,14 +676,14 @@ searcher_next_token(struct _searcher *s)
token->offset = s->offset;
tok = (guchar *)token->tok;
- d(printf("new token %d '%s'\n", token->offset, token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
+ d (printf("new token %d '%s'\n", token->offset, token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok));
/* tag test, reset state on unknown tags */
if (tok[0] == TAG_ESCAPE) {
if (!ignore_tag ((gchar *)tok)) {
/* force reset */
- output_subpending(s);
- output_pending(s);
+ output_subpending (s);
+ output_pending (s);
q = &t->root;
}
@@ -753,12 +694,12 @@ searcher_next_token(struct _searcher *s)
pre_tok = stok = tok;
while ((c = camel_utf8_getc (&tok))) {
if ((s->flags & SEARCH_CASE) == 0)
- c = g_unichar_tolower(c);
- while (q && (m = g(q, c)) == NULL)
+ c = g_unichar_tolower (c);
+ while (q && (m = g (q, c)) == NULL)
q = q->fail;
if (q == NULL) {
/* mismatch ... reset state */
- output_subpending(s);
+ output_subpending (s);
q = &t->root;
} else if (m != NULL) {
/* keep track of previous offsets of utf8 chars, rotating buffer */
@@ -777,21 +718,21 @@ searcher_next_token(struct _searcher *s)
if (q->matches == NULL) {
if (s->submatchp == 0) {
/* nothing pending, always put something in so we can try merge */
- push_subpending(s, offstart, offend);
- } else if (!merge_subpending(s, offstart, offend)) {
+ push_subpending (s, offstart, offend);
+ } else if (!merge_subpending (s, offstart, offend)) {
/* can't merge, output what we have, and start againt */
- output_subpending(s);
- push_subpending(s, offstart, offend);
+ output_subpending (s);
+ push_subpending (s, offstart, offend);
/*output_match(s, offstart, offend);*/
} else if (e_dlist_length(&s->input) > 8) {
/* we're continuing to match and merge, but we have a lot of stuff
waiting, so flush it out now since this is a safe point to do it */
- output_subpending(s);
+ output_subpending (s);
}
} else {
/* merge/add subpending */
- if (!merge_subpending(s, offstart, offend))
- push_subpending(s, offstart, offend);
+ if (!merge_subpending (s, offstart, offend))
+ push_subpending (s, offstart, offend);
}
}
}
@@ -808,7 +749,7 @@ searcher_next_token(struct _searcher *s)
if (s->current)
free_token(s->current);
- s->current = token = (struct _token *)e_dlist_remhead(&s->output);
+ s->current = token = (struct _token *)e_dlist_remhead (&s->output);
return token ? g_strdup (token->tok) : NULL;
}
@@ -822,7 +763,7 @@ searcher_peek_token(struct _searcher *s)
tok = searcher_next_token(s);
if (tok) {
/* need to clear this so we dont free it while its still active */
- e_dlist_addhead(&s->output, (EDListNode *)s->current);
+ e_dlist_addhead (&s->output, (EDListNode *)s->current);
s->current = NULL;
}
@@ -830,7 +771,7 @@ searcher_peek_token(struct _searcher *s)
}
static gint
-searcher_pending(struct _searcher *s)
+searcher_pending (struct _searcher *s)
{
return !(e_dlist_empty(&s->input) && e_dlist_empty(&s->output));
}
@@ -839,7 +780,7 @@ searcher_pending(struct _searcher *s)
struct _search_info {
GPtrArray *strv;
- gchar *colour;
+ gchar *color;
guint size:8;
guint flags:8;
};
@@ -847,12 +788,12 @@ struct _search_info {
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
static struct _search_info *
-search_info_new(void)
+search_info_new (void)
{
struct _search_info *s;
s = g_malloc0(sizeof(struct _search_info));
- s->strv = g_ptr_array_new();
+ s->strv = g_ptr_array_new ();
return s;
}
@@ -864,14 +805,14 @@ search_info_set_flags(struct _search_info *si, guint flags, guint mask)
}
static void
-search_info_set_colour(struct _search_info *si, const gchar *colour)
+search_info_set_color (struct _search_info *si, const gchar *color)
{
- g_free(si->colour);
- si->colour = g_strdup(colour);
+ g_free (si->color);
+ si->color = g_strdup (color);
}
static void
-search_info_add_string(struct _search_info *si, const gchar *s)
+search_info_add_string (struct _search_info *si, const gchar *s)
{
const guchar *start;
guint32 c;
@@ -888,44 +829,44 @@ search_info_add_string(struct _search_info *si, const gchar *s)
}
/* should probably also strip trailing, but i'm lazy today */
if (start[0])
- g_ptr_array_add(si->strv, g_strdup ((gchar *)start));
+ g_ptr_array_add (si->strv, g_strdup ((gchar *)start));
}
}
static void
-search_info_clear(struct _search_info *si)
+search_info_clear (struct _search_info *si)
{
gint i;
for (i=0;i<si->strv->len;i++)
- g_free(si->strv->pdata[i]);
+ g_free (si->strv->pdata[i]);
- g_ptr_array_set_size(si->strv, 0);
+ g_ptr_array_set_size (si->strv, 0);
}
static void
-search_info_free(struct _search_info *si)
+search_info_free (struct _search_info *si)
{
gint i;
for (i=0;i<si->strv->len;i++)
- g_free(si->strv->pdata[i]);
+ g_free (si->strv->pdata[i]);
- g_ptr_array_free(si->strv, TRUE);
- g_free(si->colour);
- g_free(si);
+ g_ptr_array_free (si->strv, TRUE);
+ g_free (si->color);
+ g_free (si);
}
static struct _search_info *
-search_info_clone(struct _search_info *si)
+search_info_clone (struct _search_info *si)
{
struct _search_info *out;
gint i;
- out = search_info_new();
+ out = search_info_new ();
for (i=0;i<si->strv->len;i++)
- g_ptr_array_add(out->strv, g_strdup(si->strv->pdata[i]));
- out->colour = g_strdup(si->colour);
+ g_ptr_array_add (out->strv, g_strdup (si->strv->pdata[i]));
+ out->color = g_strdup (si->color);
out->flags = si->flags;
out->size = si->size;
@@ -933,7 +874,7 @@ search_info_clone(struct _search_info *si)
}
static struct _searcher *
-search_info_to_searcher(struct _search_info *si)
+search_info_to_searcher (struct _search_info *si)
{
gchar *tags, *tage;
const gchar *col;
@@ -941,10 +882,10 @@ search_info_to_searcher(struct _search_info *si)
if (si->strv->len == 0)
return NULL;
- if (si->colour == NULL)
+ if (si->color == NULL)
col = "red";
else
- col = si->colour;
+ col = si->color;
tags = alloca(20+strlen(col));
sprintf(tags, "%c<font color=\"%s\">", TAG_ESCAPE, col);
@@ -963,287 +904,289 @@ struct _ESearchingTokenizerPrivate {
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
-static void
-e_searching_tokenizer_finalise (GObject *obj)
-{
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (obj);
- struct _ESearchingTokenizerPrivate *p = st->priv;
-
- search_info_free (p->primary);
- search_info_free (p->secondary);
- if (p->engine)
- searcher_free(p->engine);
+/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
- /* again wtf?
- shared_state_unref (st->priv->shared);
- */
+/* blah blah the htmltokeniser doesn't like being asked
+ for a token if it doens't hvae any! */
+static gchar *
+get_token (HTMLTokenizer *tokenizer)
+{
+ HTMLTokenizerClass *class = HTML_TOKENIZER_CLASS (parent_class);
- g_free (p);
+ if (class->has_more (tokenizer))
+ return class->next_token (tokenizer);
- if (G_OBJECT_CLASS (parent_class)->finalize)
- G_OBJECT_CLASS (parent_class)->finalize(obj);
+ return NULL;
}
+/* proxy matched event, not sure what its for otherwise */
static void
-e_searching_tokenizer_class_init (ESearchingTokenizerClass *klass)
+matched (ESearchingTokenizer *tokenizer)
{
- GObjectClass *obj_class = (GObjectClass *) klass;
- HTMLTokenizerClass *tok_class = HTML_TOKENIZER_CLASS (klass);
-
- parent_class = g_type_class_ref (HTML_TYPE_TOKENIZER);
-
- signals[MATCH_SIGNAL] =
- g_signal_new ("match",
- E_TYPE_SEARCHING_TOKENIZER,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (ESearchingTokenizerClass, match),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- obj_class->finalize = e_searching_tokenizer_finalise;
-
- tok_class->begin = e_searching_tokenizer_begin;
- tok_class->end = e_searching_tokenizer_end;
-
- tok_class->peek_token = e_searching_tokenizer_peek_token;
- tok_class->next_token = e_searching_tokenizer_next_token;
- tok_class->has_more = e_searching_tokenizer_has_more;
- tok_class->clone = e_searching_tokenizer_clone;
+ /*++tokenizer->priv->match_count;*/
+ g_signal_emit (tokenizer, signals[MATCH_SIGNAL], 0);
}
-static void
-e_searching_tokenizer_init (ESearchingTokenizer *st)
-{
- struct _ESearchingTokenizerPrivate *p;
-
- p = st->priv = g_new0 (struct _ESearchingTokenizerPrivate, 1);
-
- p->primary = search_info_new();
- search_info_set_flags(p->primary, SEARCH_BOLD, SEARCH_CASE|SEARCH_BOLD);
- search_info_set_colour(p->primary, "red");
-
- p->secondary = search_info_new();
- search_info_set_flags(p->secondary, SEARCH_BOLD, SEARCH_CASE|SEARCH_BOLD);
- search_info_set_colour(p->secondary, "purple");
-}
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-GType
-e_searching_tokenizer_get_type (void)
+static void
+searching_tokenizer_finalize (GObject *object)
{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (ESearchingTokenizerClass),
- NULL, NULL,
- (GClassInitFunc) e_searching_tokenizer_class_init,
- NULL, NULL,
- sizeof (ESearchingTokenizer),
- 0,
- (GInstanceInitFunc) e_searching_tokenizer_init,
- };
-
- type = g_type_register_static (HTML_TYPE_TOKENIZER, "ESearchingTokenizer", &info, 0);
- }
-
- return type;
-}
+ ESearchingTokenizerPrivate *priv;
-ESearchingTokenizer *
-e_searching_tokenizer_new (void)
-{
- return g_object_new (E_TYPE_SEARCHING_TOKENIZER, NULL);
-}
+ priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (object);
-/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
+ search_info_free (priv->primary);
+ search_info_free (priv->secondary);
-/* blah blah the htmltokeniser doesn't like being asked
- for a token if it doens't hvae any! */
-static gchar *get_token(HTMLTokenizer *t)
-{
- HTMLTokenizerClass *klass = HTML_TOKENIZER_CLASS (parent_class);
+ if (priv->engine != NULL)
+ searcher_free (priv->engine);
- return klass->has_more(t) ? klass->next_token(t) : NULL;
+ /* Chain up to parent's finalize () method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-e_searching_tokenizer_begin (HTMLTokenizer *t, const gchar *content_type)
+searching_tokenizer_begin (HTMLTokenizer *tokenizer,
+ const gchar *content_type)
{
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (t);
- struct _ESearchingTokenizerPrivate *p = st->priv;
+ ESearchingTokenizerPrivate *priv;
+
+ priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer);
/* reset search */
- if (p->engine) {
- searcher_free(p->engine);
- p->engine = NULL;
+ if (priv->engine != NULL) {
+ searcher_free (priv->engine);
+ priv->engine = NULL;
}
- if ((p->engine = search_info_to_searcher(p->primary))
- || (p->engine = search_info_to_searcher(p->secondary))) {
- /*HTMLTokenizerClass *klass = HTML_TOKENIZER_CLASS (parent_class);*/
-
- /*searcher_set_tokenfunc(p->engine, klass->next_token, st);*/
- searcher_set_tokenfunc(p->engine, get_token, st);
+ if ((priv->engine = search_info_to_searcher (priv->primary))
+ || (priv->engine = search_info_to_searcher (priv->secondary))) {
+ searcher_set_tokenfunc(priv->engine, get_token, tokenizer);
}
/* else - no engine, no search active */
- HTML_TOKENIZER_CLASS (parent_class)->begin (t, content_type);
-}
-
-static void
-e_searching_tokenizer_end (HTMLTokenizer *t)
-{
- /* so end gets called before any get/next tokens.
- I dont get it. */
-#if 0
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (t);
- struct _ESearchingTokenizerPrivate *p = st->priv;
-
- /* not sure if we should reset search every time ... *shrug* */
- if (p->engine) {
- searcher_free(p->engine);
- p->engine = NULL;
- }
-#endif
-
- HTML_TOKENIZER_CLASS (parent_class)->end (t);
+ /* Chain up to parent's begin() method. */
+ HTML_TOKENIZER_CLASS (parent_class)->begin (tokenizer, content_type);
}
static gchar *
-e_searching_tokenizer_peek_token (HTMLTokenizer *tok)
+searching_tokenizer_peek_token (HTMLTokenizer *tokenizer)
{
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok);
+ ESearchingTokenizerPrivate *priv;
- /* If no search is active, just use the default method. */
- if (st->priv->engine == NULL)
- return HTML_TOKENIZER_CLASS (parent_class)->peek_token (tok);
+ priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer);
- return searcher_peek_token(st->priv->engine);
+ if (priv->engine != NULL)
+ return searcher_peek_token (priv->engine);
+
+ /* Chain up to parent's peek_token() method. */
+ return HTML_TOKENIZER_CLASS (parent_class)->peek_token (tokenizer);
}
static gchar *
-e_searching_tokenizer_next_token (HTMLTokenizer *tok)
+searching_tokenizer_next_token (HTMLTokenizer *tokenizer)
{
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok);
+ ESearchingTokenizerPrivate *priv;
gint oldmatched;
gchar *token;
+ priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer);
+
/* If no search is active, just use the default method. */
- if (st->priv->engine == NULL)
- return HTML_TOKENIZER_CLASS (parent_class)->next_token (tok);
+ if (priv->engine == NULL)
+ return HTML_TOKENIZER_CLASS (parent_class)->next_token (tokenizer);
- oldmatched = st->priv->engine->matchcount;
+ oldmatched = priv->engine->matchcount;
- token = searcher_next_token(st->priv->engine);
+ token = searcher_next_token (priv->engine);
/* not sure if this has to be accurate or just say we had some matches */
- if (oldmatched != st->priv->engine->matchcount)
- g_signal_emit (st, signals[MATCH_SIGNAL], 0);
+ if (oldmatched != priv->engine->matchcount)
+ g_signal_emit (tokenizer, signals[MATCH_SIGNAL], 0);
return token;
}
static gboolean
-e_searching_tokenizer_has_more (HTMLTokenizer *tok)
+searching_tokenizer_has_more (HTMLTokenizer *tokenizer)
{
- ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok);
+ ESearchingTokenizerPrivate *priv;
- return (st->priv->engine != NULL && searcher_pending(st->priv->engine))
- || HTML_TOKENIZER_CLASS (parent_class)->has_more (tok);
+ priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer);
+
+ return (priv->engine != NULL && searcher_pending (priv->engine)) ||
+ HTML_TOKENIZER_CLASS (parent_class)->has_more (tokenizer);
}
-/* proxy matched event, not sure what its for otherwise */
+static HTMLTokenizer *
+searching_tokenizer_clone (HTMLTokenizer *tokenizer)
+{
+ ESearchingTokenizer *orig_st;
+ ESearchingTokenizer *new_st;
+
+ orig_st = E_SEARCHING_TOKENIZER (tokenizer);
+ new_st = e_searching_tokenizer_new ();
+
+ search_info_free (new_st->priv->primary);
+ search_info_free (new_st->priv->secondary);
+
+ new_st->priv->primary = search_info_clone (orig_st->priv->primary);
+ new_st->priv->secondary = search_info_clone (orig_st->priv->secondary);
+
+ g_signal_connect_swapped (
+ new_st, "match", G_CALLBACK (matched), orig_st);
+
+ return HTML_TOKENIZER (new_st);
+}
static void
-matched (ESearchingTokenizer *st)
+searching_tokenizer_class_init (ESearchingTokenizerClass *class)
{
- /*++st->priv->match_count;*/
- g_signal_emit (st, signals[MATCH_SIGNAL], 0);
+ GObjectClass *object_class;
+ HTMLTokenizerClass *tokenizer_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (ESearchingTokenizerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = searching_tokenizer_finalize;
+
+ tokenizer_class = HTML_TOKENIZER_CLASS (class);
+ tokenizer_class->begin = searching_tokenizer_begin;
+ tokenizer_class->peek_token = searching_tokenizer_peek_token;
+ tokenizer_class->next_token = searching_tokenizer_next_token;
+ tokenizer_class->has_more = searching_tokenizer_has_more;
+ tokenizer_class->clone = searching_tokenizer_clone;
+
+ signals[MATCH_SIGNAL] = g_signal_new (
+ "match",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ESearchingTokenizerClass, match),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
-static HTMLTokenizer *
-e_searching_tokenizer_clone (HTMLTokenizer *tok)
+static void
+searching_tokenizer_init (ESearchingTokenizer *tokenizer)
{
- ESearchingTokenizer *orig_st = E_SEARCHING_TOKENIZER (tok);
- ESearchingTokenizer *new_st = E_SEARCHING_TOKENIZER (e_searching_tokenizer_new ());
+ tokenizer->priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer);
+
+ tokenizer->priv->primary = search_info_new ();
+ search_info_set_flags (
+ tokenizer->priv->primary,
+ SEARCH_BOLD, SEARCH_CASE | SEARCH_BOLD);
+ search_info_set_color (tokenizer->priv->primary, "red");
+
+ tokenizer->priv->secondary = search_info_new ();
+ search_info_set_flags(
+ tokenizer->priv->secondary,
+ SEARCH_BOLD, SEARCH_CASE | SEARCH_BOLD);
+ search_info_set_color (tokenizer->priv->secondary, "purple");
+}
- search_info_free(new_st->priv->primary);
- search_info_free(new_st->priv->secondary);
+GType
+e_searching_tokenizer_get_type (void)
+{
+ static GType type = 0;
- new_st->priv->primary = search_info_clone(orig_st->priv->primary);
- new_st->priv->secondary = search_info_clone(orig_st->priv->secondary);
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (ESearchingTokenizerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) searching_tokenizer_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (ESearchingTokenizer),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) searching_tokenizer_init,
+ NULL /* value_table */
+ };
-#if 0
- shared_state_ref (orig_st->priv->shared);
- shared_state_unref (new_st->priv->shared);
- new_st->priv->shared = orig_st->priv->shared;
-#endif
+ type = g_type_register_static (
+ HTML_TYPE_TOKENIZER, "ESearchingTokenizer",
+ &type_info, 0);
+ }
- g_signal_connect_swapped (new_st, "match", G_CALLBACK(matched), orig_st);
+ return type;
+}
- return HTML_TOKENIZER (new_st);
+ESearchingTokenizer *
+e_searching_tokenizer_new (void)
+{
+ return g_object_new (E_TYPE_SEARCHING_TOKENIZER, NULL);
}
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
void
-e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *st, const gchar *search_str)
+e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *tokenizer,
+ const gchar *primary_string)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_clear(st->priv->primary);
- search_info_add_string(st->priv->primary, search_str);
+ search_info_clear (tokenizer->priv->primary);
+ search_info_add_string (tokenizer->priv->primary, primary_string);
}
void
-e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *st, const gchar *search_str)
+e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *tokenizer,
+ const gchar *primary_string)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_add_string(st->priv->primary, search_str);
+ search_info_add_string (tokenizer->priv->primary, primary_string);
}
void
-e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *st, gboolean iscase)
+e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *tokenizer,
+ gboolean case_sensitive)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_set_flags(st->priv->primary, iscase?SEARCH_CASE:0, SEARCH_CASE);
+ search_info_set_flags (
+ tokenizer->priv->primary,
+ case_sensitive ? SEARCH_CASE : 0, SEARCH_CASE);
}
void
-e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str)
+e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *tokenizer,
+ const gchar *secondary_string)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_clear(st->priv->secondary);
- search_info_add_string(st->priv->secondary, search_str);
+ search_info_clear (tokenizer->priv->secondary);
+ search_info_add_string (tokenizer->priv->secondary, secondary_string);
}
void
-e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str)
+e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *tokenizer,
+ const gchar *secondary_string)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_add_string(st->priv->secondary, search_str);
+ search_info_add_string (tokenizer->priv->secondary, secondary_string);
}
void
-e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *st, gboolean iscase)
+e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *tokenizer,
+ gboolean case_sensitive)
{
- g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+ g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer));
- search_info_set_flags(st->priv->secondary, iscase?SEARCH_CASE:0, SEARCH_CASE);
+ search_info_set_flags (
+ tokenizer->priv->secondary,
+ case_sensitive ? SEARCH_CASE : 0, SEARCH_CASE);
}
/* Note: only returns the primary search string count */
gint
-e_searching_tokenizer_match_count (ESearchingTokenizer *st)
+e_searching_tokenizer_match_count (ESearchingTokenizer *tokenizer)
{
- g_return_val_if_fail (E_IS_SEARCHING_TOKENIZER (st), -1);
+ g_return_val_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer), -1);
- if (st->priv->engine && st->priv->primary->strv->len)
- return st->priv->engine->matchcount;
+ if (tokenizer->priv->engine && tokenizer->priv->primary->strv->len)
+ return tokenizer->priv->engine->matchcount;
return 0;
}
diff --git a/mail/e-searching-tokenizer.h b/mail/e-searching-tokenizer.h
index ddb47d7f05..7eb603a25d 100644
--- a/mail/e-searching-tokenizer.h
+++ b/mail/e-searching-tokenizer.h
@@ -21,49 +21,72 @@
*
*/
-#ifndef __E_SEARCHING_TOKENIZER_H__
-#define __E_SEARCHING_TOKENIZER_H__
+#ifndef E_SEARCHING_TOKENIZER_H
+#define E_SEARCHING_TOKENIZER_H
#include <glib.h>
#include <gtkhtml/htmltokenizer.h>
-#define E_TYPE_SEARCHING_TOKENIZER (e_searching_tokenizer_get_type ())
-#define E_SEARCHING_TOKENIZER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizer))
-#define E_SEARCHING_TOKENIZER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerClass))
-#define E_IS_SEARCHING_TOKENIZER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_SEARCHING_TOKENIZER))
-#define E_IS_SEARCHING_TOKENIZER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_SEARCHING_TOKENIZER))
+/* Standard GObject macros */
+#define E_TYPE_SEARCHING_TOKENIZER \
+ (e_searching_tokenizer_get_type ())
+#define E_SEARCHING_TOKENIZER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizer))
+#define E_SEARCHING_TOKENIZER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerClass))
+#define E_IS_SEARCHING_TOKENIZER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_SEARCHING_TOKENIZER))
+#define E_IS_SEARCHING_TOKENIZER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_SEARCHING_TOKENIZER))
+#define E_SEARCH_TOKENIZER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerClass))
+
+G_BEGIN_DECLS
typedef struct _ESearchingTokenizer ESearchingTokenizer;
typedef struct _ESearchingTokenizerClass ESearchingTokenizerClass;
-
-struct _ESearchingTokenizerPrivate;
+typedef struct _ESearchingTokenizerPrivate ESearchingTokenizerPrivate;
struct _ESearchingTokenizer {
HTMLTokenizer parent;
-
- struct _ESearchingTokenizerPrivate *priv;
+ ESearchingTokenizerPrivate *priv;
};
struct _ESearchingTokenizerClass {
HTMLTokenizerClass parent_class;
- void (*match) (ESearchingTokenizer *);
+ void (*match) (ESearchingTokenizer *tokenizer);
};
-GType e_searching_tokenizer_get_type (void);
-
-ESearchingTokenizer *e_searching_tokenizer_new (void);
-
-/* For now, just a simple API */
-
-void e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *, const gchar *);
-void e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *, const gchar *);
-void e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *, gboolean is_case_sensitive);
-
-void e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *, const gchar *);
-void e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str);
-void e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *, gboolean is_case_sensitive);
-
-gint e_searching_tokenizer_match_count (ESearchingTokenizer *);
-
-#endif /* __E_SEARCHING_TOKENIZER_H__ */
+GType e_searching_tokenizer_get_type (void);
+ESearchingTokenizer *
+ e_searching_tokenizer_new (void);
+void e_searching_tokenizer_set_primary_search_string
+ (ESearchingTokenizer *tokenizer,
+ const gchar *primary_string);
+void e_searching_tokenizer_add_primary_search_string
+ (ESearchingTokenizer *tokenizer,
+ const gchar *primary_string);
+void e_searching_tokenizer_set_primary_case_sensitivity
+ (ESearchingTokenizer *tokenizer,
+ gboolean case_sensitive);
+void e_searching_tokenizer_set_secondary_search_string
+ (ESearchingTokenizer *tokenizer,
+ const gchar *secondary_string);
+void e_searching_tokenizer_add_secondary_search_string
+ (ESearchingTokenizer *tokenizer,
+ const gchar *secondary_string);
+void e_searching_tokenizer_set_secondary_case_sensitivity
+ (ESearchingTokenizer *tokenizer,
+ gboolean case_sensitive);
+gint e_searching_tokenizer_match_count
+ (ESearchingTokenizer *tokenizer);
+
+G_END_DECLS
+
+#endif /* E_SEARCHING_TOKENIZER_H */
diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c
index f2d93a7363..6c674465fe 100644
--- a/mail/em-account-editor.c
+++ b/mail/em-account-editor.c
@@ -51,21 +51,22 @@
#include <libgnomeui/gnome-druid.h>
#include <libgnomeui/gnome-druid-page-standard.h>
-#include <libedataserver/e-account-list.h>
-#include <e-util/e-signature-list.h>
-
+#include "shell/e-shell.h"
#include "e-util/e-error.h"
+#include "e-util/e-account-utils.h"
+#include "e-util/e-signature-list.h"
+#include "e-util/e-signature-utils.h"
#include "e-util/e-util-private.h"
+#include "widgets/misc/e-signature-editor.h"
+#include "e-mail-local.h"
+#include "e-mail-store.h"
#include "em-config.h"
#include "em-folder-selection-button.h"
#include "em-account-editor.h"
#include "mail-session.h"
#include "mail-send-recv.h"
-#include "mail-signature-editor.h"
-#include "mail-component.h"
#include "em-utils.h"
-#include "em-composer-prefs.h"
#include "mail-config.h"
#include "mail-ops.h"
#include "mail-mt.h"
@@ -74,6 +75,10 @@
#include "smime/gui/e-cert-selector.h"
#endif
+#define EM_ACCOUNT_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditorPrivate))
+
#define d(x)
/* econfig item for the extra config hings */
@@ -128,6 +133,10 @@ typedef struct _EMAccountEditorService {
} EMAccountEditorService;
struct _EMAccountEditorPrivate {
+
+ EAccount *modified_account;
+ EAccount *original_account;
+
struct _EMConfig *config;
GList *providers;
@@ -188,53 +197,186 @@ struct _EMAccountEditorPrivate {
guint management_set:1;
};
+enum {
+ PROP_0,
+ PROP_MODIFIED_ACCOUNT,
+ PROP_ORIGINAL_ACCOUNT,
+ PROP_SHELL
+};
+
static void emae_refresh_authtype (EMAccountEditor *emae, EMAccountEditorService *service);
-static void em_account_editor_construct (EMAccountEditor *emae, EAccount *account, em_account_editor_t type, const gchar *id);
+static void em_account_editor_construct (EMAccountEditor *emae, EMAccountEditorType type, const gchar *id);
static void emae_account_folder_changed (EMFolderSelectionButton *folder, EMAccountEditor *emae);
-static GtkVBoxClass *emae_parent;
+
+static gpointer parent_class;
static void
-emae_init (GObject *o)
+emae_set_original_account (EMAccountEditor *emae,
+ EAccount *original_account)
{
- EMAccountEditor *emae = (EMAccountEditor *)o;
+ EAccount *modified_account;
- emae->priv = g_malloc0(sizeof (*emae->priv));
+ g_return_if_fail (emae->priv->original_account == NULL);
- emae->priv->source.emae = emae;
- emae->priv->transport.emae = emae;
+ /* Editing an existing account. */
+ if (original_account != NULL) {
+ gchar *xml;
+
+ xml = e_account_to_xml (original_account);
+ modified_account = e_account_new_from_xml (xml);
+ g_free (xml);
+
+ g_object_ref (original_account);
+ emae->do_signature = TRUE;
+
+ /* Creating a new account. */
+ } else {
+ modified_account = e_account_new ();
+ modified_account->enabled = TRUE;
+
+ e_account_set_string (
+ modified_account, E_ACCOUNT_DRAFTS_FOLDER_URI,
+ e_mail_local_get_folder_uri (E_MAIL_FOLDER_DRAFTS));
+
+ e_account_set_string (
+ modified_account, E_ACCOUNT_SENT_FOLDER_URI,
+ e_mail_local_get_folder_uri (E_MAIL_FOLDER_SENT));
+ }
+
+ emae->priv->original_account = original_account;
+ emae->priv->modified_account = modified_account;
}
static void
-emae_finalise (GObject *o)
+emae_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- EMAccountEditor *emae = (EMAccountEditor *)o;
- EMAccountEditorPrivate *p = emae->priv;
+ switch (property_id) {
+ case PROP_ORIGINAL_ACCOUNT:
+ emae_set_original_account (
+ EM_ACCOUNT_EDITOR (object),
+ g_value_get_object (value));
+ return;
+ }
- if (p->sig_added_id) {
- ESignatureList *signatures = mail_config_get_signatures ();
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
- g_signal_handler_disconnect (signatures, p->sig_added_id);
- g_signal_handler_disconnect (signatures, p->sig_removed_id);
- g_signal_handler_disconnect (signatures, p->sig_changed_id);
+static void
+emae_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_MODIFIED_ACCOUNT:
+ g_value_set_object (
+ value,
+ em_account_editor_get_modified_account (
+ EM_ACCOUNT_EDITOR (object)));
+ return;
+
+ case PROP_ORIGINAL_ACCOUNT:
+ g_value_set_object (
+ value,
+ em_account_editor_get_original_account (
+ EM_ACCOUNT_EDITOR (object)));
+ return;
}
- g_list_free (p->source.authtypes);
- g_list_free (p->transport.authtypes);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+emae_dispose (GObject *object)
+{
+ EMAccountEditorPrivate *priv;
- g_list_free (p->providers);
- g_free (p);
+ priv = EM_ACCOUNT_EDITOR_GET_PRIVATE (object);
- g_object_unref (emae->account);
- if (emae->original)
- g_object_unref (emae->original);
+ if (priv->modified_account != NULL) {
+ g_object_unref (priv->modified_account);
+ priv->modified_account = NULL;
+ }
- ((GObjectClass *)emae_parent)->finalize (o);
+ if (priv->original_account != NULL) {
+ g_object_unref (priv->original_account);
+ priv->original_account = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-emae_class_init (GObjectClass *klass)
+emae_finalize (GObject *object)
{
- klass->finalize = emae_finalise;
+ EMAccountEditor *emae = EM_ACCOUNT_EDITOR (object);
+ EMAccountEditorPrivate *priv = emae->priv;
+
+ if (priv->sig_added_id) {
+ ESignatureList *signatures;
+
+ signatures = e_get_signature_list ();
+ g_signal_handler_disconnect (signatures, priv->sig_added_id);
+ g_signal_handler_disconnect (signatures, priv->sig_removed_id);
+ g_signal_handler_disconnect (signatures, priv->sig_changed_id);
+ }
+
+ g_list_free (priv->source.authtypes);
+ g_list_free (priv->transport.authtypes);
+
+ g_list_free (priv->providers);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+emae_class_init (GObjectClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMAccountEditorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = emae_set_property;
+ object_class->get_property = emae_get_property;
+ object_class->dispose = emae_dispose;
+ object_class->finalize = emae_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODIFIED_ACCOUNT,
+ g_param_spec_object (
+ "modified-account",
+ "Modified Account",
+ NULL,
+ E_TYPE_ACCOUNT,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ORIGINAL_ACCOUNT,
+ g_param_spec_object (
+ "original-account",
+ "Original Account",
+ NULL,
+ E_TYPE_ACCOUNT,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+emae_init (EMAccountEditor *emae)
+{
+ emae->priv = EM_ACCOUNT_EDITOR_GET_PRIVATE (emae);
+
+ emae->priv->source.emae = emae;
+ emae->priv->transport.emae = emae;
}
GType
@@ -242,17 +384,22 @@ em_account_editor_get_type (void)
{
static GType type = 0;
- if (type == 0) {
- static const GTypeInfo info = {
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
sizeof (EMAccountEditorClass),
- NULL, NULL,
- (GClassInitFunc)emae_class_init,
- NULL, NULL,
- sizeof (EMAccountEditor), 0,
- (GInstanceInitFunc)emae_init
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) emae_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMAccountEditor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) emae_init,
+ NULL /* value_table */
};
- emae_parent = g_type_class_ref (G_TYPE_OBJECT);
- type = g_type_register_static (G_TYPE_OBJECT, "EMAccountEditor", &info, 0);
+
+ type = g_type_register_static (
+ G_TYPE_OBJECT, "EMAccountEditor", &type_info, 0);
}
return type;
@@ -269,11 +416,18 @@ em_account_editor_get_type (void)
*
* Return value:
**/
-EMAccountEditor *em_account_editor_new (EAccount *account, em_account_editor_t type, const gchar *id)
+EMAccountEditor *
+em_account_editor_new (EAccount *account,
+ EMAccountEditorType type,
+ const gchar *id)
{
- EMAccountEditor *emae = g_object_new (em_account_editor_get_type (), NULL);
+ EMAccountEditor *emae;
- em_account_editor_construct (emae, account, type, id);
+ emae = g_object_new (
+ EM_TYPE_ACCOUNT_EDITOR,
+ "original-account", account, NULL);
+
+ em_account_editor_construct (emae, type, id);
return emae;
}
@@ -289,15 +443,40 @@ EMAccountEditor *em_account_editor_new (EAccount *account, em_account_editor_t t
*
* Return value:
**/
-EMAccountEditor *em_account_editor_new_for_pages (EAccount *account, em_account_editor_t type, gchar *id, GtkWidget **pages)
+EMAccountEditor *
+em_account_editor_new_for_pages (EAccount *account,
+ EMAccountEditorType type,
+ const gchar *id,
+ GtkWidget **pages)
{
- EMAccountEditor *emae = g_object_new (em_account_editor_get_type (), NULL);
+ EMAccountEditor *emae;
+
+ emae = g_object_new (
+ EM_TYPE_ACCOUNT_EDITOR,
+ "original-account", account, NULL);
+
emae->pages = pages;
- em_account_editor_construct (emae, account, type, id);
+ em_account_editor_construct (emae, type, id);
return emae;
}
+EAccount *
+em_account_editor_get_modified_account (EMAccountEditor *emae)
+{
+ g_return_val_if_fail (EM_IS_ACCOUNT_EDITOR (emae), NULL);
+
+ return emae->priv->modified_account;
+}
+
+EAccount *
+em_account_editor_get_original_account (EMAccountEditor *emae)
+{
+ g_return_val_if_fail (EM_IS_ACCOUNT_EDITOR (emae), NULL);
+
+ return emae->priv->original_account;
+}
+
/* ********************************************************************** */
static struct {
@@ -337,10 +516,12 @@ is_email (const gchar *address)
static CamelURL *
emae_account_url (EMAccountEditor *emae, gint urlid)
{
+ EAccount *account;
CamelURL *url = NULL;
const gchar *uri;
- uri = e_account_get_string (emae->account, urlid);
+ account = em_account_editor_get_modified_account (emae);
+ uri = e_account_get_string (account, urlid);
if (uri && uri[0])
url = camel_url_new (uri, NULL);
@@ -469,11 +650,11 @@ default_folders_clicked (GtkButton *button, gpointer user_data)
EMAccountEditor *emae = user_data;
const gchar *uri;
- uri = mail_component_get_folder_uri (NULL, MAIL_COMPONENT_FOLDER_DRAFTS);
+ uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_DRAFTS);
em_folder_selection_button_set_selection ((EMFolderSelectionButton *)emae->priv->drafts_folder_button, uri);
emae_account_folder_changed ((EMFolderSelectionButton *)emae->priv->drafts_folder_button, emae);
- uri = mail_component_get_folder_uri (NULL, MAIL_COMPONENT_FOLDER_SENT);
+ uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_SENT);
em_folder_selection_button_set_selection ((EMFolderSelectionButton *)emae->priv->sent_folder_button, uri);
emae_account_folder_changed ((EMFolderSelectionButton *)emae->priv->sent_folder_button, emae);
}
@@ -484,7 +665,8 @@ GtkWidget *em_account_editor_folder_selector_button_new (gchar *widget_name, gch
GtkWidget *
em_account_editor_folder_selector_button_new (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2)
{
- return (GtkWidget *)em_folder_selection_button_new (string1 ? string1 : _("Select Folder"), NULL);
+ return (GtkWidget *)em_folder_selection_button_new (
+ string1 ? string1 : _("Select Folder"), NULL);
}
GtkWidget *em_account_editor_dropdown_new (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2);
@@ -492,7 +674,7 @@ GtkWidget *em_account_editor_dropdown_new (gchar *widget_name, gchar *string1, g
GtkWidget *
em_account_editor_dropdown_new (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2)
{
- return (GtkWidget *)gtk_combo_box_new ();
+ return gtk_combo_box_new ();
}
GtkWidget *em_account_editor_ssl_selector_new (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2);
@@ -659,34 +841,53 @@ emae_signature_changed (ESignatureList *signatures, ESignature *sig, EMAccountEd
static void
emae_signaturetype_changed (GtkComboBox *dropdown, EMAccountEditor *emae)
{
+ EAccount *account;
gint id = gtk_combo_box_get_active (dropdown);
GtkTreeModel *model;
GtkTreeIter iter;
gchar *uid = NULL;
+ account = em_account_editor_get_modified_account (emae);
+
if (id != -1) {
model = gtk_combo_box_get_model (dropdown);
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, id))
gtk_tree_model_get (model, &iter, 1, &uid, -1);
}
- e_account_set_string (emae->account, E_ACCOUNT_ID_SIGNATURE, uid);
+ e_account_set_string (account, E_ACCOUNT_ID_SIGNATURE, uid);
g_free (uid);
}
static void
-emae_signature_new (GtkWidget *w, EMAccountEditor *emae)
+emae_signature_new (GtkWidget *widget, EMAccountEditor *emae)
{
- /* TODO: why is this in composer prefs? apart from it being somewhere to put it? */
- em_composer_prefs_new_signature ((GtkWindow *)gtk_widget_get_toplevel (w),
- gconf_client_get_bool (mail_config_get_gconf_client (),
- "/apps/evolution/mail/composer/send_html", NULL));
+ EShell *shell;
+ EShellSettings *shell_settings;
+ GtkWidget *editor;
+ gboolean html_mode;
+ gpointer parent;
+
+ shell = e_shell_get_default ();
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ parent = gtk_widget_get_toplevel (widget);
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ html_mode = e_shell_settings_get_boolean (
+ shell_settings, "composer-format-html");
+
+ editor = e_signature_editor_new ();
+ gtkhtml_editor_set_html_mode (GTKHTML_EDITOR (editor), html_mode);
+ gtk_window_set_transient_for (GTK_WINDOW (editor), parent);
+ gtk_widget_show (editor);
}
static GtkWidget *
emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
{
EMAccountEditorPrivate *p = emae->priv;
+ EAccount *account;
GtkComboBox *dropdown = (GtkComboBox *)glade_xml_get_widget (xml, "signature_dropdown");
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
GtkListStore *store;
@@ -694,9 +895,12 @@ emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
GtkTreeIter iter;
ESignatureList *signatures;
EIterator *it;
- const gchar *current = e_account_get_string (emae->account, E_ACCOUNT_ID_SIGNATURE);
+ const gchar *current;
GtkWidget *button;
+ account = em_account_editor_get_modified_account (emae);
+ current = e_account_get_string (account, E_ACCOUNT_ID_SIGNATURE);
+
emae->priv->signatures_dropdown = dropdown;
gtk_widget_show ((GtkWidget *)dropdown);
@@ -705,7 +909,7 @@ emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, _("None"), 1, NULL, -1);
- signatures = mail_config_get_signatures ();
+ signatures = e_get_signature_list ();
if (p->sig_added_id == 0) {
p->sig_added_id = g_signal_connect (signatures, "signature-added", G_CALLBACK(emae_signature_added), emae);
@@ -737,7 +941,7 @@ emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
gtk_combo_box_set_active (dropdown, active);
g_signal_connect (dropdown, "changed", G_CALLBACK(emae_signaturetype_changed), emae);
- gtk_widget_set_sensitive ((GtkWidget *)dropdown, e_account_writable (emae->account, E_ACCOUNT_ID_SIGNATURE));
+ gtk_widget_set_sensitive ((GtkWidget *)dropdown, e_account_writable (account, E_ACCOUNT_ID_SIGNATURE));
button = glade_xml_get_widget (xml, "sigAddNew");
g_signal_connect (button, "clicked", G_CALLBACK(emae_signature_new), emae);
@@ -751,29 +955,32 @@ emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
static void
emae_receipt_policy_changed (GtkComboBox *dropdown, EMAccountEditor *emae)
{
+ EAccount *account;
gint id = gtk_combo_box_get_active (dropdown);
GtkTreeModel *model;
GtkTreeIter iter;
EAccountReceiptPolicy policy;
+ account = em_account_editor_get_modified_account (emae);
+
if (id != -1) {
model = gtk_combo_box_get_model (dropdown);
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, id)) {
gtk_tree_model_get (model, &iter, 1, &policy, -1);
- e_account_set_int (emae->account, E_ACCOUNT_RECEIPT_POLICY, policy);
+ e_account_set_int (account, E_ACCOUNT_RECEIPT_POLICY, policy);
}
}
-
}
static GtkWidget *
emae_setup_receipt_policy (EMAccountEditor *emae, GladeXML *xml)
{
+ EAccount *account;
GtkComboBox *dropdown = (GtkComboBox *)glade_xml_get_widget (xml, "receipt_policy_dropdown");
GtkListStore *store;
gint i = 0, active = 0;
GtkTreeIter iter;
- EAccountReceiptPolicy current = emae->account->receipt_policy;
+ EAccountReceiptPolicy current;
static struct {
EAccountReceiptPolicy policy;
const gchar *label;
@@ -783,6 +990,9 @@ emae_setup_receipt_policy (EMAccountEditor *emae, GladeXML *xml)
{ E_ACCOUNT_RECEIPT_ASK, N_("Ask for each message") }
};
+ account = em_account_editor_get_modified_account (emae);
+ current = account->receipt_policy;
+
gtk_widget_show ((GtkWidget *)dropdown);
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
@@ -801,7 +1011,7 @@ emae_setup_receipt_policy (EMAccountEditor *emae, GladeXML *xml)
gtk_combo_box_set_active (dropdown, active);
g_signal_connect (dropdown, "changed", G_CALLBACK(emae_receipt_policy_changed), emae);
- gtk_widget_set_sensitive ((GtkWidget *)dropdown, e_account_writable (emae->account, E_ACCOUNT_RECEIPT_POLICY));
+ gtk_widget_set_sensitive ((GtkWidget *)dropdown, e_account_writable (account, E_ACCOUNT_RECEIPT_POLICY));
return (GtkWidget *)dropdown;
}
@@ -809,24 +1019,32 @@ emae_setup_receipt_policy (EMAccountEditor *emae, GladeXML *xml)
static void
emae_account_entry_changed (GtkEntry *entry, EMAccountEditor *emae)
{
- gint item = GPOINTER_TO_INT(g_object_get_data ((GObject *)entry, "account-item"));
+ EAccount *account;
+ const gchar *text;
+ gpointer data;
- e_account_set_string (emae->account, item, gtk_entry_get_text (entry));
+ account = em_account_editor_get_modified_account (emae);
+ data = g_object_get_data (G_OBJECT (entry), "account-item");
+ text = gtk_entry_get_text (entry);
+
+ e_account_set_string (account, GPOINTER_TO_INT (data), text);
}
static GtkEntry *
emae_account_entry (EMAccountEditor *emae, const gchar *name, gint item, GladeXML *xml)
{
+ EAccount *account;
GtkEntry *entry;
const gchar *text;
+ account = em_account_editor_get_modified_account (emae);
entry = (GtkEntry *)glade_xml_get_widget (xml, name);
- text = e_account_get_string (emae->account, item);
+ text = e_account_get_string (account, item);
if (text)
gtk_entry_set_text (entry, text);
g_object_set_data ((GObject *)entry, "account-item", GINT_TO_POINTER(item));
g_signal_connect (entry, "changed", G_CALLBACK(emae_account_entry_changed), emae);
- gtk_widget_set_sensitive ((GtkWidget *)entry, e_account_writable (emae->account, item));
+ gtk_widget_set_sensitive ((GtkWidget *)entry, e_account_writable (account, item));
return entry;
}
@@ -834,18 +1052,39 @@ emae_account_entry (EMAccountEditor *emae, const gchar *name, gint item, GladeXM
static void
emae_account_toggle_changed (GtkToggleButton *toggle, EMAccountEditor *emae)
{
- gint item = GPOINTER_TO_INT(g_object_get_data ((GObject *)toggle, "account-item"));
+ EAccount *account;
+ gboolean active;
+ gpointer data;
+
+ account = em_account_editor_get_modified_account (emae);
+ data = g_object_get_data (G_OBJECT (toggle), "account-item");
+ active = gtk_toggle_button_get_active (toggle);
- e_account_set_bool (emae->account, item, gtk_toggle_button_get_active (toggle));
+ e_account_set_bool (account, GPOINTER_TO_INT (data), active);
}
static void
emae_account_toggle_widget (EMAccountEditor *emae, GtkToggleButton *toggle, gint item)
{
- gtk_toggle_button_set_active (toggle, e_account_get_bool (emae->account, item));
- g_object_set_data ((GObject *)toggle, "account-item", GINT_TO_POINTER(item));
- g_signal_connect (toggle, "toggled", G_CALLBACK(emae_account_toggle_changed), emae);
- gtk_widget_set_sensitive ((GtkWidget *)toggle, e_account_writable (emae->account, item));
+ EAccount *account;
+ gboolean active;
+ gboolean writable;
+
+ account = em_account_editor_get_modified_account (emae);
+
+ active = e_account_get_bool (account, item);
+ gtk_toggle_button_set_active (toggle, active);
+
+ writable = e_account_writable (account, item);
+ gtk_widget_set_sensitive (GTK_WIDGET (toggle), writable);
+
+ g_object_set_data (
+ G_OBJECT (toggle), "account-item",
+ GINT_TO_POINTER (item));
+
+ g_signal_connect (
+ toggle, "toggled",
+ G_CALLBACK (emae_account_toggle_changed), emae);
}
static GtkToggleButton *
@@ -862,18 +1101,39 @@ emae_account_toggle (EMAccountEditor *emae, const gchar *name, gint item, GladeX
static void
emae_account_spinint_changed (GtkSpinButton *spin, EMAccountEditor *emae)
{
- gint item = GPOINTER_TO_INT(g_object_get_data ((GObject *)spin, "account-item"));
+ EAccount *account;
+ gpointer data;
+ gint value;
- e_account_set_int (emae->account, item, gtk_spin_button_get_value (spin));
+ account = em_account_editor_get_modified_account (emae);
+ data = g_object_get_data (G_OBJECT (spin), "account-item");
+ value = gtk_spin_button_get_value (spin);
+
+ e_account_set_int (account, GPOINTER_TO_INT (data), value);
}
static void
emae_account_spinint_widget (EMAccountEditor *emae, GtkSpinButton *spin, gint item)
{
- gtk_spin_button_set_value (spin, e_account_get_int (emae->account, item));
- g_object_set_data ((GObject *)spin, "account-item", GINT_TO_POINTER(item));
- g_signal_connect (spin, "value_changed", G_CALLBACK(emae_account_spinint_changed), emae);
- gtk_widget_set_sensitive ((GtkWidget *)spin, e_account_writable (emae->account, item));
+ EAccount *account;
+ gboolean writable;
+ gint v_int;
+
+ account = em_account_editor_get_modified_account (emae);
+
+ v_int = e_account_get_int (account, item);
+ gtk_spin_button_set_value (spin, v_int);
+
+ writable = e_account_writable (account, item);
+ gtk_widget_set_sensitive (GTK_WIDGET (spin), writable);
+
+ g_object_set_data (
+ G_OBJECT (spin), "account-item",
+ GINT_TO_POINTER (item));
+
+ g_signal_connect (
+ spin, "value-changed",
+ G_CALLBACK(emae_account_spinint_changed), emae);
}
#if 0
@@ -892,26 +1152,37 @@ emae_account_spinint (EMAccountEditor *emae, const gchar *name, gint item)
static void
emae_account_folder_changed (EMFolderSelectionButton *folder, EMAccountEditor *emae)
{
- gint item = GPOINTER_TO_INT(g_object_get_data ((GObject *)folder, "account-item"));
+ EAccount *account;
+ gpointer data;
+ const gchar *selection;
+
+ account = em_account_editor_get_modified_account (emae);
+ data = g_object_get_data (G_OBJECT (folder), "account-item");
+ selection = em_folder_selection_button_get_selection (folder);
- e_account_set_string (emae->account, item, em_folder_selection_button_get_selection (folder));
+ e_account_set_string (account, GPOINTER_TO_INT (data), selection);
}
static EMFolderSelectionButton *
emae_account_folder (EMAccountEditor *emae, const gchar *name, gint item, gint deffolder, GladeXML *xml)
{
+ EAccount *account;
EMFolderSelectionButton *folder;
const gchar *uri;
+ account = em_account_editor_get_modified_account (emae);
folder = (EMFolderSelectionButton *)glade_xml_get_widget (xml, name);
- uri = e_account_get_string (emae->account, item);
+ uri = e_account_get_string (account, item);
if (uri) {
gchar *tmp = em_uri_to_camel (uri);
em_folder_selection_button_set_selection (folder, tmp);
g_free (tmp);
} else {
- em_folder_selection_button_set_selection (folder, mail_component_get_folder_uri (NULL, deffolder));
+ const gchar *uri;
+
+ uri = e_mail_local_get_folder_uri (deffolder);
+ em_folder_selection_button_set_selection (folder, uri);
}
g_object_set_data ((GObject *)folder, "account-item", GINT_TO_POINTER(item));
@@ -919,7 +1190,7 @@ emae_account_folder (EMAccountEditor *emae, const gchar *name, gint item, gint d
g_signal_connect (folder, "selected", G_CALLBACK(emae_account_folder_changed), emae);
gtk_widget_show ((GtkWidget *)folder);
- gtk_widget_set_sensitive ((GtkWidget *)folder, e_account_writable (emae->account, item));
+ gtk_widget_set_sensitive ((GtkWidget *)folder, e_account_writable (account, item));
return folder;
}
@@ -1128,17 +1399,19 @@ static struct _service_info {
static void
emae_uri_changed (EMAccountEditorService *service, CamelURL *url)
{
+ EAccount *account;
gchar *uri;
+ account = em_account_editor_get_modified_account (service->emae);
uri = camel_url_to_string (url, 0);
- e_account_set_string (service->emae->account, emae_service_info[service->type].account_uri_key, uri);
+ e_account_set_string (account, emae_service_info[service->type].account_uri_key, uri);
/* small hack for providers which are store and transport - copy settings across */
if (service->type == CAMEL_PROVIDER_STORE
&& service->provider
&& CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT(service->provider))
- e_account_set_string (service->emae->account, E_ACCOUNT_TRANSPORT_URL, uri);
+ e_account_set_string (account, E_ACCOUNT_TRANSPORT_URL, uri);
g_free (uri);
}
@@ -1263,10 +1536,13 @@ emae_ssl_changed (GtkComboBox *dropdown, EMAccountEditorService *service)
static void
emae_service_provider_changed (EMAccountEditorService *service)
{
+ EAccount *account;
gint i, j;
void (*show)(GtkWidget *);
CamelURL *url = emae_account_url (service->emae, emae_service_info[service->type].account_uri_key);
+ account = em_account_editor_get_modified_account (service->emae);
+
if (service->provider) {
gint enable;
GtkWidget *dwidget = NULL;
@@ -1278,14 +1554,14 @@ emae_service_provider_changed (EMAccountEditorService *service)
else
gtk_widget_show (service->frame);
- enable = e_account_writable_option (service->emae->account, service->provider->protocol, "auth");
+ enable = e_account_writable_option (account, service->provider->protocol, "auth");
gtk_widget_set_sensitive ((GtkWidget *)service->authtype, enable);
gtk_widget_set_sensitive ((GtkWidget *)service->check_supported, enable);
- enable = e_account_writable_option (service->emae->account, service->provider->protocol, "use_ssl");
+ enable = e_account_writable_option (account, service->provider->protocol, "use_ssl");
gtk_widget_set_sensitive ((GtkWidget *)service->use_ssl, enable);
- enable = e_account_writable (service->emae->account, emae_service_info[service->type].save_passwd_key);
+ enable = e_account_writable (account, emae_service_info[service->type].save_passwd_key);
gtk_widget_set_sensitive ((GtkWidget *)service->remember, enable);
for (i=0;emae_service_info[service->type].host_info[i].flag;i++) {
@@ -1395,7 +1671,7 @@ emae_provider_changed (GtkComboBox *dropdown, EMAccountEditorService *service)
static void
emae_refresh_providers (EMAccountEditor *emae, EMAccountEditorService *service)
{
- EAccount *account = emae->account;
+ EAccount *account;
GtkListStore *store;
GtkTreeIter iter;
GList *l;
@@ -1403,11 +1679,14 @@ emae_refresh_providers (EMAccountEditor *emae, EMAccountEditorService *service)
GtkComboBox *dropdown;
gint active = 0, i;
struct _service_info *info = &emae_service_info[service->type];
- const gchar *uri = e_account_get_string (account, info->account_uri_key);
- const gchar *tmp;
+ const gchar *uri;
gchar *current = NULL;
+ const gchar *tmp;
CamelURL *url;
+ account = em_account_editor_get_modified_account (emae);
+ uri = e_account_get_string (account, info->account_uri_key);
+
dropdown = service->providers;
gtk_widget_show ((GtkWidget *)dropdown);
@@ -1422,7 +1701,7 @@ emae_refresh_providers (EMAccountEditor *emae, EMAccountEditorService *service)
current[len] = 0;
}
} else {
- current = (gchar *)"imap";
+ current = (gchar *) "imap";
}
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
@@ -1496,6 +1775,7 @@ emae_refresh_providers (EMAccountEditor *emae, EMAccountEditorService *service)
static void
emae_authtype_changed (GtkComboBox *dropdown, EMAccountEditorService *service)
{
+ EAccount *account;
gint id = gtk_combo_box_get_active (dropdown);
GtkTreeModel *model;
GtkTreeIter iter;
@@ -1505,6 +1785,8 @@ emae_authtype_changed (GtkComboBox *dropdown, EMAccountEditorService *service)
if (id == -1)
return;
+ account = em_account_editor_get_modified_account (service->emae);
+
url = emae_account_url (service->emae, emae_service_info[service->type].account_uri_key);
model = gtk_combo_box_get_model (dropdown);
if (gtk_tree_model_iter_nth_child (model, &iter, NULL, id)) {
@@ -1519,7 +1801,7 @@ emae_authtype_changed (GtkComboBox *dropdown, EMAccountEditorService *service)
gtk_widget_set_sensitive ((GtkWidget *)service->remember,
authtype
- ?(authtype->need_password && e_account_writable (service->emae->account, emae_service_info[service->type].save_passwd_key))
+ ?(authtype->need_password && e_account_writable (account, emae_service_info[service->type].save_passwd_key))
:FALSE);
}
@@ -1546,17 +1828,20 @@ static void emae_check_authtype (GtkWidget *w, EMAccountEditorService *service);
static void
emae_refresh_authtype (EMAccountEditor *emae, EMAccountEditorService *service)
{
- EAccount *account = emae->account;
+ EAccount *account;
GtkListStore *store;
GtkTreeIter iter;
GtkComboBox *dropdown;
gint active = 0;
gint i;
struct _service_info *info = &emae_service_info[service->type];
- const gchar *uri = e_account_get_string (account, info->account_uri_key);
+ const gchar *uri;
GList *l, *ll;
CamelURL *url = NULL;
+ account = em_account_editor_get_modified_account (emae);
+ uri = e_account_get_string (account, info->account_uri_key);
+
dropdown = service->authtype;
gtk_widget_show ((GtkWidget *)dropdown);
@@ -1640,10 +1925,13 @@ static void emae_check_authtype_response (GtkWidget *d, gint button, EMAccountEd
static void emae_check_authtype (GtkWidget *w, EMAccountEditorService *service)
{
EMAccountEditor *emae = service->emae;
+ EAccount *account;
const gchar *uri;
+ account = em_account_editor_get_modified_account (emae);
+
/* TODO: do we need to remove the auth mechanism from the uri? */
- uri = e_account_get_string (emae->account, emae_service_info[service->type].account_uri_key);
+ uri = e_account_get_string (account, emae_service_info[service->type].account_uri_key);
g_object_ref (emae);
service->check_dialog = e_error_new (emae->editor ? (GtkWindow *)gtk_widget_get_toplevel (emae->editor) : NULL,
@@ -1658,12 +1946,16 @@ static void emae_check_authtype (GtkWidget *w, EMAccountEditorService *service)
static void
emae_setup_service (EMAccountEditor *emae, EMAccountEditorService *service, GladeXML *xml)
{
+ EAccount *account;
struct _service_info *info = &emae_service_info[service->type];
CamelURL *url = emae_account_url (emae, info->account_uri_key);
- const gchar *uri = e_account_get_string (emae->account, info->account_uri_key);
+ const gchar *uri;
const gchar *tmp;
gint i;
+ account = em_account_editor_get_modified_account (emae);
+ uri = e_account_get_string (account, info->account_uri_key);
+
service->provider = uri?camel_provider_get (uri, NULL):NULL;
service->frame = glade_xml_get_widget (xml, info->frame);
service->container = glade_xml_get_widget (xml, info->container);
@@ -1752,7 +2044,7 @@ emae_setup_service (EMAccountEditor *emae, EMAccountEditorService *service, Glad
service->needs_auth = NULL;
}
- if (!e_account_writable (emae->account, info->account_uri_key))
+ if (!e_account_writable (account, info->account_uri_key))
gtk_widget_set_sensitive (service->container, FALSE);
else
gtk_widget_set_sensitive (service->container, TRUE);
@@ -1800,7 +2092,7 @@ emae_identity_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
{
EMAccountEditor *emae = data;
EMAccountEditorPrivate *gui = emae->priv;
- EAccount *account = emae->account;
+ EAccount *account;
gint i;
GtkWidget *w;
GladeXML *xml;
@@ -1809,6 +2101,8 @@ emae_identity_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
/*if (old)
return old;*/
+ account = em_account_editor_get_modified_account (emae);
+
gladefile = g_build_filename (EVOLUTION_GLADEDIR,
"mail-config.glade",
NULL);
@@ -1822,9 +2116,9 @@ emae_identity_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
gui->management_frame = glade_xml_get_widget (xml, "management_frame");
gui->default_account = GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "management_default"));
- if (!mail_config_get_default_account ()
- || (account == mail_config_get_default_account ())
- || (GPOINTER_TO_INT(g_object_get_data (G_OBJECT (emae->account), "default_flagged"))) )
+ if (!e_get_default_account ()
+ || (account == e_get_default_account ())
+ || (GPOINTER_TO_INT(g_object_get_data (G_OBJECT (account), "default_flagged"))) )
gtk_toggle_button_set_active (gui->default_account, TRUE);
if (emae->do_signature) {
@@ -2394,6 +2688,7 @@ emae_defaults_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
{
EMAccountEditor *emae = data;
EMAccountEditorPrivate *gui = emae->priv;
+ EAccount *account;
GtkWidget *w;
GladeXML *xml;
gchar *gladefile;
@@ -2401,6 +2696,8 @@ emae_defaults_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
/*if (old)
return old;*/
+ account = em_account_editor_get_modified_account (emae);
+
gladefile = g_build_filename (EVOLUTION_GLADEDIR,
"mail-config.glade",
NULL);
@@ -2408,8 +2705,8 @@ emae_defaults_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
g_free (gladefile);
/* Special folders */
- gui->drafts_folder_button = (GtkButton *)emae_account_folder (emae, "drafts_button", E_ACCOUNT_DRAFTS_FOLDER_URI, MAIL_COMPONENT_FOLDER_DRAFTS, xml);
- gui->sent_folder_button = (GtkButton *)emae_account_folder (emae, "sent_button", E_ACCOUNT_SENT_FOLDER_URI, MAIL_COMPONENT_FOLDER_SENT, xml);
+ gui->drafts_folder_button = (GtkButton *)emae_account_folder (emae, "drafts_button", E_ACCOUNT_DRAFTS_FOLDER_URI, E_MAIL_FOLDER_DRAFTS, xml);
+ gui->sent_folder_button = (GtkButton *)emae_account_folder (emae, "sent_button", E_ACCOUNT_SENT_FOLDER_URI, E_MAIL_FOLDER_SENT, xml);
/* Special Folders "Reset Defaults" button */
gui->restore_folders_button = (GtkButton *)glade_xml_get_widget (xml, "default_folders_button");
@@ -2421,18 +2718,18 @@ emae_defaults_page (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget
emae_account_toggle (emae, "always_bcc", E_ACCOUNT_BCC_ALWAYS, xml);
emae_account_entry (emae, "bcc_addrs", E_ACCOUNT_BCC_ADDRS, xml);
- gtk_widget_set_sensitive ((GtkWidget *)gui->drafts_folder_button, e_account_writable (emae->account, E_ACCOUNT_DRAFTS_FOLDER_URI));
+ gtk_widget_set_sensitive ((GtkWidget *)gui->drafts_folder_button, e_account_writable (account, E_ACCOUNT_DRAFTS_FOLDER_URI));
gtk_widget_set_sensitive ( (GtkWidget *)gui->sent_folder_button,
- e_account_writable (emae->account, E_ACCOUNT_SENT_FOLDER_URI)
+ e_account_writable (account, E_ACCOUNT_SENT_FOLDER_URI)
&&
(emae->priv->source.provider ? !(emae->priv->source.provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER): TRUE)
);
gtk_widget_set_sensitive ((GtkWidget *)gui->restore_folders_button,
- (e_account_writable (emae->account, E_ACCOUNT_SENT_FOLDER_URI)
+ (e_account_writable (account, E_ACCOUNT_SENT_FOLDER_URI)
&& ((emae->priv->source.provider && !( emae->priv->source.provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER))
- || e_account_writable (emae->account, E_ACCOUNT_DRAFTS_FOLDER_URI))));
+ || e_account_writable (account, E_ACCOUNT_DRAFTS_FOLDER_URI))));
/* Receipt policy */
emae_setup_receipt_policy (emae, xml);
@@ -2680,6 +2977,7 @@ emae_free_auto (EConfig *ec, GSList *items, gpointer data)
static gboolean
emae_service_complete (EMAccountEditor *emae, EMAccountEditorService *service)
{
+ EAccount *account;
CamelURL *url;
gint ok = TRUE;
const gchar *uri;
@@ -2687,7 +2985,9 @@ emae_service_complete (EMAccountEditor *emae, EMAccountEditorService *service)
if (service->provider == NULL)
return TRUE;
- uri = e_account_get_string (emae->account, emae_service_info[service->type].account_uri_key);
+ account = em_account_editor_get_modified_account (emae);
+
+ uri = e_account_get_string (account, emae_service_info[service->type].account_uri_key);
if (uri == NULL || (url = camel_url_new (uri, NULL)) == NULL)
return FALSE;
@@ -2749,11 +3049,17 @@ static gboolean
emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
{
EMAccountEditor *emae = data;
+ EAccount *account;
+ EAccount *original_account;
gint ok = TRUE;
const gchar *tmp;
EAccount *ea;
gboolean refresh = FALSE;
- gboolean edit = emae->original != NULL;
+ gboolean new_account;
+
+ account = em_account_editor_get_modified_account (emae);
+ original_account = em_account_editor_get_original_account (emae);
+ new_account = (original_account == NULL);
/* We use the page-check of various pages to 'prepare' or
pre-load their values, only in the druid */
@@ -2778,11 +3084,11 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
if (!emae->priv->receive_set) {
gchar *user, *at;
gint index;
- gchar *uri = g_strdup (e_account_get_string (emae->account, E_ACCOUNT_SOURCE_URL));
+ gchar *uri = g_strdup (e_account_get_string (account, E_ACCOUNT_SOURCE_URL));
CamelURL *url;
emae->priv->receive_set = 1;
- tmp = (gchar *)e_account_get_string (emae->account, E_ACCOUNT_ID_ADDRESS);
+ tmp = (gchar *)e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
at = strchr (tmp, '@');
user = g_alloca (at-tmp+1);
memcpy (user, tmp, at-tmp);
@@ -2792,7 +3098,7 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
index = check_servers (at);
gtk_entry_set_text (emae->priv->source.username, user);
gtk_entry_set_text (emae->priv->transport.username, user);
- if (!edit && uri && (url = camel_url_new (uri, NULL)) != NULL) {
+ if (new_account && uri && (url = camel_url_new (uri, NULL)) != NULL) {
refresh = TRUE;
camel_url_set_user (url, user);
if (index != -1) {
@@ -2801,20 +3107,16 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
camel_url_set_host (url, mail_servers[index].recv);
gtk_entry_set_text (emae->priv->source.hostname, mail_servers[index].recv);
gtk_entry_set_text (emae->priv->transport.hostname, mail_servers[index].send);
- camel_url_set_host (url, mail_servers[index].recv);
-
} else {
camel_url_set_host (url, "");
}
- camel_url_set_user (url, user);
g_free (uri);
uri = camel_url_to_string (url, 0);
- e_account_set_string (emae->account, E_ACCOUNT_SOURCE_URL, uri);
- g_free (uri);
+ e_account_set_string (account, E_ACCOUNT_SOURCE_URL, uri);
+
camel_url_free (url);
- } else {
- g_free (uri);
}
+ g_free (uri);
}
} else if (!strcmp (pageid, "30.send")) {
@@ -2822,9 +3124,10 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
CamelURL *url;
gchar *at, *user;
gint index;
- gchar *uri = (gchar *)e_account_get_string (emae->account, E_ACCOUNT_TRANSPORT_URL);
+ gchar *uri = (gchar *)e_account_get_string (account, E_ACCOUNT_TRANSPORT_URL);
+
emae->priv->send_set = 1;
- tmp = e_account_get_string (emae->account, E_ACCOUNT_ID_ADDRESS);
+ tmp = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
at = strchr (tmp, '@');
user = g_alloca (at-tmp+1);
memcpy (user, tmp, at-tmp);
@@ -2832,19 +3135,19 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
at++;
index = check_servers (at);
- if (index != -1 && uri && (url = camel_url_new (uri, NULL)) != NULL) {
+ if (index != -1 && uri && (url = camel_url_new (uri, NULL)) != NULL) {
refresh = TRUE;
camel_url_set_protocol (url, "smtp");
camel_url_set_param (url, "use_ssl", mail_servers[index].ssl);
camel_url_set_host (url, mail_servers[index].send);
camel_url_set_user (url, user);
uri = camel_url_to_string (url, 0);
- e_account_set_string (emae->account, E_ACCOUNT_TRANSPORT_URL, uri);
+ e_account_set_string (account, E_ACCOUNT_TRANSPORT_URL, uri);
g_free (uri);
camel_url_free (url);
}
-
}
+
} else if (!strcmp (pageid, "20.receive_options")) {
if (emae->priv->source.provider
&& emae->priv->extra_provider != emae->priv->source.provider) {
@@ -2857,11 +3160,11 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
guint i = 0, len;
emae->priv->management_set = 1;
- tmp = e_account_get_string (emae->account, E_ACCOUNT_ID_ADDRESS);
+ tmp = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
len = strlen (tmp);
template = alloca (len + 14);
strcpy (template, tmp);
- while (mail_config_get_account_by_name (template))
+ while (e_get_account_by_name (template))
sprintf (template + len, " (%d)", i++);
gtk_entry_set_text (emae->priv->identity_entries[0], template);
@@ -2875,15 +3178,15 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
editing multiple accounts at a time
*/
if (gtk_toggle_button_get_active (emae->priv->default_account))
- g_object_set_data (G_OBJECT (emae->account), "default_flagged", GINT_TO_POINTER(1));
+ g_object_set_data (G_OBJECT (account), "default_flagged", GINT_TO_POINTER(1));
if (pageid == NULL || !strcmp (pageid, "00.identity")) {
/* TODO: check the account name is set, and unique in the account list */
- ok = (tmp = e_account_get_string (emae->account, E_ACCOUNT_ID_NAME))
+ ok = (tmp = e_account_get_string (account, E_ACCOUNT_ID_NAME))
&& tmp[0]
- && (tmp = e_account_get_string (emae->account, E_ACCOUNT_ID_ADDRESS))
+ && (tmp = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS))
&& is_email (tmp)
- && ((tmp = e_account_get_string (emae->account, E_ACCOUNT_ID_REPLY_TO)) == NULL
+ && ((tmp = e_account_get_string (account, E_ACCOUNT_ID_REPLY_TO)) == NULL
|| tmp[0] == 0
|| is_email (tmp));
if (!ok) {
@@ -2912,10 +3215,10 @@ emae_check_complete (EConfig *ec, const gchar *pageid, gpointer data)
}
if (ok && (pageid == NULL || !strcmp (pageid, "40.management"))) {
- ok = (tmp = e_account_get_string (emae->account, E_ACCOUNT_NAME))
+ ok = (tmp = e_account_get_string (account, E_ACCOUNT_NAME))
&& tmp[0]
- && ((ea = mail_config_get_account_by_name (tmp)) == NULL
- || ea == emae->original);
+ && ((ea = e_get_account_by_name (tmp)) == NULL
+ || ea == original_account);
if (!ok) {
d (printf ("management page incomplete\n"));
}
@@ -2934,40 +3237,44 @@ em_account_editor_check (EMAccountEditor *emae, const gchar *page)
static void
add_new_store (gchar *uri, CamelStore *store, gpointer user_data)
{
- MailComponent *component = mail_component_peek ();
EAccount *account = user_data;
if (store == NULL)
return;
- mail_component_add_store (component, store, account->name);
+ e_mail_store_add (store, account->name);
}
static void
emae_commit (EConfig *ec, GSList *items, gpointer data)
{
EMAccountEditor *emae = data;
- EAccountList *accounts = mail_config_get_accounts ();
+ EAccountList *accounts = e_get_account_list ();
EAccount *account;
+ EAccount *modified_account;
+ EAccount *original_account;
/* the mail-config*acconts* api needs a lot of work */
- if (emae->original) {
- d (printf ("Committing account '%s'\n", e_account_get_string (emae->account, E_ACCOUNT_NAME)));
- e_account_import (emae->original, emae->account);
- account = emae->original;
+ modified_account = em_account_editor_get_modified_account (emae);
+ original_account = em_account_editor_get_original_account (emae);
+
+ if (original_account != NULL) {
+ d (printf ("Committing account '%s'\n", e_account_get_string (modified_account, E_ACCOUNT_NAME)));
+ e_account_import (original_account, modified_account);
+ account = original_account;
e_account_list_change (accounts, account);
} else {
- d (printf ("Adding new account '%s'\n", e_account_get_string (emae->account, E_ACCOUNT_NAME)));
- e_account_list_add (accounts, emae->account);
- account = emae->account;
+ d (printf ("Adding new account '%s'\n", e_account_get_string (account, E_ACCOUNT_NAME)));
+ e_account_list_add (accounts, modified_account);
+ account = modified_account;
/* HACK: this will add the account to the folder tree.
We should just be listening to the account list directly for changed events */
if (account->enabled
&& emae->priv->source.provider
&& (emae->priv->source.provider->flags & CAMEL_PROVIDER_IS_STORAGE))
- mail_get_store (e_account_get_string (emae->account, E_ACCOUNT_SOURCE_URL), NULL, add_new_store, account);
+ mail_get_store (e_account_get_string (modified_account, E_ACCOUNT_SOURCE_URL), NULL, add_new_store, account);
}
if (gtk_toggle_button_get_active (emae->priv->default_account))
@@ -2990,9 +3297,10 @@ emae_editor_destroyed (GtkWidget *dialog, EMAccountEditor *emae)
}
static void
-em_account_editor_construct (EMAccountEditor *emae, EAccount *account, em_account_editor_t type, const gchar *id)
+em_account_editor_construct (EMAccountEditor *emae, EMAccountEditorType type, const gchar *id)
{
EMAccountEditorPrivate *gui = emae->priv;
+ EAccount *account;
gint i, index;
GSList *l;
GList *prov;
@@ -3002,25 +3310,6 @@ em_account_editor_construct (EMAccountEditor *emae, EAccount *account, em_accoun
EConfigItem *items;
emae->type = type;
- emae->original = account;
- if (emae->original) {
- gchar *xml;
-
- g_object_ref (emae->original);
- xml = e_account_to_xml (emae->original);
- emae->account = e_account_new_from_xml (xml);
- g_free (xml);
-
- emae->do_signature = TRUE;
- } else {
- /* TODO: have a get_default_account thing?? */
- emae->account = e_account_new ();
- emae->account->enabled = TRUE;
- e_account_set_string (emae->account, E_ACCOUNT_DRAFTS_FOLDER_URI,
- mail_component_get_folder_uri (NULL, MAIL_COMPONENT_FOLDER_DRAFTS));
- e_account_set_string (emae->account, E_ACCOUNT_SENT_FOLDER_URI,
- mail_component_get_folder_uri (NULL, MAIL_COMPONENT_FOLDER_SENT));
- }
/* sort the providers, remote first */
gui->providers = g_list_sort (camel_provider_list (TRUE), (GCompareFunc)provider_compare);
@@ -3099,7 +3388,8 @@ em_account_editor_construct (EMAccountEditor *emae, EAccount *account, em_accoun
e_config_add_page_check ((EConfig *)ec, NULL, emae_check_complete, emae);
- target = em_config_target_new_account (ec, emae->account);
+ account = em_account_editor_get_modified_account (emae);
+ target = em_config_target_new_account (ec, account);
e_config_set_target ((EConfig *)ec, (EConfigTarget *)target);
if (type != EMAE_PAGES) {
diff --git a/mail/em-account-editor.h b/mail/em-account-editor.h
index d8d96f58f0..0c2f5e38aa 100644
--- a/mail/em-account-editor.h
+++ b/mail/em-account-editor.h
@@ -25,9 +25,27 @@
#define EM_ACCOUNT_EDITOR_H
#include <gtk/gtk.h>
-
#include <mail/em-config.h>
+/* Standard GObject macros */
+#define EM_TYPE_ACCOUNT_EDITOR \
+ (em_account_editor_get_type ())
+#define EM_ACCOUNT_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditor))
+#define EM_ACCOUNT_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditorClass))
+#define EM_IS_ACCOUNT_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_ACCOUNT_EDITOR))
+#define EM_IS_ACCOUNT_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_ACCOUNT_EDITOR))
+#define EM_ACCOUNT_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditorClass))
+
G_BEGIN_DECLS
typedef struct _EMAccountEditor EMAccountEditor;
@@ -38,48 +56,63 @@ typedef enum {
EMAE_NOTEBOOK,
EMAE_DRUID,
EMAE_PAGES
-} em_account_editor_t;
+} EMAccountEditorType;
struct _EMAccountEditor {
- GObject gobject;
+ GObject parent;
EMAccountEditorPrivate *priv;
- em_account_editor_t type;
+ EMAccountEditorType type;
GtkWidget *editor; /* gtknotebook or druid, depending on type */
EMConfig *config; /* driver object */
- EAccount *account; /* working account, must instant apply to this */
- EAccount *original; /* original account, not changed unless commit is invoked */
-
GtkWidget **pages; /* Pages for Anjal's page type editor */
guint do_signature:1; /* allow editing signature */
};
struct _EMAccountEditorClass {
- GObjectClass gobject_class;
+ GObjectClass parent_class;
};
-GType em_account_editor_get_type(void);
-
-EMAccountEditor *em_account_editor_new(EAccount *account, em_account_editor_t type, const gchar *id);
-EMAccountEditor *em_account_editor_new_for_pages(EAccount *account, em_account_editor_t type, gchar *id, GtkWidget **pages);
-void em_account_editor_commit (EMAccountEditor *emae);
-void em_account_editor_check (EMAccountEditor *emae, const gchar *page);
-
-gboolean em_account_editor_save (EMAccountEditor *gui);
-void em_account_editor_destroy (EMAccountEditor *gui);
-
-gboolean em_account_editor_identity_complete (EMAccountEditor *gui, GtkWidget **incomplete);
-gboolean em_account_editor_source_complete (EMAccountEditor *gui, GtkWidget **incomplete);
-gboolean em_account_editor_transport_complete (EMAccountEditor *gui, GtkWidget **incomplete);
-gboolean em_account_editor_management_complete (EMAccountEditor *gui, GtkWidget **incomplete);
-
-void em_account_editor_build_extra_conf (EMAccountEditor *gui, const gchar *url);
-
-void em_account_editor_auto_detect_extra_conf (EMAccountEditor *gui);
+GType em_account_editor_get_type (void);
+EMAccountEditor *
+ em_account_editor_new (EAccount *account,
+ EMAccountEditorType type,
+ const gchar *id);
+EMAccountEditor *
+ em_account_editor_new_for_pages (EAccount *account,
+ EMAccountEditorType type,
+ const gchar *id,
+ GtkWidget **pages);
+EAccount * em_account_editor_get_modified_account
+ (EMAccountEditor *emae);
+EAccount * em_account_editor_get_original_account
+ (EMAccountEditor *emae);
+void em_account_editor_commit (EMAccountEditor *emae);
+void em_account_editor_check (EMAccountEditor *emae,
+ const gchar *page);
+gboolean em_account_editor_save (EMAccountEditor *emae);
+void em_account_editor_destroy (EMAccountEditor *emae);
+gboolean em_account_editor_identity_complete
+ (EMAccountEditor *emae,
+ GtkWidget **incomplete);
+gboolean em_account_editor_source_complete
+ (EMAccountEditor *emae,
+ GtkWidget **incomplete);
+gboolean EMAccountEditorTyperansport_complete
+ (EMAccountEditor *emae,
+ GtkWidget **incomplete);
+gboolean em_account_editor_management_complete
+ (EMAccountEditor *emae,
+ GtkWidget **incomplete);
+void em_account_editor_build_extra_conf
+ (EMAccountEditor *emae,
+ const gchar *url);
+void em_account_editor_auto_detect_extra_conf
+ (EMAccountEditor *emae);
G_END_DECLS
diff --git a/mail/em-account-prefs.c b/mail/em-account-prefs.c
deleted file mode 100644
index 535fbd277f..0000000000
--- a/mail/em-account-prefs.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <camel/camel-url.h>
-
-#include <glib/gi18n.h>
-
-#include "mail-component.h"
-#include "mail-config.h"
-#include "mail-ops.h"
-#include "mail-send-recv.h"
-
-#include "libedataserver/e-account-list.h"
-#include "e-util/e-error.h"
-#include "e-util/e-util-private.h"
-
-#include "em-account-prefs.h"
-
-#include "em-account-editor.h"
-
-static void em_account_prefs_class_init (EMAccountPrefsClass *class);
-static void em_account_prefs_init (EMAccountPrefs *prefs);
-static void em_account_prefs_finalise (GObject *obj);
-static void em_account_prefs_destroy (GtkObject *object);
-
-static void mail_accounts_load (EMAccountPrefs *prefs);
-
-static GtkVBoxClass *parent_class = NULL;
-
-#define PREFS_WINDOW(prefs) GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (prefs), GTK_TYPE_WINDOW))
-
-GType
-em_account_prefs_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- GTypeInfo type_info = {
- sizeof (EMAccountPrefsClass),
- NULL, NULL,
- (GClassInitFunc) em_account_prefs_class_init,
- NULL, NULL,
- sizeof (EMAccountPrefs),
- 0,
- (GInstanceInitFunc) em_account_prefs_init,
- };
-
- type = g_type_register_static (gtk_vbox_get_type (), "EMAccountPrefs", &type_info, 0);
- }
-
- return type;
-}
-
-static void
-em_account_prefs_class_init (EMAccountPrefsClass *klass)
-{
- GtkObjectClass *gtk_object_class = (GtkObjectClass *) klass;
- GObjectClass *object_class = (GObjectClass *) klass;
-
- parent_class = g_type_class_ref (gtk_vbox_get_type ());
-
- gtk_object_class->destroy = em_account_prefs_destroy;
-
- object_class->finalize = em_account_prefs_finalise;
-}
-
-static void
-em_account_prefs_init (EMAccountPrefs *prefs)
-{
- prefs->druid = NULL;
- prefs->editor = NULL;
-}
-
-static void
-em_account_prefs_destroy (GtkObject *obj)
-{
- EMAccountPrefs *prefs = (EMAccountPrefs *) obj;
-
- prefs->destroyed = TRUE;
-
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
-}
-
-static void
-em_account_prefs_finalise (GObject *obj)
-{
- EMAccountPrefs *prefs = (EMAccountPrefs *) obj;
-
- g_object_unref (prefs->gui);
-
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static void
-account_add_finished (EMAccountPrefs *prefs, GObject *deadbeef)
-{
- /* Either Cancel or Finished was clicked in the druid so reload the accounts */
- prefs->druid = NULL;
-
- if (!prefs->destroyed)
- mail_accounts_load (prefs);
-
- g_object_unref (prefs);
-}
-
-#include "em-config.h"
-
-static void
-account_add_clicked (GtkButton *button, gpointer user_data)
-{
- EMAccountPrefs *prefs = (EMAccountPrefs *) user_data;
-
- if (prefs->druid == NULL) {
- EMAccountEditor *emae;
-
- /** @HookPoint-EMConfig: New Mail Account Druid
- * @Id: org.gnome.evolution.mail.config.accountDruid
- * @Type: E_CONFIG_DRUID
- * @Class: org.gnome.evolution.mail.config:1.0
- * @Target: EMConfigTargetAccount
- *
- * The new mail account druid.
- */
- emae = em_account_editor_new(NULL, EMAE_DRUID, "org.gnome.evolution.mail.config.accountDruid");
- prefs->druid = emae->editor;
-
- gtk_window_set_transient_for((GtkWindow *)prefs->druid, (GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)prefs));
- g_object_ref(prefs);
- /* rather nasty hack to reload the accounts, it should just listen to the e-account-list */
- g_object_weak_ref((GObject *) prefs->druid, (GWeakNotify) account_add_finished, prefs);
- gtk_widget_show(emae->editor);
- } else {
- gdk_window_raise (prefs->druid->window);
- }
-}
-
-static void
-account_edit_finished (EMAccountPrefs *prefs, GObject *deadbeef)
-{
- prefs->editor = NULL;
-
- if (!prefs->destroyed)
- mail_accounts_load (prefs);
-
- g_object_unref (prefs);
-}
-
-static void
-account_edit_clicked (GtkButton *button, gpointer user_data)
-{
- EMAccountPrefs *prefs = (EMAccountPrefs *) user_data;
-
- if (prefs->editor == NULL) {
- GtkTreeSelection *selection;
- EAccount *account = NULL;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- selection = gtk_tree_view_get_selection (prefs->table);
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- gtk_tree_model_get (model, &iter, 3, &account, -1);
-
- if (account && !account->parent_uid && !mail_config_has_proxies (account)) {
- EMAccountEditor *emae;
-
- /** @HookPoint-EMConfig: Mail Account Editor
- * @Id: org.gnome.evolution.mail.config.accountEditor
- * @Type: E_CONFIG_BOOK
- * @Class: org.gnome.evolution.mail.config:1.0
- * @Target: EMConfigTargetAccount
- *
- * The account editor window.
- */
- emae = em_account_editor_new(account, EMAE_NOTEBOOK, "org.gnome.evolution.mail.config.accountEditor");
- prefs->editor = emae->editor;
-
- gtk_window_set_transient_for((GtkWindow *)prefs->editor, (GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)prefs));
- g_object_ref(prefs);
- /* rather nasty hack to reload the accounts, it should just listen to the e-account-list */
- g_object_weak_ref((GObject *)prefs->editor, (GWeakNotify) account_edit_finished, prefs);
- gtk_widget_show(emae->editor);
- }
- } else {
- gdk_window_raise (prefs->editor->window);
- }
-}
-
-static void
-account_delete_clicked (GtkButton *button, gpointer user_data)
-{
- EMAccountPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- EAccount *account = NULL;
- EAccountList *accounts;
- GtkTreeModel *model;
- GtkTreeIter iter;
- gint ans;
- gboolean has_proxies = FALSE;
-
- selection = gtk_tree_view_get_selection (prefs->table);
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- gtk_tree_model_get (model, &iter, 3, &account, -1);
-
- /* make sure we have a valid account selected and that we aren't editing anything... */
- if (account == NULL || prefs->editor != NULL)
- return;
-
- has_proxies = mail_config_has_proxies (account);
- ans = e_error_run(PREFS_WINDOW(prefs), has_proxies?"mail:ask-delete-account-with-proxies":"mail:ask-delete-account",NULL);
-
- if (ans == GTK_RESPONSE_YES) {
- gint len;
-
- /* remove it from the folder-tree in the shell */
- if (account->enabled && account->source && account->source->url)
- mail_component_remove_store_by_uri (mail_component_peek (), account->source->url);
-
- /* remove all the proxies account has created*/
- if (has_proxies)
- mail_config_remove_account_proxies (account);
-
- /* remove it from the config file */
- mail_config_remove_account (account);
- accounts = mail_config_get_accounts ();
-
- mail_config_write ();
-
- gtk_list_store_remove ((GtkListStore *) model, &iter);
-
- len = e_list_length ((EList *) accounts);
- if (len > 0) {
- if ( !gtk_list_store_iter_is_valid ((GtkListStore *) model, &iter))
- gtk_tree_model_get_iter_first (model, &iter);
-
- gtk_tree_selection_select_iter (selection, &iter);
- } else {
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_edit), FALSE);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_delete), FALSE);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_default), FALSE);
- }
- }
-}
-
-static void
-account_default_clicked (GtkButton *button, gpointer user_data)
-{
- EMAccountPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- EAccount *account = NULL;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- selection = gtk_tree_view_get_selection (prefs->table);
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- gtk_tree_model_get (model, &iter, 3, &account, -1);
-
- if (account) {
- mail_config_set_default_account (account);
-
- mail_config_write ();
-
- mail_accounts_load (prefs);
- }
-}
-
-static void
-account_able_changed(EAccount *account)
-{
- MailComponent *component = mail_component_peek ();
-
- /* FIXME: do this directly by listening to the mail accounts changed events in the relevant components */
-
- if (account->source->url) {
- if (account->enabled)
- mail_component_load_store_by_uri (component,
- account->source->url,
- account->name);
- else
- mail_component_remove_store_by_uri (component, account->source->url);
- }
-
- mail_config_write ();
-}
-
-static void
-account_able_toggled (GtkCellRendererToggle *renderer, gchar *arg1, gpointer user_data)
-{
- EMAccountPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- EAccount *account = NULL;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- path = gtk_tree_path_new_from_string (arg1);
- model = gtk_tree_view_get_model (prefs->table);
- selection = gtk_tree_view_get_selection (prefs->table);
-
- if (gtk_tree_model_get_iter (model, &iter, path)) {
- gtk_tree_model_get (model, &iter, 3, &account, -1);
-
- if (mail_config_has_proxies (account)) {
- gint ans;
-
- ans = e_error_run(PREFS_WINDOW(prefs), "mail:ask-delete-proxy-accounts",NULL);
-
- if (ans == GTK_RESPONSE_NO) {
- gtk_tree_path_free (path);
- return;
- }
-
- mail_config_remove_account_proxies (account);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_edit), 1);
- }
-
- account->enabled = !account->enabled;
- e_account_list_change(mail_config_get_accounts(), account);
- account_able_changed (account);
- gtk_list_store_set ((GtkListStore *) model, &iter, 0, account->enabled, -1);
-
- /* let the rest of the application know it changed */
- }
-
- gtk_tree_path_free (path);
-}
-
-static void
-account_double_click (GtkTreeView *treeview, GtkTreePath *path,
- GtkTreeViewColumn *column, EMAccountPrefs *prefs)
-{
- account_edit_clicked (NULL, prefs);
-}
-
-static void
-account_cursor_change (GtkTreeSelection *selection, EMAccountPrefs *prefs)
-{
- EAccount *account = NULL;
- GtkTreeModel *model;
- GtkTreeIter iter;
- const gchar *url = NULL;
- gint state;
- EAccount *default_account;
- default_account = mail_config_get_default_account ();
-
- state = gconf_client_key_is_writable(mail_config_get_gconf_client(), "/apps/evolution/mail/accounts", NULL);
- if (state) {
- state = gtk_tree_selection_get_selected (selection, &model, &iter);
- if (state) {
- gtk_tree_model_get (model, &iter, 3, &account, -1);
- url = e_account_get_string (account, E_ACCOUNT_SOURCE_URL);
- } else {
- gtk_widget_grab_focus (GTK_WIDGET (prefs->mail_add));
- }
- gtk_widget_set_sensitive (GTK_WIDGET (prefs), TRUE);
- } else {
- gtk_widget_set_sensitive (GTK_WIDGET (prefs), FALSE);
- }
-
- if( url != NULL )
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_edit), !mail_config_has_proxies(account));
-
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_delete), state);
-
- if(account == default_account)
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_default), FALSE);
- else
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->mail_default), state);
-}
-
-static void
-mail_accounts_load (EMAccountPrefs *prefs)
-{
- EAccount *default_account;
- EAccountList *accounts;
- GtkListStore *model;
- GtkTreeIter iter;
- gchar *name, *val;
- EIterator *node;
- gint row = 0;
- GtkTreeSelection *selection;
-
- model = (GtkListStore *) gtk_tree_view_get_model (prefs->table);
- gtk_list_store_clear (model);
-
- default_account = mail_config_get_default_account ();
-
- accounts = mail_config_get_accounts ();
- node = e_list_get_iterator ((EList *) accounts);
- selection = gtk_tree_view_get_selection(prefs->table);
-
- while (e_iterator_is_valid (node)) {
- EAccount *account;
- CamelURL *url;
-
- account = (EAccount *) e_iterator_get (node);
-
- if (!account->parent_uid) {
- url = account->source && account->source->url ? camel_url_new (account->source->url, NULL) : NULL;
-
- gtk_list_store_append (model, &iter);
- if (account == default_account) {
- /* translators: default account indicator */
- name = val = g_strdup_printf ("%s %s", account->name, _("[Default]"));
- } else {
- val = account->name;
- name = NULL;
- }
-
- gtk_list_store_set (model, &iter,
- 0, account->enabled,
- 1, val,
- 2, url && url->protocol ? url->protocol : (gchar *) _("None"),
- 3, account,
- -1);
- g_free (name);
-
- if (url)
- camel_url_free (url);
-
- /* select the first row by default */
- if (row == 0 && !prefs->changed)
- gtk_tree_selection_select_iter (selection, &iter);
- row++;
- }
-
- e_iterator_next (node);
- }
-
- g_object_unref (node);
-}
-
-GtkWidget *em_account_prefs_treeview_new (gchar *widget_name, gchar *string1, gchar *string2,
- gint int1, gint int2);
-
-GtkWidget *
-em_account_prefs_treeview_new (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2)
-{
- GtkWidget *table, *scrolled;
- GtkTreeSelection *selection;
- GtkCellRenderer *renderer;
- GtkListStore *model;
-
- scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN);
-
- renderer = gtk_cell_renderer_toggle_new ();
- g_object_set ((GObject *) renderer, "activatable", TRUE, NULL);
-
- model = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
- table = gtk_tree_view_new_with_model ((GtkTreeModel *) model);
- g_object_unref (model);
- gtk_tree_view_insert_column_with_attributes ((GtkTreeView *) table, -1, _("Enabled"),
- renderer, "active", 0, NULL);
-
- g_object_set_data ((GObject *) scrolled, "renderer", renderer);
-
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_insert_column_with_attributes ((GtkTreeView *) table, -1, _("Account name"),
- renderer, "text", 1, NULL);
- gtk_tree_view_insert_column_with_attributes ((GtkTreeView *)table, -1, _("Protocol"),
- renderer, "text", 2, NULL);
- selection = gtk_tree_view_get_selection ((GtkTreeView *) table);
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
- gtk_tree_view_set_headers_visible ((GtkTreeView *) table, TRUE);
- atk_object_set_name (gtk_widget_get_accessible (table), _("Mail Accounts"));
-
- /* FIXME: column auto-resize? */
- /* Is this needed?
- gtk_tree_view_column_set_alignment (gtk_tree_view_get_column (prefs->table, 0), 1.0);*/
-
- gtk_container_add (GTK_CONTAINER (scrolled), table);
-
- g_object_set_data ((GObject *) scrolled, "table", table);
-
- gtk_widget_show (scrolled);
- gtk_widget_show (table);
-
- return scrolled;
-}
-
-static void
-em_account_prefs_construct (EMAccountPrefs *prefs)
-{
- GtkWidget *toplevel, *widget;
- GtkCellRenderer *renderer;
- GladeXML *gui;
- gchar *gladefile;
-
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-config.glade",
- NULL);
- gui = glade_xml_new (gladefile, "accounts_tab", NULL);
- g_free (gladefile);
-
- prefs->gui = gui;
-
- /* get our toplevel widget */
- toplevel = glade_xml_get_widget (gui, "toplevel");
-
- /* reparent */
- g_object_ref (toplevel);
- gtk_container_remove (GTK_CONTAINER (toplevel->parent), toplevel);
- gtk_container_add (GTK_CONTAINER (prefs), toplevel);
- g_object_unref (toplevel);
-
- widget = glade_xml_get_widget (gui, "etableMailAccounts");
-
- prefs->table = (GtkTreeView *) g_object_get_data ((GObject *) widget, "table");
-
- renderer = g_object_get_data ((GObject *) widget, "renderer");
- g_signal_connect (renderer, "toggled", G_CALLBACK (account_able_toggled), prefs);
-
- prefs->changed = FALSE;
- mail_accounts_load (prefs);
- prefs->changed = TRUE;
-
- prefs->mail_add = GTK_BUTTON (glade_xml_get_widget (gui, "cmdAccountAdd"));
- g_signal_connect (prefs->mail_add, "clicked", G_CALLBACK (account_add_clicked), prefs);
-
- prefs->mail_edit = GTK_BUTTON (glade_xml_get_widget (gui, "cmdAccountEdit"));
- g_signal_connect (prefs->mail_edit, "clicked", G_CALLBACK (account_edit_clicked), prefs);
-
- prefs->mail_delete = GTK_BUTTON (glade_xml_get_widget (gui, "cmdAccountDelete"));
- g_signal_connect (prefs->mail_delete, "clicked", G_CALLBACK (account_delete_clicked), prefs);
-
- prefs->mail_default = GTK_BUTTON (glade_xml_get_widget (gui, "cmdAccountDefault"));
- g_signal_connect (prefs->mail_default, "clicked", G_CALLBACK (account_default_clicked), prefs);
-
- g_signal_connect (gtk_tree_view_get_selection (prefs->table),
- "changed", G_CALLBACK (account_cursor_change), prefs);
- g_signal_connect (prefs->table, "row-activated", G_CALLBACK (account_double_click), prefs);
-
- account_cursor_change(gtk_tree_view_get_selection(prefs->table), prefs);
-}
-
-GtkWidget *
-em_account_prefs_new (GNOME_Evolution_Shell shell)
-{
- EMAccountPrefs *new;
-
- new = (EMAccountPrefs *) g_object_new (em_account_prefs_get_type (), NULL);
- em_account_prefs_construct (new);
- new->shell = shell;
-
- return (GtkWidget *) new;
-}
diff --git a/mail/em-account-prefs.h b/mail/em-account-prefs.h
deleted file mode 100644
index 2415e1366b..0000000000
--- a/mail/em-account-prefs.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EM_ACCOUNT_PREFS_H__
-#define __EM_ACCOUNT_PREFS_H__
-
-#include <gtk/gtk.h>
-#include <glade/glade.h>
-
-#include <table/e-table.h>
-
-#include "evolution-config-control.h"
-
-#include <shell/Evolution.h>
-
-G_BEGIN_DECLS
-
-#define EM_ACCOUNT_PREFS_TYPE (em_account_prefs_get_type ())
-#define EM_ACCOUNT_PREFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EM_ACCOUNT_PREFS_TYPE, EMAccountPrefs))
-#define EM_ACCOUNT_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EM_ACCOUNT_PREFS_TYPE, EMAccountPrefsClass))
-#define EM_IS_ACCOUNT_PREFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EM_ACCOUNT_PREFS_TYPE))
-#define EM_IS_ACCOUNT_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EM_ACCOUNT_PREFS_TYPE))
-
-typedef struct _EMAccountPrefs EMAccountPrefs;
-typedef struct _EMAccountPrefsClass EMAccountPrefsClass;
-
-struct _EMAccountPrefs {
- GtkVBox parent_object;
-
- GNOME_Evolution_Shell shell;
-
- GladeXML *gui;
-
- GtkWidget *druid;
- GtkWidget *editor;
-
- GtkTreeView *table;
-
- GtkButton *mail_add;
- GtkButton *mail_edit;
- GtkButton *mail_delete;
- GtkButton *mail_default;
-
- guint destroyed : 1;
- guint changed : 1;
-};
-
-struct _EMAccountPrefsClass {
- GtkVBoxClass parent_class;
-
- /* signals */
-
-};
-
-GType em_account_prefs_get_type (void);
-
-GtkWidget *em_account_prefs_new (GNOME_Evolution_Shell shell);
-
-/* needed by global config */
-#define EM_ACCOUNT_PREFS_CONTROL_ID "OAFIID:GNOME_Evolution_Mail_AccountPrefs_ConfigControl:" BASE_VERSION
-
-G_END_DECLS
-
-#endif /* __EM_ACCOUNT_PREFS_H__ */
diff --git a/mail/em-composer-prefs.c b/mail/em-composer-prefs.c
deleted file mode 100644
index ab2bb2d8a4..0000000000
--- a/mail/em-composer-prefs.c
+++ /dev/null
@@ -1,1066 +0,0 @@
-/*
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "e-util/e-signature.h"
-#include "e-util/e-signature-list.h"
-#include "e-util/gconf-bridge.h"
-
-#include "em-composer-prefs.h"
-#include "composer/e-msg-composer.h"
-
-#include <bonobo/bonobo-generic-factory.h>
-
-#include <camel/camel-iconv.h>
-
-#include <misc/e-gui-utils.h>
-
-#include <glib/gstdio.h>
-#include <gdk/gdkkeysyms.h>
-
-#include <gtkhtml/gtkhtml.h>
-#include <editor/gtkhtml-spell-language.h>
-
-#include "misc/e-charset-picker.h"
-#include "e-util/e-error.h"
-#include "e-util/e-util-private.h"
-
-#include "mail-config.h"
-#include "mail-signature-editor.h"
-#include "em-config.h"
-
-static gpointer parent_class;
-
-static void
-composer_prefs_dispose (GObject *object)
-{
- EMComposerPrefs *prefs = (EMComposerPrefs *) object;
- ESignatureList *signature_list;
-
- signature_list = mail_config_get_signatures ();
-
- if (prefs->sig_added_id != 0) {
- g_signal_handler_disconnect (
- signature_list, prefs->sig_added_id);
- prefs->sig_added_id = 0;
- }
-
- if (prefs->sig_removed_id != 0) {
- g_signal_handler_disconnect (
- signature_list, prefs->sig_removed_id);
- prefs->sig_removed_id = 0;
- }
-
- if (prefs->sig_changed_id != 0) {
- g_signal_handler_disconnect (
- signature_list, prefs->sig_changed_id);
- prefs->sig_changed_id = 0;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-composer_prefs_finalize (GObject *object)
-{
- EMComposerPrefs *prefs = (EMComposerPrefs *) object;
-
- g_object_unref (prefs->gui);
-
- g_hash_table_destroy (prefs->sig_hash);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-composer_prefs_class_init (EMComposerPrefsClass *class)
-{
- GObjectClass *object_class;
-
- parent_class = g_type_class_peek_parent (class);
-
- object_class = G_OBJECT_CLASS (class);
- object_class->dispose = composer_prefs_dispose;
- object_class->finalize = composer_prefs_finalize;
-}
-
-static void
-composer_prefs_init (EMComposerPrefs *prefs)
-{
- prefs->sig_hash = g_hash_table_new_full (
- g_direct_hash, g_direct_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) gtk_tree_row_reference_free);
-}
-
-GType
-em_composer_prefs_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EMComposerPrefsClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) composer_prefs_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EMComposerPrefs),
- 0, /* n_allocs */
- (GInstanceInitFunc) composer_prefs_init,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- GTK_TYPE_VBOX, "EMComposerPrefs", &type_info, 0);
- }
-
- return type;
-}
-
-static void
-sig_load_preview (EMComposerPrefs *prefs,
- ESignature *signature)
-{
- GtkHTML *html;
- gchar *str;
-
- html = prefs->sig_preview;
-
- if (signature == NULL) {
- gtk_html_load_from_string (html, " ", 1);
- return;
- }
-
- if (signature->script)
- str = mail_config_signature_run_script (signature->filename);
- else
- str = e_msg_composer_get_sig_file_content (
- signature->filename, signature->html);
- if (!str || !*str) {
- /* make html stream happy and write at least one character */
- g_free (str);
- str = g_strdup (" ");
- }
-
- if (signature->html) {
- gtk_html_load_from_string (html, str, strlen (str));
- } else {
- GtkHTMLStream *stream;
- gint len;
-
- len = strlen (str);
- stream = gtk_html_begin_content (html, "text/html; charset=utf-8");
- gtk_html_write (html, stream, "<PRE>", 5);
- if (len)
- gtk_html_write (html, stream, str, len);
- gtk_html_write (html, stream, "</PRE>", 6);
- gtk_html_end (html, stream, GTK_HTML_STREAM_OK);
- }
-
- g_free (str);
-}
-
-static void
-signature_added (ESignatureList *signature_list,
- ESignature *signature,
- EMComposerPrefs *prefs)
-{
- GtkTreeRowReference *row;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- /* autogen signature is special */
- if (signature->autogen)
- return;
-
- model = gtk_tree_view_get_model (prefs->sig_list);
- gtk_list_store_append (GTK_LIST_STORE (model), &iter);
- gtk_list_store_set (
- GTK_LIST_STORE (model), &iter,
- 0, signature->name, 1, signature, -1);
-
- path = gtk_tree_model_get_path (model, &iter);
- row = gtk_tree_row_reference_new (model, path);
- gtk_tree_path_free (path);
-
- g_hash_table_insert (prefs->sig_hash, signature, row);
-}
-
-static void
-signature_removed (ESignatureList *signature_list,
- ESignature *signature,
- EMComposerPrefs *prefs)
-{
- GtkTreeRowReference *row;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
-
- if (!(row = g_hash_table_lookup (prefs->sig_hash, signature)))
- return;
-
- model = gtk_tree_view_get_model (prefs->sig_list);
- path = gtk_tree_row_reference_get_path (row);
- g_hash_table_remove (prefs->sig_hash, signature);
-
- if (!gtk_tree_model_get_iter (model, &iter, path)) {
- gtk_tree_path_free (path);
- return;
- }
-
- gtk_list_store_remove ((GtkListStore *) model, &iter);
-}
-
-static void
-signature_changed (ESignatureList *signature_list,
- ESignature *signature,
- EMComposerPrefs *prefs)
-{
- GtkTreeSelection *selection;
- GtkTreeRowReference *row;
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- ESignature *cur;
-
- if (!(row = g_hash_table_lookup (prefs->sig_hash, signature)))
- return;
-
- model = gtk_tree_view_get_model (prefs->sig_list);
- path = gtk_tree_row_reference_get_path (row);
-
- if (!gtk_tree_model_get_iter (model, &iter, path)) {
- gtk_tree_path_free (path);
- return;
- }
-
- gtk_tree_path_free (path);
-
- gtk_list_store_set ((GtkListStore *) model, &iter, 0, signature->name, -1);
-
- selection = gtk_tree_view_get_selection (prefs->sig_list);
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- gtk_tree_model_get (model, &iter, 1, &cur, -1);
- if (cur == signature)
- sig_load_preview (prefs, signature);
- }
-}
-
-static void
-sig_edit_cb (GtkWidget *widget, EMComposerPrefs *prefs)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkWidget *parent;
- GtkTreeIter iter;
- ESignature *signature;
-
- selection = gtk_tree_view_get_selection (prefs->sig_list);
- if (!gtk_tree_selection_get_selected (selection, &model, &iter))
- return;
-
- gtk_tree_model_get (model, &iter, 1, &signature, -1);
-
- if (!signature->script) {
- GtkWidget *editor;
-
- /* normal signature */
- if (!signature->filename || *signature->filename == '\0') {
- g_free (signature->filename);
- signature->filename = g_strdup (_("Unnamed"));
- }
-
- editor = e_signature_editor_new ();
- e_signature_editor_set_signature (
- E_SIGNATURE_EDITOR (editor), signature);
-
- parent = gtk_widget_get_toplevel ((GtkWidget *) prefs);
- if (GTK_WIDGET_TOPLEVEL (parent))
- gtk_window_set_transient_for (
- GTK_WINDOW (editor), GTK_WINDOW (parent));
-
- gtk_widget_show (editor);
- } else {
- /* signature script */
- GtkWidget *entry;
-
- entry = glade_xml_get_widget (prefs->sig_script_gui, "filechooserbutton_add_script");
- gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (entry), signature->filename);
-
- entry = glade_xml_get_widget (prefs->sig_script_gui, "entry_add_script_name");
- gtk_entry_set_text (GTK_ENTRY (entry), signature->name);
-
- g_object_set_data ((GObject *) entry, "sig", signature);
-
- gtk_window_present ((GtkWindow *) prefs->sig_script_dialog);
- }
-}
-
-void
-em_composer_prefs_new_signature (GtkWindow *parent,
- gboolean html_mode)
-{
- GtkWidget *editor;
-
- editor = e_signature_editor_new ();
- gtkhtml_editor_set_html_mode (GTKHTML_EDITOR (editor), html_mode);
- gtk_window_set_transient_for (GTK_WINDOW (editor), parent);
- gtk_widget_show (editor);
-}
-
-static void
-sig_delete_cb (GtkWidget *widget, EMComposerPrefs *prefs)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- ESignature *signature;
-
- selection = gtk_tree_view_get_selection (prefs->sig_list);
-
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- gtk_tree_model_get (model, &iter, 1, &signature, -1);
- mail_config_remove_signature (signature);
- }
- gtk_widget_grab_focus ((GtkWidget *)prefs->sig_list);
-}
-
-static void
-sig_add_cb (GtkWidget *widget, EMComposerPrefs *prefs)
-{
- gboolean send_html;
- GtkWidget *parent;
-
- send_html = gconf_client_get_bool (
- mail_config_get_gconf_client (),
- "/apps/evolution/mail/composer/send_html", NULL);
-
- parent = gtk_widget_get_toplevel (GTK_WIDGET (prefs));
- parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
-
- em_composer_prefs_new_signature (GTK_WINDOW (parent), send_html);
- gtk_widget_grab_focus (GTK_WIDGET (prefs->sig_list));
-}
-
-static void
-sig_add_script_response (GtkWidget *widget, gint button, EMComposerPrefs *prefs)
-{
- gchar *script, **argv = NULL;
- GtkWidget *entry;
- const gchar *name;
- gint argc;
-
- if (button == GTK_RESPONSE_ACCEPT) {
- entry = glade_xml_get_widget (prefs->sig_script_gui, "filechooserbutton_add_script");
- script = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (entry));
-
- entry = glade_xml_get_widget (prefs->sig_script_gui, "entry_add_script_name");
- name = gtk_entry_get_text (GTK_ENTRY (entry));
- if (script && *script && g_shell_parse_argv (script, &argc, &argv, NULL)) {
- struct stat st;
-
- if (g_stat (argv[0], &st) == 0 && S_ISREG (st.st_mode) && g_access (argv[0], X_OK) == 0) {
- ESignature *signature;
-
- if ((signature = g_object_get_data ((GObject *) entry, "sig"))) {
- /* we're just editing an existing signature script */
- g_free (signature->name);
- signature->name = g_strdup (name);
- g_free(signature->filename);
- signature->filename = g_strdup(script);
- e_signature_list_change (mail_config_get_signatures (), signature);
- } else {
- signature = mail_config_signature_new (script, TRUE, TRUE);
- signature->name = g_strdup (name);
-
- e_signature_list_add (mail_config_get_signatures (), signature);
- g_object_unref (signature);
- }
-
- mail_config_save_signatures();
-
- gtk_widget_hide (prefs->sig_script_dialog);
- g_strfreev (argv);
- g_free (script);
-
- return;
- }
- }
-
- e_error_run((GtkWindow *)prefs->sig_script_dialog, "mail:signature-notscript", argv ? argv[0] : script, NULL);
- g_strfreev (argv);
- g_free (script);
- return;
- }
-
- gtk_widget_hide (widget);
-}
-
-static void
-sig_add_script_cb (GtkWidget *widget, EMComposerPrefs *prefs)
-{
- GtkWidget *entry;
-
- entry = glade_xml_get_widget (prefs->sig_script_gui, "entry_add_script_name");
- gtk_entry_set_text (GTK_ENTRY (entry), _("Unnamed"));
-
- g_object_set_data ((GObject *) entry, "sig", NULL);
-
- gtk_window_present ((GtkWindow *) prefs->sig_script_dialog);
-}
-
-static void
-sig_selection_changed (GtkTreeSelection *selection,
- EMComposerPrefs *prefs)
-{
- ESignature *signature;
- GtkTreeModel *model;
- GtkTreeIter iter;
- gboolean valid;
-
- valid = gtk_tree_selection_get_selected (selection, &model, &iter);
-
- if (valid) {
- gtk_tree_model_get (model, &iter, 1, &signature, -1);
- sig_load_preview (prefs, signature);
- } else
- sig_load_preview (prefs, NULL);
-
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->sig_delete), valid);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->sig_edit), valid);
-}
-
-static void
-sig_fill_list (EMComposerPrefs *prefs)
-{
- ESignatureList *signature_list;
- GtkTreeModel *model;
- EIterator *iterator;
-
- model = gtk_tree_view_get_model (prefs->sig_list);
- gtk_list_store_clear (GTK_LIST_STORE (model));
-
- signature_list = mail_config_get_signatures ();
- iterator = e_list_get_iterator ((EList *) signature_list);
-
- while (e_iterator_is_valid (iterator)) {
- ESignature *signature;
-
- signature = (ESignature *) e_iterator_get (iterator);
- signature_added (signature_list, signature, prefs);
-
- e_iterator_next (iterator);
- }
-
- g_object_unref (iterator);
-
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->sig_edit), FALSE);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->sig_delete), FALSE);
-
- prefs->sig_added_id = g_signal_connect (
- signature_list, "signature-added",
- G_CALLBACK (signature_added), prefs);
-
- prefs->sig_removed_id = g_signal_connect (
- signature_list, "signature-removed",
- G_CALLBACK (signature_removed), prefs);
-
- prefs->sig_changed_id = g_signal_connect (
- signature_list, "signature-changed",
- G_CALLBACK (signature_changed), prefs);
-}
-
-static void
-url_requested (GtkHTML *html,
- const gchar *url,
- GtkHTMLStream *handle)
-{
- GtkHTMLStreamStatus status;
- gchar buf[128];
- gssize size;
- gint fd;
- gchar *filename;
-
- if (strncmp (url, "file:", 5) == 0)
- filename = g_filename_from_uri (url, NULL, NULL);
- else
- filename = g_strdup (url);
- fd = g_open (filename, O_RDONLY | O_BINARY, 0);
- g_free (filename);
-
- status = GTK_HTML_STREAM_OK;
- if (fd != -1) {
- while ((size = read (fd, buf, sizeof (buf)))) {
- if (size == -1) {
- status = GTK_HTML_STREAM_ERROR;
- break;
- } else
- gtk_html_write (html, handle, buf, size);
- }
- } else
- status = GTK_HTML_STREAM_ERROR;
-
- gtk_html_end (html, handle, status);
- if (fd > 0)
- close (fd);
-}
-
-static void
-spell_color_set (GtkColorButton *color_button,
- EMComposerPrefs *prefs)
-{
- GConfClient *client;
- const gchar *key;
- GdkColor color;
- gchar *string;
-
- gtk_color_button_get_color (color_button, &color);
- string = gdk_color_to_string (&color);
-
- client = mail_config_get_gconf_client ();
- key = "/apps/evolution/mail/composer/spell_color";
- gconf_client_set_string (client, key, string, NULL);
-
- g_free (string);
-}
-
-static void
-spell_language_toggled_cb (GtkCellRendererToggle *renderer,
- const gchar *path_string,
- EMComposerPrefs *prefs)
-{
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- gboolean active;
- gboolean valid;
-
- model = prefs->language_model;
-
- /* Convert the path string to a tree iterator. */
- path = gtk_tree_path_new_from_string (path_string);
- valid = gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
- g_return_if_fail (valid);
-
- /* Toggle the active state. */
- gtk_tree_model_get (model, &iter, 0, &active, -1);
- gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, !active, -1);
-}
-
-static void
-spell_language_save (EMComposerPrefs *prefs)
-{
- GList *spell_languages = NULL;
- GtkTreeModel *model;
- GtkTreeIter iter;
- gboolean valid;
-
- model = prefs->language_model;
-
- /* Build a list of active spell languages. */
- valid = gtk_tree_model_get_iter_first (model, &iter);
- while (valid) {
- const GtkhtmlSpellLanguage *language;
- gboolean active;
-
- gtk_tree_model_get (
- model, &iter, 0, &active, 2, &language, -1);
-
- if (active)
- spell_languages = g_list_prepend (
- spell_languages, (gpointer) language);
-
- valid = gtk_tree_model_iter_next (model, &iter);
- }
- spell_languages = g_list_reverse (spell_languages);
-
- /* Update the GConf value. */
- e_save_spell_languages (spell_languages);
-
- g_list_free (spell_languages);
-}
-
-static void
-spell_setup (EMComposerPrefs *prefs)
-{
- const GList *available_languages;
- GList *active_languages;
- GConfClient *client;
- GtkListStore *store;
- GdkColor color;
- const gchar *key;
- gchar *string;
-
- client = mail_config_get_gconf_client ();
- store = GTK_LIST_STORE (prefs->language_model);
- available_languages = gtkhtml_spell_language_get_available ();
-
- active_languages = e_load_spell_languages ();
-
- /* Populate the GtkListStore. */
- while (available_languages != NULL) {
- const GtkhtmlSpellLanguage *language;
- GtkTreeIter tree_iter;
- const gchar *name;
- gboolean active;
-
- language = available_languages->data;
- name = gtkhtml_spell_language_get_name (language);
- active = (g_list_find (active_languages, language) != NULL);
-
- gtk_list_store_append (store, &tree_iter);
-
- gtk_list_store_set (
- store, &tree_iter,
- 0, active, 1, name, 2, language, -1);
-
- available_languages = available_languages->next;
- }
-
- g_list_free (active_languages);
-
- key = "/apps/evolution/mail/composer/spell_color";
- string = gconf_client_get_string (client, key, NULL);
- if (string == NULL || !gdk_color_parse (string, &color))
- gdk_color_parse ("Red", &color);
- gtk_color_button_set_color (GTK_COLOR_BUTTON (prefs->color), &color);
-
- g_signal_connect (
- prefs->color, "color_set",
- G_CALLBACK (spell_color_set), prefs);
-}
-
-static gint
-reply_style_new_order (gint style_id,
- gboolean from_enum_to_option_id)
-{
- gint values[] = {
- MAIL_CONFIG_REPLY_ATTACH, 0,
- MAIL_CONFIG_REPLY_OUTLOOK, 1,
- MAIL_CONFIG_REPLY_QUOTED, 2,
- MAIL_CONFIG_REPLY_DO_NOT_QUOTE, 3,
- -1, -1};
- gint ii;
-
- for (ii = from_enum_to_option_id ? 0 : 1; values[ii] != -1; ii += 2) {
- if (values[ii] == style_id)
- return values [from_enum_to_option_id ? ii + 1 : ii - 1];
- }
-
- return style_id;
-}
-
-static void
-style_changed (GtkComboBox *combobox, const gchar *key)
-{
- GConfClient *client;
- gint style;
-
- client = mail_config_get_gconf_client ();
- style = gtk_combo_box_get_active (combobox);
- g_return_if_fail (style >= 0);
-
- if (g_str_has_suffix (key, "/reply_style"))
- style = reply_style_new_order (style, FALSE);
-
- gconf_client_set_int (client, key, style, NULL);
-}
-
-static void
-charset_activate (GtkWidget *item,
- EMComposerPrefs *prefs)
-{
- GConfClient *client;
- GtkWidget *menu;
- gchar *string;
-
- client = mail_config_get_gconf_client ();
- menu = gtk_option_menu_get_menu (prefs->charset);
- string = e_charset_picker_get_charset (menu);
-
- if (string == NULL)
- string = g_strdup (camel_iconv_locale_charset ());
-
- gconf_client_set_string (
- client, "/apps/evolution/mail/composer/charset",
- string, NULL);
-
- g_free (string);
-}
-
-static void
-option_menu_connect (EMComposerPrefs *prefs,
- GtkOptionMenu *omenu,
- GCallback callback,
- const gchar *key)
-{
- GConfClient *client;
- GtkWidget *menu;
- GList *list;
-
- client = mail_config_get_gconf_client ();
- menu = gtk_option_menu_get_menu (omenu);
- list = GTK_MENU_SHELL (menu)->children;
-
- while (list != NULL) {
- GtkWidget *widget = list->data;
-
- g_object_set_data (G_OBJECT (widget), "key", (gpointer) key);
- g_signal_connect (widget, "activate", callback, prefs);
- list = list->next;
- }
-
- if (!gconf_client_key_is_writable (client, key, NULL))
- gtk_widget_set_sensitive (GTK_WIDGET (omenu), FALSE);
-}
-
-static GtkWidget *
-emcp_widget_glade (EConfig *ec,
- EConfigItem *item,
- GtkWidget *parent,
- GtkWidget *old,
- gpointer data)
-{
- EMComposerPrefs *prefs = data;
-
- return glade_xml_get_widget (prefs->gui, item->label);
-}
-
-/* plugin meta-data */
-static EMConfigItem emcp_items[] = {
- { E_CONFIG_BOOK, (gchar *) "", (gchar *) "composer_toplevel", emcp_widget_glade },
- { E_CONFIG_PAGE, (gchar *) "00.general", (gchar *) "vboxGeneral", emcp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "00.general/00.behavior", (gchar *) "vboxBehavior", emcp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "00.general/10.alerts", (gchar *) "vboxAlerts", emcp_widget_glade },
- { E_CONFIG_PAGE, (gchar *) "10.signatures", (gchar *) "vboxSignatures", emcp_widget_glade },
- /* signature/signatures and signature/preview parts not usable */
-
- { E_CONFIG_PAGE, (gchar *) "20.spellcheck", (gchar *) "vboxSpellChecking", emcp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "20.spellcheck/00.languages", (gchar *) "vbox178", emcp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "20.spellcheck/00.options", (gchar *) "vboxOptions", emcp_widget_glade },
-};
-
-static void
-emcp_free (EConfig *ec, GSList *items, gpointer data)
-{
- /* the prefs data is freed automagically */
- g_slist_free (items);
-}
-
-static gboolean
-signature_key_press_cb (GtkTreeView *tree_view,
- GdkEventKey *event,
- EMComposerPrefs *prefs)
-{
- /* No need to care about anything other than DEL key */
- if (event->keyval == GDK_Delete) {
- sig_delete_cb (GTK_WIDGET (tree_view), prefs);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-sig_tree_event_cb (GtkTreeView *tree_view,
- GdkEvent *event,
- EMComposerPrefs *prefs)
-{
- if (event->type == GDK_2BUTTON_PRESS) {
- sig_edit_cb (GTK_WIDGET (tree_view), prefs);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-em_composer_prefs_construct (EMComposerPrefs *prefs)
-{
- GtkWidget *toplevel, *widget, *menu, *info_pixmap;
- GtkDialog *dialog;
- GladeXML *gui;
- GtkTreeView *view;
- GtkListStore *store;
- GtkTreeSelection *selection;
- GtkCellRenderer *renderer;
- GConfBridge *bridge;
- GConfClient *client;
- const gchar *key;
- gint style;
- gchar *buf;
- EMConfig *ec;
- EMConfigTargetPrefs *target;
- GSList *l;
- gint i;
- gchar *gladefile;
- gboolean sensitive;
-
- bridge = gconf_bridge_get ();
- client = mail_config_get_gconf_client ();
-
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-config.glade",
- NULL);
- gui = glade_xml_new (gladefile, "composer_toplevel", NULL);
- prefs->gui = gui;
- prefs->sig_script_gui = glade_xml_new (gladefile, "vbox_add_script_signature", NULL);
- g_free (gladefile);
-
- /** @HookPoint-EMConfig: Mail Composer Preferences
- * @Id: org.gnome.evolution.mail.composerPrefs
- * @Type: E_CONFIG_BOOK
- * @Class: org.gnome.evolution.mail.config:1.0
- * @Target: EMConfigTargetPrefs
- *
- * The mail composer preferences settings page.
- */
- ec = em_config_new(E_CONFIG_BOOK, "org.gnome.evolution.mail.composerPrefs");
- l = NULL;
- for (i = 0; i < G_N_ELEMENTS (emcp_items); i++)
- l = g_slist_prepend(l, &emcp_items[i]);
- e_config_add_items((EConfig *)ec, l, NULL, NULL, emcp_free, prefs);
-
- /* General tab */
-
- /* Default Behavior */
- key = "/apps/evolution/mail/composer/send_html";
- widget = glade_xml_get_widget (gui, "chkSendHTML");
- if (!gconf_client_key_is_writable (client, key, NULL))
- gtk_widget_set_sensitive (widget, FALSE);
- gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
-
- key = "/apps/evolution/mail/prompts/empty_subject";
- widget = glade_xml_get_widget (gui, "chkPromptEmptySubject");
- if (!gconf_client_key_is_writable (client, key, NULL))
- gtk_widget_set_sensitive (widget, FALSE);
- gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
-
- key = "/apps/evolution/mail/prompts/only_bcc";
- widget = glade_xml_get_widget (gui, "chkPromptBccOnly");
- if (!gconf_client_key_is_writable (client, key, NULL))
- gtk_widget_set_sensitive (widget, FALSE);
- gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
-
- key = "/apps/evolution/mail/composer/magic_smileys";
- widget = glade_xml_get_widget (gui, "chkAutoSmileys");
- if (!gconf_client_key_is_writable (client, key, NULL))
- gtk_widget_set_sensitive (widget, FALSE);
- gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
-
- key = "/apps/evolution/mail/composer/request_receipt";
- widget = glade_xml_get_widget (gui, "chkRequestReceipt");
- if (!gconf_client_key_is_writable (client, key, NULL))
- gtk_widget_set_sensitive (widget, FALSE);
- gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
-
- key = "/apps/evolution/mail/composer/reply_start_bottom";
- widget = glade_xml_get_widget (gui, "chkReplyStartBottom");
- if (!gconf_client_key_is_writable (client, key, NULL))
- gtk_widget_set_sensitive (widget, FALSE);
- gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
-
- key = "/apps/evolution/mail/composer/outlook_filenames";
- widget = glade_xml_get_widget (gui, "chkOutlookFilenames");
- if (!gconf_client_key_is_writable (client, key, NULL))
- gtk_widget_set_sensitive (widget, FALSE);
- gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
-
- key = "/apps/evolution/mail/composer/top_signature";
- widget = glade_xml_get_widget (gui, "chkTopSignature");
- if (!gconf_client_key_is_writable (client, key, NULL))
- gtk_widget_set_sensitive (widget, FALSE);
- gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
-
- key = "/apps/evolution/mail/composer/inline_spelling";
- widget = glade_xml_get_widget (gui, "chkEnableSpellChecking");
- gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
-
- prefs->charset = GTK_OPTION_MENU (
- glade_xml_get_widget (gui, "omenuCharset1"));
- buf = gconf_client_get_string (
- client, "/apps/evolution/mail/composer/charset", NULL);
- menu = e_charset_picker_new (
- buf && *buf ? buf : camel_iconv_locale_charset ());
- gtk_option_menu_set_menu (prefs->charset, GTK_WIDGET (menu));
- option_menu_connect (
- prefs, prefs->charset,
- G_CALLBACK (charset_activate),
- "/apps/evolution/mail/composer/charset");
- g_free (buf);
-
- /* Spell Checking */
- widget = glade_xml_get_widget (gui, "colorButtonSpellCheckColor");
- prefs->color = GTK_COLOR_BUTTON (widget);
- widget = glade_xml_get_widget (gui, "listSpellCheckLanguage");
- view = GTK_TREE_VIEW (widget);
- store = gtk_list_store_new (
- 3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER);
- g_signal_connect_swapped (
- store, "row-changed",
- G_CALLBACK (spell_language_save), prefs);
- prefs->language_model = GTK_TREE_MODEL (store);
- gtk_tree_view_set_model (view, prefs->language_model);
- renderer = gtk_cell_renderer_toggle_new ();
- g_signal_connect (
- renderer, "toggled",
- G_CALLBACK (spell_language_toggled_cb), prefs);
- gtk_tree_view_insert_column_with_attributes (
- view, -1, _("Enabled"),
- renderer, "active", 0, NULL);
-
- gtk_tree_view_insert_column_with_attributes (
- view, -1, _("Language(s)"),
- gtk_cell_renderer_text_new (),
- "text", 1, NULL);
- selection = gtk_tree_view_get_selection (view);
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
- info_pixmap = glade_xml_get_widget (gui, "pixmapSpellInfo");
- gtk_image_set_from_stock (
- GTK_IMAGE (info_pixmap),
- GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_BUTTON);
- spell_setup (prefs);
-
- /* Forwards and Replies */
- prefs->forward_style = GTK_COMBO_BOX (glade_xml_get_widget (gui, "comboboxForwardStyle"));
- style = gconf_client_get_int (client, "/apps/evolution/mail/format/forward_style", NULL);
- gtk_combo_box_set_active (prefs->forward_style, style);
- g_signal_connect (prefs->forward_style, "changed", G_CALLBACK (style_changed), (gpointer) "/apps/evolution/mail/format/forward_style");
-
- prefs->reply_style = GTK_COMBO_BOX (glade_xml_get_widget (gui, "comboboxReplyStyle"));
- style = gconf_client_get_int (client, "/apps/evolution/mail/format/reply_style", NULL);
- gtk_combo_box_set_active (prefs->reply_style, reply_style_new_order (style, TRUE));
- g_signal_connect (prefs->reply_style, "changed", G_CALLBACK (style_changed), (gpointer) "/apps/evolution/mail/format/reply_style");
-
- /* Signatures */
- dialog = (GtkDialog *) gtk_dialog_new ();
-
- gtk_widget_realize ((GtkWidget *) dialog);
- gtk_container_set_border_width ((GtkContainer *)dialog->action_area, 12);
- gtk_container_set_border_width ((GtkContainer *)dialog->vbox, 0);
-
- prefs->sig_script_dialog = (GtkWidget *) dialog;
- gtk_dialog_add_buttons (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
- GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
- gtk_dialog_set_has_separator (dialog, FALSE);
- gtk_window_set_title ((GtkWindow *) dialog, _("Add signature script"));
- g_signal_connect (dialog, "response", G_CALLBACK (sig_add_script_response), prefs);
- widget = glade_xml_get_widget (prefs->sig_script_gui, "vbox_add_script_signature");
- gtk_box_pack_start ((GtkBox *) dialog->vbox, widget, TRUE, TRUE, 0);
-
- key = "/apps/evolution/mail/signatures";
- sensitive = gconf_client_key_is_writable (client, key, NULL);
-
- widget = glade_xml_get_widget (gui, "cmdSignatureAdd");
- gtk_widget_set_sensitive (widget, sensitive);
- g_signal_connect (
- widget, "clicked",
- G_CALLBACK (sig_add_cb), prefs);
- prefs->sig_add = GTK_BUTTON (widget);
-
- widget = glade_xml_get_widget (gui, "cmdSignatureAddScript");
- gtk_widget_set_sensitive (widget, sensitive && !mail_config_scripts_disabled ());
- g_signal_connect (
- widget, "clicked",
- G_CALLBACK (sig_add_script_cb), prefs);
- prefs->sig_add_script = GTK_BUTTON (widget);
-
- widget = glade_xml_get_widget (gui, "cmdSignatureEdit");
- gtk_widget_set_sensitive (widget, sensitive);
- g_signal_connect (
- widget, "clicked",
- G_CALLBACK (sig_edit_cb), prefs);
- prefs->sig_edit = GTK_BUTTON (widget);
-
- widget = glade_xml_get_widget (gui, "cmdSignatureDelete");
- gtk_widget_set_sensitive (widget, sensitive);
- g_signal_connect (
- widget, "clicked",
- G_CALLBACK (sig_delete_cb), prefs);
- prefs->sig_delete = GTK_BUTTON (widget);
-
- widget = glade_xml_get_widget (gui, "listSignatures");
- gtk_widget_set_sensitive (widget, sensitive);
- prefs->sig_list = GTK_TREE_VIEW (widget);
- store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
- gtk_tree_view_set_model (prefs->sig_list, GTK_TREE_MODEL (store));
- gtk_tree_view_insert_column_with_attributes (
- prefs->sig_list, -1, _("Signature(s)"),
- gtk_cell_renderer_text_new (), "text", 0, NULL);
- selection = gtk_tree_view_get_selection (prefs->sig_list);
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
- g_signal_connect (
- selection, "changed",
- G_CALLBACK (sig_selection_changed), prefs);
- g_signal_connect (
- prefs->sig_list, "event",
- G_CALLBACK (sig_tree_event_cb), prefs);
-
- sig_fill_list (prefs);
-
- /* preview GtkHTML widget */
- widget = glade_xml_get_widget (gui, "scrolled-sig");
- prefs->sig_preview = (GtkHTML *) gtk_html_new ();
- g_signal_connect (
- prefs->sig_preview, "url_requested",
- G_CALLBACK (url_requested), NULL);
- gtk_widget_show (GTK_WIDGET (prefs->sig_preview));
- gtk_container_add (
- GTK_CONTAINER (widget),
- GTK_WIDGET (prefs->sig_preview));
-
- /* get our toplevel widget */
- target = em_config_target_new_prefs (ec, client);
- e_config_set_target ((EConfig *)ec, (EConfigTarget *)target);
- toplevel = e_config_create_widget ((EConfig *)ec);
- gtk_container_add (GTK_CONTAINER (prefs), toplevel);
-
- g_signal_connect (
- prefs->sig_list, "key-press-event",
- G_CALLBACK (signature_key_press_cb), prefs);
-}
-
-GtkWidget *
-em_composer_prefs_new (void)
-{
- EMComposerPrefs *prefs;
-
- prefs = g_object_new (EM_TYPE_COMPOSER_PREFS, NULL);
- em_composer_prefs_construct (prefs);
-
- return GTK_WIDGET (prefs);
-}
diff --git a/mail/em-composer-prefs.h b/mail/em-composer-prefs.h
deleted file mode 100644
index 1ff850623d..0000000000
--- a/mail/em-composer-prefs.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EM_COMPOSER_PREFS_H__
-#define __EM_COMPOSER_PREFS_H__
-
-#include <gtk/gtk.h>
-#include <glade/glade.h>
-#include <gtkhtml/gtkhtml.h>
-
-/* Standard GObject macros */
-#define EM_TYPE_COMPOSER_PREFS \
- (em_composer_prefs_get_type ())
-#define EM_COMPOSER_PREFS(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), EM_TYPE_COMPOSER_PREFS, EMComposerPrefs))
-#define EM_COMPOSER_PREFS_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), EM_TYPE_COMPOSER_PREFS, EMComposerPrefsClass))
-#define EM_IS_COMPOSER_PREFS(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), EM_TYPE_COMPOSER_PREFS))
-#define EM_IS_COMPOSER_PREFS_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), EM_TYPE_COMPOSER_PREFS))
-#define EM_COMPOSER_PREFS_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), EM_TYPE_COMPOSER_PREFS, EMComposerPrefsClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EMComposerPrefs EMComposerPrefs;
-typedef struct _EMComposerPrefsClass EMComposerPrefsClass;
-
-struct _ESignature;
-struct _GladeXML;
-
-struct _EMComposerPrefs {
- GtkVBox parent;
-
- GladeXML *gui;
-
- /* General tab */
-
- /* Default Behavior */
- GtkOptionMenu *charset;
-
- GtkColorButton *color;
- GtkTreeModel *language_model;
-
- /* Forwards and Replies */
- GtkComboBox *forward_style;
- GtkComboBox *reply_style;
-
- /* Signatures */
- GtkTreeView *sig_list;
- GHashTable *sig_hash;
- GtkButton *sig_add;
- GtkButton *sig_add_script;
- GtkButton *sig_edit;
- GtkButton *sig_delete;
- GtkHTML *sig_preview;
-
- GladeXML *sig_script_gui;
- GtkWidget *sig_script_dialog;
-
- guint sig_added_id;
- guint sig_removed_id;
- guint sig_changed_id;
-};
-
-struct _EMComposerPrefsClass {
- GtkVBoxClass parent_class;
-};
-
-GType em_composer_prefs_get_type (void);
-GtkWidget * em_composer_prefs_new (void);
-void em_composer_prefs_new_signature (GtkWindow *parent,
- gboolean html_mode);
-
-/* needed by global config */
-#define EM_COMPOSER_PREFS_CONTROL_ID \
- "OAFIID:GNOME_Evolution_Mail_ComposerPrefs_ConfigControl:" BASE_VERSION
-
-G_END_DECLS
-
-#endif /* __EM_COMPOSER_PREFS_H__ */
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
index 402a6d2ca1..472d499b06 100644
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@ -37,20 +37,23 @@
#include "mail-config.h"
#include "mail-session.h"
#include "mail-send-recv.h"
-#include "mail-component.h"
#include "e-util/e-error.h"
+#include "e-util/e-account-utils.h"
+#include "e-mail-local.h"
#include "em-utils.h"
#include "em-composer-utils.h"
#include "composer/e-msg-composer.h"
#include "composer/e-composer-autosave.h"
+#include "composer/e-composer-post-header.h"
+#include "em-folder-selector.h"
+#include "em-folder-tree.h"
#include "em-format-html.h"
+#include "em-format-html-print.h"
#include "em-format-quote.h"
#include "em-event.h"
-#include "libedataserver/e-account-list.h"
-
#include <camel/camel-folder.h>
#include <camel/camel-multipart.h>
#include <camel/camel-string-utils.h>
@@ -72,6 +75,9 @@
static EAccount * guess_account (CamelMimeMessage *message, CamelFolder *folder);
+static void em_utils_composer_send_cb (EMsgComposer *composer);
+static void em_utils_composer_save_draft_cb (EMsgComposer *composer);
+
struct emcs_t {
guint ref_count;
@@ -88,28 +94,63 @@ emcs_new (void)
{
struct emcs_t *emcs;
- emcs = g_new (struct emcs_t, 1);
+ emcs = g_new0 (struct emcs_t, 1);
emcs->ref_count = 1;
- emcs->drafts_folder = NULL;
- emcs->drafts_uid = NULL;
- emcs->folder = NULL;
- emcs->flags = 0;
- emcs->set = 0;
- emcs->uid = NULL;
return emcs;
}
static void
+emcs_set_drafts_info (struct emcs_t *emcs,
+ CamelFolder *drafts_folder,
+ const gchar *drafts_uid)
+{
+ g_return_if_fail (emcs != NULL);
+ g_return_if_fail (drafts_folder != NULL);
+ g_return_if_fail (drafts_uid != NULL);
+
+ if (emcs->drafts_folder != NULL)
+ camel_object_unref (emcs->drafts_folder);
+ g_free (emcs->drafts_uid);
+
+ camel_object_ref (drafts_folder);
+ emcs->drafts_folder = drafts_folder;
+ emcs->drafts_uid = g_strdup (drafts_uid);
+}
+
+static void
+emcs_set_folder_info (struct emcs_t *emcs,
+ CamelFolder *folder,
+ const gchar *uid,
+ guint32 flags,
+ guint32 set)
+{
+ g_return_if_fail (emcs != NULL);
+ g_return_if_fail (folder != NULL);
+ g_return_if_fail (uid != NULL);
+
+ if (emcs->folder != NULL)
+ camel_object_unref (emcs->folder);
+ g_free (emcs->uid);
+
+ camel_object_ref (folder);
+ emcs->folder = folder;
+ emcs->uid = g_strdup (uid);
+ emcs->flags = flags;
+ emcs->set = set;
+}
+
+static void
free_emcs (struct emcs_t *emcs)
{
- if (emcs->drafts_folder)
+ if (emcs->drafts_folder != NULL)
camel_object_unref (emcs->drafts_folder);
g_free (emcs->drafts_uid);
- if (emcs->folder)
+ if (emcs->folder != NULL)
camel_object_unref (emcs->folder);
g_free (emcs->uid);
+
g_free (emcs);
}
@@ -127,12 +168,6 @@ emcs_unref (struct emcs_t *emcs)
free_emcs (emcs);
}
-static void
-composer_destroy_cb (gpointer user_data, GObject *deadbeef)
-{
- emcs_unref (user_data);
-}
-
static gboolean
ask_confirm_for_unwanted_html_mail (EMsgComposer *composer, EDestination **recipients)
{
@@ -226,17 +261,6 @@ composer_send_queued_cb (CamelFolder *folder, CamelMimeMessage *msg, CamelMessag
mail_send ();
}
} else {
- if (!emcs) {
- /* disconnect the previous signal handlers */
- g_signal_handlers_disconnect_matched (send->composer, G_SIGNAL_MATCH_FUNC, 0,
- 0, NULL, em_utils_composer_send_cb, NULL);
- g_signal_handlers_disconnect_matched (send->composer, G_SIGNAL_MATCH_FUNC, 0,
- 0, NULL, em_utils_composer_save_draft_cb, NULL);
-
- /* reconnect to the signals using a non-NULL emcs for the callback data */
- em_composer_utils_setup_default_callbacks (send->composer);
- }
-
e_msg_composer_set_enable_autosave (send->composer, TRUE);
gtk_widget_show (GTK_WIDGET (send->composer));
}
@@ -416,46 +440,49 @@ composer_get_message (EMsgComposer *composer, gboolean save_html_object_data)
return message;
}
-void
-em_utils_composer_send_cb (EMsgComposer *composer, gpointer user_data)
+static void
+em_utils_composer_send_cb (EMsgComposer *composer)
{
EComposerHeaderTable *table;
CamelMimeMessage *message;
CamelMessageInfo *info;
struct _send_data *send;
- CamelFolder *mail_folder;
+ CamelFolder *folder;
EAccount *account;
table = e_msg_composer_get_header_table (composer);
account = e_composer_header_table_get_account (table);
if (!account || !account->enabled) {
- e_error_run((GtkWindow *)composer, "mail:send-no-account-enabled", NULL);
+ e_error_run (
+ GTK_WINDOW (composer),
+ "mail:send-no-account-enabled", NULL);
return;
}
- if (!(message = composer_get_message (composer, FALSE)))
+ if ((message = composer_get_message (composer, FALSE)) == NULL)
return;
- mail_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
- camel_object_ref (mail_folder);
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ camel_object_ref (folder);
/* mail the message */
- info = camel_message_info_new(NULL);
- camel_message_info_set_flags(info, CAMEL_MESSAGE_SEEN, ~0);
+ info = camel_message_info_new (NULL);
+ camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, ~0);
send = g_malloc (sizeof (*send));
- send->emcs = user_data;
+ send->emcs = g_object_get_data (G_OBJECT (composer), "emcs");
if (send->emcs)
emcs_ref (send->emcs);
send->send = TRUE;
- send->composer = composer;
- g_object_ref (composer);
+ send->composer = g_object_ref (composer);
gtk_widget_hide (GTK_WIDGET (composer));
e_msg_composer_set_enable_autosave (composer, FALSE);
- mail_append_mail (mail_folder, message, info, composer_send_queued_cb, send);
- camel_object_unref (mail_folder);
+ mail_append_mail (
+ folder, message, info, composer_send_queued_cb, send);
+
+ camel_object_unref (folder);
camel_object_unref (message);
}
@@ -495,17 +522,9 @@ save_draft_done (CamelFolder *folder, CamelMimeMessage *msg, CamelMessageInfo *i
composer_set_no_change (sdi->composer, FALSE, FALSE);
- if ((emcs = sdi->emcs) == NULL) {
+ if ((emcs = sdi->emcs) == NULL)
emcs = emcs_new ();
- /* disconnect the previous signal handlers */
- g_signal_handlers_disconnect_by_func (sdi->composer, G_CALLBACK (em_utils_composer_send_cb), NULL);
- g_signal_handlers_disconnect_by_func (sdi->composer, G_CALLBACK (em_utils_composer_save_draft_cb), NULL);
-
- /* reconnect to the signals using a non-NULL emcs for the callback data */
- em_composer_utils_setup_default_callbacks (sdi->composer);
- }
-
if (emcs->drafts_folder) {
/* delete the original draft message */
camel_folder_set_message_flags (emcs->drafts_folder, emcs->drafts_uid,
@@ -557,13 +576,13 @@ save_draft_folder (gchar *uri, CamelFolder *folder, gpointer data)
}
}
-void
-em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data)
+static void
+em_utils_composer_save_draft_cb (EMsgComposer *composer)
{
- const gchar *default_drafts_folder_uri = mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS);
- CamelFolder *drafts_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS);
+ CamelFolder *local_drafts_folder;
EComposerHeaderTable *table;
struct _save_draft_info *sdi;
+ const gchar *local_drafts_folder_uri;
CamelFolder *folder = NULL;
CamelMimeMessage *msg;
CamelMessageInfo *info;
@@ -573,19 +592,24 @@ em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data)
* get destroyed while we're in mail_msg_wait() a little lower
* down, waiting for the folder to open */
- g_object_ref(composer);
+ local_drafts_folder =
+ e_mail_local_get_folder (E_MAIL_FOLDER_DRAFTS);
+ local_drafts_folder_uri =
+ e_mail_local_get_folder_uri (E_MAIL_FOLDER_DRAFTS);
+
+ g_object_ref (composer);
msg = e_msg_composer_get_message_draft (composer);
table = e_msg_composer_get_header_table (composer);
account = e_composer_header_table_get_account (table);
- sdi = g_malloc(sizeof(struct _save_draft_info));
+ sdi = g_malloc (sizeof(struct _save_draft_info));
sdi->composer = composer;
- sdi->emcs = user_data;
+ sdi->emcs = g_object_get_data (G_OBJECT (composer), "emcs");
if (sdi->emcs)
- emcs_ref(sdi->emcs);
+ emcs_ref (sdi->emcs);
if (account && account->drafts_folder_uri &&
- strcmp (account->drafts_folder_uri, default_drafts_folder_uri) != 0) {
+ strcmp (account->drafts_folder_uri, local_drafts_folder_uri) != 0) {
gint id;
id = mail_get_folder (account->drafts_folder_uri, 0, save_draft_folder, &folder, mail_msg_unordered_push);
@@ -601,11 +625,11 @@ em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data)
return;
}
- folder = drafts_folder;
- camel_object_ref (drafts_folder);
+ folder = local_drafts_folder;
+ camel_object_ref (local_drafts_folder);
}
} else {
- folder = drafts_folder;
+ folder = local_drafts_folder;
camel_object_ref (folder);
}
@@ -617,43 +641,24 @@ em_utils_composer_save_draft_cb (EMsgComposer *composer, gpointer user_data)
camel_object_unref (msg);
}
-void
-em_composer_utils_setup_callbacks (EMsgComposer *composer,
- CamelFolder *folder,
- const gchar *uid,
- guint32 flags,
- guint32 set,
- CamelFolder *drafts,
- const gchar *drafts_uid)
+static void
+em_utils_composer_print_cb (EMsgComposer *composer,
+ GtkPrintOperationAction action)
{
- struct emcs_t *emcs;
-
- emcs = emcs_new ();
-
- if (folder && uid) {
- camel_object_ref (folder);
- emcs->folder = folder;
- emcs->uid = g_strdup (uid);
- emcs->flags = flags;
- emcs->set = set;
- }
-
- if (drafts && drafts_uid) {
- camel_object_ref (drafts);
- emcs->drafts_folder = drafts;
- emcs->drafts_uid = g_strdup (drafts_uid);
- }
+ CamelMimeMessage *message;
+ EMFormatHTMLPrint *efhp;
- g_signal_connect (composer, "send", G_CALLBACK (em_utils_composer_send_cb), emcs);
- g_signal_connect (composer, "save-draft", G_CALLBACK (em_utils_composer_save_draft_cb), emcs);
+ message = e_msg_composer_get_message_print (composer, 1);
- g_object_weak_ref ((GObject *) composer, (GWeakNotify) composer_destroy_cb, emcs);
+ efhp = em_format_html_print_new (NULL, action);
+ em_format_html_print_raw_message (efhp, message);
+ g_object_unref (efhp);
}
/* Composing messages... */
static EMsgComposer *
-create_new_composer (const gchar *subject, const gchar *fromuri, gboolean use_default_callbacks, gboolean lite)
+create_new_composer (const gchar *subject, const gchar *fromuri, gboolean lite)
{
EMsgComposer *composer;
EComposerHeaderTable *table;
@@ -678,9 +683,6 @@ create_new_composer (const gchar *subject, const gchar *fromuri, gboolean use_de
e_composer_header_table_set_account (table, account);
e_composer_header_table_set_subject (table, subject);
- if (use_default_callbacks)
- em_composer_utils_setup_default_callbacks (composer);
-
return composer;
}
@@ -695,7 +697,7 @@ em_utils_compose_new_message (const gchar *fromuri)
{
GtkWidget *composer;
- composer = (GtkWidget *) create_new_composer ("", fromuri, TRUE, FALSE);
+ composer = (GtkWidget *) create_new_composer ("", fromuri, FALSE);
if (composer == NULL)
return;
@@ -715,7 +717,7 @@ em_utils_compose_lite_new_message (const gchar *fromuri)
{
GtkWidget *composer;
- composer = (GtkWidget *) create_new_composer ("", fromuri, TRUE, TRUE);
+ composer = (GtkWidget *) create_new_composer ("", fromuri, TRUE);
if (composer == NULL)
return NULL;
@@ -732,7 +734,7 @@ em_utils_compose_lite_new_message (const gchar *fromuri)
* window. If @url is non-NULL, the composer fields will be filled in
* according to the values in the mailto url.
**/
-struct _EMsgComposer *
+EMsgComposer *
em_utils_compose_new_message_with_mailto (const gchar *url, const gchar *fromuri)
{
EMsgComposer *composer;
@@ -745,7 +747,6 @@ em_utils_compose_new_message_with_mailto (const gchar *url, const gchar *fromuri
composer = e_msg_composer_new ();
table = e_msg_composer_get_header_table (composer);
- em_composer_utils_setup_default_callbacks (composer);
if (fromuri
&& (account = mail_config_get_account_by_source_url(fromuri)))
@@ -753,7 +754,7 @@ em_utils_compose_new_message_with_mailto (const gchar *url, const gchar *fromuri
composer_set_no_change (composer, TRUE, url == NULL);
- if (!e_msg_composer_get_lite()) {
+ if (!e_msg_composer_get_lite ()) {
gtk_widget_show ((GtkWidget *) composer);
gdk_window_raise (((GtkWidget *) composer)->window);
}
@@ -903,10 +904,12 @@ edit_message (CamelMimeMessage *message, CamelFolder *drafts, const gchar *uid)
composer = e_msg_composer_new_with_message (message);
- if (em_utils_folder_is_templates(drafts, NULL) == TRUE)
- em_composer_utils_setup_callbacks (composer, NULL, NULL, 0, 0, NULL, NULL);
- else
- em_composer_utils_setup_callbacks (composer, NULL, NULL, 0, 0, drafts, uid);
+ if (em_utils_folder_is_drafts (drafts, NULL)) {
+ struct emcs_t *emcs;
+
+ emcs = g_object_get_data (G_OBJECT (composer), "emcs");
+ emcs_set_drafts_info (emcs, drafts, uid);
+ }
composer_set_no_change (composer, TRUE, FALSE);
@@ -1035,7 +1038,7 @@ forward_attached (CamelFolder *folder, GPtrArray *uids, GPtrArray *messages, Cam
{
EMsgComposer *composer;
- composer = create_new_composer (subject, fromuri, TRUE, FALSE);
+ composer = create_new_composer (subject, fromuri, FALSE);
if (composer == NULL)
return;
@@ -1113,7 +1116,7 @@ forward_non_attached (CamelFolder *folder, GPtrArray *uids, GPtrArray *messages,
text = em_utils_message_to_html (message, _("-------- Forwarded Message --------"), flags, &len, NULL, NULL);
if (text) {
- composer = create_new_composer (subject, fromuri, !uids || !uids->pdata [i], FALSE);
+ composer = create_new_composer (subject, fromuri, FALSE);
if (composer) {
if (CAMEL_IS_MULTIPART(camel_medium_get_content_object((CamelMedium *)message)))
@@ -1121,8 +1124,12 @@ forward_non_attached (CamelFolder *folder, GPtrArray *uids, GPtrArray *messages,
e_msg_composer_set_body_text (composer, text, len);
- if (uids && uids->pdata[i])
- em_composer_utils_setup_callbacks (composer, folder, uids->pdata[i], CAMEL_MESSAGE_FORWARDED, CAMEL_MESSAGE_FORWARDED, NULL, NULL);
+ if (uids && uids->pdata[i]) {
+ struct emcs_t *emcs;
+
+ emcs = g_object_get_data (G_OBJECT (composer), "emcs");
+ emcs_set_folder_info (emcs, folder, uids->pdata[i], CAMEL_MESSAGE_FORWARDED, CAMEL_MESSAGE_FORWARDED);
+ }
composer_set_no_change (composer, TRUE, FALSE);
@@ -1278,8 +1285,6 @@ redirect_get_composer (CamelMimeMessage *message)
composer = e_msg_composer_new_redirect (message, account ? account->name : NULL);
- em_composer_utils_setup_default_callbacks (composer);
-
return composer;
}
@@ -1521,8 +1526,8 @@ em_utils_send_receipt (CamelFolder *folder, CamelMimeMessage *message)
}
/* Send the receipt */
- out_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
info = camel_message_info_new (NULL);
+ out_folder = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
mail_append_mail (out_folder, receipt, info, em_utils_receipt_done, NULL);
}
@@ -1617,8 +1622,8 @@ em_utils_forward_message_raw (CamelFolder *folder, CamelMimeMessage *message, co
g_free (subject);
/* and send it */
- out_folder = mail_component_get_folder (NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
info = camel_message_info_new (NULL);
+ out_folder = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
camel_message_info_set_flags (info, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
mail_append_mail (out_folder, forward, info, emu_forward_raw_done, NULL);
}
@@ -1633,10 +1638,10 @@ generate_account_hash (void)
EAccountList *accounts;
EIterator *iter;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
account_hash = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
- def = mail_config_get_default_account ();
+ def = e_get_default_account ();
iter = e_list_get_iterator ((EList *) accounts);
while (e_iterator_is_valid (iter)) {
@@ -2316,6 +2321,7 @@ em_utils_reply_to_message(CamelFolder *folder, const gchar *uid, CamelMimeMessag
guint32 flags;
EMEvent *eme;
EMEventTargetMessage *target;
+ struct emcs_t *emcs;
if (folder && uid && message == NULL) {
struct _reply_data *rd = g_malloc0(sizeof(*rd));
@@ -2380,7 +2386,8 @@ em_utils_reply_to_message(CamelFolder *folder, const gchar *uid, CamelMimeMessag
composer_set_body (composer, message, source);
- em_composer_utils_setup_callbacks (composer, folder, uid, flags, flags, NULL, NULL);
+ emcs = g_object_get_data (G_OBJECT (composer), "emcs");
+ emcs_set_folder_info (emcs, folder, uid, flags, flags);
composer_set_no_change (composer, TRUE, FALSE);
@@ -2389,3 +2396,105 @@ em_utils_reply_to_message(CamelFolder *folder, const gchar *uid, CamelMimeMessag
return composer;
}
+
+static void
+post_header_clicked_cb (EComposerPostHeader *header)
+{
+ GtkTreeSelection *selection;
+ GtkWidget *folder_tree;
+ GtkWidget *dialog;
+ GList *list;
+
+ folder_tree = em_folder_tree_new ();
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+
+ em_folder_tree_set_excluded (
+ EM_FOLDER_TREE (folder_tree),
+ EMFT_EXCLUDE_NOSELECT |
+ EMFT_EXCLUDE_VIRTUAL |
+ EMFT_EXCLUDE_VTRASH);
+
+ dialog = em_folder_selector_new (
+ EM_FOLDER_TREE (folder_tree),
+ EM_FOLDER_SELECTOR_CAN_CREATE,
+ _("Posting destination"),
+ _("Choose folders to post the message to."),
+ NULL);
+
+ list = e_composer_post_header_get_folders (header);
+ em_folder_selector_set_selected_list (
+ EM_FOLDER_SELECTOR (dialog), list);
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK) {
+ /* Prevent the header's "custom" flag from being reset,
+ * which is what the default method will do next. */
+ g_signal_stop_emission_by_name (header, "clicked");
+ goto exit;
+ }
+
+ list = em_folder_selector_get_selected_uris (
+ EM_FOLDER_SELECTOR (dialog));
+ e_composer_post_header_set_folders (header, list);
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
+
+exit:
+ gtk_widget_destroy (dialog);
+}
+
+/**
+ * em_configure_new_composer:
+ * @composer: a newly created #EMsgComposer
+ *
+ * Integrates a newly created #EMsgComposer into the mail backend. The
+ * composer can't link directly to the mail backend without introducing
+ * circular library dependencies, so this function finishes configuring
+ * things the #EMsgComposer instance can't do itself.
+ **/
+void
+em_configure_new_composer (EMsgComposer *composer)
+{
+ EComposerHeaderTable *table;
+ EComposerHeaderType header_type;
+ EComposerHeader *header;
+ struct emcs_t *emcs;
+
+ g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+ header_type = E_COMPOSER_HEADER_POST_TO;
+ table = e_msg_composer_get_header_table (composer);
+ header = e_composer_header_table_get_header (table, header_type);
+
+ emcs = emcs_new ();
+
+ g_object_set_data_full (
+ G_OBJECT (composer), "emcs", emcs,
+ (GDestroyNotify) emcs_unref);
+
+ g_signal_connect (
+ composer, "send",
+ G_CALLBACK (em_utils_composer_send_cb), NULL);
+
+ g_signal_connect (
+ composer, "save-draft",
+ G_CALLBACK (em_utils_composer_save_draft_cb), NULL);
+
+ g_signal_connect (
+ composer, "print",
+ G_CALLBACK (em_utils_composer_print_cb), NULL);
+
+ /* Handle "Post To:" button clicks, which displays a folder tree
+ * widget. The composer doesn't know about folder tree widgets,
+ * so it can't handle this itself.
+ *
+ * Note: This is a G_SIGNAL_RUN_LAST signal, which allows us to
+ * stop the signal emission if the user cancels or closes
+ * the folder selector dialog. See the handler function. */
+ g_signal_connect (
+ header, "clicked",
+ G_CALLBACK (post_header_clicked_cb), NULL);
+}
diff --git a/mail/em-composer-utils.h b/mail/em-composer-utils.h
index 66168e3a43..763de3301c 100644
--- a/mail/em-composer-utils.h
+++ b/mail/em-composer-utils.h
@@ -27,19 +27,11 @@
#include <glib.h>
#include <camel/camel-nntp-address.h>
-#include <mail/em-format.h>
+#include <em-format/em-format.h>
#include <composer/e-msg-composer.h>
G_BEGIN_DECLS
-void em_composer_utils_setup_callbacks (EMsgComposer *composer, CamelFolder *folder, const gchar *uid,
- guint32 flags, guint32 set, CamelFolder *drafts, const gchar *drafts_uid);
-
-#define em_composer_utils_setup_default_callbacks(composer) em_composer_utils_setup_callbacks (composer, NULL, NULL, 0, 0, NULL, NULL)
-
-void em_utils_composer_send_cb(EMsgComposer *composer, gpointer user_data);
-void em_utils_composer_save_draft_cb(EMsgComposer *composer, gpointer user_data);
-
void em_utils_compose_new_message (const gchar *fromuri);
EMsgComposer * em_utils_compose_lite_new_message (const gchar *fromuri);
@@ -76,6 +68,8 @@ void em_utils_get_reply_all (CamelMimeMessage *message, CamelInternetAddress *to
EMsgComposer * em_utils_reply_to_message (CamelFolder *, const gchar *uid, CamelMimeMessage *message, gint mode, EMFormat *source);
EDestination ** em_utils_camel_address_to_destination (CamelInternetAddress *iaddr);
+void em_configure_new_composer (struct _EMsgComposer *composer);
+
G_END_DECLS
#endif /* __EM_COMPOSER_UTILS_H__ */
diff --git a/mail/em-event.c b/mail/em-event.c
index b1bf7a7d05..5bc03ac875 100644
--- a/mail/em-event.c
+++ b/mail/em-event.c
@@ -147,16 +147,6 @@ em_event_target_new_folder (EMEvent *eme, const gchar *uri, guint new)
return t;
}
-EMEventTargetFolderBrowser *
-em_event_target_new_folder_browser (EMEvent *eme, EMFolderBrowser *emfb)
-{
- EMEventTargetFolderBrowser *t = e_event_target_new(&eme->popup, EM_EVENT_TARGET_FOLDER_BROWSER, sizeof(*t));
-
- t->emfb = emfb;
-
- return t;
-}
-
EMEventTargetComposer *
em_event_target_new_composer (EMEvent *eme, const EMsgComposer *composer, guint32 flags)
{
@@ -221,11 +211,6 @@ static const EEventHookTargetMask emeh_folder_masks[] = {
{ NULL }
};
-static const EEventHookTargetMask emeh_folder_browser_masks[] = {
- { "folderbrowser", EM_EVENT_FOLDER_BROWSER },
- { NULL }
-};
-
static const EEventHookTargetMask emeh_composer_masks[] = {
{ "sendoption", EM_EVENT_COMPOSER_SEND_OPTION },
{ NULL }
@@ -248,7 +233,6 @@ static const EEventHookTargetMask emeh_custom_icon_masks[] = {
static const EEventHookTargetMap emeh_targets[] = {
{ "folder", EM_EVENT_TARGET_FOLDER, emeh_folder_masks },
- { "folderbrowser", EM_EVENT_TARGET_FOLDER_BROWSER, emeh_folder_browser_masks },
{ "message", EM_EVENT_TARGET_MESSAGE, emeh_message_masks },
{ "composer", EM_EVENT_TARGET_COMPOSER, emeh_composer_masks},
{ "sendreceive", EM_EVENT_TARGET_SEND_RECEIVE, emeh_send_receive_masks},
diff --git a/mail/em-event.h b/mail/em-event.h
index e2235a122a..6680e88982 100644
--- a/mail/em-event.h
+++ b/mail/em-event.h
@@ -28,7 +28,6 @@
#include "e-util/e-event.h"
#include "composer/e-msg-composer.h"
-#include "mail/em-folder-browser.h"
G_BEGIN_DECLS
@@ -38,18 +37,12 @@ typedef struct _EMEventClass EMEventClass;
/* Current target description */
enum _em_event_target_t {
EM_EVENT_TARGET_FOLDER,
- EM_EVENT_TARGET_FOLDER_BROWSER,
EM_EVENT_TARGET_MESSAGE,
EM_EVENT_TARGET_COMPOSER,
EM_EVENT_TARGET_SEND_RECEIVE,
EM_EVENT_TARGET_CUSTOM_ICON
};
-/* Flags for FOLDER BROWSER Events*/
-enum {
- EM_EVENT_FOLDER_BROWSER = 1<< 0
-};
-
/* Flags that describe TARGET_FOLDER */
enum {
EM_EVENT_FOLDER_NEWMAIL = 1<< 0
@@ -102,14 +95,6 @@ struct _EMEventTargetComposer {
EMsgComposer *composer;
};
-typedef struct _EMEventTargetFolderBrowser EMEventTargetFolderBrowser;
-
-struct _EMEventTargetFolderBrowser {
- EEventTarget target;
-
- EMFolderBrowser *emfb;
-};
-
typedef struct _EMEventTargetSendReceive EMEventTargetSendReceive;
struct _EMEventTargetSendReceive {
@@ -148,7 +133,6 @@ GType em_event_get_type(void);
EMEvent *em_event_peek(void);
EMEventTargetFolder *em_event_target_new_folder(EMEvent *emp, const gchar *uri, guint32 flags);
-EMEventTargetFolderBrowser *em_event_target_new_folder_browser (EMEvent *eme, EMFolderBrowser *emfb);
EMEventTargetComposer *em_event_target_new_composer(EMEvent *emp, const EMsgComposer *composer, guint32 flags);
EMEventTargetMessage *em_event_target_new_message(EMEvent *emp, CamelFolder *folder, CamelMimeMessage *message, const gchar *uid, guint32 flags);
EMEventTargetSendReceive * em_event_target_new_send_receive(EMEvent *eme, GtkWidget *table, gpointer data, gint row, guint32 flags);
diff --git a/mail/em-filter-folder-element.c b/mail/em-filter-folder-element.c
index b531780287..7b64ef9aa6 100644
--- a/mail/em-filter-folder-element.c
+++ b/mail/em-filter-folder-element.c
@@ -33,7 +33,6 @@
#include "em-filter-folder-element.h"
#include "mail/em-folder-selection-button.h"
-#include "mail/mail-component.h"
#include "mail/em-utils.h"
#include "libedataserver/e-sexp.h"
#include "e-util/e-error.h"
@@ -255,8 +254,11 @@ get_widget(FilterElement *fe)
uri = ff->uri;
else
uri = em_uri_to_camel (ff->uri);
- button = em_folder_selection_button_new(_("Select Folder"), NULL);
- em_folder_selection_button_set_selection(EM_FOLDER_SELECTION_BUTTON(button), uri);
+
+ button = em_folder_selection_button_new (_("Select Folder"), NULL);
+
+ em_folder_selection_button_set_selection(
+ EM_FOLDER_SELECTION_BUTTON (button), uri);
if (!ff->store_camel_uri)
g_free(uri);
diff --git a/mail/em-folder-browser.c b/mail/em-folder-browser.c
index c6c90caffb..ce3a3c493f 100644
--- a/mail/em-folder-browser.c
+++ b/mail/em-folder-browser.c
@@ -58,13 +58,6 @@
#include <camel/camel-vee-store.h>
#include <camel/camel-operation.h>
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <bonobo/bonobo-ui-util.h>
-
/* for efilterbar stuff */
#include <libedataserver/e-sexp.h>
#include "mail-vfolder.h"
@@ -149,7 +142,6 @@ static void emfb_search_menu_activated(ESearchBar *esb, gint id, EMFolderBrowser
static void emfb_search_search_activated(ESearchBar *esb, EMFolderBrowser *emfb);
static void emfb_search_search_cleared(ESearchBar *esb);
-static gint emfb_list_key_press(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *ev, EMFolderBrowser *emfb);
static void emfb_list_message_selected (MessageList *ml, const gchar *uid, EMFolderBrowser *emfb);
static void emfb_expand_all_threads(BonoboUIComponent *uid, gpointer data, const gchar *path);
@@ -214,27 +206,6 @@ enum {
/* label IDs are set above this number */
#define VIEW_ITEMS_MASK 63
-/* Options for View */
-static EMFBSearchBarItem emfb_view_items[] = {
- {{ (gchar *) N_("All Messages"), VIEW_ALL_MESSAGES, 0 }, NULL},
- {{ (gchar *) N_("Unread Messages"), VIEW_UNREAD_MESSAGES, 0 }, "mail-unread"},
- {{ NULL, 0, 0 }, NULL},
- {{ (gchar *) N_("No Label"),VIEW_NO_LABEL, 0 }, NULL},
- {{ NULL, -1, 0 }, NULL}
-};
-
-/* TODO: Following options should be customizable */
-static EMFBSearchBarItem temp_view_items[] = {
- {{ NULL, 0, 0 }, NULL},
- {{ (gchar *) N_("Read Messages"), VIEW_READ_MESSAGES, 0 }, "mail-read"},
- {{ (gchar *) N_("Recent Messages"), VIEW_RECENT_MESSAGES, 0 }, NULL},
- {{ (gchar *) N_("Last 5 Days' Messages"), VIEW_LAST_FIVE_DAYS, 0 }, NULL},
- {{ (gchar *) N_("Messages with Attachments"), VIEW_WITH_ATTACHMENTS, 0 }, "mail-attachment"},
- {{ (gchar *) N_("Important Messages"), VIEW_MESSAGES_MARKED_AS_IMPORTANT, 0}, "emblem-important"},
- {{ (gchar *) N_("Messages Not Junk"), VIEW_NOT_JUNK, 0 }, "mail-mark-notjunk"},
- {{ NULL, -1, 0 }, NULL}
-};
-
static ESearchBarItem emfb_search_scope_items[] = {
E_FILTERBAR_CURRENT_FOLDER,
E_FILTERBAR_CURRENT_ACCOUNT,
@@ -244,239 +215,25 @@ static ESearchBarItem emfb_search_scope_items[] = {
static EMFolderViewClass *emfb_parent;
-/* Needed since the paned wont take the position its given otherwise ... */
-static void
-emfb_pane_realised(GtkWidget *w, EMFolderBrowser *emfb)
-{
- GConfClient *gconf;
-
- gconf = mail_config_get_gconf_client ();
-
- if (emfb->priv->show_wide)
- gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int(gconf, "/apps/evolution/mail/display/hpaned_size", NULL));
- else
- gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int(gconf, "/apps/evolution/mail/display/paned_size", NULL));
-}
-
-static gboolean
-emfb_pane_button_release_event(GtkWidget *w, GdkEventButton *e, EMFolderBrowser *emfb)
-{
- GConfClient *gconf = mail_config_get_gconf_client ();
-
- if (GTK_WIDGET_REALIZED (w)) {
- if (emfb->priv->show_wide)
- gconf_client_set_int(gconf, "/apps/evolution/mail/display/hpaned_size",
- gtk_paned_get_position(GTK_PANED(w)), NULL);
- else
- gconf_client_set_int(gconf, "/apps/evolution/mail/display/paned_size",
- gtk_paned_get_position(GTK_PANED(w)), NULL);
-
- }
-
- return FALSE;
-}
-
-static void
-free_one_ui_file (gpointer data,
- gpointer user_data)
-{
- g_free (data);
-}
-
-static GtkWidget *
-generate_viewoption_menu (GtkWidget *emfv)
-{
- GtkWidget *menu, *menu_item;
- gint i = 0;
- GSList *l;
-
- menu = gtk_menu_new ();
-
- for (i = 0; emfb_view_items[i].search.id != -1; ++i) {
- if (emfb_view_items[i].search.text) {
- gchar *str;
-
- str = e_str_without_underscores (_(emfb_view_items[i].search.text));
- menu_item = gtk_image_menu_item_new_with_label (str);
- if (emfb_view_items[i].image) {
- GtkWidget *image;
-
- image = gtk_image_new_from_icon_name (
- emfb_view_items[i].image,
- GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (
- GTK_IMAGE_MENU_ITEM (menu_item),
- image);
- }
- g_free (str);
- } else {
- menu_item = gtk_menu_item_new ();
- gtk_widget_set_sensitive (menu_item, FALSE);
- }
-
- g_object_set_data (G_OBJECT (menu_item), "EsbItemId",
- GINT_TO_POINTER (emfb_view_items[i].search.id));
-
- gtk_widget_show (menu_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- }
-
- /* Add the labels */
- for (l = mail_config_get_labels (), i = 0; l; l = l->next, i++) {
- EUtilLabel *label = l->data;
- if (label->name && *(label->name)) {
- gchar *str;
- GdkPixmap *pixmap;
- GdkColor colour;
- GdkGC *gc;
- GtkWidget *image;
-
- gdk_color_parse(label->colour, &colour);
- gdk_colormap_alloc_color(gdk_colormap_get_system(), &colour, FALSE, TRUE);
-
- pixmap = gdk_pixmap_new(((GtkWidget *)emfv)->window, 16, 16, -1);
- gc = gdk_gc_new(((GtkWidget *)emfv)->window);
- gdk_gc_set_foreground(gc, &colour);
- gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, 16, 16);
- g_object_unref(gc);
-
- image = gtk_image_new_from_pixmap(pixmap, NULL);
- str = e_str_without_underscores (label->name);
- menu_item = gtk_image_menu_item_new_with_label (str);
- g_free (str);
- gtk_image_menu_item_set_image ((GtkImageMenuItem *)menu_item, image);
- g_object_set_data (G_OBJECT (menu_item), "EsbItemId",
- GINT_TO_POINTER (VIEW_LABEL + (VIEW_ITEMS_MASK + 1) * i));
-
- g_object_set_data_full (G_OBJECT (menu_item), "LabelTag",
- g_strdup (strncmp (label->tag, "$Label", 6) == 0 ? label->tag + 6 : label->tag),
- g_free);
- }
-
- gtk_widget_show (menu_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- }
-
- for (i = 0; temp_view_items[i].search.id != -1; ++i) {
- if (temp_view_items[i].search.text) {
- gchar *str;
- str = e_str_without_underscores (_(temp_view_items[i].search.text));
- menu_item = gtk_image_menu_item_new_with_label (str);
- if (temp_view_items[i].image) {
- GtkWidget *image;
-
- image = gtk_image_new_from_icon_name (
- temp_view_items[i].image,
- GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (
- GTK_IMAGE_MENU_ITEM (menu_item),
- image);
- }
- g_free (str);
- } else {
- menu_item = gtk_menu_item_new ();
- gtk_widget_set_sensitive (menu_item, FALSE);
- }
-
- g_object_set_data (G_OBJECT (menu_item), "EsbItemId",
- GINT_TO_POINTER (temp_view_items[i].search.id));
-
- gtk_widget_show (menu_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- }
-
- return menu;
-}
-
-#if 0
-static GArray *
-viewoption_menu_generator ()
-{
- GArray *menu = g_array_new (FALSE, FALSE, sizeof (ESearchBarItem));
- gint i = 0;
- ESearchBarItem dup_item;
- GSList *l;
-
- for (i = 0; emfb_view_items[i].search.id != -1; i++)
- g_array_append_vals (menu, &emfb_view_items[i], 1);
-
- for (l = mail_config_get_labels (); l; l = l->next) {
- ESearchBarItem item;
- EUtilLabel *label = l->data;
-
- item.text = label->name;
- item.id = VIEW_LABEL;
-
- g_array_append_vals (menu, &item, 1);
- }
-
- dup_item.id = -1;
- dup_item.text = NULL;
- g_array_append_vals (menu, &dup_item, 1);
-
- return menu;
-}
-#endif
-
-static void
-emfb_realize (GtkWidget *widget)
-{
- GtkWidget *menu;
- EMFolderBrowser *emfb = (EMFolderBrowser *)widget;
- gint id;
-
- menu = generate_viewoption_menu (widget);
- id = e_search_bar_get_viewitem_id (E_SEARCH_BAR (emfb->search));
-
- e_search_bar_set_viewoption_menu (E_SEARCH_BAR (emfb->search), menu);
-
- /* restore last selected ID, if any */
- if (id != -1)
- e_search_bar_set_viewitem_id (E_SEARCH_BAR (emfb->search), id);
-}
-
-static void
-html_scroll (GtkHTML *html,
- GtkOrientation orientation,
- GtkScrollType scroll_type,
- gfloat position,
- EMFolderBrowser *emfb)
-
-{
- if (html->binding_handled || orientation != GTK_ORIENTATION_VERTICAL || !mail_config_get_enable_magic_spacebar ())
- return;
-
- if (scroll_type == GTK_SCROLL_PAGE_FORWARD) {
- gtk_widget_grab_focus ((GtkWidget *)((EMFolderView *) emfb)->list);
- message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN);
- } else if (scroll_type == GTK_SCROLL_PAGE_BACKWARD) {
- gtk_widget_grab_focus ((GtkWidget *)((EMFolderView *) emfb)->list);
- message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN);
- }
-}
-
-static gboolean
-labels_changed_idle_cb (gpointer user_data)
-{
- EMFolderBrowser *emfb = (EMFolderBrowser*) user_data;
-
- emfb_realize (GTK_WIDGET (emfb));
-
- emfb->priv->labels_change_idle_id = 0;
-
- return FALSE;
-}
-
-static void
-gconf_labels_changed (GConfClient *client, guint cnxn_id,
- GConfEntry *entry, gpointer user_data)
-{
- EMFolderBrowser *emfb = (EMFolderBrowser*) user_data;
-
- /* regenerate menu option whenever something changed in labels */
- if (emfb && !emfb->priv->labels_change_idle_id)
- emfb->priv->labels_change_idle_id = g_idle_add (labels_changed_idle_cb, emfb);
-}
+//static void
+//html_scroll (GtkHTML *html,
+// GtkOrientation orientation,
+// GtkScrollType scroll_type,
+// gfloat position,
+// EMFolderBrowser *emfb)
+//
+//{
+// if (html->binding_handled || orientation != GTK_ORIENTATION_VERTICAL || !mail_config_get_enable_magic_spacebar ())
+// return;
+//
+// if (scroll_type == GTK_SCROLL_PAGE_FORWARD) {
+// gtk_widget_grab_focus ((GtkWidget *)((EMFolderView *) emfb)->list);
+// message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN);
+// } else if (scroll_type == GTK_SCROLL_PAGE_BACKWARD) {
+// gtk_widget_grab_focus ((GtkWidget *)((EMFolderView *) emfb)->list);
+// message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN);
+// }
+//}
static void
emfb_init(GObject *o)
@@ -494,82 +251,80 @@ emfb_init(GObject *o)
emfb->view.preview_active = TRUE;
emfb->view.list_active = TRUE;
- g_signal_connect_after (((EMFormatHTML *)(emfb->view.preview))->html, "scroll", G_CALLBACK (html_scroll), emfb);
+// g_signal_connect_after (((EMFormatHTML *)(emfb->view.preview))->html, "scroll", G_CALLBACK (html_scroll), emfb);
- g_slist_foreach (emfb->view.ui_files, free_one_ui_file, NULL);
- g_slist_free(emfb->view.ui_files);
+// g_slist_foreach (emfb->view.ui_files, free_one_ui_file, NULL);
+// g_slist_free(emfb->view.ui_files);
- emfb->view.ui_files = g_slist_append(NULL,
- g_build_filename (EVOLUTION_UIDIR,
- "evolution-mail-global.xml",
- NULL));
- emfb->view.ui_files = g_slist_append(emfb->view.ui_files,
- g_build_filename (EVOLUTION_UIDIR,
- "evolution-mail-list.xml",
- NULL));
- emfb->view.ui_files = g_slist_append(emfb->view.ui_files,
- g_build_filename (EVOLUTION_UIDIR,
- "evolution-mail-message.xml",
- NULL));
+// emfb->view.ui_files = g_slist_append(NULL,
+// g_build_filename (EVOLUTION_UIDIR,
+// "evolution-mail-global.xml",
+// NULL));
+// emfb->view.ui_files = g_slist_append(emfb->view.ui_files,
+// g_build_filename (EVOLUTION_UIDIR,
+// "evolution-mail-list.xml",
+// NULL));
+// emfb->view.ui_files = g_slist_append(emfb->view.ui_files,
+// g_build_filename (EVOLUTION_UIDIR,
+// "evolution-mail-message.xml",
+// NULL));
emfb->view.enable_map = g_slist_prepend(emfb->view.enable_map, (gpointer)emfb_enable_map);
- if (search_context) {
- const gchar *systemrules = g_object_get_data (G_OBJECT (search_context), "system");
- const gchar *userrules = g_object_get_data (G_OBJECT (search_context), "user");
- EFilterBar *efb;
- GConfClient *gconf;
-
- emfb->search = e_filter_bar_new(search_context, systemrules, userrules, emfb_search_config_search, emfb);
- efb = (EFilterBar *)emfb->search;
- efb->account_search_vf = NULL;
- efb->all_account_search_vf = NULL;
- efb->account_search_cancel = NULL;
- e_search_bar_set_menu ((ESearchBar *)emfb->search, emfb_search_items);
- e_search_bar_set_scopeoption ((ESearchBar *)emfb->search, emfb_search_scope_items);
- emfb->priv->scope_restricted = TRUE;
- g_signal_connect(emfb, "realize", G_CALLBACK(emfb_realize), NULL);
- gtk_widget_show((GtkWidget *)emfb->search);
-
- p->search_menu_activated_id = g_signal_connect(emfb->search, "menu_activated", G_CALLBACK(emfb_search_menu_activated), emfb);
- p->search_activated_id = g_signal_connect(emfb->search, "search_activated", G_CALLBACK(emfb_search_search_activated), emfb);
- g_signal_connect(emfb->search, "search_cleared", G_CALLBACK(emfb_search_search_cleared), NULL);
-
- gtk_box_pack_start((GtkBox *)emfb, (GtkWidget *)emfb->search, FALSE, TRUE, 0);
-
- gconf = mail_config_get_gconf_client ();
- emfb->priv->labels_change_notify_id = gconf_client_notify_add (gconf, E_UTIL_LABELS_GCONF_KEY, gconf_labels_changed, emfb, NULL, NULL);
- }
-
- emfb->priv->show_wide = gconf_client_get_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/display/show_wide", NULL);
- emfb->vpane = emfb->priv->show_wide?gtk_hpaned_new():gtk_vpaned_new();
-
- g_signal_connect(emfb->vpane, "realize", G_CALLBACK(emfb_pane_realised), emfb);
- emfb->priv->vpane_resize_id = g_signal_connect(emfb->vpane, "button_release_event", G_CALLBACK(emfb_pane_button_release_event), emfb);
-
- gtk_widget_show(emfb->vpane);
-
- gtk_box_pack_start((GtkBox *)emfb, emfb->vpane, TRUE, TRUE, 0);
-
- gtk_paned_pack1 (GTK_PANED (emfb->vpane), GTK_WIDGET (emfb->view.list), FALSE, FALSE);
- gtk_widget_show((GtkWidget *)emfb->view.list);
-
- /* currently: just use a scrolledwindow for preview widget */
- p->scroll = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_policy((GtkScrolledWindow *)p->scroll, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type((GtkScrolledWindow *)p->scroll, GTK_SHADOW_IN);
- gtk_widget_show(p->scroll);
-
- html = GTK_WIDGET (emfb->view.preview->formathtml.html);
-
- p->preview = gtk_vbox_new (FALSE, 1);
- p->search_bar = e_mail_search_bar_new (GTK_HTML (html));
- gtk_container_add((GtkContainer *)p->scroll, html);
- gtk_widget_show(html);
- gtk_box_pack_start ((GtkBox *)p->preview, p->scroll, TRUE, TRUE, 0);
- gtk_box_pack_start ((GtkBox *)p->preview, p->search_bar, FALSE, FALSE, 0);
- gtk_paned_pack2 (GTK_PANED (emfb->vpane), p->preview, TRUE, FALSE);
- gtk_widget_show(p->preview);
+// if (search_context) {
+// const gchar *systemrules = g_object_get_data (G_OBJECT (search_context), "system");
+// const gchar *userrules = g_object_get_data (G_OBJECT (search_context), "user");
+// EFilterBar *efb;
+// GConfClient *gconf;
+//
+// emfb->search = e_filter_bar_new(search_context, systemrules, userrules, emfb_search_config_search, emfb);
+// efb = (EFilterBar *)emfb->search;
+// efb->account_search_vf = NULL;
+// efb->all_account_search_vf = NULL;
+// efb->account_search_cancel = NULL;
+// e_search_bar_set_menu ((ESearchBar *)emfb->search, emfb_search_items);
+// e_search_bar_set_scopeoption ((ESearchBar *)emfb->search, emfb_search_scope_items);
+// e_search_bar_scope_enable ((ESearchBar *)emfb->search, E_FILTERBAR_CURRENT_MESSAGE_ID, FALSE);
+// emfb->priv->scope_restricted = TRUE;
+// g_signal_connect(emfb, "realize", G_CALLBACK(emfb_realize), NULL);
+// gtk_widget_show((GtkWidget *)emfb->search);
+//
+// p->search_menu_activated_id = g_signal_connect(emfb->search, "menu_activated", G_CALLBACK(emfb_search_menu_activated), emfb);
+// p->search_activated_id = g_signal_connect(emfb->search, "search_activated", G_CALLBACK(emfb_search_search_activated), emfb);
+// g_signal_connect(emfb->search, "search_cleared", G_CALLBACK(emfb_search_search_cleared), NULL);
+//
+// gtk_box_pack_start((GtkBox *)emfb, (GtkWidget *)emfb->search, FALSE, TRUE, 0);
+//
+// gconf = mail_config_get_gconf_client ();
+// emfb->priv->labels_change_notify_id = gconf_client_notify_add (gconf, E_UTIL_LABELS_GCONF_KEY, gconf_labels_changed, emfb, NULL, NULL);
+// }
+//
+// emfb->priv->show_wide = gconf_client_get_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/display/show_wide", NULL);
+// emfb->vpane = emfb->priv->show_wide?gtk_hpaned_new():gtk_vpaned_new();
+//
+// g_signal_connect(emfb->vpane, "realize", G_CALLBACK(emfb_pane_realised), emfb);
+// emfb->priv->vpane_resize_id = g_signal_connect(emfb->vpane, "button_release_event", G_CALLBACK(emfb_pane_button_release_event), emfb);
+//
+// gtk_widget_show(emfb->vpane);
+//
+// gtk_box_pack_start_defaults((GtkBox *)emfb, emfb->vpane);
+//
+// gtk_paned_pack1 (GTK_PANED (emfb->vpane), GTK_WIDGET (emfb->view.list), FALSE, FALSE);
+// gtk_widget_show((GtkWidget *)emfb->view.list);
+//
+// /* currently: just use a scrolledwindow for preview widget */
+// p->scroll = gtk_scrolled_window_new(NULL, NULL);
+// gtk_scrolled_window_set_policy((GtkScrolledWindow *)p->scroll, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+// gtk_scrolled_window_set_shadow_type((GtkScrolledWindow *)p->scroll, GTK_SHADOW_IN);
+// gtk_widget_show(p->scroll);
+//
+// p->preview = gtk_vbox_new (FALSE, 6);
+// gtk_container_add((GtkContainer *)p->scroll, (GtkWidget *)emfb->view.preview->formathtml.html);
+// gtk_widget_show((GtkWidget *)emfb->view.preview->formathtml.html);
+// gtk_box_pack_start ((GtkBox *)p->preview, p->scroll, TRUE, TRUE, 0);
+// gtk_box_pack_start ((GtkBox *)p->preview, em_format_html_get_search_dialog (emfb->view.preview), FALSE, FALSE, 0);
+// gtk_paned_pack2 (GTK_PANED (emfb->vpane), p->preview, TRUE, FALSE);
+// gtk_widget_show(p->preview);
g_signal_connect_swapped (
p->search_bar, "changed",
@@ -586,23 +341,11 @@ emfb_init(GObject *o)
e_event_emit((EEvent *)eme, "emfb.created", (EEventTarget *)target);
- g_signal_connect (((EMFolderView *) emfb)->list->tree, "key_press", G_CALLBACK(emfb_list_key_press), emfb);
g_signal_connect (((EMFolderView *) emfb)->list, "message_selected", G_CALLBACK (emfb_list_message_selected), emfb);
}
static void
-emfb_finalise(GObject *o)
-{
- EMFolderBrowser *emfb = (EMFolderBrowser *)o;
-
- g_free (emfb->priv->select_uid);
- g_free (emfb->priv);
-
- ((GObjectClass *)emfb_parent)->finalize(o);
-}
-
-static void
emfb_destroy(GtkObject *o)
{
EMFolderBrowser *emfb = (EMFolderBrowser *)o;
@@ -622,8 +365,8 @@ emfb_destroy(GtkObject *o)
emfb->priv->idle_scroll_id = 0;
}
- if (emfb->view.folder && emfb->priv->folder_changed_id)
- camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
+// if (emfb->view.folder && emfb->priv->folder_changed_id)
+// camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
if (emfb->priv->labels_change_notify_id) {
GConfClient *gconf = mail_config_get_gconf_client ();
@@ -643,83 +386,6 @@ emfb_destroy(GtkObject *o)
((GtkObjectClass *)emfb_parent)->destroy(o);
}
-static void
-emfb_show_search_bar (EMFolderView *folder_view)
-{
- EMFolderBrowser *browser = (EMFolderBrowser *) folder_view;
-
- gtk_widget_show (browser->priv->search_bar);
-}
-
-static void
-emfb_class_init(GObjectClass *klass)
-{
- klass->finalize = emfb_finalise;
-
- folder_browser_signals[ACCOUNT_SEARCH_ACTIVATED] =
- g_signal_new ("account_search_activated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMFolderBrowserClass, account_search_activated),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- folder_browser_signals[ACCOUNT_SEARCH_CLEARED] =
- g_signal_new ("account_search_cleared",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMFolderBrowserClass, account_search_cleared),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- ((GtkObjectClass *)klass)->destroy = emfb_destroy;
- ((EMFolderViewClass *)klass)->set_folder = emfb_set_folder;
- ((EMFolderViewClass *)klass)->activate = emfb_activate;
- ((EMFolderViewClass *)klass)->show_search_bar = emfb_show_search_bar;
-}
-
-GType
-em_folder_browser_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFolderBrowserClass),
- NULL, NULL,
- (GClassInitFunc)emfb_class_init,
- NULL, NULL,
- sizeof(EMFolderBrowser), 0,
- (GInstanceInitFunc)emfb_init
- };
- emfb_parent = g_type_class_ref(em_folder_view_get_type());
- type = g_type_register_static(em_folder_view_get_type(), "EMFolderBrowser", &info, 0);
- }
-
- return type;
-}
-
-GtkWidget *em_folder_browser_new(void)
-{
- EMFolderBrowser *emfb = g_object_new(em_folder_browser_get_type(), 0);
-
- /** @HookPoint-EMMenu: Main Mail Menu
- * @Id: org.gnome.evolution.mail.browser
- * @Class: org.gnome.evolution.mail.bonobomenu:1.0
- * @Target: EMMenuTargetSelect
- *
- * The main menu of mail view of the main application window.
- * If the folder is NULL (not selected), the target will be empty, not NULL.
- */
- ((EMFolderView *)emfb)->menu = em_menu_new("org.gnome.evolution.mail.browser");
-
- return (GtkWidget *)emfb;
-}
-
void em_folder_browser_show_preview(EMFolderBrowser *emfb, gboolean state)
{
if ((emfb->view.preview_active ^ state) == 0
@@ -775,42 +441,6 @@ gboolean em_folder_browser_get_wide (EMFolderBrowser *emfb)
return emfb->priv->show_wide;
}
-void em_folder_browser_show_wide(EMFolderBrowser *emfb, gboolean state)
-{
- GtkWidget *w;
- gint paned_size;
-
- if ((emfb->priv->show_wide && state)
- || emfb->view.list == NULL) {
- emfb->priv->show_wide = state;
- return;
- }
-
- emfb->priv->show_wide = state;
-
- w = emfb->priv->show_wide?gtk_hpaned_new():gtk_vpaned_new();
-
- g_signal_handler_disconnect(emfb->vpane, emfb->priv->vpane_resize_id);
- g_signal_connect(w, "realize", G_CALLBACK(emfb_pane_realised), emfb);
- emfb->priv->vpane_resize_id = g_signal_connect(w, "button_release_event", G_CALLBACK(emfb_pane_button_release_event), emfb);
-
- gtk_box_pack_start((GtkBox *)emfb, w, TRUE, TRUE, 0);
- gtk_widget_reparent((GtkWidget *)emfb->view.list, w);
- gtk_widget_reparent((GtkWidget *)emfb->priv->preview, w);
- gtk_widget_destroy(emfb->vpane);
- gtk_container_child_set (GTK_CONTAINER (w), GTK_WIDGET (emfb->view.list), "resize", FALSE, "shrink", FALSE, NULL);
- gtk_container_child_set (GTK_CONTAINER (w), GTK_WIDGET (emfb->priv->preview), "resize", TRUE, "shrink", FALSE, NULL);
- gtk_container_resize_children ((GtkContainer *)w);
- emfb->vpane = w;
- gtk_widget_show(w);
-
- paned_size = gconf_client_get_int(mail_config_get_gconf_client(), emfb->priv->show_wide ? "/apps/evolution/mail/display/hpaned_size":"/apps/evolution/mail/display/paned_size", NULL);
- gtk_paned_set_position (GTK_PANED (emfb->vpane), paned_size);
-
- if (((EMFolderView *)emfb)->folder)
- em_folder_view_setup_view_instance ((EMFolderView *) emfb);
-}
-
/* ********************************************************************** */
/* FIXME: Need to separate system rules from user ones */
@@ -848,164 +478,6 @@ emfb_search_menu_activated(ESearchBar *esb, gint id, EMFolderBrowser *emfb)
}
}
-static void
-emfb_search_config_search(EFilterBar *efb, FilterRule *rule, gint id, const gchar *query, gpointer data)
-{
- EMFolderBrowser *emfb = data;
- EMailSearchBar *search_bar;
- ESearchingTokenizer *tokenizer;
- GList *partl;
- struct _camel_search_words *words;
- gint i;
- GSList *strings = NULL;
-
- /* we scan the parts of a rule, and set all the types we know about to the query string */
- partl = rule->parts;
- while (partl) {
- FilterPart *part = partl->data;
-
- if (!strcmp(part->name, "subject")) {
- FilterInput *input = (FilterInput *)filter_part_find_element(part, "subject");
- if (input)
- filter_input_set_value(input, query);
- } else if (!strcmp(part->name, "body")) {
- FilterInput *input = (FilterInput *)filter_part_find_element(part, "word");
- if (input)
- filter_input_set_value(input, query);
-
- words = camel_search_words_split((guchar *)query);
- for (i=0;i<words->len;i++)
- strings = g_slist_prepend(strings, g_strdup(words->words[i]->word));
- camel_search_words_free (words);
- } else if(!strcmp(part->name, "sender")) {
- FilterInput *input = (FilterInput *)filter_part_find_element(part, "sender");
- if (input)
- filter_input_set_value(input, query);
- } else if(!strcmp(part->name, "to")) {
- FilterInput *input = (FilterInput *)filter_part_find_element(part, "recipient");
- if (input)
- filter_input_set_value(input, query);
- }
-
- partl = partl->next;
- }
-
- search_bar = E_MAIL_SEARCH_BAR (emfb->priv->search_bar);
-
- /* XXX This is a hack, but this code is on its way out anyway.
- * Function is called once before the search bar is created. */
- if (!E_IS_MAIL_SEARCH_BAR (search_bar))
- return;
-
- tokenizer = e_mail_search_bar_get_tokenizer (search_bar);
-
- e_searching_tokenizer_set_secondary_case_sensitivity (tokenizer, FALSE);
- e_searching_tokenizer_set_secondary_search_string (tokenizer, NULL);
-
- while (strings != NULL) {
- e_searching_tokenizer_add_secondary_search_string (
- tokenizer, strings->data);
- g_free (strings->data);
- strings = g_slist_delete_link (strings, strings);
- }
-
- e_mail_search_bar_changed (search_bar);
-}
-
-static const gchar *
-get_view_query (ESearchBar *esb, CamelFolder *folder, const gchar *folder_uri)
-{
- const gchar *view_sexp = NULL;
- gint id;
- GtkWidget *menu_item;
- gchar *tag;
- gboolean duplicate = TRUE;
-
- /* Get the current selected view */
- id = e_search_bar_get_viewitem_id (esb);
- menu_item = e_search_bar_get_selected_viewitem (esb);
-
- switch (id & VIEW_ITEMS_MASK) {
- case VIEW_ALL_MESSAGES:
- /* one space indicates no filtering */
- view_sexp = " ";
- break;
-
- /* README: All the sexp below are not rocket science but it is not straightforward as well.
- I believe it is better to document the assumptions and the conventions followed for the sexp,
- before I forget so that no one else again needs to read through the code -- Sankar */
-
- case VIEW_UNREAD_MESSAGES:
- view_sexp = "(match-all (not (system-flag \"Seen\")))";
- break;
- case VIEW_READ_MESSAGES:
- view_sexp = "(match-all (system-flag \"Seen\" ))";
- break;
- case VIEW_RECENT_MESSAGES:
- if (!em_utils_folder_is_sent (folder, folder_uri))
- view_sexp = "(match-all (> (get-received-date) (- (get-current-date) 86400)))";
- else
- view_sexp = "(match-all (> (get-sent-date) (- (get-current-date) 86400)))";
- break;
- case VIEW_LAST_FIVE_DAYS:
- if (!em_utils_folder_is_sent (folder, folder_uri))
- view_sexp = " (match-all (> (get-received-date) (- (get-current-date) 432000)))";
- else
- view_sexp = " (match-all (> (get-sent-date) (- (get-current-date) 432000)))";
- break;
- case VIEW_WITH_ATTACHMENTS:
- view_sexp = "(match-all (system-flag \"Attachments\" ))";
- break;
- case VIEW_NOT_JUNK:
- view_sexp = "(match-all (not (system-flag \"junk\")))";
- break;
- case VIEW_NO_LABEL: {
- GSList *l;
- GString *s = g_string_new ("(and");
-
- for (l = mail_config_get_labels (); l; l = l->next) {
- EUtilLabel *label = (EUtilLabel *)l->data;
-
- if (label && label->tag) {
- const gchar *tag = label->tag;
-
- if (strncmp (tag, "$Label", 6) == 0)
- tag += 6;
-
- g_string_append_printf (s, " (match-all (not (or (= (user-tag \"label\") \"%s\") (user-flag \"$Label%s\") (user-flag \"%s\"))))", tag, tag, tag);
- /* FIXME: I dont see a way of mapping this kind of sexp into sql atm. I guess this option could be kicked out */
- /* May be we should copy what I did for system flags -- Sankar */
- }
- }
-
- g_string_append (s, ")");
-
- duplicate = FALSE;
- view_sexp = g_string_free (s, FALSE);
- } break;
- case VIEW_LABEL:
- tag = (gchar *)g_object_get_data (G_OBJECT (menu_item), "LabelTag");
- view_sexp = g_strdup_printf ("(match-all (or (= (user-tag \"label\") \"%s\") (user-flag \"$Label%s\") (user-flag \"%s\")))", tag, tag, tag);
- duplicate = FALSE;
- break;
- case VIEW_MESSAGES_MARKED_AS_IMPORTANT:
- view_sexp = "(match-all (system-flag \"Flagged\" ))";
- break;
- case VIEW_ANY_FIELD_CONTAINS:
- break;
-
- case VIEW_CUSTOMIZE:
- /* one space indicates no filtering, so here use two */
- view_sexp = " ";
- break;
- }
-
- if (duplicate)
- view_sexp = g_strdup (view_sexp);
-
- return view_sexp;
-}
-
struct _setup_msg {
MailMsg base;
@@ -1334,60 +806,6 @@ emfb_search_search_cleared(ESearchBar *esb)
/* ********************************************************************** */
-static gint
-emfb_list_key_press(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *ev, EMFolderBrowser *emfb)
-{
- gboolean state, folder_choose = TRUE;
- if ((ev->key.state & GDK_CONTROL_MASK) != 0)
- return FALSE;
-
- switch (ev->key.keyval) {
- case GDK_space:
- if (!emfb->view.preview->caret_mode && mail_config_get_enable_magic_spacebar ()) {
- state = gtk_html_command(((EMFormatHTML *)((EMFolderView *) emfb)->preview)->html, "scroll-forward");
- if (!state) {
- folder_choose = message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN);
- if (!folder_choose)
- folder_choose = message_list_select(((EMFolderView *) emfb)->list,
- MESSAGE_LIST_SELECT_NEXT | MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
- }
-
- } else
- em_utils_adjustment_page(gtk_scrolled_window_get_vadjustment((GtkScrolledWindow *)emfb->priv->scroll), TRUE);
- break;
- case GDK_BackSpace:
- if (!emfb->view.preview->caret_mode && mail_config_get_enable_magic_spacebar ()) {
- state = gtk_html_command(((EMFormatHTML *)((EMFolderView *) emfb)->preview)->html, "scroll-backward");
- if (!state) {
- folder_choose = message_list_select(((EMFolderView *) emfb)->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, CAMEL_MESSAGE_SEEN);
- if (!folder_choose)
- folder_choose = message_list_select(((EMFolderView *) emfb)->list,
- MESSAGE_LIST_SELECT_PREVIOUS | MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
- }
-
- } else
- em_utils_adjustment_page(gtk_scrolled_window_get_vadjustment((GtkScrolledWindow *)emfb->priv->scroll), FALSE);
- break;
- default:
- return FALSE;
- }
-
- if (!folder_choose && !emfb->view.preview->caret_mode && mail_config_get_enable_magic_spacebar ()) {
- /* check for unread messages. if yes .. rewindback to the folder */
- EMFolderTree *emft = g_object_get_data((GObject*)emfb, "foldertree");
- switch (ev->key.keyval) {
- case GDK_space:
- em_folder_tree_select_next_path (emft, TRUE);
- break;
- case GDK_BackSpace:
- em_folder_tree_select_prev_path (emft, TRUE);
- break;
- }
- gtk_widget_grab_focus ((GtkWidget *)((EMFolderView *) emfb)->list);
- }
- return TRUE;
-}
-
static void
emfb_list_message_selected (MessageList *ml, const gchar *uid, EMFolderBrowser *emfb)
{
@@ -1411,329 +829,6 @@ emfb_list_message_selected (MessageList *ml, const gchar *uid, EMFolderBrowser *
/* ********************************************************************** */
static void
-emfb_edit_cut(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- /* TODO: pity we can't sucblass this method, ugh, virtualise it? */
-
- if (GTK_WIDGET_HAS_FOCUS(((ESearchBar *)emfb->search)->entry))
- gtk_editable_cut_clipboard((GtkEditable *)((ESearchBar *)emfb->search)->entry);
- else if (GTK_WIDGET_HAS_FOCUS(emfb->view.preview->formathtml.html))
- em_format_html_display_cut(emfb->view.preview);
- else
- message_list_copy(emfb->view.list, TRUE);
-}
-
-static void
-emfb_edit_copy(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- if (GTK_WIDGET_HAS_FOCUS(((ESearchBar *)emfb->search)->entry))
- gtk_editable_copy_clipboard((GtkEditable *)((ESearchBar *)emfb->search)->entry);
- else if (GTK_WIDGET_HAS_FOCUS(emfb->view.preview->formathtml.html))
- em_format_html_display_copy(emfb->view.preview);
- else
- message_list_copy(emfb->view.list, FALSE);
-}
-
-static void
-emfb_edit_paste(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- if (GTK_WIDGET_HAS_FOCUS(((ESearchBar *)emfb->search)->entry))
- gtk_editable_paste_clipboard((GtkEditable *)((ESearchBar *)emfb->search)->entry);
- else
- message_list_paste(emfb->view.list);
-}
-
-static void
-emfb_edit_invert_selection(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_invert_selection(emfv->list);
-}
-
-static gboolean
-emfb_select_all_daemon (MessageList *ml)
-{
- message_list_select_all(ml);
- gtk_widget_grab_focus ((GtkWidget *)ml);
- return FALSE;
-}
-
-static void
-emfb_edit_select_all(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->list->threaded) {
-
- emfb_expand_all_threads (uid, data, path);
-
- /* The time out below is added so that the execution thread to
- expand all conversations threads would've completed.
-
- The timeout 505 is just to ensure that the value is a small delta
- more than the timeout value in expand_all_threads thread. */
-
- g_timeout_add (505, (GSourceFunc) emfb_select_all_daemon, emfv->list);
-
- } else {
- /* If there is no threading, just select-all immediately */
- emfb_select_all_daemon (emfv->list);
- }
-}
-
-static void
-emfb_edit_select_thread(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select_thread(emfv->list);
-}
-
-static void
-emfb_edit_select_subthread(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select_subthread (emfv->list);
-}
-
-static void
-emfb_folder_properties(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- if (emfb->view.folder_uri)
- em_folder_properties_show(NULL, emfb->view.folder, emfb->view.folder_uri);
-}
-
-/* VIEWTHREADED*/
-static void
-emfb_expand_all_threads(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_set_threaded_expand_all(emfv->list);
-
-}
-
-static void
-emfb_collapse_all_threads(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_set_threaded_collapse_all(emfv->list);
-}
-
-static void
-emfb_folder_copy(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
- CamelFolderInfo *fi = NULL;
- CamelException ex;
-
- /* FIXME: This function MUST become multi-threaded.
- FIXME: This interface should NOT use a folderinfo */
-
- camel_exception_init (&ex);
-
- if ((fi = camel_store_get_folder_info (emfb->view.folder->parent_store,
- emfb->view.folder->full_name,
- CAMEL_STORE_FOLDER_INFO_FAST,
- &ex)) != NULL)
- em_folder_utils_copy_folder(fi, FALSE);
-
- camel_exception_clear (&ex);
-
- return;
-}
-
-static void
-emfb_folder_move(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
- CamelFolderInfo *fi = NULL;
- CamelException ex;
-
- camel_exception_init (&ex);
-
- /* FIXME: This function MUST become multi-threaded.
- FIXME: This interface should NOT use a folderinfo */
-
- if ((fi = camel_store_get_folder_info (emfb->view.folder->parent_store,
- emfb->view.folder->full_name,
- CAMEL_STORE_FOLDER_INFO_FAST,
- &ex)) != NULL)
- em_folder_utils_copy_folder(fi, TRUE);
-
- camel_exception_clear (&ex);
-
- return;
-}
-
-static void
-emfb_folder_delete(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- em_folder_utils_delete_folder (emfb->view.folder);
-
- return;
-}
-
-static void
-emfb_folder_refresh(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
- EMFolderTree *tree = g_object_get_data (G_OBJECT (emfb), "foldertree");
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (tree)) != NULL) {
- EMEvent *e = em_event_peek();
- EMEventTargetFolder *t = em_event_target_new_folder(e, folder->full_name, 0);
- e_event_emit((EEvent *)e, "folder.refresh", (EEventTarget *)t);
- mail_refresh_folder(folder, NULL, NULL);
- }
-}
-
-static void
-emfb_folder_rename(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- em_folder_utils_rename_folder (emfb->view.folder);
-
- return;
-}
-
-static void
-emfb_folder_create(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
- CamelFolderInfo *fi = NULL;
- EMFolderTree *tree = g_object_get_data (G_OBJECT (emfb), "foldertree");
-
- /* FIXME: This function MUST be multithreaded
- FIXME: This interface should NOT use a folderinfo */
- if (emfb->view.folder) {
- if ((fi = em_folder_tree_get_selected_folder_info (tree)) != NULL) {
- em_folder_utils_create_folder (fi, tree, NULL);
- camel_folder_info_free(fi);
- }
- } else {
- em_folder_utils_create_folder (NULL, tree, NULL);
- }
-
- return;
-}
-
-static void
-emfb_folder_expunge(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- if (emfb->view.folder)
- em_utils_expunge_folder(gtk_widget_get_toplevel((GtkWidget *)emfb), emfb->view.folder);
-}
-
-static void
-emfb_mark_all_read(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- /* FIXME: make a 'mark messages' function? */
- EMFolderView *emfv = data;
- GPtrArray *uids;
- gint i;
-
- if (emfv->folder == NULL)
- return;
- if( em_utils_prompt_user((GtkWindow *)emfv, "/apps/evolution/mail/prompts/mark_all_read","mail:ask-mark-all-read", NULL)){
- uids = message_list_get_uids(emfv->list);
- camel_folder_freeze(emfv->folder);
- for (i=0;i<uids->len;i++)
- camel_folder_set_message_flags(emfv->folder, uids->pdata[i], CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
- camel_folder_thaw(emfv->folder);
- message_list_free_uids(emfv->list, uids);
- }
-}
-
-static void
-emfb_view_hide_read(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_hide_add(emfv->list, "(match-all (system-flag \"seen\"))", ML_HIDE_SAME, ML_HIDE_SAME);
-}
-
-static void
-emfb_view_hide_selected(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- /* TODO: perhaps this should sit directly on message_list? */
- /* is it worth it, it's so trivial */
-
- /* A new flag CAMEL_MESSAGE_HIDDEN is added by Sankar
- while extending the CAMEL_MESSAGE_FLAGS for proxy permissions.
- This can be used to hide messages. */
-
- uids = message_list_get_selected(emfv->list);
- message_list_hide_uids(emfv->list, uids);
- message_list_free_uids(emfv->list, uids);
-}
-
-static void
-emfb_view_show_all(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_hide_clear(emfv->list);
-}
-
-/* ********************************************************************** */
-
-static void
-emfb_mail_stop(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- mail_cancel_all();
-}
-
-static void
-emfb_tools_filters(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- em_utils_edit_filters ((GtkWidget *) emfb);
-}
-
-static void
-emfb_subscribe_editor_destroy(GtkWidget *w, EMFolderBrowser *emfb)
-{
- emfb->priv->subscribe_editor = NULL;
-}
-
-static void
-emfb_tools_subscriptions(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderBrowser *emfb = data;
-
- if (emfb->priv->subscribe_editor) {
- gdk_window_show(emfb->priv->subscribe_editor->window);
- } else {
- emfb->priv->subscribe_editor = (GtkWidget *)em_subscribe_editor_new();
- e_dialog_set_transient_for((GtkWindow *)emfb->priv->subscribe_editor, (GtkWidget *)emfb);
- g_signal_connect(emfb->priv->subscribe_editor, "destroy", G_CALLBACK(emfb_subscribe_editor_destroy), emfb);
- gtk_widget_show(emfb->priv->subscribe_editor);
- }
-}
-
-static void
emfb_focus_search(BonoboUIComponent *uid, gpointer data, const gchar *path)
{
EMFolderBrowser *emfb = data;
@@ -1747,46 +842,9 @@ emfb_help_debug (BonoboUIComponent *uid, gpointer data, const gchar *path)
mail_component_show_logger ((GtkWidget *) data);
}
-static void
-emfb_tools_vfolders(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- /* FIXME: rename/refactor this */
- vfolder_edit();
-}
-
static BonoboUIVerb emfb_verbs[] = {
- BONOBO_UI_UNSAFE_VERB ("EditCut", emfb_edit_cut),
- BONOBO_UI_UNSAFE_VERB ("EditCopy", emfb_edit_copy),
- BONOBO_UI_UNSAFE_VERB ("EditPaste", emfb_edit_paste),
-
- BONOBO_UI_UNSAFE_VERB ("EditInvertSelection", emfb_edit_invert_selection),
- BONOBO_UI_UNSAFE_VERB ("EditSelectAll", emfb_edit_select_all),
- BONOBO_UI_UNSAFE_VERB ("EditSelectThread", emfb_edit_select_thread),
- BONOBO_UI_UNSAFE_VERB ("EditSelectSubthread", emfb_edit_select_subthread),
- BONOBO_UI_UNSAFE_VERB ("ChangeFolderProperties", emfb_folder_properties),
- BONOBO_UI_UNSAFE_VERB ("FolderExpunge", emfb_folder_expunge),
- /* HideDeleted is a toggle */
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAllAsRead", emfb_mark_all_read),
- BONOBO_UI_UNSAFE_VERB ("ViewHideRead", emfb_view_hide_read),
- BONOBO_UI_UNSAFE_VERB ("ViewHideSelected", emfb_view_hide_selected),
- BONOBO_UI_UNSAFE_VERB ("ViewShowAll", emfb_view_show_all),
- /* ViewThreaded is a toggle */
-
- BONOBO_UI_UNSAFE_VERB ("ViewThreadsExpandAll", emfb_expand_all_threads),
- BONOBO_UI_UNSAFE_VERB ("ViewThreadsCollapseAll", emfb_collapse_all_threads),
-
- BONOBO_UI_UNSAFE_VERB ("FolderCopy", emfb_folder_copy),
- BONOBO_UI_UNSAFE_VERB ("FolderMove", emfb_folder_move),
- BONOBO_UI_UNSAFE_VERB ("FolderDelete", emfb_folder_delete),
- BONOBO_UI_UNSAFE_VERB ("FolderRefresh", emfb_folder_refresh),
- BONOBO_UI_UNSAFE_VERB ("FolderRename", emfb_folder_rename),
- BONOBO_UI_UNSAFE_VERB ("FolderCreate", emfb_folder_create),
BONOBO_UI_UNSAFE_VERB ("HelpDebug", emfb_help_debug),
- BONOBO_UI_UNSAFE_VERB ("MailStop", emfb_mail_stop),
- BONOBO_UI_UNSAFE_VERB ("ToolsFilters", emfb_tools_filters),
- BONOBO_UI_UNSAFE_VERB ("ToolsSubscriptions", emfb_tools_subscriptions),
- BONOBO_UI_UNSAFE_VERB ("ToolsVFolders", emfb_tools_vfolders),
BONOBO_UI_UNSAFE_VERB ("FocusSearch", emfb_focus_search),
/* ViewPreview is a toggle */
@@ -1794,227 +852,33 @@ static BonoboUIVerb emfb_verbs[] = {
BONOBO_UI_VERB_END
};
-static EPixmap emfb_pixmaps[] = {
- E_PIXMAP ("/commands/FolderCreate", "folder-new", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ChangeFolderProperties", "document-properties", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/FolderCopy", "folder-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/FolderMove", "folder-move", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAllAsRead", "mail-read", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP_END
-};
-
-static void
-emfb_hide_deleted(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- GConfClient *gconf;
- EMFolderView *emfv = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- gconf = mail_config_get_gconf_client ();
- gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_deleted", state[0] == '0', NULL);
- em_folder_view_set_hide_deleted(emfv, state[0] != '0');
-}
-
-static void
-emfb_view_threaded(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- GConfClient *gconf;
- EMFolderView *emfv = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- gconf = mail_config_get_gconf_client ();
- gconf_client_set_bool(gconf, "/apps/evolution/mail/display/thread_list", state[0] != '0', NULL);
-
- if (camel_object_meta_set(emfv->folder, "evolution:thread_list", state))
- camel_object_state_write(emfv->folder);
-
- /* FIXME: do set_threaded via meta-data listener on folder? */
- message_list_set_threaded(emfv->list, state[0] != '0');
-
- /* FIXME: update selection state? */
-}
-
-static void
-emfb_view_preview(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- GConfClient *gconf;
- EMFolderView *emfv = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- gconf = mail_config_get_gconf_client ();
- gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_preview", state[0] != '0', NULL);
-
- if (camel_object_meta_set(emfv->folder, "evolution:show_preview", state))
- camel_object_state_write(emfv->folder);
-
- /* FIXME: do this via folder listener */
- em_folder_browser_show_preview((EMFolderBrowser *)emfv, state[0] != '0');
-}
-
-static void
-emfb_show_next(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- GConfClient *gconf;
- EMFolderBrowser *emfb = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- gconf = mail_config_get_gconf_client ();
- gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_wide", state[0] != '0', NULL);
-
- em_folder_browser_show_wide(emfb, state[0] != '0');
-}
-
-static void
-emfb_show_below(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- GConfClient *gconf;
- EMFolderBrowser *emfb = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- gconf = mail_config_get_gconf_client ();
- gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_wide", state[0] == '0', NULL);
-
- em_folder_browser_show_wide(emfb, state[0] == '0');
-}
-
-static void
-emfb_list_scrolled (MessageList *ml, EMFolderBrowser *emfb)
-{
- EMFolderView *emfv = (EMFolderView *) emfb;
- double position;
- gchar *state;
-
- position = message_list_get_scrollbar_position (ml);
- state = g_strdup_printf ("%f", position);
-
- if (camel_object_meta_set (emfv->folder, "evolution:list_scroll_position", state))
- camel_object_state_write (emfv->folder);
-
- g_free (state);
-}
-
-static gboolean
-scroll_idle_cb (EMFolderBrowser *emfb)
-{
- EMFolderView *emfv = (EMFolderView *) emfb;
- double position;
- gchar *state;
-
- if ((state = camel_object_meta_get (emfv->folder, "evolution:list_scroll_position"))) {
- position = strtod (state, NULL);
- g_free (state);
- } else {
- position = emfb->priv->default_scroll_position;
- }
-
- message_list_set_scrollbar_position (emfv->list, position);
-
- emfb->priv->list_scrolled_id = g_signal_connect (emfv->list, "message_list_scrolled", G_CALLBACK (emfb_list_scrolled), emfb);
-
- emfb->priv->idle_scroll_id = 0;
-
- return FALSE;
-}
-
-static void
-emfb_gui_folder_changed(CamelFolder *folder, gpointer dummy, EMFolderBrowser *emfb)
-{
- if (emfb->priv->select_uid) {
- CamelMessageInfo *mi;
-
- mi = camel_folder_get_message_info(emfb->view.folder, emfb->priv->select_uid);
- if (mi) {
- /* because some sub-functions might free the pointer before it's done here */
- gchar *uid = g_strdup (emfb->priv->select_uid);
-
- camel_folder_free_message_info(emfb->view.folder, mi);
- em_folder_view_set_message (&emfb->view, uid, FALSE);
- g_free (uid);
- g_free (emfb->priv->select_uid);
- emfb->priv->select_uid = NULL;
- }
- }
-
- g_object_unref(emfb);
-}
-
-static void
-emfb_folder_changed(CamelFolder *folder, CamelFolderChangeInfo *changes, EMFolderBrowser *emfb)
-{
- g_object_ref(emfb);
- mail_async_event_emit(emfb->view.async, MAIL_ASYNC_GUI, (MailAsyncFunc)emfb_gui_folder_changed, folder, NULL, emfb);
-}
-
-static void
-emfb_etree_unfreeze (GtkWidget *widget, GdkEvent *event, EMFolderView *emfv)
-{
-
- ETableItem *item = e_tree_get_item (emfv->list->tree);
-
- g_object_set_data (G_OBJECT (((GnomeCanvasItem *) item)->canvas), "freeze-cursor", 0);
-}
-
-/* TODO: This should probably be handled by message-list, by storing/queueing
- up the select operation if its busy rebuilding the message-list */
-static void
-emfb_list_built (MessageList *ml, EMFolderBrowser *emfb)
-{
- EMFolderView *emfv = (EMFolderView *) emfb;
- double position = 0.0f;
-
- g_signal_handler_disconnect (ml, emfb->priv->list_built_id);
- emfb->priv->list_built_id = 0;
-
- if (emfv->list->cursor_uid == NULL) {
- if (emfb->priv->select_uid) {
- CamelMessageInfo *mi;
-
- /* If the message isn't in the folder yet, keep select_uid around, it could be caught by
- folder_changed, at some later date */
- mi = camel_folder_get_message_info(emfv->folder, emfb->priv->select_uid);
- if (mi) {
- camel_folder_free_message_info(emfv->folder, mi);
- em_folder_view_set_message(emfv, emfb->priv->select_uid, TRUE);
- g_free (emfb->priv->select_uid);
- emfb->priv->select_uid = NULL;
- }
-
- /* change the default to the current position */
- position = message_list_get_scrollbar_position (ml);
- } else {
- /* NOTE: not all users want this, so we need a preference for it perhaps? see bug #52887 */
- /* FIXME: if the 1st message in the list is unread, this will actually select the second unread msg */
- /*message_list_select (ml, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN, TRUE);*/
- }
- }
-
- emfb->priv->default_scroll_position = position;
-
- /* FIXME: this is a gross workaround for an etable bug that I can't fix - bug #55303 */
- /* this needs to be a lower priority than anything in e-table-item/e-canvas, since
- * e_canvas_item_region_show_relay() uses a timeout, we have to use a timeout of the
- * same interval but a lower priority. */
- emfb->priv->idle_scroll_id = g_timeout_add_full (G_PRIORITY_LOW, 250, (GSourceFunc) scroll_idle_cb, emfb, NULL);
- /* FIXME: This is another ugly hack done to hide a bug that above hack leaves. */
- g_signal_connect (((GtkScrolledWindow *) ml)->vscrollbar, "button-press-event", G_CALLBACK (emfb_etree_unfreeze), emfb);
-}
+//static gboolean
+//emfb_select_all_daemon (MessageList *ml)
+//{
+// message_list_select_all(ml);
+// gtk_widget_grab_focus ((GtkWidget *)ml);
+// return FALSE;
+//}
+
+//static void
+//emfb_hide_deleted(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
+//{
+// GConfClient *gconf;
+// EMFolderView *emfv = data;
+//
+// if (type != Bonobo_UIComponent_STATE_CHANGED)
+// return;
+//
+// gconf = mail_config_get_gconf_client ();
+// gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_deleted", state[0] == '0', NULL);
+// em_folder_view_set_hide_deleted(emfv, state[0] != '0');
+//}
static void
emfb_set_search_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
{
EMFolderBrowser *emfb = (EMFolderBrowser *) emfv;
- const gchar *state;
+ gchar *state;
message_list_freeze(emfv->list);
@@ -2028,10 +892,10 @@ emfb_set_search_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri
emfb->priv->idle_scroll_id = 0;
}
- if (emfb->view.folder) {
- camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
- emfb->priv->folder_changed_id = 0;
- }
+// if (emfb->view.folder) {
+// camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
+// emfb->priv->folder_changed_id = 0;
+// }
emfb_parent->set_folder(emfv, folder, uri);
@@ -2053,7 +917,7 @@ emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
struct _EMFolderBrowserPrivate *p = emfb->priv;
gboolean different_folder;
- message_list_freeze(emfv->list);
+// message_list_freeze(emfv->list);
if (emfb->priv->list_scrolled_id) {
g_signal_handler_disconnect (emfv->list, emfb->priv->list_scrolled_id);
@@ -2065,16 +929,16 @@ emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
emfb->priv->idle_scroll_id = 0;
}
- if (emfb->view.folder && emfb->priv->folder_changed_id) {
- camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
- emfb->priv->folder_changed_id = 0;
- }
-
- different_folder =
- emfb->view.folder != NULL &&
- folder != emfb->view.folder;
-
- emfb_parent->set_folder(emfv, folder, uri);
+// if (emfb->view.folder && emfb->priv->folder_changed_id) {
+// camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id);
+// emfb->priv->folder_changed_id = 0;
+// }
+//
+// different_folder =
+// emfb->view.folder != NULL &&
+// folder != emfb->view.folder;
+//
+// emfb_parent->set_folder(emfv, folder, uri);
/* This is required since we get activated the first time
before the folder is open and need to override the
@@ -2096,32 +960,32 @@ emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
gconf_client_set_bool (gconf, "/apps/evolution/mail/display/safe_list", FALSE, NULL);
}
- mail_refresh_folder(folder, NULL, NULL);
-
- emfb->priv->folder_changed_id = camel_object_hook_event(folder, "folder_changed",
- (CamelObjectEventHookFunc)emfb_folder_changed, emfb);
-
- /* FIXME: this mostly copied from activate() */
- if ((sstate = camel_object_meta_get(folder, "evolution:show_preview"))) {
- state = sstate[0] != '0';
- g_free(sstate);
- } else
- state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_preview", NULL);
- em_folder_browser_show_preview(emfb, state);
- if (emfv->uic)
- bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewPreview", "state", state?"1":"0", NULL);
-
- if ((sstate = camel_object_meta_get(folder, "evolution:thread_list"))) {
- state = sstate[0] != '0';
- g_free(sstate);
- } else
- state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/thread_list", NULL);
- message_list_set_threaded(emfv->list, state);
- if (emfv->uic) {
- bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreaded", "state", state?"1":"0", NULL);
- bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreadsCollapseAll", "sensitive", state?"1":"0", NULL);
- bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreadsExpandAll", "sensitive", state?"1":"0", NULL);
- }
+// mail_refresh_folder(folder, NULL, NULL);
+//
+// emfb->priv->folder_changed_id = camel_object_hook_event(folder, "folder_changed",
+// (CamelObjectEventHookFunc)emfb_folder_changed, emfb);
+//
+// /* FIXME: this mostly copied from activate() */
+// if ((sstate = camel_object_meta_get(folder, "evolution:show_preview"))) {
+// state = sstate[0] != '0';
+// g_free(sstate);
+// } else
+// state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_preview", NULL);
+// em_folder_browser_show_preview(emfb, state);
+// if (emfv->uic)
+// bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewPreview", "state", state?"1":"0", NULL);
+//
+// if ((sstate = camel_object_meta_get(folder, "evolution:thread_list"))) {
+// state = sstate[0] != '0';
+// g_free(sstate);
+// } else
+// state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/thread_list", NULL);
+// message_list_set_threaded(emfv->list, state);
+// if (emfv->uic) {
+// bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreaded", "state", state?"1":"0", NULL);
+// bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreadsCollapseAll", "sensitive", state?"1":"0", NULL);
+// bonobo_ui_component_set_prop(emfv->uic, "/commands/ViewThreadsExpandAll", "sensitive", state?"1":"0", NULL);
+// }
if (emfv->uic) {
state = (folder->folder_flags & CAMEL_FOLDER_IS_TRASH) == 0;
@@ -2157,26 +1021,26 @@ emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
e_search_bar_paint ((ESearchBar *)emfb->search);
}
- /* This function gets triggered several times at startup,
- * so we don't want to reset the message suppression state
- * unless we're actually switching to a different folder. */
- if (different_folder)
- p->suppress_message_selection = FALSE;
-
- if (!p->suppress_message_selection)
- sstate = camel_object_meta_get (
- folder, "evolution:selected_uid");
- else
- sstate = NULL;
-
- g_free (p->select_uid);
- p->select_uid = sstate;
-
- if (emfv->list->cursor_uid == NULL && emfb->priv->list_built_id == 0)
- p->list_built_id = g_signal_connect(emfv->list, "message_list_built", G_CALLBACK (emfb_list_built), emfv);
- }
-
- message_list_thaw(emfv->list);
+// /* This function gets triggered several times at startup,
+// * so we don't want to reset the message suppression state
+// * unless we're actually switching to a different folder. */
+// if (different_folder)
+// p->suppress_message_selection = FALSE;
+//
+// if (!p->suppress_message_selection)
+// sstate = camel_object_meta_get (
+// folder, "evolution:selected_uid");
+// else
+// sstate = NULL;
+//
+// g_free (p->select_uid);
+// p->select_uid = sstate;
+//
+// if (emfv->list->cursor_uid == NULL && emfb->priv->list_built_id == 0)
+// p->list_built_id = g_signal_connect(emfv->list, "message_list_built", G_CALLBACK (emfb_list_built), emfv);
+// }
+//
+// message_list_thaw(emfv->list);
}
static void
@@ -2188,98 +1052,20 @@ emfb_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint act)
gchar *sstate;
EMFolderBrowser *emfb = (EMFolderBrowser *) emfv;
- gconf = mail_config_get_gconf_client ();
-
- /* parent loads all ui files via ui_files */
- emfb_parent->activate(emfv, uic, act);
-
- bonobo_ui_component_add_verb_list_with_data(uic, emfb_verbs, emfv);
- e_pixmaps_update(uic, emfb_pixmaps);
-
- /* FIXME: finish */
- /* (Pre)view pane size (do this first because it affects the
- preview settings - see folder_browser_set_message_preview()
- internals for details) */
- g_signal_handler_block(emfb->vpane, emfb->priv->vpane_resize_id);
- gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int (gconf, emfb->priv->show_wide ? "/apps/evolution/mail/display/hpaned_size": "/apps/evolution/mail/display/paned_size", NULL));
- g_signal_handler_unblock(emfb->vpane, emfb->priv->vpane_resize_id);
-
- /* (Pre)view toggle */
- if (emfv->folder
- && (sstate = camel_object_meta_get(emfv->folder, "evolution:show_preview"))) {
- state = sstate[0] == '1';
- g_free(sstate);
- } else {
- state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_preview", NULL);
- }
-
- bonobo_ui_component_set_prop(uic, "/commands/ViewPreview", "state", state?"1":"0", NULL);
- em_folder_browser_show_preview((EMFolderBrowser *)emfv, state);
- bonobo_ui_component_add_listener(uic, "ViewPreview", emfb_view_preview, emfv);
-
/* Stop button */
state = mail_msg_active((guint)-1);
bonobo_ui_component_set_prop(uic, "/commands/MailStop", "sensitive", state?"1":"0", NULL);
- /* HideDeleted */
- state = !gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_deleted", NULL);
- if (emfv->folder && (emfv->folder->folder_flags & CAMEL_FOLDER_IS_TRASH)) {
- state = FALSE;
- bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "sensitive", "0", NULL);
- } else
- bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "sensitive", "1", NULL);
- bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "state", state ? "1" : "0", NULL);
- bonobo_ui_component_add_listener(uic, "HideDeleted", emfb_hide_deleted, emfv);
- em_folder_view_set_hide_deleted(emfv, state); /* <- not sure if this optimal, but it'll do */
-
- /* FIXME: If we have no folder, we can't do a few of the lookups we need,
- perhaps we should postpone till we can */
-
- /* ViewThreaded */
- if (emfv->folder
- && (sstate = camel_object_meta_get(emfv->folder, "evolution:thread_list"))) {
- state = sstate[0] != '0';
- g_free(sstate);
- } else {
- state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/thread_list", NULL);
- }
-
- bonobo_ui_component_set_prop(uic, "/commands/ViewThreaded", "state", state?"1":"0", NULL);
- bonobo_ui_component_set_prop(uic, "/commands/ViewThreadsCollapseAll", "sensitive", state?"1":"0", NULL);
- bonobo_ui_component_set_prop(uic, "/commands/ViewThreadsExpandAll", "sensitive", state?"1":"0", NULL);
- bonobo_ui_component_add_listener(uic, "ViewThreaded", emfb_view_threaded, emfv);
- message_list_set_threaded(emfv->list, state);
-
- /* Show wide display */
- if (emfb->priv->show_wide) {
- bonobo_ui_component_set_prop(uic, "/commands/ViewAfter", "state", "1", NULL);
- bonobo_ui_component_set_prop(uic, "/commands/ViewBelow", "state", "0", NULL);
- } else {
- bonobo_ui_component_set_prop(uic, "/commands/ViewAfter", "state", "0", NULL);
- bonobo_ui_component_set_prop(uic, "/commands/ViewBelow", "state", "1", NULL);
- }
-
- bonobo_ui_component_add_listener(uic, "ViewAfter", emfb_show_next, emfv);
- bonobo_ui_component_add_listener(uic, "ViewBelow", emfb_show_below, emfv);
- /* em_folder_browser_show_wide((EMFolderBrowser *)emfv, state); */
-
- /* FIXME: Selection state */
-
- /* FIXME: property menu customisation */
- /*folder_browser_setup_property_menu (fb, fb->uicomp);*/
-
- if (((EMFolderBrowser *)emfv)->search)
- e_search_bar_set_ui_component((ESearchBar *)((EMFolderBrowser *)emfv)->search, uic);
- } else {
- const BonoboUIVerb *v;
-
- for (v = &emfb_verbs[0]; v->cname; v++)
- bonobo_ui_component_remove_verb(uic, v->cname);
-
- if (((EMFolderBrowser *)emfv)->search)
- e_search_bar_set_ui_component((ESearchBar *)((EMFolderBrowser *)emfv)->search, NULL);
-
- emfb_parent->activate(emfv, uic, act);
+// /* HideDeleted */
+// state = !gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_deleted", NULL);
+// if (emfv->folder && (emfv->folder->folder_flags & CAMEL_FOLDER_IS_TRASH)) {
+// state = FALSE;
+// bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "sensitive", "0", NULL);
+// } else
+// bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "sensitive", "1", NULL);
+// bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "state", state ? "1" : "0", NULL);
+// bonobo_ui_component_add_listener(uic, "HideDeleted", emfb_hide_deleted, emfv);
+// em_folder_view_set_hide_deleted(emfv, state); /* <- not sure if this optimal, but it'll do */
}
}
diff --git a/mail/em-folder-properties.c b/mail/em-folder-properties.c
index 709491a686..a7236e66dd 100644
--- a/mail/em-folder-properties.c
+++ b/mail/em-folder-properties.c
@@ -39,7 +39,7 @@
#include "em-folder-properties.h"
#include "em-config.h"
-#include "mail-component.h"
+#include "e-mail-local.h"
#include "mail-ops.h"
#include "mail-mt.h"
#include "mail-vfolder.h"
@@ -287,7 +287,10 @@ static EMConfigItem emfp_items[] = {
static gboolean emfp_items_translated = FALSE;
static void
-emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota, gpointer data)
+emfp_dialog_got_folder_quota (CamelFolder *folder,
+ const gchar *folder_uri,
+ CamelFolderQuotaInfo *quota,
+ gpointer data)
{
GtkWidget *dialog, *w;
struct _prop_data *prop_data;
@@ -295,20 +298,25 @@ emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota,
gint32 count, i,deleted;
EMConfig *ec;
EMConfigTargetFolder *target;
+ EShellWindow *shell_window;
+ EShellView *shell_view;
CamelArgGetV *arggetv;
CamelArgV *argv;
+ CamelStore *local_store;
gboolean hide_deleted;
GConfClient *gconf;
CamelStore *store;
- gchar *uri = (gchar *)data;
- if (folder == NULL) {
- g_free (uri);
+ if (folder == NULL)
return;
- }
store = folder->parent_store;
+ shell_view = E_SHELL_VIEW (data);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ local_store = e_mail_local_get_store ();
+
prop_data = g_malloc0 (sizeof (*prop_data));
prop_data->object = folder;
camel_object_ref (folder);
@@ -341,7 +349,7 @@ emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota,
camel_object_get (folder, NULL, CAMEL_FOLDER_TOTAL, &prop_data->total, NULL);
}
- if (store == mail_component_peek_local_store(NULL)
+ if (store == local_store
&& (!strcmp(prop_data->name, "Drafts")
|| !strcmp(prop_data->name, "Templates")
|| !strcmp(prop_data->name, "Inbox")
@@ -387,11 +395,11 @@ emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota,
g_free (arggetv);
prop_data->argv = argv;
- dialog = gtk_dialog_new_with_buttons (_("Folder Properties"), NULL,
- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OK, GTK_RESPONSE_OK,
- NULL);
+ dialog = gtk_dialog_new_with_buttons (
+ _("Folder Properties"), GTK_WINDOW (shell_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
gtk_window_set_default_size ((GtkWindow *) dialog, 192, 160);
gtk_widget_ensure_style (dialog);
gtk_container_set_border_width ((GtkContainer *) ((GtkDialog *) dialog)->vbox, 12);
@@ -411,7 +419,7 @@ emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota,
l = g_slist_prepend(l, &emfp_items[i]);
e_config_add_items((EConfig *)ec, l, emfp_commit, NULL, emfp_free, prop_data);
- target = em_config_target_new_folder(ec, folder, uri);
+ target = em_config_target_new_folder(ec, folder, folder_uri);
e_config_set_target((EConfig *)ec, (EConfigTarget *)target);
w = e_config_create_widget((EConfig *)ec);
@@ -421,15 +429,17 @@ emfp_dialog_got_folder_quota (CamelFolder *folder, CamelFolderQuotaInfo *quota,
g_signal_connect (dialog, "response", G_CALLBACK (emfp_dialog_response), prop_data);
gtk_widget_show (dialog);
-
- g_free (uri);
}
static void
emfp_dialog_got_folder (gchar *uri, CamelFolder *folder, gpointer data)
{
+ EShellView *shell_view = data;
+
/* this should be called in a thread too */
- mail_get_folder_quota (folder, emfp_dialog_got_folder_quota, g_strdup (uri), mail_msg_unordered_push);
+ mail_get_folder_quota (
+ folder, uri, emfp_dialog_got_folder_quota,
+ shell_view, mail_msg_unordered_push);
}
/**
@@ -442,27 +452,32 @@ emfp_dialog_got_folder (gchar *uri, CamelFolder *folder, gpointer data)
* as NULL, then the folder @uri will be loaded first.
**/
void
-em_folder_properties_show(GtkWindow *parent, CamelFolder *folder, const gchar *uri)
+em_folder_properties_show (EShellView *shell_view,
+ CamelFolder *folder,
+ const gchar *uri)
{
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+ g_return_if_fail (uri != NULL);
+
/* HACK: its the old behaviour, not very 'neat' but it works */
- if (!strncmp(uri, "vfolder:", 8)) {
- CamelURL *url = camel_url_new(uri, NULL);
+ if (!strncmp (uri, "vfolder:", 8)) {
+ CamelURL *url = camel_url_new (uri, NULL);
/* MORE HACK: UNMATCHED is a special folder which you can't modify, so check for it here */
if (url == NULL
|| url->fragment == NULL
|| strcmp(url->fragment, CAMEL_UNMATCHED_NAME) != 0) {
if (url)
- camel_url_free(url);
- vfolder_edit_rule(uri);
+ camel_url_free (url);
+ vfolder_edit_rule (uri);
return;
}
- if (url)
- camel_url_free(url);
+ if (url != NULL)
+ camel_url_free (url);
}
if (folder == NULL)
- mail_get_folder(uri, 0, emfp_dialog_got_folder, NULL, mail_msg_unordered_push);
+ mail_get_folder(uri, 0, emfp_dialog_got_folder, shell_view, mail_msg_unordered_push);
else
- emfp_dialog_got_folder((gchar *)uri, folder, NULL);
+ emfp_dialog_got_folder((gchar *)uri, folder, shell_view);
}
diff --git a/mail/em-folder-properties.h b/mail/em-folder-properties.h
index 958a5669c3..330be151a3 100644
--- a/mail/em-folder-properties.h
+++ b/mail/em-folder-properties.h
@@ -24,12 +24,14 @@
#ifndef __EM_FOLDER_PROPERTIES_H__
#define __EM_FOLDER_PROPERTIES_H__
-#include <gtk/gtk.h>
#include <camel/camel-folder.h>
+#include <shell/e-shell-view.h>
G_BEGIN_DECLS
-void em_folder_properties_show(GtkWindow *parent, CamelFolder *folder, const gchar *uri);
+void em_folder_properties_show (EShellView *shell_view,
+ CamelFolder *folder,
+ const gchar *uri);
G_END_DECLS
diff --git a/mail/em-folder-selection-button.c b/mail/em-folder-selection-button.c
index 983c4a180f..ec818221b4 100644
--- a/mail/em-folder-selection-button.c
+++ b/mail/em-folder-selection-button.c
@@ -25,11 +25,9 @@
#endif
#include <string.h>
-
-#include <e-util/e-util.h>
#include <glib/gi18n.h>
+#include <e-util/e-util.h>
-#include "mail-component.h"
#include "mail-config.h"
#include "em-folder-tree.h"
#include "em-folder-selector.h"
@@ -37,21 +35,15 @@
#include "em-folder-selection-button.h"
-static void em_folder_selection_button_class_init (EMFolderSelectionButtonClass *klass);
-static void em_folder_selection_button_init (EMFolderSelectionButton *emfsb);
-static void em_folder_selection_button_destroy (GtkObject *obj);
-static void em_folder_selection_button_finalize (GObject *obj);
-static void em_folder_selection_button_clicked (GtkButton *button);
-
-static GtkButtonClass *parent_class = NULL;
+#define EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButtonPrivate))
struct _EMFolderSelectionButtonPrivate {
GtkWidget *icon;
GtkWidget *label;
- GtkWidget *selector;
-
- gchar *uri; /* for single-select mode */
+ gchar *uri; /* for single-select mode */
GList *uris; /* for multi-select mode */
gchar *title;
@@ -61,223 +53,377 @@ struct _EMFolderSelectionButtonPrivate {
};
enum {
+ PROP_0,
+ PROP_CAPTION,
+ PROP_MULTISELECT,
+ PROP_TITLE
+};
+
+enum {
SELECTED,
LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL] = { 0 };
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
-GType
-em_folder_selection_button_get_type (void)
+static void
+folder_selection_button_unselected (EMFolderSelectionButton *button)
{
- static GType type = 0;
+ const gchar *text;
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMFolderSelectionButtonClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_folder_selection_button_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMFolderSelectionButton),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_folder_selection_button_init,
- };
+ text = _("<click here to select a folder>");
+ gtk_image_set_from_pixbuf (GTK_IMAGE (button->priv->icon), NULL);
+ gtk_label_set_text (GTK_LABEL (button->priv->label), text);
+}
+
+static void
+folder_selection_button_set_contents (EMFolderSelectionButton *button)
+{
+ EAccount *account;
+ GtkLabel *label;
+ const gchar *uri;
+ gchar *folder_name;
+
+ uri = button->priv->uri;
+ label = GTK_LABEL (button->priv->label);
+ folder_name = em_utils_folder_name_from_uri (uri);
- type = g_type_register_static (GTK_TYPE_BUTTON, "EMFolderSelectionButton", &info, 0);
+ if (folder_name == NULL) {
+ folder_selection_button_unselected (button);
+ return;
}
- return type;
+ account = mail_config_get_account_by_source_url (uri);
+
+ if (account != NULL) {
+ gchar *tmp = folder_name;
+
+ folder_name = g_strdup_printf (
+ "%s/%s", e_account_get_string (
+ account, E_ACCOUNT_NAME), _(folder_name));
+ gtk_label_set_text (label, folder_name);
+ g_free (tmp);
+ } else
+ gtk_label_set_text (label, _(folder_name));
+
+ g_free (folder_name);
}
static void
-em_folder_selection_button_class_init (EMFolderSelectionButtonClass *klass)
+folder_selection_button_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
- GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
-
- parent_class = g_type_class_ref (GTK_TYPE_BUTTON);
-
- object_class->finalize = em_folder_selection_button_finalize;
- gtk_object_class->destroy = em_folder_selection_button_destroy;
- button_class->clicked = em_folder_selection_button_clicked;
-
- signals[SELECTED] = g_signal_new ("selected",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderSelectionButtonClass, selected),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ switch (property_id) {
+ case PROP_CAPTION:
+ em_folder_selection_button_set_caption (
+ EM_FOLDER_SELECTION_BUTTON (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_MULTISELECT:
+ em_folder_selection_button_set_multiselect (
+ EM_FOLDER_SELECTION_BUTTON (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_TITLE:
+ em_folder_selection_button_set_title (
+ EM_FOLDER_SELECTION_BUTTON (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-set_contents_unselected (EMFolderSelectionButton *button)
+folder_selection_button_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- gtk_image_set_from_pixbuf (GTK_IMAGE (button->priv->icon), NULL);
- gtk_label_set_text (GTK_LABEL (button->priv->label), _("<click here to select a folder>"));
+ switch (property_id) {
+ case PROP_CAPTION:
+ g_value_set_string (
+ value,
+ em_folder_selection_button_get_caption (
+ EM_FOLDER_SELECTION_BUTTON (object)));
+ return;
+
+ case PROP_MULTISELECT:
+ g_value_set_boolean (
+ value,
+ em_folder_selection_button_get_multiselect (
+ EM_FOLDER_SELECTION_BUTTON (object)));
+ return;
+
+ case PROP_TITLE:
+ g_value_set_string (
+ value,
+ em_folder_selection_button_get_title (
+ EM_FOLDER_SELECTION_BUTTON (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-set_contents (EMFolderSelectionButton *button)
+folder_selection_button_finalize (GObject *object)
{
- struct _EMFolderSelectionButtonPrivate *priv = button->priv;
- gchar *folder_name = em_utils_folder_name_from_uri (priv->uri);
+ EMFolderSelectionButtonPrivate *priv;
- if (folder_name) {
- EAccount *account = mail_config_get_account_by_source_url (priv->uri);
+ priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (object);
- if (account) {
- gchar *tmp = folder_name;
- folder_name = g_strdup_printf ("%s/%s", e_account_get_string (account, E_ACCOUNT_NAME), folder_name);
- g_free (tmp);
- gtk_label_set_text (GTK_LABEL (priv->label), folder_name);
- } else
- gtk_label_set_text (GTK_LABEL (priv->label), _(folder_name));
+ g_list_foreach (priv->uris, (GFunc) g_free, NULL);
+ g_list_free (priv->uris);
- g_free (folder_name);
- } else {
- set_contents_unselected (button);
- }
+ g_free (priv->title);
+ g_free (priv->caption);
+ g_free (priv->uri);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-em_folder_selection_button_init (EMFolderSelectionButton *emfsb)
+folder_selection_button_destroy (GtkObject *object)
{
- struct _EMFolderSelectionButtonPrivate *priv;
- GtkWidget *box;
+ EMFolderSelectionButtonPrivate *priv;
- priv = g_new0 (struct _EMFolderSelectionButtonPrivate, 1);
- emfsb->priv = priv;
+ priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (object);
- priv->multiple_select = FALSE;
+ /* Chain up to parent's destroy() method. */
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
- box = gtk_hbox_new (FALSE, 4);
+static void
+folder_selection_button_clicked (GtkButton *button)
+{
+ EMFolderSelectionButtonPrivate *priv;
+ EMFolderTree *emft;
+ GtkWidget *dialog;
+ GtkTreeSelection *selection;
+ GtkSelectionMode mode;
- priv->icon = gtk_image_new ();
- gtk_widget_show (priv->icon);
- gtk_box_pack_start (GTK_BOX (box), priv->icon, FALSE, TRUE, 0);
+ priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (button);
- priv->label = gtk_label_new ("");
- gtk_widget_show (priv->label);
- gtk_label_set_justify (GTK_LABEL (priv->label), GTK_JUSTIFY_LEFT);
- gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.0);
- gtk_box_pack_start (GTK_BOX (box), priv->label, TRUE, TRUE, 0);
+ emft = (EMFolderTree *) em_folder_tree_new ();
- gtk_widget_show (box);
- gtk_container_add (GTK_CONTAINER (emfsb), box);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (emft));
+ if (priv->multiple_select)
+ mode = GTK_SELECTION_MULTIPLE;
+ else
+ mode = GTK_SELECTION_SINGLE;
+ gtk_tree_selection_set_mode (selection, mode);
- set_contents (emfsb);
-}
+ em_folder_tree_set_excluded (
+ emft, EMFT_EXCLUDE_NOSELECT |
+ EMFT_EXCLUDE_VIRTUAL | EMFT_EXCLUDE_VTRASH);
-static void
-em_folder_selection_button_destroy (GtkObject *obj)
-{
- struct _EMFolderSelectionButtonPrivate *priv = ((EMFolderSelectionButton *) obj)->priv;
+ dialog = em_folder_selector_new (
+ emft, EM_FOLDER_SELECTOR_CAN_CREATE,
+ priv->title, priv->caption, NULL);
- if (priv->selector) {
- gtk_widget_destroy(priv->selector);
- priv->selector = NULL;
+ if (priv->multiple_select)
+ em_folder_selector_set_selected_list (
+ EM_FOLDER_SELECTOR (dialog), priv->uris);
+ else
+ em_folder_selector_set_selected (
+ EM_FOLDER_SELECTOR (dialog), priv->uri);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ if (priv->multiple_select) {
+ GList *uris;
+
+ uris = em_folder_selector_get_selected_uris (
+ EM_FOLDER_SELECTOR (dialog));
+ em_folder_selection_button_set_selection_mult (
+ EM_FOLDER_SELECTION_BUTTON (button), uris);
+ } else {
+ const gchar *uri;
+
+ uri = em_folder_selector_get_selected_uri (
+ EM_FOLDER_SELECTOR (dialog));
+ em_folder_selection_button_set_selection (
+ EM_FOLDER_SELECTION_BUTTON (button), uri);
}
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
+ g_signal_emit (button, signals[SELECTED], 0);
+
+exit:
+ gtk_widget_destroy (dialog);
}
static void
-em_folder_selection_button_finalize (GObject *obj)
+folder_selection_button_class_init (EMFolderSelectionButtonClass *class)
{
- struct _EMFolderSelectionButtonPrivate *priv = ((EMFolderSelectionButton *) obj)->priv;
-
- GList *lst = ((EMFolderSelectionButton*) obj)->priv->uris;
- g_list_foreach (lst, (GFunc) g_free, NULL);
- g_list_free (lst);
-
- g_free (priv->title);
- g_free (priv->caption);
- g_free (priv->uri);
- g_free (priv);
-
- G_OBJECT_CLASS (parent_class)->finalize (obj);
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
+ GtkButtonClass *button_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFolderSelectionButtonPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = folder_selection_button_set_property;
+ object_class->get_property = folder_selection_button_get_property;
+ object_class->finalize = folder_selection_button_finalize;
+
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = folder_selection_button_destroy;
+
+ button_class = GTK_BUTTON_CLASS (class);
+ button_class->clicked = folder_selection_button_clicked;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CAPTION,
+ g_param_spec_string (
+ "caption",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MULTISELECT,
+ g_param_spec_boolean (
+ "multiselect",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TITLE,
+ g_param_spec_string (
+ "title",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ signals[SELECTED] = g_signal_new (
+ "selected",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderSelectionButtonClass, selected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
-emfsb_selector_response (EMFolderSelector *emfs, gint response, EMFolderSelectionButton *button)
+folder_selection_button_init (EMFolderSelectionButton *emfsb)
{
- if (response == GTK_RESPONSE_OK) {
- if (button->priv->multiple_select) {
- GList *uris = em_folder_selector_get_selected_uris (emfs);
+ GtkWidget *box;
- em_folder_selection_button_set_selection_mult (button, uris);
- g_signal_emit (button, signals[SELECTED], 0);
- } else {
- const gchar *uri = em_folder_selector_get_selected_uri (emfs);
+ emfsb->priv = EM_FOLDER_SELECTION_BUTTON_GET_PRIVATE (emfsb);
- em_folder_selection_button_set_selection (button, uri);
- g_signal_emit (button, signals[SELECTED], 0);
- }
- }
+ emfsb->priv->multiple_select = FALSE;
- gtk_widget_destroy ((GtkWidget *) emfs);
+ box = gtk_hbox_new (FALSE, 4);
+
+ emfsb->priv->icon = gtk_image_new ();
+ gtk_widget_show (emfsb->priv->icon);
+ gtk_box_pack_start (GTK_BOX (box), emfsb->priv->icon, FALSE, TRUE, 0);
+
+ emfsb->priv->label = gtk_label_new ("");
+ gtk_widget_show (emfsb->priv->label);
+ gtk_label_set_justify (GTK_LABEL (emfsb->priv->label), GTK_JUSTIFY_LEFT);
+ gtk_misc_set_alignment (GTK_MISC (emfsb->priv->label), 0.0, 0.0);
+ gtk_box_pack_start (GTK_BOX (box), emfsb->priv->label, TRUE, TRUE, 0);
+
+ gtk_widget_show (box);
+ gtk_container_add (GTK_CONTAINER (emfsb), box);
+
+ folder_selection_button_set_contents (emfsb);
}
-static void
-em_folder_selection_button_clicked (GtkButton *button)
+GType
+em_folder_selection_button_get_type (void)
{
- struct _EMFolderSelectionButtonPrivate *priv = EM_FOLDER_SELECTION_BUTTON (button)->priv;
- EMFolderTreeModel *model;
- EMFolderTree *emft;
- GtkWidget *dialog;
+ static GType type = 0;
- if (GTK_BUTTON_CLASS (parent_class)->clicked != NULL)
- (* GTK_BUTTON_CLASS (parent_class)->clicked) (button);
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFolderSelectionButtonClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) folder_selection_button_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFolderSelectionButton),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) folder_selection_button_init,
+ NULL /* value_table */
+ };
- if (priv->selector) {
- gtk_window_present((GtkWindow *)priv->selector);
- return;
+ type = g_type_register_static (
+ GTK_TYPE_BUTTON, "EMFolderSelectionButton",
+ &type_info, 0);
}
- model = mail_component_peek_tree_model (mail_component_peek ());
- emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
- g_object_unref (model);
- em_folder_tree_set_multiselect (emft, priv->multiple_select);
- em_folder_tree_set_excluded(emft, EMFT_EXCLUDE_NOSELECT|EMFT_EXCLUDE_VIRTUAL|EMFT_EXCLUDE_VTRASH);
- dialog = em_folder_selector_new (emft, EM_FOLDER_SELECTOR_CAN_CREATE, priv->title, priv->caption, NULL);
- if (priv->multiple_select)
- em_folder_selector_set_selected_list ((EMFolderSelector *) dialog, priv->uris);
- else
- em_folder_selector_set_selected ((EMFolderSelector *) dialog, priv->uri);
- g_signal_connect (dialog, "response", G_CALLBACK (emfsb_selector_response), button);
- priv->selector = dialog;
- g_signal_connect(dialog, "destroy", G_CALLBACK(gtk_widget_destroyed), &priv->selector);
- gtk_widget_show (dialog);
+ return type;
}
GtkWidget *
-em_folder_selection_button_new (const gchar *title, const gchar *caption)
+em_folder_selection_button_new (const gchar *title,
+ const gchar *caption)
{
- EMFolderSelectionButton *button = g_object_new (EM_TYPE_FOLDER_SELECTION_BUTTON, NULL);
+ return g_object_new (
+ EM_TYPE_FOLDER_SELECTION_BUTTON,
+ "title", title, "caption", caption, NULL);
+}
- button->priv->title = g_strdup (title);
- button->priv->caption = g_strdup (caption);
+const gchar *
+em_folder_selection_button_get_caption (EMFolderSelectionButton *button)
+{
+ g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), NULL);
- return GTK_WIDGET (button);
+ return button->priv->caption;
}
void
-em_folder_selection_button_set_selection (EMFolderSelectionButton *button, const gchar *uri)
+em_folder_selection_button_set_caption (EMFolderSelectionButton *button,
+ const gchar *caption)
{
- struct _EMFolderSelectionButtonPrivate *priv = button->priv;
+ g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
+
+ g_free (button->priv->caption);
+ button->priv->caption = g_strdup (caption);
+
+ g_object_notify (G_OBJECT (button), "caption");
+}
+
+gboolean
+em_folder_selection_button_get_multiselect (EMFolderSelectionButton *button)
+{
+ g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), FALSE);
+
+ return button->priv->multiple_select;
+}
+void
+em_folder_selection_button_set_multiselect (EMFolderSelectionButton *button,
+ gboolean multiselect)
+{
g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
- if (priv->uri != uri) {
- g_free (priv->uri);
- priv->uri = g_strdup (uri);
- }
+ button->priv->multiple_select = multiselect;
- set_contents (button);
+ g_object_notify (G_OBJECT (button), "multiselect");
}
const gchar *
@@ -289,20 +435,40 @@ em_folder_selection_button_get_selection (EMFolderSelectionButton *button)
}
void
-em_folder_selection_button_set_selection_mult (EMFolderSelectionButton *button, GList *uris)
+em_folder_selection_button_set_selection (EMFolderSelectionButton *button,
+ const gchar *uri)
+{
+ g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
+
+ if (g_strcmp0 (button->priv->uri, uri) == 0)
+ return;
+
+ g_free (button->priv->uri);
+ button->priv->uri = g_strdup (uri);
+
+ folder_selection_button_set_contents (button);
+}
+
+GList *
+em_folder_selection_button_get_selection_mult (EMFolderSelectionButton *button)
+{
+ g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), NULL);
+
+ return button->priv->uris;
+}
+
+void
+em_folder_selection_button_set_selection_mult (EMFolderSelectionButton *button,
+ GList *uris)
{
- struct _EMFolderSelectionButtonPrivate *priv = button->priv;
gchar *caption, *tmp, *tmp2;
g_return_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button));
- if (priv->uris) {
- g_list_foreach (priv->uris, (GFunc) g_free, NULL);
- g_list_free (priv->uris);
- priv->uris = NULL;
- }
+ g_list_foreach (button->priv->uris, (GFunc) g_free, NULL);
+ g_list_free (button->priv->uris);
- priv->uris = uris;
+ button->priv->uris = uris;
/* compile the name */
caption = g_strdup ("");
@@ -319,34 +485,36 @@ em_folder_selection_button_set_selection_mult (EMFolderSelectionButton *button,
/* apparently, we do not know this folder, so we'll just skip it */
g_free (uris->data);
uris = g_list_next (uris);
- priv->uris = g_list_remove (priv->uris, uris->data);
+ button->priv->uris = g_list_remove (
+ button->priv->uris, uris->data);
}
}
if (caption[0])
- gtk_label_set_text (GTK_LABEL (priv->label), caption + 2);
+ gtk_label_set_text (
+ GTK_LABEL (button->priv->label), caption + 2);
else
- set_contents_unselected (button);
+ folder_selection_button_unselected (button);
g_free (caption);
}
-GList *
-em_folder_selection_button_get_selection_mult (EMFolderSelectionButton *button)
+const gchar *
+em_folder_selection_button_get_title (EMFolderSelectionButton *button)
{
- g_return_val_if_fail (EM_IS_FOLDER_SELECTION_BUTTON (button), NULL);
+ g_return_val_if_fail (EM_FOLDER_SELECTION_BUTTON (button), NULL);
- return button->priv->uris;
+ return button->priv->title;
}
void
-em_folder_selection_button_set_multiselect (EMFolderSelectionButton *button, gboolean value)
+em_folder_selection_button_set_title (EMFolderSelectionButton *button,
+ const gchar *title)
{
- button->priv->multiple_select = value;
-}
+ g_return_if_fail (EM_FOLDER_SELECTION_BUTTON (button));
-gboolean
-em_folder_selection_button_get_multiselect (EMFolderSelectionButton *button)
-{
- return button->priv->multiple_select;
+ g_free (button->priv->title);
+ button->priv->title = g_strdup (title);
+
+ g_object_notify (G_OBJECT (button), "title");
}
diff --git a/mail/em-folder-selection-button.h b/mail/em-folder-selection-button.h
index d30867435e..cc75fac1dd 100644
--- a/mail/em-folder-selection-button.h
+++ b/mail/em-folder-selection-button.h
@@ -21,26 +21,39 @@
*
*/
-#ifndef __EM_FOLDER_SELECTION_BUTTON_H__
-#define __EM_FOLDER_SELECTION_BUTTON_H__
+#ifndef EM_FOLDER_SELECTION_BUTTON_H
+#define EM_FOLDER_SELECTION_BUTTON_H
#include <gtk/gtk.h>
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define EM_TYPE_FOLDER_SELECTION_BUTTON \
+ (em_folder_selection_button_get_type ())
+#define EM_FOLDER_SELECTION_BUTTON(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButton))
+#define EM_FOLDER_SELECTION_BUTTON_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButtonClass))
+#define EM_IS_FOLDER_SELECTION_BUTTON(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON))
+#define EM_IS_FOLDER_SELECTION_BUTTON_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON))
+#define EM_FOLDER_SELECTION_BUTTON_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButtonClass))
-#define EM_TYPE_FOLDER_SELECTION_BUTTON (em_folder_selection_button_get_type ())
-#define EM_FOLDER_SELECTION_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButton))
-#define EM_FOLDER_SELECTION_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EM_TYPE_FOLDER_SELECTION_BUTTON, EMFolderSelectionButtonClass))
-#define EM_IS_FOLDER_SELECTION_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON))
-#define EM_IS_FOLDER_SELECTION_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EM_TYPE_FOLDER_SELECTION_BUTTON))
+G_BEGIN_DECLS
-typedef struct _EMFolderSelectionButton EMFolderSelectionButton;
-typedef struct _EMFolderSelectionButtonClass EMFolderSelectionButtonClass;
+typedef struct _EMFolderSelectionButton EMFolderSelectionButton;
+typedef struct _EMFolderSelectionButtonClass EMFolderSelectionButtonClass;
+typedef struct _EMFolderSelectionButtonPrivate EMFolderSelectionButtonPrivate;
struct _EMFolderSelectionButton {
GtkButton parent;
-
- struct _EMFolderSelectionButtonPrivate *priv;
+ EMFolderSelectionButtonPrivate *priv;
};
struct _EMFolderSelectionButtonClass {
@@ -48,22 +61,39 @@ struct _EMFolderSelectionButtonClass {
/* Signals. */
- void (* selected) (EMFolderSelectionButton *button);
+ void (*selected) (EMFolderSelectionButton *button);
};
-GType em_folder_selection_button_get_type (void);
-
-GtkWidget *em_folder_selection_button_new (const gchar *title, const gchar *caption);
-
-void em_folder_selection_button_set_selection (EMFolderSelectionButton *button, const gchar *uri);
-const gchar *em_folder_selection_button_get_selection (EMFolderSelectionButton *button);
-
-void em_folder_selection_button_set_selection_mult (EMFolderSelectionButton *button, GList *uris);
-GList *em_folder_selection_button_get_selection_mult (EMFolderSelectionButton *button);
-
-void em_folder_selection_button_set_multiselect (EMFolderSelectionButton *button, gboolean value);
-gboolean em_folder_selection_button_get_multiselect (EMFolderSelectionButton *button);
+GType em_folder_selection_button_get_type (void);
+GtkWidget * em_folder_selection_button_new
+ (const gchar *title,
+ const gchar *caption);
+const gchar * em_folder_selection_button_get_caption
+ (EMFolderSelectionButton *button);
+void em_folder_selection_button_set_caption
+ (EMFolderSelectionButton *button,
+ const gchar *caption);
+gboolean em_folder_selection_button_get_multiselect
+ (EMFolderSelectionButton *button);
+void em_folder_selection_button_set_multiselect
+ (EMFolderSelectionButton *button,
+ gboolean multiselect);
+const gchar * em_folder_selection_button_get_selection
+ (EMFolderSelectionButton *button);
+void em_folder_selection_button_set_selection
+ (EMFolderSelectionButton *button,
+ const gchar *uri);
+GList * em_folder_selection_button_get_selection_mult
+ (EMFolderSelectionButton *button);
+void em_folder_selection_button_set_selection_mult
+ (EMFolderSelectionButton *button,
+ GList *uris);
+const gchar * em_folder_selection_button_get_title
+ (EMFolderSelectionButton *button);
+void em_folder_selection_button_set_title
+ (EMFolderSelectionButton *button,
+ const gchar *title);
G_END_DECLS
-#endif /* __EM_FOLDER_SELECTION_BUTTON_H__ */
+#endif /* EM_FOLDER_SELECTION_BUTTON_H */
diff --git a/mail/em-folder-selection.c b/mail/em-folder-selection.c
index 8fe6292e32..1e77525c9b 100644
--- a/mail/em-folder-selection.c
+++ b/mail/em-folder-selection.c
@@ -32,53 +32,46 @@
#include "em-folder-tree.h"
#include "em-folder-selector.h"
#include "em-folder-selection.h"
-#include "mail-component.h"
/* TODO: rmeove this file, it could just go on em-folder-selection or em-utils */
-struct _select_folder_data {
- void (*done) (const gchar *uri, gpointer data);
- gpointer data;
-};
-
-static void
-emfs_selector_response(EMFolderSelector *emfs, gint response, struct _select_folder_data *d)
-{
- if (response == GTK_RESPONSE_OK) {
- const gchar *uri = em_folder_selector_get_selected_uri(emfs);
-
- d->done(uri, d->data);
- }
-
- gtk_widget_destroy((GtkWidget *)emfs);
-}
-
void
-em_select_folder (GtkWindow *parent_window, const gchar *title, const gchar *oklabel, const gchar *default_uri,
- EMFTExcludeFunc exclude,
- void (*done) (const gchar *uri, gpointer user_data), gpointer user_data)
+em_select_folder (const gchar *title,
+ const gchar *oklabel,
+ const gchar *default_uri,
+ EMFTExcludeFunc exclude,
+ void (*done) (const gchar *uri, gpointer user_data),
+ gpointer user_data)
{
- struct _select_folder_data *d;
- EMFolderTreeModel *model;
GtkWidget *dialog;
EMFolderTree *emft;
- model = mail_component_peek_tree_model (mail_component_peek ());
- emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
+ g_return_if_fail (done != NULL);
+
+ /* XXX Do we leak this reference? */
+ emft = (EMFolderTree *) em_folder_tree_new ();
+
if (exclude)
- em_folder_tree_set_excluded_func(emft, exclude, user_data);
+ em_folder_tree_set_excluded_func (emft, exclude, user_data);
else
- em_folder_tree_set_excluded (emft, EMFT_EXCLUDE_NOSELECT|EMFT_EXCLUDE_VIRTUAL|EMFT_EXCLUDE_VTRASH);
+ em_folder_tree_set_excluded (
+ emft, EMFT_EXCLUDE_NOSELECT |
+ EMFT_EXCLUDE_VIRTUAL | EMFT_EXCLUDE_VTRASH);
- dialog = em_folder_selector_new(emft, EM_FOLDER_SELECTOR_CAN_CREATE, title, NULL, oklabel);
+ dialog = em_folder_selector_new (
+ emft, EM_FOLDER_SELECTOR_CAN_CREATE, title, NULL, oklabel);
- d = g_malloc0(sizeof(*d));
- d->data = user_data;
- d->done = done;
- g_signal_connect(dialog, "response", G_CALLBACK (emfs_selector_response), d);
- g_object_set_data_full((GObject *)dialog, "e-select-data", d, (GDestroyNotify)g_free);
- gtk_widget_show(dialog);
+ if (default_uri != NULL)
+ em_folder_selector_set_selected (
+ EM_FOLDER_SELECTOR (dialog), default_uri);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
+ const gchar *uri;
+
+ uri = em_folder_selector_get_selected_uri (
+ EM_FOLDER_SELECTOR (dialog));
+ done (uri, user_data);
+ }
- if (default_uri)
- em_folder_selector_set_selected((EMFolderSelector *)dialog, default_uri);
+ gtk_widget_destroy (dialog);
}
diff --git a/mail/em-folder-selection.h b/mail/em-folder-selection.h
index af3243fdd5..3f6b4b3a3b 100644
--- a/mail/em-folder-selection.h
+++ b/mail/em-folder-selection.h
@@ -24,15 +24,16 @@
#ifndef EM_FOLDER_SELECTION_H
#define EM_FOLDER_SELECTION_H
-#include <gtk/gtk.h>
-#include "em-folder-tree.h"
+#include <glib.h>
G_BEGIN_DECLS
-void em_select_folder (GtkWindow *parent_window, const gchar *title, const gchar *oklabel, const gchar *default_uri,
- EMFTExcludeFunc exclude,
- void (*done)(const gchar *uri, gpointer data),
- gpointer data);
+void em_select_folder (const gchar *title,
+ const gchar *oklabel,
+ const gchar *default_uri,
+ EMFTExcludeFunc exclude,
+ void (*done)(const gchar *uri, gpointer data),
+ gpointer data);
G_END_DECLS
diff --git a/mail/em-folder-selector.c b/mail/em-folder-selector.c
index 95339ff8ad..198264e62b 100644
--- a/mail/em-folder-selector.c
+++ b/mail/em-folder-selector.c
@@ -21,14 +21,8 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <string.h>
-
#include <glib/gi18n.h>
-
#include <e-util/e-util.h>
#include <misc/e-gui-utils.h>
@@ -43,82 +37,83 @@
#define d(x)
extern CamelSession *session;
+static gpointer parent_class;
-static void em_folder_selector_class_init (EMFolderSelectorClass *klass);
-static void em_folder_selector_init (EMFolderSelector *emfs);
-static void em_folder_selector_destroy (GtkObject *obj);
-static void em_folder_selector_finalize (GObject *obj);
+static void
+folder_selector_finalize (GObject *object)
+{
+ EMFolderSelector *emfs = EM_FOLDER_SELECTOR (object);
-static GtkDialogClass *parent_class = NULL;
+ g_free (emfs->selected_path);
+ g_free (emfs->selected_uri);
+ g_free (emfs->created_uri);
-GType
-em_folder_selector_get_type (void)
-{
- static GType type = 0;
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMFolderSelectorClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_folder_selector_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMFolderSelector),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_folder_selector_init,
- };
+static void
+folder_selector_destroy (GtkObject *object)
+{
+ EMFolderSelector *emfs = EM_FOLDER_SELECTOR (object);
+ GtkTreeModel *model;
- type = g_type_register_static (GTK_TYPE_DIALOG, "EMFolderSelector", &info, 0);
+ if (emfs->created_id != 0) {
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emfs->emft));
+ g_signal_handler_disconnect (model, emfs->created_id);
+ emfs->created_id = 0;
}
- return type;
+ /* Chain up to parent's destroy() method. */
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
-em_folder_selector_class_init (EMFolderSelectorClass *klass)
+folder_selector_class_init (EMFolderSelectorClass *class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
+
+ parent_class = g_type_class_peek_parent (class);
- parent_class = g_type_class_ref (GTK_TYPE_DIALOG);
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = folder_selector_finalize;
- object_class->finalize = em_folder_selector_finalize;
- gtk_object_class->destroy = em_folder_selector_destroy;
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = folder_selector_destroy;
}
static void
-em_folder_selector_init (EMFolderSelector *emfs)
+folder_selector_init (EMFolderSelector *emfs)
{
emfs->selected_path = NULL;
emfs->selected_uri = NULL;
}
-static void
-em_folder_selector_destroy (GtkObject *obj)
+GType
+em_folder_selector_get_type (void)
{
- EMFolderSelector *emfs = (EMFolderSelector *) obj;
- EMFolderTreeModel *model;
-
- if (emfs->created_id != 0) {
- model = em_folder_tree_get_model (emfs->emft);
- g_signal_handler_disconnect (model, emfs->created_id);
- emfs->created_id = 0;
- }
-
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
-}
+ static GType type = 0;
-static void
-em_folder_selector_finalize (GObject *obj)
-{
- EMFolderSelector *emfs = (EMFolderSelector *) obj;
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFolderSelectorClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) folder_selector_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFolderSelector),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) folder_selector_init,
+ NULL /* value_table */
+ };
- g_free (emfs->selected_path);
- g_free (emfs->selected_uri);
- g_free (emfs->created_uri);
+ type = g_type_register_static (
+ GTK_TYPE_DIALOG, "EMFolderSelector", &type_info, 0);
+ }
- G_OBJECT_CLASS (parent_class)->finalize (obj);
+ return type;
}
static void
@@ -128,7 +123,9 @@ emfs_response (GtkWidget *dialog, gint response, EMFolderSelector *emfs)
return;
g_object_set_data ((GObject *)emfs->emft, "select", GUINT_TO_POINTER (1));
- em_folder_utils_create_folder (NULL, emfs->emft, GTK_WINDOW (dialog));
+
+ /* FIXME Pass a parent window. */
+ em_folder_utils_create_folder (NULL, emfs->emft, NULL);
g_signal_stop_emission_by_name (emfs, "response");
}
@@ -168,7 +165,7 @@ folder_activated_cb (EMFolderTree *emft, const gchar *path, const gchar *uri, EM
void
em_folder_selector_construct (EMFolderSelector *emfs, EMFolderTree *emft, guint32 flags, const gchar *title, const gchar *text, const gchar *oklabel)
{
- GtkWidget *label;
+ GtkWidget *widget;
gtk_window_set_modal (GTK_WINDOW (emfs), FALSE);
gtk_window_set_default_size (GTK_WINDOW (emfs), 350, 300);
@@ -190,19 +187,29 @@ em_folder_selector_construct (EMFolderSelector *emfs, EMFolderTree *emft, guint3
gtk_dialog_set_response_sensitive (GTK_DIALOG (emfs), GTK_RESPONSE_OK, FALSE);
gtk_dialog_set_default_response (GTK_DIALOG (emfs), GTK_RESPONSE_OK);
+ widget = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (widget),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+ gtk_box_pack_end (
+ GTK_BOX (GTK_DIALOG (emfs)->vbox), widget, TRUE, TRUE, 6);
+ gtk_widget_show (widget);
+
emfs->emft = emft;
- gtk_widget_show ((GtkWidget *) emft);
+ gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (emft));
+ gtk_widget_show (GTK_WIDGET (emft));
g_signal_connect (emfs->emft, "folder-selected", G_CALLBACK (folder_selected_cb), emfs);
g_signal_connect (emfs->emft, "folder-activated", G_CALLBACK (folder_activated_cb), emfs);
- gtk_box_pack_end (GTK_BOX (GTK_DIALOG (emfs)->vbox), (GtkWidget *)emft, TRUE, TRUE, 6);
if (text != NULL) {
- label = gtk_label_new (text);
- gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
- gtk_widget_show (label);
+ widget = gtk_label_new (text);
+ gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_LEFT);
+ gtk_widget_show (widget);
- gtk_box_pack_end (GTK_BOX (GTK_DIALOG (emfs)->vbox), label, FALSE, TRUE, 6);
+ gtk_box_pack_end (GTK_BOX (GTK_DIALOG (emfs)->vbox), widget, FALSE, TRUE, 6);
}
gtk_widget_grab_focus ((GtkWidget *) emfs->emft);
diff --git a/mail/em-folder-selector.h b/mail/em-folder-selector.h
index f358fc059d..131c4a4574 100644
--- a/mail/em-folder-selector.h
+++ b/mail/em-folder-selector.h
@@ -26,17 +26,30 @@
#include <gtk/gtk.h>
-#define EM_TYPE_FOLDER_SELECTOR (em_folder_selector_get_type ())
-#define EM_FOLDER_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_TYPE_FOLDER_SELECTOR, EMFolderSelector))
-#define EM_FOLDER_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EM_TYPE_FOLDER_SELECTOR, EMFolderSelectorClass))
-#define EM_IS_FOLDER_SELECTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_TYPE_FOLDER_SELECTOR))
-#define EM_IS_FOLDER_SELECTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EM_TYPE_FOLDER_SELECTOR))
+/* Standard GObject macros */
+#define EM_TYPE_FOLDER_SELECTOR \
+ (em_folder_selector_get_type ())
+#define EM_FOLDER_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_FOLDER_SELECTOR, EMFolderSelector))
+#define EM_FOLDER_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_FOLDER_SELECTOR, EMFolderSelectorClass))
+#define EM_IS_FOLDER_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_FOLDER_SELECTOR))
+#define EM_IS_FOLDER_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_FOLDER_SELECTOR))
+#define EM_FOLDER_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_FOLDER_SELECTOR, EMFolderSelectorClass))
G_BEGIN_DECLS
-typedef struct _EMFolderSelector EMFolderSelector;
+typedef struct _EMFolderSelector EMFolderSelector;
+typedef struct _EMFolderSelectorClass EMFolderSelectorClass;
typedef struct _EMFolderSelectorPrivate EMFolderSelectorPrivate;
-typedef struct _EMFolderSelectorClass EMFolderSelectorClass;
struct _EMFolderSelector {
GtkDialog parent;
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index c6e3e5f833..699c8dab14 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -20,9 +20,7 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "em-folder-tree-model.h"
#include <stdio.h>
#include <string.h>
@@ -32,13 +30,8 @@
#include <errno.h>
#include <sys/stat.h>
-#include <libxml/parser.h>
-
-#include <libedataserver/e-xml-utils.h>
-#include <libedataserver/e-data-server-util.h>
-
-#include <e-util/e-util.h>
-#include <e-util/e-mktemp.h>
+#include "e-util/e-util.h"
+#include "e-util/e-account-utils.h"
#include <glib/gi18n.h>
@@ -50,7 +43,6 @@
#include "mail-mt.h"
/* sigh, these 2 only needed for outbox total count checking - a mess */
-#include "mail-component.h"
#include "mail-folder-cache.h"
#include "em-utils.h"
@@ -60,22 +52,39 @@
#include <camel/camel-folder.h>
#include <camel/camel-vee-store.h>
-#include "em-folder-tree-model.h"
+#include "e-mail-local.h"
-#define u(x) /* unread count debug */
#define d(x)
-/* GObject virtual method overrides */
-static void em_folder_tree_model_class_init (EMFolderTreeModelClass *klass);
-static void em_folder_tree_model_init (EMFolderTreeModel *model);
-static void em_folder_tree_model_finalize (GObject *obj);
+#define EM_FOLDER_TREE_MODEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModelPrivate))
+
+struct _EMFolderTreeModelPrivate {
+ /* This is set by EMailShellSidebar. It allows new EMFolderTree
+ * instances to initialize their selection and expanded states to
+ * mimic the sidebar. */
+ GtkTreeSelection *selection; /* weak reference */
+
+ EAccountList *accounts;
-/* interface init methods */
-static void tree_model_iface_init (GtkTreeModelIface *iface);
-static void tree_sortable_iface_init (GtkTreeSortableIface *iface);
+ /* EAccount -> EMFolderTreeStoreInfo */
+ GHashTable *account_index;
-static void account_changed (EAccountList *accounts, EAccount *account, gpointer user_data);
-static void account_removed (EAccountList *accounts, EAccount *account, gpointer user_data);
+ /* CamelStore -> EMFolderTreeStoreInfo */
+ GHashTable *store_index;
+
+ /* URI -> GtkTreeRowReference */
+ GHashTable *uri_index;
+
+ gulong account_changed_id;
+ gulong account_removed_id;
+};
+
+enum {
+ PROP_0,
+ PROP_SELECTION
+};
enum {
LOADING_ROW,
@@ -86,94 +95,30 @@ enum {
extern CamelStore *vfolder_store;
-static guint signals[LAST_SIGNAL] = { 0, };
-static GtkTreeStoreClass *parent_class = NULL;
-
-GType
-em_folder_tree_model_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMFolderTreeModelClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_folder_tree_model_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMFolderTreeModel),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_folder_tree_model_init,
- };
- static const GInterfaceInfo tree_model_info = {
- (GInterfaceInitFunc) tree_model_iface_init,
- NULL,
- NULL
- };
- static const GInterfaceInfo sortable_info = {
- (GInterfaceInitFunc) tree_sortable_iface_init,
- NULL,
- NULL
- };
-
- type = g_type_register_static (GTK_TYPE_TREE_STORE, "EMFolderTreeModel", &info, 0);
-
- g_type_add_interface_static (type, GTK_TYPE_TREE_MODEL,
- &tree_model_info);
- g_type_add_interface_static (type, GTK_TYPE_TREE_SORTABLE,
- &sortable_info);
- }
-
- return type;
-}
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
static void
-em_folder_tree_model_class_init (EMFolderTreeModelClass *klass)
+store_info_free (EMFolderTreeModelStoreInfo *si)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_ref (GTK_TYPE_TREE_STORE);
-
- object_class->finalize = em_folder_tree_model_finalize;
-
- /* signals */
- signals[LOADING_ROW] =
- g_signal_new ("loading-row",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeModelClass, loading_row),
- NULL, NULL,
- e_marshal_VOID__POINTER_POINTER,
- G_TYPE_NONE, 2,
- G_TYPE_POINTER,
- G_TYPE_POINTER);
-
- signals[LOADED_ROW] =
- g_signal_new ("loaded-row",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeModelClass, loaded_row),
- NULL, NULL,
- e_marshal_VOID__POINTER_POINTER,
- G_TYPE_NONE, 2,
- G_TYPE_POINTER,
- G_TYPE_POINTER);
-
- signals[FOLDER_ADDED] =
- g_signal_new ("folder-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeModelClass, folder_added),
- NULL, NULL,
- e_marshal_VOID__STRING_STRING,
- G_TYPE_NONE, 2,
- G_TYPE_STRING,
- G_TYPE_STRING);
+ camel_object_remove_event (si->store, si->created_id);
+ camel_object_remove_event (si->store, si->deleted_id);
+ camel_object_remove_event (si->store, si->renamed_id);
+ camel_object_remove_event (si->store, si->subscribed_id);
+ camel_object_remove_event (si->store, si->unsubscribed_id);
+
+ g_free (si->display_name);
+ camel_object_unref (si->store);
+ gtk_tree_row_reference_free (si->row);
+ g_hash_table_destroy (si->full_hash);
+ g_free (si);
}
static gint
-sort_cb (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
+folder_tree_model_sort (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer user_data)
{
gchar *aname, *bname;
CamelStore *store;
@@ -181,13 +126,21 @@ sort_cb (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data
guint32 aflags, bflags;
gint rv = -2;
- gtk_tree_model_get (model, a, COL_BOOL_IS_STORE, &is_store,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_DISPLAY_NAME, &aname, COL_UINT_FLAGS, &aflags, -1);
- gtk_tree_model_get (model, b, COL_STRING_DISPLAY_NAME, &bname, COL_UINT_FLAGS, &bflags, -1);
+ gtk_tree_model_get (
+ model, a,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_DISPLAY_NAME, &aname,
+ COL_UINT_FLAGS, &aflags, -1);
+
+ gtk_tree_model_get (
+ model, b,
+ COL_STRING_DISPLAY_NAME, &bname,
+ COL_UINT_FLAGS, &bflags, -1);
if (is_store) {
- /* On This Computer is always first and Search Folders is always last */
+ /* On This Computer is always first, and Search Folders
+ * is always last. */
if (!strcmp (aname, _("On This Computer")))
rv = -1;
else if (!strcmp (bname, _("On This Computer")))
@@ -197,13 +150,13 @@ sort_cb (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data
else if (!strcmp (bname, _("Search Folders")))
rv = -1;
} else if (store == vfolder_store) {
- /* UNMATCHED is always last */
+ /* UNMATCHED is always last. */
if (aname && !strcmp (aname, _("UNMATCHED")))
rv = 1;
else if (bname && !strcmp (bname, _("UNMATCHED")))
rv = -1;
} else {
- /* Inbox is always first */
+ /* Inbox is always first. */
if ((aflags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
rv = -1;
else if ((bflags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
@@ -226,136 +179,203 @@ sort_cb (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data
}
static void
-store_info_free (struct _EMFolderTreeModelStoreInfo *si)
+account_changed_cb (EAccountList *accounts,
+ EAccount *account,
+ EMFolderTreeModel *model)
{
- camel_object_remove_event (si->store, si->created_id);
- camel_object_remove_event (si->store, si->deleted_id);
- camel_object_remove_event (si->store, si->renamed_id);
- camel_object_remove_event (si->store, si->subscribed_id);
- camel_object_remove_event (si->store, si->unsubscribed_id);
+ EMFolderTreeModelStoreInfo *si;
+ CamelProvider *provider;
+ CamelStore *store;
+ CamelException ex;
+ gchar *uri;
- g_free (si->display_name);
- camel_object_unref (si->store);
- gtk_tree_row_reference_free (si->row);
- g_hash_table_destroy (si->full_hash);
- g_free (si);
-}
+ si = g_hash_table_lookup (model->priv->account_index, account);
+ if (si == NULL)
+ return;
-static void
-emft_model_unread_count_changed (GtkTreeModel *model, GtkTreeIter *iter)
-{
- GtkTreeIter parent_iter;
- GtkTreeIter child_iter = *iter;
+ em_folder_tree_model_remove_store (model, si->store);
- g_signal_handlers_block_by_func (
- model, emft_model_unread_count_changed, NULL);
+ /* check if store needs to be added at all*/
+ if (!account->enabled ||!(uri = account->source->url))
+ return;
- /* Folders are displayed with a bold weight to indicate that
- they contain unread messages. We signal that parent rows
- have changed here to update them. */
+ camel_exception_init (&ex);
+ if (!(provider = camel_provider_get(uri, &ex))) {
+ camel_exception_clear (&ex);
+ return;
+ }
- while (gtk_tree_model_iter_parent (model, &parent_iter, &child_iter)) {
- GtkTreePath *parent_path;
+ /* make sure the new store belongs in the tree */
+ if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
+ return;
- parent_path = gtk_tree_model_get_path (model, &parent_iter);
- gtk_tree_model_row_changed (model, parent_path, &parent_iter);
- gtk_tree_path_free (parent_path);
- child_iter = parent_iter;
+ if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
+ camel_exception_clear (&ex);
+ return;
}
- g_signal_handlers_unblock_by_func (
- model, emft_model_unread_count_changed, NULL);
+ em_folder_tree_model_add_store (model, store, account->name);
+ camel_object_unref (store);
}
static void
-em_folder_tree_model_init (EMFolderTreeModel *model)
+account_removed_cb (EAccountList *accounts,
+ EAccount *account,
+ EMFolderTreeModel *model)
{
- model->store_hash = g_hash_table_new_full (
- g_direct_hash, g_direct_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) store_info_free);
+ EMFolderTreeModelStoreInfo *si;
- model->uri_hash = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) gtk_tree_row_reference_free);
-
- gtk_tree_sortable_set_default_sort_func ((GtkTreeSortable *) model, sort_cb, NULL, NULL);
+ si = g_hash_table_lookup (model->priv->account_index, account);
+ if (si == NULL)
+ return;
- model->accounts = mail_config_get_accounts ();
- model->account_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
- model->account_changed_id = g_signal_connect (model->accounts, "account-changed", G_CALLBACK (account_changed), model);
- model->account_removed_id = g_signal_connect (model->accounts, "account-removed", G_CALLBACK (account_removed), model);
- /* g_signal_connect (model, "row-changed", G_CALLBACK (emft_model_unread_count_changed), NULL); */
+ em_folder_tree_model_remove_store (model, si->store);
}
static void
-em_folder_tree_model_finalize (GObject *obj)
+folder_tree_model_selection_finalized_cb (EMFolderTreeModel *model)
{
- EMFolderTreeModel *model = (EMFolderTreeModel *) obj;
-
- g_free (model->filename);
- if (model->state)
- xmlFreeDoc (model->state);
+ model->priv->selection = NULL;
- g_hash_table_destroy (model->store_hash);
- g_hash_table_destroy (model->uri_hash);
+ g_object_notify (G_OBJECT (model), "selection");
+}
- g_hash_table_destroy (model->account_hash);
- g_signal_handler_disconnect (model->accounts, model->account_changed_id);
- g_signal_handler_disconnect (model->accounts, model->account_removed_id);
+static void
+folder_tree_model_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SELECTION:
+ em_folder_tree_model_set_selection (
+ EM_FOLDER_TREE_MODEL (object),
+ g_value_get_object (value));
+ return;
+ }
- G_OBJECT_CLASS (parent_class)->finalize (obj);
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-tree_model_iface_init (GtkTreeModelIface *iface)
+folder_tree_model_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- ;
+ switch (property_id) {
+ case PROP_SELECTION:
+ g_value_set_object (
+ value,
+ em_folder_tree_model_get_selection (
+ EM_FOLDER_TREE_MODEL (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-tree_sortable_iface_init (GtkTreeSortableIface *iface)
+folder_tree_model_dispose (GObject *object)
{
- ;
+ EMFolderTreeModelPrivate *priv;
+
+ priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (object);
+
+ if (priv->selection != NULL) {
+ g_object_weak_unref (
+ G_OBJECT (priv->selection), (GWeakNotify)
+ folder_tree_model_selection_finalized_cb, object);
+ priv->selection = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-em_folder_tree_model_load_state (EMFolderTreeModel *model, const gchar *filename)
+folder_tree_model_finalize (GObject *object)
{
- xmlNodePtr root, node;
+ EMFolderTreeModelPrivate *priv;
- if (model->state)
- xmlFreeDoc (model->state);
+ priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (object);
- if ((model->state = e_xml_parse_file (filename)) != NULL) {
- node = xmlDocGetRootElement (model->state);
- if (!node || strcmp ((gchar *)node->name, "tree-state") != 0) {
- /* it is not expected XML file, thus free it and use the default */
- xmlFreeDoc (model->state);
- } else
- return;
- }
+ g_hash_table_destroy (priv->account_index);
+ g_hash_table_destroy (priv->store_index);
+ g_hash_table_destroy (priv->uri_index);
- /* setup some defaults - expand "Local Folders" and "Search Folders" */
- model->state = xmlNewDoc ((const guchar *)"1.0");
- root = xmlNewDocNode (model->state, NULL, (const guchar *)"tree-state", NULL);
- xmlDocSetRootElement (model->state, root);
+ g_signal_handler_disconnect (
+ priv->accounts, priv->account_changed_id);
+ g_signal_handler_disconnect (
+ priv->accounts, priv->account_removed_id);
- node = xmlNewChild (root, NULL, (const guchar *)"node", NULL);
- xmlSetProp (node, (const guchar *)"name", (const guchar *)"local");
- xmlSetProp (node, (const guchar *)"expand", (const guchar *)"true");
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
- node = xmlNewChild (root, NULL, (const guchar *)"node", NULL);
- xmlSetProp (node, (const guchar *)"name", (const guchar *)"vfolder");
- xmlSetProp (node, (const guchar *)"expand", (const guchar *)"true");
+static void
+folder_tree_model_class_init (EMFolderTreeModelClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFolderTreeModelPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = folder_tree_model_set_property;
+ object_class->get_property = folder_tree_model_get_property;
+ object_class->dispose = folder_tree_model_dispose;
+ object_class->finalize = folder_tree_model_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTION,
+ g_param_spec_object (
+ "selection",
+ "Selection",
+ NULL,
+ GTK_TYPE_TREE_SELECTION,
+ G_PARAM_READWRITE));
+
+ signals[LOADING_ROW] = g_signal_new (
+ "loading-row",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeModelClass, loading_row),
+ NULL, NULL,
+ e_marshal_VOID__POINTER_POINTER,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
+ signals[LOADED_ROW] = g_signal_new (
+ "loaded-row",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeModelClass, loaded_row),
+ NULL, NULL,
+ e_marshal_VOID__POINTER_POINTER,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
+ signals[FOLDER_ADDED] = g_signal_new (
+ "folder-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeModelClass, folder_added),
+ NULL, NULL,
+ e_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
}
-EMFolderTreeModel *
-em_folder_tree_model_new (const gchar *evolution_dir)
+static void
+folder_tree_model_init (EMFolderTreeModel *model)
{
- EMFolderTreeModel *model;
- gchar *filename;
+ GHashTable *store_index;
+ GHashTable *uri_index;
GType col_types[] = {
G_TYPE_STRING, /* display name */
@@ -371,80 +391,134 @@ em_folder_tree_model_new (const gchar *evolution_dir)
G_TYPE_UINT /* last known unread count */
};
- model = g_object_new (EM_TYPE_FOLDER_TREE_MODEL, NULL);
- gtk_tree_store_set_column_types ((GtkTreeStore *) model, NUM_COLUMNS, col_types);
- gtk_tree_sortable_set_sort_column_id ((GtkTreeSortable *) model,
- GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
- GTK_SORT_ASCENDING);
+ store_index = g_hash_table_new_full (
+ g_direct_hash, g_direct_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) store_info_free);
- filename = g_build_filename (evolution_dir, "mail", "config", "folder-tree-expand-state.xml", NULL);
- em_folder_tree_model_load_state (model, filename);
- model->filename = filename;
+ uri_index = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) gtk_tree_row_reference_free);
- return model;
+ model->priv = EM_FOLDER_TREE_MODEL_GET_PRIVATE (model);
+ model->priv->store_index = store_index;
+ model->priv->uri_index = uri_index;
+
+ gtk_tree_store_set_column_types (
+ GTK_TREE_STORE (model), NUM_COLUMNS, col_types);
+ gtk_tree_sortable_set_default_sort_func (
+ GTK_TREE_SORTABLE (model),
+ folder_tree_model_sort, NULL, NULL);
+ gtk_tree_sortable_set_sort_column_id (
+ GTK_TREE_SORTABLE (model),
+ GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
+ GTK_SORT_ASCENDING);
+
+ model->priv->accounts = e_get_account_list ();
+ model->priv->account_index =
+ g_hash_table_new (g_direct_hash, g_direct_equal);
+ model->priv->account_changed_id = g_signal_connect (
+ model->priv->accounts, "account-changed",
+ G_CALLBACK (account_changed_cb), model);
+ model->priv->account_removed_id = g_signal_connect (
+ model->priv->accounts, "account-removed",
+ G_CALLBACK (account_removed_cb), model);
}
-static void
-account_changed (EAccountList *accounts, EAccount *account, gpointer user_data)
+GType
+em_folder_tree_model_get_type (void)
{
- EMFolderTreeModel *model = user_data;
- struct _EMFolderTreeModelStoreInfo *si;
- CamelProvider *provider;
- CamelStore *store;
- CamelException ex;
- gchar *uri;
+ static GType type = 0;
- if (!(si = g_hash_table_lookup (model->account_hash, account)))
- return;
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFolderTreeModelClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) folder_tree_model_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFolderTreeModel),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) folder_tree_model_init,
+ NULL /* value_table */
+ };
- em_folder_tree_model_remove_store (model, si->store);
+ type = g_type_register_static (
+ GTK_TYPE_TREE_STORE, "EMFolderTreeModel",
+ &type_info, 0);
+ }
- /* check if store needs to be added at all*/
- if (!account->enabled ||!(uri = account->source->url))
- return;
+ return type;
+}
- camel_exception_init (&ex);
- if (!(provider = camel_provider_get(uri, &ex))) {
- camel_exception_clear (&ex);
- return;
- }
+EMFolderTreeModel *
+em_folder_tree_model_new (void)
+{
+ return g_object_new (EM_TYPE_FOLDER_TREE_MODEL, NULL);
+}
- /* make sure the new store belongs in the tree */
- if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
- return;
+EMFolderTreeModel *
+em_folder_tree_model_get_default (void)
+{
+ static EMFolderTreeModel *default_folder_tree_model;
- if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
- camel_exception_clear (&ex);
- return;
- }
+ if (G_UNLIKELY (default_folder_tree_model == NULL))
+ default_folder_tree_model = em_folder_tree_model_new ();
- em_folder_tree_model_add_store (model, store, account->name);
- camel_object_unref (store);
+ return default_folder_tree_model;
}
-static void
-account_removed (EAccountList *accounts, EAccount *account, gpointer user_data)
+GtkTreeSelection *
+em_folder_tree_model_get_selection (EMFolderTreeModel *model)
{
- EMFolderTreeModel *model = user_data;
- struct _EMFolderTreeModelStoreInfo *si;
+ g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
- if (!(si = g_hash_table_lookup (model->account_hash, account)))
- return;
+ return GTK_TREE_SELECTION (model->priv->selection);
+}
- em_folder_tree_model_remove_store (model, si->store);
+void
+em_folder_tree_model_set_selection (EMFolderTreeModel *model,
+ GtkTreeSelection *selection)
+{
+ g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
+
+ if (selection != NULL)
+ g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
+
+ if (model->priv->selection != NULL) {
+ g_object_weak_unref (
+ G_OBJECT (model->priv->selection), (GWeakNotify)
+ folder_tree_model_selection_finalized_cb, model);
+ model->priv->selection = NULL;
+ }
+
+ model->priv->selection = selection;
+
+ if (model->priv->selection != NULL)
+ g_object_weak_ref (
+ G_OBJECT (model->priv->selection), (GWeakNotify)
+ folder_tree_model_selection_finalized_cb, model);
+
+ g_object_notify (G_OBJECT (model), "selection");
}
void
-em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *iter,
- struct _EMFolderTreeModelStoreInfo *si,
- CamelFolderInfo *fi, gint fully_loaded)
+em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
+ GtkTreeIter *iter,
+ EMFolderTreeModelStoreInfo *si,
+ CamelFolderInfo *fi,
+ gint fully_loaded)
{
GtkTreeRowReference *uri_row, *path_row;
GtkTreeStore *tree_store;
guint unread;
GtkTreePath *path;
GtkTreeIter sub;
- gboolean load = FALSE, is_drafts = FALSE, is_templates = FALSE;
+ gboolean load = FALSE;
+ gboolean is_drafts = FALSE;
+ gboolean is_templates = FALSE;
CamelFolder *folder;
gboolean emitted = FALSE;
const gchar *name;
@@ -461,20 +535,28 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
if (!fully_loaded)
load = fi->child == NULL && !(fi->flags & (CAMEL_FOLDER_NOCHILDREN | CAMEL_FOLDER_NOINFERIORS));
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
- uri_row = gtk_tree_row_reference_new ((GtkTreeModel *) model, path);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
+ uri_row = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), path);
path_row = gtk_tree_row_reference_copy (uri_row);
gtk_tree_path_free (path);
- g_hash_table_insert (model->uri_hash, g_strdup (fi->uri), uri_row);
- g_hash_table_insert (si->full_hash, g_strdup (fi->full_name), path_row);
+ g_hash_table_insert (
+ model->priv->uri_index, g_strdup (fi->uri), uri_row);
+ g_hash_table_insert (
+ si->full_hash, g_strdup (fi->full_name), path_row);
/* HACK: if we have the folder, and its the outbox folder, we need the total count, not unread */
/* HACK2: We do the same to the draft folder */
/* This is duplicated in mail-folder-cache too, should perhaps be functionised */
unread = fi->unread;
if (mail_note_get_folder_from_uri(fi->uri, &folder) && folder) {
- if (folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX)) {
+ CamelFolder *local_drafts;
+ CamelFolder *local_outbox;
+
+ local_drafts = e_mail_local_get_folder (E_MAIL_FOLDER_DRAFTS);
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+
+ if (folder == local_outbox) {
gint total;
if ((total = camel_folder_get_message_count (folder)) > 0) {
@@ -486,7 +568,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
unread = total > 0 ? total : 0;
}
- if (folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)) {
+ if (folder == local_drafts) {
gint total;
if ((total = camel_folder_get_message_count (folder)) > 0) {
@@ -505,7 +587,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
/* TODO: maybe this should be handled by mail_get_folderinfo (except em-folder-tree doesn't use it, duh) */
flags = fi->flags;
name = fi->name;
- if (si->store == mail_component_peek_local_store(NULL)) {
+ if (si->store == e_mail_local_get_store ()) {
if (!strcmp(fi->full_name, "Drafts")) {
name = _("Drafts");
is_drafts = TRUE;
@@ -589,7 +671,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
COL_UINT_UNREAD_LAST_SEL, 0,
-1);
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
g_signal_emit (model, signals[LOADING_ROW], 0, path, iter);
gtk_tree_path_free (path);
return;
@@ -602,7 +684,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
gtk_tree_store_append (tree_store, &sub, iter);
if (!emitted) {
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
g_signal_emit (model, signals[LOADED_ROW], 0, path, iter);
gtk_tree_path_free (path);
emitted = TRUE;
@@ -614,23 +696,26 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *ite
}
if (!emitted) {
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, iter);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
g_signal_emit (model, signals[LOADED_ROW], 0, path, iter);
gtk_tree_path_free (path);
}
}
static void
-folder_subscribed (CamelStore *store, CamelFolderInfo *fi, EMFolderTreeModel *model)
+folder_subscribed (CamelStore *store,
+ CamelFolderInfo *fi,
+ EMFolderTreeModel *model)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
GtkTreeIter parent, iter;
GtkTreePath *path;
gboolean load;
gchar *dirname, *p;
- if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
goto done;
/* make sure we don't already know about it? */
@@ -643,140 +728,159 @@ folder_subscribed (CamelStore *store, CamelFolderInfo *fi, EMFolderTreeModel *mo
p = strrchr(dirname, '/');
if (p == NULL) {
/* user subscribed to a toplevel folder */
- row = si->row;
+ reference = si->row;
} else {
*p = 0;
- row = g_hash_table_lookup (si->full_hash, dirname);
-
- /* if row is NULL, don't bother adding to the tree,
- * when the user expands enough nodes - it will be
- * added auto-magically */
- if (row == NULL)
- goto done;
+ reference = g_hash_table_lookup (si->full_hash, dirname);
}
- path = gtk_tree_row_reference_get_path (row);
- if (!(gtk_tree_model_get_iter ((GtkTreeModel *) model, &parent, path))) {
- gtk_tree_path_free (path);
+ if (!gtk_tree_row_reference_valid (reference))
goto done;
- }
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent, path);
gtk_tree_path_free (path);
/* make sure parent's subfolders have already been loaded */
- gtk_tree_model_get ((GtkTreeModel *) model, &parent, COL_BOOL_LOAD_SUBDIRS, &load, -1);
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), &parent,
+ COL_BOOL_LOAD_SUBDIRS, &load, -1);
if (load)
goto done;
/* append a new node */
- gtk_tree_store_append ((GtkTreeStore *) model, &iter, &parent);
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent);
em_folder_tree_model_set_folder_info (model, &iter, si, fi, TRUE);
g_signal_emit (model, signals[FOLDER_ADDED], 0, fi->full_name, fi->uri);
- done:
-
+done:
camel_object_unref (store);
camel_folder_info_free (fi);
}
static void
-folder_subscribed_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *model)
+folder_subscribed_cb (CamelStore *store,
+ gpointer event_data,
+ EMFolderTreeModel *model)
{
CamelFolderInfo *fi;
camel_object_ref (store);
fi = camel_folder_info_clone (event_data);
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) folder_subscribed, store, fi, model);
+
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)
+ folder_subscribed, store, fi, model);
}
static void
-folder_unsubscribed (CamelStore *store, CamelFolderInfo *fi, EMFolderTreeModel *model)
+folder_unsubscribed (CamelStore *store,
+ CamelFolderInfo *fi,
+ EMFolderTreeModel *model)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
GtkTreePath *path;
GtkTreeIter iter;
- if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
goto done;
- if (!(row = g_hash_table_lookup (si->full_hash, fi->full_name)))
+ reference = g_hash_table_lookup (si->full_hash, fi->full_name);
+ if (!gtk_tree_row_reference_valid (reference))
goto done;
- path = gtk_tree_row_reference_get_path (row);
- if (!(gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path))) {
- gtk_tree_path_free (path);
- goto done;
- }
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+ gtk_tree_path_free (path);
em_folder_tree_model_remove_folders (model, si, &iter);
- done:
-
+done:
camel_object_unref (store);
camel_folder_info_free (fi);
}
static void
-folder_unsubscribed_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *model)
+folder_unsubscribed_cb (CamelStore *store,
+ gpointer event_data,
+ EMFolderTreeModel *model)
{
CamelFolderInfo *fi;
camel_object_ref (store);
fi = camel_folder_info_clone (event_data);
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) folder_unsubscribed, store, fi, model);
+
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)
+ folder_unsubscribed, store, fi, model);
}
static void
-folder_created_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *model)
+folder_created_cb (CamelStore *store,
+ gpointer event_data,
+ EMFolderTreeModel *model)
{
CamelFolderInfo *fi;
- /* we only want created events to do more work if we don't support subscriptions */
+ /* We only want created events to do more
+ * work if we don't support subscriptions. */
if (camel_store_supports_subscriptions (store))
return;
camel_object_ref (store);
fi = camel_folder_info_clone (event_data);
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) folder_subscribed, store, fi, model);
+
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)
+ folder_subscribed, store, fi, model);
}
static void
-folder_deleted_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *model)
+folder_deleted_cb (CamelStore *store,
+ gpointer event_data,
+ EMFolderTreeModel *model)
{
CamelFolderInfo *fi;
- /* we only want deleted events to do more work if we don't support subscriptions */
+ /* We only want deleted events to do more
+ * work if we don't support subscriptions. */
if (camel_store_supports_subscriptions (store))
return;
camel_object_ref (store);
fi = camel_folder_info_clone (event_data);
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) folder_unsubscribed_cb, store, fi, model);
+
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)
+ folder_unsubscribed_cb, store, fi, model);
}
static void
-folder_renamed (CamelStore *store, CamelRenameInfo *info, EMFolderTreeModel *model)
+folder_renamed (CamelStore *store,
+ CamelRenameInfo *info,
+ EMFolderTreeModel *model)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
GtkTreeIter root, iter;
GtkTreePath *path;
gchar *parent, *p;
- if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
goto done;
- if (!(row = g_hash_table_lookup (si->full_hash, info->old_base)))
+ reference = g_hash_table_lookup (si->full_hash, info->old_base);
+ if (!gtk_tree_row_reference_valid (reference))
goto done;
- path = gtk_tree_row_reference_get_path (row);
- if (!(gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path))) {
- gtk_tree_path_free (path);
- goto done;
- }
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+ gtk_tree_path_free (path);
em_folder_tree_model_remove_folders (model, si, &iter);
@@ -784,36 +888,25 @@ folder_renamed (CamelStore *store, CamelRenameInfo *info, EMFolderTreeModel *mod
p = strrchr(parent, '/');
if (p)
*p = 0;
- if (p == NULL || parent == p) {
+ if (p == NULL || parent == p)
/* renamed to a toplevel folder on the store */
- path = gtk_tree_row_reference_get_path (si->row);
- } else {
- if (!(row = g_hash_table_lookup (si->full_hash, parent))) {
- /* NOTE: this should never happen, but I
- * suppose if it does in reality, we can add
- * code here to add the missing nodes to the
- * tree */
- g_warning ("This shouldn't be reached\n");
- g_free (parent);
- goto done;
- }
-
- path = gtk_tree_row_reference_get_path (row);
- }
+ reference = si->row;
+ else
+ reference = g_hash_table_lookup (si->full_hash, parent);
g_free (parent);
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &root, path)) {
- gtk_tree_path_free (path);
- g_warning ("This shouldn't be reached\n");
+ if (!gtk_tree_row_reference_valid (reference))
goto done;
- }
- gtk_tree_store_append ((GtkTreeStore *) model, &iter, &root);
- em_folder_tree_model_set_folder_info (model, &iter, si, info->new, TRUE);
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &root, path);
+ gtk_tree_path_free (path);
- done:
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &root);
+ em_folder_tree_model_set_folder_info (model, &iter, si, info->new, TRUE);
+done:
camel_object_unref (store);
g_free (info->old_base);
@@ -822,7 +915,9 @@ folder_renamed (CamelStore *store, CamelRenameInfo *info, EMFolderTreeModel *mod
}
static void
-folder_renamed_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *model)
+folder_renamed_cb (CamelStore *store,
+ gpointer event_data,
+ EMFolderTreeModel *model)
{
CamelRenameInfo *rinfo, *info = event_data;
@@ -832,14 +927,19 @@ folder_renamed_cb (CamelStore *store, gpointer event_data, EMFolderTreeModel *mo
rinfo->old_base = g_strdup (info->old_base);
rinfo->new = camel_folder_info_clone (info->new);
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) folder_renamed, store, rinfo, model);
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)
+ folder_renamed, store, rinfo, model);
}
void
-em_folder_tree_model_add_store (EMFolderTreeModel *model, CamelStore *store, const gchar *display_name)
+em_folder_tree_model_add_store (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *display_name)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
+ GtkTreeStore *tree_store;
GtkTreeIter root, iter;
GtkTreePath *path;
EAccount *account;
@@ -849,62 +949,77 @@ em_folder_tree_model_add_store (EMFolderTreeModel *model, CamelStore *store, con
g_return_if_fail (CAMEL_IS_STORE (store));
g_return_if_fail (display_name != NULL);
- if ((si = g_hash_table_lookup (model->store_hash, store)))
+ tree_store = GTK_TREE_STORE (model);
+
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si != NULL)
em_folder_tree_model_remove_store (model, store);
- uri = camel_url_to_string (((CamelService *) store)->url, CAMEL_URL_HIDE_ALL);
+ uri = camel_url_to_string (
+ ((CamelService *) store)->url, CAMEL_URL_HIDE_ALL);
account = mail_config_get_account_by_source_url (uri);
/* add the store to the tree */
- gtk_tree_store_append ((GtkTreeStore *) model, &iter, NULL);
- gtk_tree_store_set ((GtkTreeStore *) model, &iter,
- COL_STRING_DISPLAY_NAME, display_name,
- COL_POINTER_CAMEL_STORE, store,
- COL_STRING_FULL_NAME, NULL,
- COL_BOOL_LOAD_SUBDIRS, TRUE,
- COL_BOOL_IS_STORE, TRUE,
- COL_STRING_URI, uri, -1);
-
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, &iter);
- row = gtk_tree_row_reference_new ((GtkTreeModel *) model, path);
-
- si = g_new (struct _EMFolderTreeModelStoreInfo, 1);
+ gtk_tree_store_append (tree_store, &iter, NULL);
+ gtk_tree_store_set (
+ tree_store, &iter,
+ COL_STRING_DISPLAY_NAME, display_name,
+ COL_POINTER_CAMEL_STORE, store,
+ COL_STRING_FULL_NAME, NULL,
+ COL_BOOL_LOAD_SUBDIRS, TRUE,
+ COL_BOOL_IS_STORE, TRUE,
+ COL_STRING_URI, uri, -1);
+
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+ reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), path);
+
+ si = g_new (EMFolderTreeModelStoreInfo, 1);
si->display_name = g_strdup (display_name);
camel_object_ref (store);
si->store = store;
si->account = account;
- si->row = row;
+ si->row = gtk_tree_row_reference_copy (reference);
si->full_hash = g_hash_table_new_full (
g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) gtk_tree_row_reference_free);
- g_hash_table_insert (model->store_hash, store, si);
- g_hash_table_insert (model->account_hash, account, si);
+ g_hash_table_insert (model->priv->store_index, store, si);
+ g_hash_table_insert (model->priv->account_index, account, si);
+
+ /* Transfer ownership of the URI and GtkTreeRowReference. */
+ g_hash_table_insert (model->priv->uri_index, uri, reference);
/* each store has folders... but we don't load them until the user demands them */
root = iter;
- gtk_tree_store_append ((GtkTreeStore *) model, &iter, &root);
- gtk_tree_store_set ((GtkTreeStore *) model, &iter,
- COL_STRING_DISPLAY_NAME, _("Loading..."),
- COL_POINTER_CAMEL_STORE, NULL,
- COL_STRING_FULL_NAME, NULL,
- COL_BOOL_LOAD_SUBDIRS, FALSE,
- COL_BOOL_IS_STORE, FALSE,
- COL_STRING_URI, NULL,
- COL_UINT_UNREAD, 0,
- COL_UINT_UNREAD_LAST_SEL, 0,
- -1);
-
- g_free (uri);
+ gtk_tree_store_append (tree_store, &iter, &root);
+ gtk_tree_store_set (
+ tree_store, &iter,
+ COL_STRING_DISPLAY_NAME, _("Loading..."),
+ COL_POINTER_CAMEL_STORE, NULL,
+ COL_STRING_FULL_NAME, NULL,
+ COL_BOOL_LOAD_SUBDIRS, FALSE,
+ COL_BOOL_IS_STORE, FALSE,
+ COL_STRING_URI, NULL,
+ COL_UINT_UNREAD, 0,
+ COL_UINT_UNREAD_LAST_SEL, 0, -1);
/* listen to store events */
-#define CAMEL_CALLBACK(func) ((CamelObjectEventHookFunc) func)
- si->created_id = camel_object_hook_event (store, "folder_created", CAMEL_CALLBACK (folder_created_cb), model);
- si->deleted_id = camel_object_hook_event (store, "folder_deleted", CAMEL_CALLBACK (folder_deleted_cb), model);
- si->renamed_id = camel_object_hook_event (store, "folder_renamed", CAMEL_CALLBACK (folder_renamed_cb), model);
- si->subscribed_id = camel_object_hook_event (store, "folder_subscribed", CAMEL_CALLBACK (folder_subscribed_cb), model);
- si->unsubscribed_id = camel_object_hook_event (store, "folder_unsubscribed", CAMEL_CALLBACK (folder_unsubscribed_cb), model);
+ si->created_id = camel_object_hook_event (
+ store, "folder_created",
+ (CamelObjectEventHookFunc) folder_created_cb, model);
+ si->deleted_id = camel_object_hook_event (
+ store, "folder_deleted",
+ (CamelObjectEventHookFunc) folder_deleted_cb, model);
+ si->renamed_id = camel_object_hook_event (
+ store, "folder_renamed",
+ (CamelObjectEventHookFunc) folder_renamed_cb, model);
+ si->subscribed_id = camel_object_hook_event (
+ store, "folder_subscribed",
+ (CamelObjectEventHookFunc) folder_subscribed_cb, model);
+ si->unsubscribed_id = camel_object_hook_event (
+ store, "folder_unsubscribed",
+ (CamelObjectEventHookFunc) folder_unsubscribed_cb, model);
g_signal_emit (model, signals[LOADED_ROW], 0, path, &root);
gtk_tree_path_free (path);
@@ -916,50 +1031,55 @@ em_folder_tree_model_remove_uri (EMFolderTreeModel *model, const gchar *uri)
g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
g_return_if_fail (uri != NULL);
- g_hash_table_remove (model->uri_hash, uri);
+ g_hash_table_remove (model->priv->uri_index, uri);
}
static void
-em_folder_tree_model_remove_store_info (EMFolderTreeModel *model, CamelStore *store)
+em_folder_tree_model_remove_store_info (EMFolderTreeModel *model,
+ CamelStore *store)
{
- struct _EMFolderTreeModelStoreInfo *si;
+ EMFolderTreeModelStoreInfo *si;
g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
g_return_if_fail (CAMEL_IS_STORE (store));
- if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
return;
- g_hash_table_remove (model->account_hash, si->account);
- /* store_hash owns and frees the si structure, thus free it after done with it */
- g_hash_table_remove (model->store_hash, si->store);
+ g_hash_table_remove (model->priv->account_index, si->account);
+ g_hash_table_remove (model->priv->store_index, si->store);
}
void
-em_folder_tree_model_remove_folders (EMFolderTreeModel *model, struct _EMFolderTreeModelStoreInfo *si, GtkTreeIter *toplevel)
+em_folder_tree_model_remove_folders (EMFolderTreeModel *model,
+ EMFolderTreeModelStoreInfo *si,
+ GtkTreeIter *toplevel)
{
gchar *uri, *full_name;
gboolean is_store, go;
GtkTreeIter iter;
- if (gtk_tree_model_iter_children ((GtkTreeModel *) model, &iter, toplevel)) {
+ if (gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, toplevel)) {
do {
GtkTreeIter next = iter;
- go = gtk_tree_model_iter_next ((GtkTreeModel *) model, &next);
+ go = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &next);
em_folder_tree_model_remove_folders (model, si, &iter);
iter = next;
} while (go);
}
- gtk_tree_model_get ((GtkTreeModel *) model, toplevel, COL_STRING_URI, &uri,
- COL_STRING_FULL_NAME, &full_name,
- COL_BOOL_IS_STORE, &is_store, -1);
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), toplevel,
+ COL_STRING_URI, &uri,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_BOOL_IS_STORE, &is_store, -1);
- if (full_name)
+ if (full_name != NULL)
g_hash_table_remove (si->full_hash, full_name);
- if (uri)
+ if (uri != NULL)
em_folder_tree_model_remove_uri (model, uri);
gtk_tree_store_remove ((GtkTreeStore *) model, toplevel);
@@ -972,298 +1092,36 @@ em_folder_tree_model_remove_folders (EMFolderTreeModel *model, struct _EMFolderT
}
void
-em_folder_tree_model_remove_store (EMFolderTreeModel *model, CamelStore *store)
+em_folder_tree_model_remove_store (EMFolderTreeModel *model,
+ CamelStore *store)
{
- struct _EMFolderTreeModelStoreInfo *si;
+ EMFolderTreeModelStoreInfo *si;
GtkTreePath *path;
GtkTreeIter iter;
g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
g_return_if_fail (CAMEL_IS_STORE (store));
- if (!(si = g_hash_table_lookup (model->store_hash, store)))
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
return;
path = gtk_tree_row_reference_get_path (si->row);
- gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, path);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
gtk_tree_path_free (path);
/* recursively remove subfolders and finally the toplevel store */
em_folder_tree_model_remove_folders (model, si, &iter);
}
-static xmlNodePtr
-find_xml_node (xmlNodePtr root, const gchar *name)
-{
- xmlNodePtr node;
- gchar *nname;
-
- node = root->children;
- while (node != NULL) {
- if (!strcmp ((gchar *)node->name, "node")) {
- nname = (gchar *)xmlGetProp (node, (const guchar *)"name");
- if (nname && !strcmp (nname, name)) {
- xmlFree (nname);
- return node;
- }
-
- xmlFree (nname);
- }
-
- node = node->next;
- }
-
- return node;
-}
-
gboolean
-em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const gchar *key)
+em_folder_tree_model_is_type_inbox (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *full)
{
- xmlNodePtr node;
- const gchar *name;
- gchar *buf, *p;
-
- /* This code needs to be rewritten.
- First it doesn't belong on the model
- Second, it shouldn't use an xml tree to store a bit table in memory! */
-
- node = model->state ? model->state->children : NULL;
- if (!node || strcmp ((gchar *)node->name, "tree-state") != 0)
- return FALSE;
-
- name = buf = g_alloca (strlen (key) + 1);
- p = g_stpcpy (buf, key);
- if (p[-1] == '/')
- p[-1] = '\0';
- p = NULL;
-
- do {
- if ((p = strchr (name, '/')))
- *p = '\0';
-
- if ((node = find_xml_node (node, name))) {
- gboolean expanded;
-
- buf = (gchar *)xmlGetProp (node, (const guchar *)"expand");
- expanded = buf && !strcmp ((gchar *)buf, "true");
- xmlFree (buf);
-
- if (!expanded || p == NULL)
- return expanded;
- }
-
- name = p ? p + 1 : NULL;
- } while (name && node);
-
- return FALSE;
-}
-
-void
-em_folder_tree_model_set_expanded (EMFolderTreeModel *model, const gchar *key, gboolean expanded)
-{
- xmlNodePtr node, parent;
- const gchar *name;
- gchar *buf, *p;
-
- if (model->state == NULL)
- model->state = xmlNewDoc ((const guchar *)"1.0");
-
- if (!model->state->children) {
- node = xmlNewDocNode (model->state, NULL, (const guchar *)"tree-state", NULL);
- xmlDocSetRootElement (model->state, node);
- } else {
- node = model->state->children;
- }
-
- name = buf = g_alloca (strlen (key) + 1);
- p = g_stpcpy (buf, key);
- if (p[-1] == '/')
- p[-1] = '\0';
- p = NULL;
-
- do {
- parent = node;
- if ((p = strchr (name, '/')))
- *p = '\0';
-
- if (!(node = find_xml_node (node, name))) {
- if (!expanded) {
- /* node doesn't exist, so we don't need to set expanded to FALSE */
- return;
- }
-
- /* node (or parent node) doesn't exist, need to add it */
- node = xmlNewChild (parent, NULL, (const guchar *)"node", NULL);
- xmlSetProp (node, (const guchar *)"name", (guchar *)name);
- }
-
- xmlSetProp (node, (const guchar *)"expand", (const guchar *)(expanded || p ? "true" : "false"));
-
- name = p ? p + 1 : NULL;
- } while (name);
-}
-
-/**
- * emftm_uri_to_key
- * Converts uri to key used in functions like em_folder_tree_model_[s/g]et_expanded.
- * @param uri Uri to be converted.
- * @return Key of the uri or NULL, if failed. Returned value should be clear by g_free.
- **/
-static gchar *
-emftm_uri_to_key (const gchar *uri)
-{
- CamelException ex = { 0 };
- CamelStore *store;
- CamelURL *url;
- gchar *key;
-
- if (!uri)
- return NULL;
-
- store = (CamelStore *)camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex);
- camel_exception_clear(&ex);
-
- url = camel_url_new (uri, NULL);
-
- if (store == NULL || url == NULL) {
- key = NULL;
- } else {
- const gchar *path;
- EAccount *account;
-
- if (((CamelService *)store)->provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH)
- path = url->fragment;
- else
- path = url->path && url->path[0]=='/' ? url->path+1:url->path;
-
- if (path == NULL)
- path = "";
-
- if ( (account = mail_config_get_account_by_source_url (uri)) )
- key = g_strdup_printf ("%s/%s", account->uid, path);
- else if (CAMEL_IS_VEE_STORE (store))
- key = g_strdup_printf ("vfolder/%s", path);
- else
- key = g_strdup_printf ("local/%s", path);
- }
-
- if (url)
- camel_url_free (url);
-
- if (store)
- camel_object_unref (store);
-
- return key;
-}
-
-/**
- * em_folder_tree_model_get_expanded_uri
- * Same as @ref em_folder_tree_model_get_expanded, but here we use uri, not key for node.
- **/
-gboolean
-em_folder_tree_model_get_expanded_uri (EMFolderTreeModel *model, const gchar *uri)
-{
- gchar *key;
- gboolean expanded;
-
- g_return_val_if_fail (model != NULL, FALSE);
- g_return_val_if_fail (uri != NULL, FALSE);
-
- key = emftm_uri_to_key (uri);
- expanded = key && em_folder_tree_model_get_expanded (model, key);
-
- g_free (key);
-
- return expanded;
-}
-
-/**
- * em_folder_tree_model_set_expanded_uri
- * Same as @ref em_folder_tree_model_set_expanded, but here we use uri, not key for node.
- **/
-void
-em_folder_tree_model_set_expanded_uri (EMFolderTreeModel *model, const gchar *uri, gboolean expanded)
-{
- gchar *key;
-
- g_return_if_fail (model != NULL);
- g_return_if_fail (uri != NULL);
-
- key = emftm_uri_to_key (uri);
- if (key)
- em_folder_tree_model_set_expanded (model, key, expanded);
-
- g_free (key);
-}
-
-void
-em_folder_tree_model_save_state (EMFolderTreeModel *model)
-{
- gchar *dirname;
-
- if (model->state == NULL)
- return;
-
- dirname = g_path_get_dirname (model->filename);
- if (g_mkdir_with_parents (dirname, 0777) == -1 && errno != EEXIST) {
- g_free (dirname);
- return;
- }
-
- g_free (dirname);
-
- e_xml_save_file (model->filename, model->state);
-}
-
-static void
-expand_foreach_r (EMFolderTreeModel *model, xmlNodePtr parent, const gchar *dirname, EMFTModelExpandFunc func, gpointer user_data)
-{
- xmlNodePtr node = parent->children;
- gchar *path, *name, *expand;
-
- while (node != NULL) {
- if (!strcmp ((gchar *)node->name, "node")) {
- name = (gchar *)xmlGetProp (node, (const guchar *)"name");
- expand = (gchar *)xmlGetProp (node, (const guchar *)"expand");
-
- if (expand && name && !strcmp ((gchar *)expand, "true")) {
- if (dirname)
- path = g_strdup_printf ("%s/%s", dirname, name);
- else
- path = g_strdup (name);
-
- func (model, path, user_data);
- if (node->children)
- expand_foreach_r (model, node, path, func, user_data);
- g_free (path);
- }
-
- xmlFree (expand);
- xmlFree (name);
- }
-
- node = node->next;
- }
-}
-
-void
-em_folder_tree_model_expand_foreach (EMFolderTreeModel *model, EMFTModelExpandFunc func, gpointer user_data)
-{
- xmlNodePtr root;
-
- root = model->state ? model->state->children : NULL;
- if (!root || !root->children || strcmp ((gchar *)root->name, "tree-state") != 0)
- return;
-
- expand_foreach_r (model, root, NULL, func, user_data);
-}
-
-gboolean
-em_folder_tree_model_is_type_inbox (EMFolderTreeModel *model, CamelStore *store, const gchar *full)
-{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
- GtkTreePath *tree_path;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
+ GtkTreePath *path;
GtkTreeIter iter;
guint32 flags;
@@ -1271,40 +1129,33 @@ em_folder_tree_model_is_type_inbox (EMFolderTreeModel *model, CamelStore *store,
g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
g_return_val_if_fail (full != NULL, FALSE);
- u(printf("Checking if the folder is an INBOX type %p '%s' %d\n", store, full, unread));
-
- if (!(si = g_hash_table_lookup (model->store_hash, store))) {
- u(printf(" can't find store\n"));
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
return FALSE;
- }
-
- if (!(row = g_hash_table_lookup (si->full_hash, full))) {
- u(printf(" can't find row\n"));
- return FALSE;
- }
- tree_path = gtk_tree_row_reference_get_path (row);
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, tree_path)) {
- gtk_tree_path_free (tree_path);
+ reference = g_hash_table_lookup (si->full_hash, full);
+ if (!gtk_tree_row_reference_valid (reference))
return FALSE;
- }
-
- gtk_tree_path_free (tree_path);
- gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, COL_UINT_FLAGS, &flags, -1);
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+ gtk_tree_path_free (path);
- if ((flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX)
- return TRUE;
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), &iter,
+ COL_UINT_FLAGS, &flags, -1);
- return FALSE;
+ return ((flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX);
}
gchar *
-em_folder_tree_model_get_folder_name (EMFolderTreeModel *model, CamelStore *store, const gchar *full)
+em_folder_tree_model_get_folder_name (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *full)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
- GtkTreePath *tree_path;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
+ GtkTreePath *path;
GtkTreeIter iter;
gchar *name = NULL;
@@ -1312,140 +1163,100 @@ em_folder_tree_model_get_folder_name (EMFolderTreeModel *model, CamelStore *stor
g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
g_return_val_if_fail (full != NULL, FALSE);
- if (!(si = g_hash_table_lookup (model->store_hash, store))) {
- u(printf(" can't find store\n"));
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
return NULL;
- }
- if (!(row = g_hash_table_lookup (si->full_hash, full))) {
- u(printf(" can't find row\n"));
+ reference = g_hash_table_lookup (si->full_hash, full);
+ if (!gtk_tree_row_reference_valid (reference))
return NULL;
- }
-
- tree_path = gtk_tree_row_reference_get_path (row);
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, tree_path)) {
- gtk_tree_path_free (tree_path);
- return NULL;
- }
- gtk_tree_path_free (tree_path);
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
+ gtk_tree_path_free (path);
- gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, COL_STRING_DISPLAY_NAME, &name, -1);
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), &iter,
+ COL_STRING_DISPLAY_NAME, &name, -1);
return name;
}
void
-em_folder_tree_model_set_unread_count (EMFolderTreeModel *model, CamelStore *store, const gchar *full, gint unread)
+em_folder_tree_model_set_unread_count (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *full,
+ gint unread)
{
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeRowReference *row;
- GtkTreePath *tree_path;
+ EMFolderTreeModelStoreInfo *si;
+ GtkTreeRowReference *reference;
+ GtkTreeModel *tree_model;
+ GtkTreePath *path;
+ GtkTreeIter parent;
GtkTreeIter iter;
guint old_unread = 0;
- gchar *uri, *sel_uri;
g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model));
g_return_if_fail (CAMEL_IS_STORE (store));
g_return_if_fail (full != NULL);
- u(printf("set unread count %p '%s' %d\n", store, full, unread));
-
if (unread < 0)
return;
- if (!(si = g_hash_table_lookup (model->store_hash, store))) {
- u(printf(" can't find store\n"));
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if (si == NULL)
return;
- }
- if (!(row = g_hash_table_lookup (si->full_hash, full))) {
- u(printf(" can't find row\n"));
+ reference = g_hash_table_lookup (si->full_hash, full);
+ if (!gtk_tree_row_reference_valid (reference))
return;
- }
- tree_path = gtk_tree_row_reference_get_path (row);
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, tree_path)) {
- gtk_tree_path_free (tree_path);
- return;
- }
+ tree_model = GTK_TREE_MODEL (model);
- gtk_tree_path_free (tree_path);
+ path = gtk_tree_row_reference_get_path (reference);
+ gtk_tree_model_get_iter (tree_model, &iter, path);
+ gtk_tree_path_free (path);
- sel_uri = em_folder_tree_model_get_selected (model);
gtk_tree_model_get (
- GTK_TREE_MODEL (model), &iter,
- COL_UINT_UNREAD_LAST_SEL, &old_unread,
- COL_STRING_URI, &uri, -1);
- if (!(g_strcmp0 (sel_uri, uri) != 0 && unread > old_unread))
- old_unread = unread;
+ tree_model, &iter,
+ COL_UINT_UNREAD_LAST_SEL, &old_unread, -1);
+
gtk_tree_store_set (
GTK_TREE_STORE (model), &iter,
COL_UINT_UNREAD, unread,
- COL_UINT_UNREAD_LAST_SEL, old_unread, -1);
-
- g_free (uri);
- g_free (sel_uri);
+ COL_UINT_UNREAD_LAST_SEL, MIN (old_unread, unread), -1);
- /* May be this is from where we should propagate unread count to parents etc. */
- emft_model_unread_count_changed (GTK_TREE_MODEL (model), &iter);
+ /* Folders are displayed with a bold weight to indicate that
+ * they contain unread messages. We signal that parent rows
+ * have changed here to update them. */
+ while (gtk_tree_model_iter_parent (tree_model, &parent, &iter)) {
+ path = gtk_tree_model_get_path (tree_model, &parent);
+ gtk_tree_model_row_changed (tree_model, path, &parent);
+ gtk_tree_path_free (path);
+ iter = parent;
+ }
}
-gchar *
-em_folder_tree_model_get_selected (EMFolderTreeModel *model)
+EMFolderTreeModelStoreInfo *
+em_folder_tree_model_lookup_store_info (EMFolderTreeModel *model,
+ CamelStore *store)
{
- xmlNodePtr node;
- gchar *buf, *uri;
-
- node = model->state ? model->state->children : NULL;
- if (!node || strcmp ((gchar *)node->name, "tree-state") != 0)
- return NULL;
-
- node = node->children;
- while (node != NULL) {
- if (!strcmp ((gchar *)node->name, "selected"))
- break;
- node = node->next;
- }
+ g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
- if (node == NULL)
- return NULL;
-
- buf = (gchar *)xmlGetProp (node, (guchar *)"uri");
- uri = g_strdup (buf);
- xmlFree (buf);
-
- if (uri && !*uri) {
- g_free (uri);
- return NULL;
- }
- return uri;
+ return g_hash_table_lookup (model->priv->store_index, store);
}
-void
-em_folder_tree_model_set_selected (EMFolderTreeModel *model, const gchar *uri)
+GtkTreeRowReference *
+em_folder_tree_model_lookup_uri (EMFolderTreeModel *model,
+ const gchar *uri)
{
- xmlNodePtr root, node;
+ GtkTreeRowReference *reference;
- if (model->state == NULL)
- model->state = xmlNewDoc ((guchar *)"1.0");
-
- if (!model->state->children) {
- root = xmlNewDocNode (model->state, NULL, (const guchar *)"tree-state", NULL);
- xmlDocSetRootElement (model->state, root);
- } else {
- root = model->state->children;
- }
-
- node = root->children;
- while (node != NULL) {
- if (!strcmp ((gchar *)node->name, "selected"))
- break;
- node = node->next;
- }
+ g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
- if (node == NULL)
- node = xmlNewChild (root, NULL, (const guchar *)"selected", NULL);
+ reference = g_hash_table_lookup (model->priv->uri_index, uri);
- xmlSetProp (node, (const guchar *)"uri", (guchar *)uri);
+ return gtk_tree_row_reference_valid (reference) ? reference : NULL;
}
diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h
index f0bf091eb1..d75e57c0b4 100644
--- a/mail/em-folder-tree-model.h
+++ b/mail/em-folder-tree-model.h
@@ -20,28 +20,37 @@
*
*/
-#ifndef __EM_FOLDER_TREE_MODEL_H__
-#define __EM_FOLDER_TREE_MODEL_H__
+#ifndef EM_FOLDER_TREE_MODEL_H
+#define EM_FOLDER_TREE_MODEL_H
#include <gtk/gtk.h>
-
-#include <libxml/tree.h>
-
#include <camel/camel-store.h>
-
#include <libedataserver/e-account-list.h>
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define EM_TYPE_FOLDER_TREE_MODEL \
+ (em_folder_tree_model_get_type ())
+#define EM_FOLDER_TREE_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModel))
+#define EM_FOLDER_TREE_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModelClass))
+#define EM_IS_FOLDER_TREE_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_FOLDER_TREE_MODEL))
+#define EM_IS_FOLDER_TREE_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_FOLDER_TREE_MODEL))
+#define EM_FOLDER_TREE_MODEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModelClass))
-#define EM_TYPE_FOLDER_TREE_MODEL (em_folder_tree_model_get_type ())
-#define EM_FOLDER_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModel))
-#define EM_FOLDER_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModelClass))
-#define EM_IS_FOLDER_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_TYPE_FOLDER_TREE_MODEL))
-#define EM_IS_FOLDER_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EM_TYPE_FOLDER_TREE_MODEL))
-#define EM_FOLDER_TREE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EM_TYPE_FOLDER_TREE_MODEL, EMFolderTreeModelClass))
+G_BEGIN_DECLS
typedef struct _EMFolderTreeModel EMFolderTreeModel;
typedef struct _EMFolderTreeModelClass EMFolderTreeModelClass;
+typedef struct _EMFolderTreeModelPrivate EMFolderTreeModelPrivate;
typedef struct _EMFolderTreeModelStoreInfo EMFolderTreeModelStoreInfo;
enum {
@@ -78,71 +87,77 @@ struct _EMFolderTreeModelStoreInfo {
};
struct _EMFolderTreeModel {
- GtkTreeStore parent_object;
-
- gchar *filename; /* state filename */
- xmlDocPtr state; /* saved expanded state from previous session */
-
- GHashTable *store_hash; /* maps CamelStore's to store-info's */
- GHashTable *uri_hash; /* maps URI's to GtkTreeRowReferences */
-
- EAccountList *accounts;
- GHashTable *account_hash; /* maps accounts to store-info's */
- gulong account_changed_id;
- gulong account_removed_id;
+ GtkTreeStore parent;
+ EMFolderTreeModelPrivate *priv;
};
struct _EMFolderTreeModelClass {
GtkTreeStoreClass parent_class;
/* signals */
- void (* loading_row) (EMFolderTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter);
-
- void (* loaded_row) (EMFolderTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter);
+ void (*loading_row) (EMFolderTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter);
- void (* folder_added) (EMFolderTreeModel *model,
- const gchar *path,
- const gchar *uri);
+ void (*loaded_row) (EMFolderTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter);
- void (* store_added) (EMFolderTreeModel *model,
- const gchar *uri);
+ void (*folder_added) (EMFolderTreeModel *model,
+ const gchar *path,
+ const gchar *uri);
};
-GType em_folder_tree_model_get_type (void);
-
-EMFolderTreeModel *em_folder_tree_model_new (const gchar *evolution_dir);
-
-void em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, GtkTreeIter *iter,
- struct _EMFolderTreeModelStoreInfo *si,
- CamelFolderInfo *fi, gint fully_loaded);
-
-void em_folder_tree_model_add_store (EMFolderTreeModel *model, CamelStore *store, const gchar *display_name);
-void em_folder_tree_model_remove_store (EMFolderTreeModel *model, CamelStore *store);
-void em_folder_tree_model_remove_folders (EMFolderTreeModel *model, struct _EMFolderTreeModelStoreInfo *si,
- GtkTreeIter *toplevel);
-
-gchar *em_folder_tree_model_get_selected (EMFolderTreeModel *model);
-void em_folder_tree_model_set_selected (EMFolderTreeModel *model, const gchar *uri);
-
-gboolean em_folder_tree_model_get_expanded (EMFolderTreeModel *model, const gchar *key);
-void em_folder_tree_model_set_expanded (EMFolderTreeModel *model, const gchar *key, gboolean expanded);
-
-gboolean em_folder_tree_model_get_expanded_uri (EMFolderTreeModel *model, const gchar *uri);
-void em_folder_tree_model_set_expanded_uri (EMFolderTreeModel *model, const gchar *uri, gboolean expanded);
-
-void em_folder_tree_model_save_state (EMFolderTreeModel *model);
-
-typedef void (* EMFTModelExpandFunc) (EMFolderTreeModel *model, const gchar *path, gpointer user_data);
-void em_folder_tree_model_expand_foreach (EMFolderTreeModel *model, EMFTModelExpandFunc func, gpointer user_data);
-
-void em_folder_tree_model_set_unread_count (EMFolderTreeModel *model, CamelStore *store, const gchar *path, gint unread);
-gboolean em_folder_tree_model_is_type_inbox (EMFolderTreeModel *model, CamelStore *store, const gchar *full);
-gchar * em_folder_tree_model_get_folder_name (EMFolderTreeModel *model, CamelStore *store, const gchar *full);
+GType em_folder_tree_model_get_type (void);
+EMFolderTreeModel *
+ em_folder_tree_model_new (void);
+EMFolderTreeModel *
+ em_folder_tree_model_get_default(void);
+GtkTreeSelection *
+ em_folder_tree_model_get_selection
+ (EMFolderTreeModel *model);
+void em_folder_tree_model_set_selection
+ (EMFolderTreeModel *model,
+ GtkTreeSelection *selection);
+void em_folder_tree_model_set_folder_info
+ (EMFolderTreeModel *model,
+ GtkTreeIter *iter,
+ EMFolderTreeModelStoreInfo *si,
+ CamelFolderInfo *fi,
+ gint fully_loaded);
+void em_folder_tree_model_add_store
+ (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *display_name);
+void em_folder_tree_model_remove_store
+ (EMFolderTreeModel *model,
+ CamelStore *store);
+void em_folder_tree_model_remove_folders
+ (EMFolderTreeModel *model,
+ EMFolderTreeModelStoreInfo *si,
+ GtkTreeIter *toplevel);
+void em_folder_tree_model_set_unread_count
+ (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *path,
+ gint unread);
+gboolean em_folder_tree_model_is_type_inbox
+ (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *full);
+gchar * em_folder_tree_model_get_folder_name
+ (EMFolderTreeModel *model,
+ CamelStore *store,
+ const gchar *full);
+EMFolderTreeModelStoreInfo *
+ em_folder_tree_model_lookup_store_info
+ (EMFolderTreeModel *model,
+ CamelStore *store);
+GtkTreeRowReference *
+ em_folder_tree_model_lookup_uri
+ (EMFolderTreeModel *model,
+ const gchar *uri);
G_END_DECLS
-#endif /* __EM_FOLDER_TREE_MODEL_H__ */
+#endif /* EM_FOLDER_TREE_MODEL_H */
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index cf9fb8a4e0..f298d19629 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -48,6 +48,7 @@
#include <camel/camel-file-utils.h>
#include <camel/camel-stream-fs.h>
+#include "e-util/e-account-utils.h"
#include "e-util/e-mktemp.h"
#include "e-util/e-request.h"
#include "e-util/e-icon-factory.h"
@@ -60,7 +61,6 @@
#include "mail-ops.h"
#include "mail-tools.h"
#include "mail-config.h"
-#include "mail-component.h"
#include "mail-send-recv.h"
#include "mail-vfolder.h"
@@ -73,8 +73,14 @@
#include "em-folder-properties.h"
#include "em-event.h"
+#include "e-mail-local.h"
+
#define d(x)
+#define EM_FOLDER_TREE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FOLDER_TREE, EMFolderTreePrivate))
+
struct _selected_uri {
gchar *key; /* store:path or account/path */
gchar *uri;
@@ -83,9 +89,6 @@ struct _selected_uri {
};
struct _EMFolderTreePrivate {
- GtkTreeView *treeview;
- EMFolderTreeModel *model;
-
GSList *select_uris; /* selected_uri structures of each path pending selection. */
GHashTable *select_uris_table; /*Removed as they're encountered, so use this to find uri's not presnet but selected */
@@ -93,14 +96,11 @@ struct _EMFolderTreePrivate {
gboolean (*excluded_func)(EMFolderTree *emft, GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
gpointer excluded_data;
- guint do_multiselect:1; /* multiple select mode */
guint cursor_set:1; /* set to TRUE means we or something
* else has set the cursor, otherwise
* we need to set it when we set the
* selection */
- guint save_state_id;
-
guint autoscroll_id;
guint autoexpand_id;
GtkTreeRowReference *autoexpand_row;
@@ -115,7 +115,7 @@ struct _EMFolderTreePrivate {
enum {
FOLDER_ACTIVATED, /* aka double-clicked or user hit enter */
FOLDER_SELECTED,
- HIDDEN_KEY_EVENT,
+ POPUP_EVENT,
LAST_SIGNAL
};
@@ -154,101 +154,613 @@ static guint signals[LAST_SIGNAL] = { 0 };
extern CamelSession *session;
extern CamelStore *vfolder_store;
-static void em_folder_tree_class_init (EMFolderTreeClass *klass);
-static void em_folder_tree_init (EMFolderTree *emft);
-static void em_folder_tree_destroy (GtkObject *obj);
-static void em_folder_tree_finalize (GObject *obj);
+struct _emft_selection_data {
+ GtkTreeModel *model;
+ GtkTreeIter *iter;
+ gboolean set;
+};
-static gboolean emft_save_state (EMFolderTree *emft);
-static void emft_queue_save_state (EMFolderTree *emft);
+static gpointer parent_class = NULL;
+
+struct _EMFolderTreeGetFolderInfo {
+ MailMsg base;
+
+ /* input data */
+ GtkTreeRowReference *root;
+ EMFolderTree *emft;
+ CamelStore *store;
+ guint32 flags;
+ gchar *top;
-static void emft_update_model_expanded_state (struct _EMFolderTreePrivate *priv, GtkTreeIter *iter, gboolean expanded);
+ /* output data */
+ CamelFolderInfo *fi;
+};
-static void emft_tree_row_activated (GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, EMFolderTree *emft);
-static gboolean emft_tree_test_collapse_row (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *path, EMFolderTree *emft);
-static void emft_tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *path, EMFolderTree *emft);
-static gboolean emft_tree_button_press (GtkTreeView *treeview, GdkEventButton *event, EMFolderTree *emft);
-static void emft_tree_selection_changed (GtkTreeSelection *selection, EMFolderTree *emft);
-static gboolean emft_tree_user_event (GtkTreeView *treeview, GdkEvent *e, EMFolderTree *emft);
-static gboolean emft_popup_menu (GtkWidget *widget);
+static gchar *
+emft_get_folder_info__desc (struct _EMFolderTreeGetFolderInfo *m)
+{
+ gchar *ret, *name;
-struct _emft_selection_data {
+ name = camel_service_get_name((CamelService *)m->store, TRUE);
+ ret = g_strdup_printf(_("Scanning folders in \"%s\""), name);
+ g_free(name);
+ return ret;
+}
+
+static void
+emft_get_folder_info__exec (struct _EMFolderTreeGetFolderInfo *m)
+{
+ guint32 flags = m->flags | CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
+
+ m->fi = camel_store_get_folder_info (m->store, m->top, flags, &m->base.ex);
+}
+
+static void
+emft_get_folder_info__done (struct _EMFolderTreeGetFolderInfo *m)
+{
+ struct _EMFolderTreeModelStoreInfo *si;
+ GtkTreeIter root, iter, titer;
+ CamelFolderInfo *fi;
+ GtkTreeView *tree_view;
GtkTreeModel *model;
- GtkTreeIter *iter;
- gboolean set;
+ GtkTreePath *path;
+ gboolean is_store;
+
+ /* check that we haven't been destroyed */
+ g_return_if_fail (GTK_IS_TREE_VIEW (m->emft));
+
+ /* check that our parent folder hasn't been deleted/unsubscribed */
+ if (!gtk_tree_row_reference_valid (m->root))
+ return;
+
+ tree_view = GTK_TREE_VIEW (m->emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ si = em_folder_tree_model_lookup_store_info (
+ EM_FOLDER_TREE_MODEL (model), m->store);
+ if (si == NULL) {
+ /* store has been removed in the interim - do nothing */
+ return;
+ }
+
+ path = gtk_tree_row_reference_get_path (m->root);
+ gtk_tree_model_get_iter (model, &root, path);
+
+ /* if we had an error, then we need to re-set the load subdirs state and collapse the node */
+ if (!m->fi && camel_exception_is_set(&m->base.ex)) {
+ gtk_tree_store_set(
+ GTK_TREE_STORE (model), &root,
+ COL_BOOL_LOAD_SUBDIRS, TRUE, -1);
+ gtk_tree_view_collapse_row (tree_view, path);
+ gtk_tree_path_free (path);
+ return;
+ }
+
+ gtk_tree_path_free (path);
+
+ /* make sure we still need to load the tree subfolders... */
+ gtk_tree_model_get (model, &root, COL_BOOL_IS_STORE, &is_store, -1);
+
+ /* get the first child (which will be a dummy node) */
+ gtk_tree_model_iter_children (model, &iter, &root);
+
+ /* Traverse to the last valid iter */
+ titer = iter;
+ while (gtk_tree_model_iter_next (model, &iter))
+ titer = iter; /* Preserve the last valid iter */
+
+ iter = titer;
+
+ /* FIXME: camel's IMAP code is totally on crack here, @top's
+ * folder info should be @fi and fi->child should be what we
+ * want to fill our tree with... *sigh* */
+ if (m->top && m->fi && !strcmp (m->fi->full_name, m->top)) {
+ if (!(fi = m->fi->child))
+ fi = m->fi->next;
+ } else
+ fi = m->fi;
+
+ if (fi == NULL) {
+ /* no children afterall... remove the "Loading..." placeholder node */
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+
+ if (is_store) {
+ path = gtk_tree_model_get_path (model, &root);
+ gtk_tree_view_collapse_row (tree_view, path);
+ gtk_tree_path_free (path);
+ return;
+ }
+ } else {
+ gint fully_loaded = (m->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? TRUE : FALSE;
+
+ do {
+ gboolean known = g_hash_table_lookup (si->full_hash, fi->full_name) != NULL;
+
+ if (!known)
+ em_folder_tree_model_set_folder_info (
+ EM_FOLDER_TREE_MODEL (model),
+ &iter, si, fi, fully_loaded);
+
+ if ((fi = fi->next) != NULL && !known)
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &root);
+ } while (fi != NULL);
+ }
+
+ gtk_tree_store_set (
+ GTK_TREE_STORE (model), &root,
+ COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
+}
+
+static void
+emft_get_folder_info__free (struct _EMFolderTreeGetFolderInfo *m)
+{
+ camel_store_free_folder_info (m->store, m->fi);
+
+ gtk_tree_row_reference_free (m->root);
+ g_object_unref(m->emft);
+ camel_object_unref (m->store);
+ g_free (m->top);
+}
+
+static MailMsgInfo get_folder_info_info = {
+ sizeof (struct _EMFolderTreeGetFolderInfo),
+ (MailMsgDescFunc) emft_get_folder_info__desc,
+ (MailMsgExecFunc) emft_get_folder_info__exec,
+ (MailMsgDoneFunc) emft_get_folder_info__done,
+ (MailMsgFreeFunc) emft_get_folder_info__free
};
-static GtkVBoxClass *parent_class = NULL;
+static void
+folder_tree_emit_popup_event (EMFolderTree *emft,
+ GdkEvent *event)
+{
+ g_signal_emit (emft, signals[POPUP_EVENT], 0, event);
+}
+
+static void
+emft_free_select_uri (struct _selected_uri *u)
+{
+ g_free (u->uri);
+ if (u->store)
+ camel_object_unref (u->store);
+ g_free (u->key);
+ g_free (u->path);
+ g_free (u);
+}
-GType
-em_folder_tree_get_type (void)
+static gboolean
+emft_select_func (GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gboolean selected)
{
- static GType type = 0;
+ EMFolderTreePrivate *priv;
+ GtkTreeView *tree_view;
+ gboolean is_store;
+ guint32 flags;
+ GtkTreeIter iter;
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMFolderTreeClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_folder_tree_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EMFolderTree),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_folder_tree_init,
- };
+ tree_view = gtk_tree_selection_get_tree_view (selection);
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (tree_view);
+
+ if (selected)
+ return TRUE;
+
+ if (priv->excluded == 0 && priv->excluded_func == NULL)
+ return TRUE;
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ return TRUE;
+
+ if (priv->excluded_func != NULL)
+ return priv->excluded_func(
+ EM_FOLDER_TREE (tree_view), model,
+ &iter, priv->excluded_data);
+
+ gtk_tree_model_get (
+ model, &iter, COL_UINT_FLAGS, &flags,
+ COL_BOOL_IS_STORE, &is_store, -1);
+
+ if (is_store)
+ flags |= CAMEL_FOLDER_NOSELECT;
+
+ return (flags & priv->excluded) == 0;
+}
+
+static void
+emft_clear_selected_list(EMFolderTree *emft)
+{
+ EMFolderTreePrivate *priv = emft->priv;
+
+ g_slist_foreach(priv->select_uris, (GFunc) emft_free_select_uri, NULL);
+ g_slist_free(priv->select_uris);
+ g_hash_table_destroy(priv->select_uris_table);
+ priv->select_uris = NULL;
+ priv->select_uris_table = g_hash_table_new(g_str_hash, g_str_equal);
+ priv->cursor_set = FALSE;
+}
+
+static void
+emft_selection_changed_cb (EMFolderTree *emft,
+ GtkTreeSelection *selection)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GList *list;
+ guint32 flags = 0;
+ guint unread = 0;
+ guint old_unread = 0;
+ gchar *full_name = NULL;
+ gchar *uri = NULL;
+
+ list = gtk_tree_selection_get_selected_rows (selection, &model);
+
+ if (list == NULL)
+ goto exit;
+
+ gtk_tree_model_get_iter (model, &iter, list->data);
+
+ gtk_tree_model_get (
+ model, &iter,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags,
+ COL_UINT_UNREAD, &unread, COL_UINT_UNREAD_LAST_SEL,
+ &old_unread, -1);
+
+ /* Sync unread counts to distinguish new incoming mail. */
+ if (unread != old_unread)
+ gtk_tree_store_set (
+ GTK_TREE_STORE (model), &iter,
+ COL_UINT_UNREAD_LAST_SEL, unread, -1);
- type = g_type_register_static (GTK_TYPE_VBOX, "EMFolderTree", &info, 0);
+exit:
+ g_signal_emit (
+ emft, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
+
+ g_free (full_name);
+ g_free (uri);
+
+ g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (list);
+}
+
+static void
+folder_tree_finalize (GObject *object)
+{
+ EMFolderTreePrivate *priv;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (object);
+
+ if (priv->select_uris != NULL) {
+ g_slist_foreach (
+ priv->select_uris,
+ (GFunc) emft_free_select_uri, NULL);
+ g_slist_free (priv->select_uris);
+ g_hash_table_destroy (priv->select_uris_table);
+ priv->select_uris = NULL;
}
- return type;
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-em_folder_tree_class_init (EMFolderTreeClass *klass)
+em_folder_tree_destroy (GtkObject *object)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ EMFolderTreePrivate *priv;
+ GtkTreeModel *model;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (object);
- parent_class = g_type_class_ref (GTK_TYPE_VBOX);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (object));
+
+ if (priv->loaded_row_id != 0) {
+ g_signal_handler_disconnect (model, priv->loaded_row_id);
+ priv->loaded_row_id = 0;
+ }
+
+ if (priv->autoscroll_id != 0) {
+ g_source_remove (priv->autoscroll_id);
+ priv->autoscroll_id = 0;
+ }
- object_class->finalize = em_folder_tree_finalize;
+ if (priv->autoexpand_id != 0) {
+ gtk_tree_row_reference_free (priv->autoexpand_row);
+ priv->autoexpand_row = NULL;
+
+ g_source_remove (priv->autoexpand_id);
+ priv->autoexpand_id = 0;
+ }
+
+ /* Chain up to parent's destroy() method. */
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
+
+static gboolean
+emft_button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ EMFolderTreePrivate *priv;
+ GtkWidgetClass *widget_class;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreePath *path;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (widget);
+
+ tree_view = GTK_TREE_VIEW (widget);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_SINGLE)
+ emft_clear_selected_list (EM_FOLDER_TREE (widget));
+
+ priv->cursor_set = TRUE;
+
+ if (event->button != 3)
+ goto chainup;
+
+ if (!gtk_tree_view_get_path_at_pos (
+ tree_view, event->x, event->y,
+ &path, NULL, NULL, NULL))
+ goto chainup;
+
+ /* select/focus the row that was right-clicked */
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
+
+ gtk_tree_path_free (path);
+
+ folder_tree_emit_popup_event (
+ EM_FOLDER_TREE (tree_view), (GdkEvent *) event);
+
+chainup:
+
+ /* Chain up to parent's button_press_event() method. */
+ widget_class = GTK_WIDGET_CLASS (parent_class);
+ return widget_class->button_press_event (widget, event);
+}
+
+static gboolean
+emft_key_press_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ EMFolderTreePrivate *priv;
+ GtkWidgetClass *widget_class;
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (widget);
+
+ tree_view = GTK_TREE_VIEW (widget);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_SINGLE)
+ emft_clear_selected_list (EM_FOLDER_TREE (widget));
+
+ priv->cursor_set = TRUE;
+
+ /* Chain up to parent's key_press_event() method. */
+ widget_class = GTK_WIDGET_CLASS (parent_class);
+ return widget_class->key_press_event (widget, event);
+}
+
+static gboolean
+emft_popup_menu (GtkWidget *widget)
+{
+ folder_tree_emit_popup_event (EM_FOLDER_TREE (widget), NULL);
+
+ return TRUE;
+}
+
+static void
+emft_row_activated (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column)
+{
+ EMFolderTreePrivate *priv;
+ GtkTreeModel *model;
+ gchar *full_name, *uri;
+ GtkTreeIter iter;
+ guint32 flags;
+
+ priv = EM_FOLDER_TREE_GET_PRIVATE (tree_view);
+
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (priv->skip_double_click)
+ return;
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ return;
+
+ gtk_tree_model_get (
+ model, &iter, COL_STRING_FULL_NAME, &full_name,
+ COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags, -1);
+
+ emft_clear_selected_list (EM_FOLDER_TREE (tree_view));
+
+ g_signal_emit (
+ tree_view, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
+
+ g_signal_emit (
+ tree_view, signals[FOLDER_ACTIVATED], 0, full_name, uri);
+
+ g_free (full_name);
+ g_free (uri);
+}
+
+static gboolean
+emft_test_collapse_row (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter cursor;
+
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &cursor))
+ goto exit;
+
+ /* Select the collapsed node IFF it is a
+ * parent of the currently selected folder. */
+ if (gtk_tree_store_is_ancestor (GTK_TREE_STORE (model), iter, &cursor))
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
+
+exit:
+ return FALSE;
+}
+
+static void
+emft_row_expanded (GtkTreeView *tree_view,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ struct _EMFolderTreeGetFolderInfo *msg;
+ GtkTreeModel *model;
+ CamelStore *store;
+ gchar *full_name;
+ gboolean load;
+
+ model = gtk_tree_view_get_model (tree_view);
+
+ gtk_tree_model_get (
+ model, iter,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_BOOL_LOAD_SUBDIRS, &load, -1);
+
+ if (!load) {
+ g_free (full_name);
+ return;
+ }
+
+ gtk_tree_store_set (
+ GTK_TREE_STORE (model), iter,
+ COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
+
+ msg = mail_msg_new (&get_folder_info_info);
+ msg->root = gtk_tree_row_reference_new (model, path);
+ camel_object_ref (store);
+ msg->store = store;
+ msg->emft = g_object_ref (tree_view);
+ msg->top = full_name;
+ msg->flags =
+ CAMEL_STORE_FOLDER_INFO_RECURSIVE |
+ CAMEL_STORE_FOLDER_INFO_FAST;
+
+ mail_msg_unordered_push (msg);
+}
+
+static void
+folder_tree_class_init (EMFolderTreeClass *class)
+{
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
+ GtkWidgetClass *widget_class;
+ GtkTreeViewClass *tree_view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFolderTreePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = folder_tree_finalize;
+
+ gtk_object_class = GTK_OBJECT_CLASS (class);
gtk_object_class->destroy = em_folder_tree_destroy;
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->button_press_event = emft_button_press_event;
+ widget_class->key_press_event = emft_key_press_event;
widget_class->popup_menu = emft_popup_menu;
- signals[FOLDER_SELECTED] =
- g_signal_new ("folder-selected",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeClass, folder_selected),
- NULL, NULL,
- e_marshal_VOID__STRING_STRING_UINT,
- G_TYPE_NONE, 3,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_UINT);
-
- signals[FOLDER_ACTIVATED] =
- g_signal_new ("folder-activated",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EMFolderTreeClass, folder_activated),
- NULL, NULL,
- e_marshal_VOID__STRING_STRING,
- G_TYPE_NONE, 2,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- signals[HIDDEN_KEY_EVENT] =
- g_signal_new ("hidden-key-event",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMFolderTreeClass, hidden_key_event),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE, 1, GDK_TYPE_EVENT);
+ tree_view_class = GTK_TREE_VIEW_CLASS (class);
+ tree_view_class->row_activated = emft_row_activated;
+ tree_view_class->test_collapse_row = emft_test_collapse_row;
+ tree_view_class->row_expanded = emft_row_expanded;
+
+ signals[FOLDER_SELECTED] = g_signal_new (
+ "folder-selected",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeClass, folder_selected),
+ NULL, NULL,
+ e_marshal_VOID__STRING_STRING_UINT,
+ G_TYPE_NONE, 3,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_UINT);
+
+ signals[FOLDER_ACTIVATED] = g_signal_new (
+ "folder-activated",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMFolderTreeClass, folder_activated),
+ NULL, NULL,
+ e_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EMFolderTreeClass, popup_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+}
+
+static void
+folder_tree_init (EMFolderTree *emft)
+{
+ GtkTreeSelection *selection;
+ GHashTable *select_uris_table;
+ EMFolderTreeModel *model;
+
+ select_uris_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+ emft->priv = EM_FOLDER_TREE_GET_PRIVATE (emft);
+ emft->priv->select_uris_table = select_uris_table;
+
+ model = em_folder_tree_model_get_default ();
+ gtk_tree_view_set_model (GTK_TREE_VIEW (emft), GTK_TREE_MODEL (model));
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (emft));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (emft_selection_changed_cb), emft);
+}
+
+GType
+em_folder_tree_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFolderTreeClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) folder_tree_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFolderTree),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) folder_tree_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TREE_VIEW, "EMFolderTree", &type_info, 0);
+ }
+
+ return type;
}
static gboolean
@@ -325,10 +837,13 @@ render_icon (GtkTreeViewColumn *column,
GtkTreeModel *model,
GtkTreeIter *iter)
{
+ GtkTreeSelection *selection;
+ GtkWidget *tree_view;
GIcon *icon;
guint unread;
guint old_unread;
gchar *icon_name;
+ gboolean row_selected;
gtk_tree_model_get (
model, iter,
@@ -341,8 +856,12 @@ render_icon (GtkTreeViewColumn *column,
icon = g_themed_icon_new (icon_name);
+ tree_view = gtk_tree_view_column_get_tree_view (column);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+ row_selected = gtk_tree_selection_iter_is_selected (selection, iter);
+
/* Show an emblem if there's new mail. */
- if (unread > old_unread) {
+ if (!row_selected && unread > old_unread) {
GIcon *temp_icon;
GEmblem *emblem;
@@ -360,133 +879,21 @@ render_icon (GtkTreeViewColumn *column,
g_object_set (renderer, "gicon", icon, NULL);
g_object_unref (icon);
- g_free (icon_name);
-}
-
-static gboolean
-emft_select_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean selected, gpointer data)
-{
- EMFolderTree *emft = data;
- gboolean is_store;
- guint32 flags;
- GtkTreeIter iter;
-
- /* NB: This will be called with selection==NULL from tree_row_activated */
- if (emft->priv->excluded == 0 && emft->priv->excluded_func == NULL)
- return TRUE;
-
- if (!gtk_tree_model_get_iter(model, &iter, path))
- return TRUE;
-
- if (emft->priv->excluded_func != NULL)
- return emft->priv->excluded_func(emft, model, &iter, emft->priv->excluded_data);
-
- gtk_tree_model_get(model, &iter, COL_UINT_FLAGS, &flags, COL_BOOL_IS_STORE, &is_store, -1);
- if (is_store)
- flags |= CAMEL_FOLDER_NOSELECT;
-
- return (flags & emft->priv->excluded) == 0;
-}
-
-static void
-emft_free_select_uri(gpointer v, gpointer data)
-{
- struct _selected_uri *u = v;
-
- g_free(u->uri);
- if (u->store)
- camel_object_unref(u->store);
- g_free(u->key);
- g_free(u->path);
- g_free(u);
-}
-
-static void
-em_folder_tree_init (EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv;
-
- priv = g_new0 (struct _EMFolderTreePrivate, 1);
- priv->select_uris_table = g_hash_table_new(g_str_hash, g_str_equal);
- priv->treeview = NULL;
- priv->model = NULL;
- priv->drag_row = NULL;
- priv->skip_double_click = FALSE;
-
- emft->priv = priv;
-}
-
-static void
-em_folder_tree_finalize (GObject *obj)
-{
- EMFolderTree *emft = (EMFolderTree *) obj;
-
- if (emft->priv->select_uris) {
- g_slist_foreach(emft->priv->select_uris, emft_free_select_uri, emft);
- g_slist_free(emft->priv->select_uris);
- g_hash_table_destroy(emft->priv->select_uris_table);
- emft->priv->select_uris = NULL;
- }
-
- g_free (emft->priv);
-
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static void
-em_folder_tree_destroy (GtkObject *obj)
-{
- EMFolderTree *emft = (EMFolderTree *) obj;
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- if (priv->loading_row_id != 0) {
- g_signal_handler_disconnect (priv->model, priv->loading_row_id);
- priv->loading_row_id = 0;
- }
-
- if (priv->loaded_row_id != 0) {
- g_signal_handler_disconnect (priv->model, priv->loaded_row_id);
- priv->loaded_row_id = 0;
- }
-
- if (priv->save_state_id != 0) {
- g_source_remove (priv->save_state_id);
- emft_save_state (emft);
- }
-
- if (priv->autoscroll_id != 0) {
- g_source_remove (priv->autoscroll_id);
- priv->autoscroll_id = 0;
- }
-
- if (priv->autoexpand_id != 0) {
- gtk_tree_row_reference_free (priv->autoexpand_row);
- priv->autoexpand_row = NULL;
-
- g_source_remove (priv->autoexpand_id);
- priv->autoexpand_id = 0;
- }
-
- priv->treeview = NULL;
- priv->model = NULL;
-
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
}
static GtkTreeView *
-folder_tree_new (EMFolderTree *emft, EMFolderTreeModel *model)
+folder_tree_new (EMFolderTree *emft)
{
GtkTreeSelection *selection;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkWidget *tree;
- gboolean side_bar_search;
GConfClient *gconf;
gconf = mail_config_get_gconf_client ();
- side_bar_search = gconf_client_get_bool (gconf, "/apps/evolution/mail/display/side_bar_search", NULL);
- tree = gtk_tree_view_new_with_model ((GtkTreeModel *) model);
+ /* FIXME[KILL-BONOBO] Gross hack */
+ tree = GTK_WIDGET (emft);
GTK_WIDGET_SET_FLAGS(tree, GTK_CAN_FOCUS);
column = gtk_tree_view_column_new ();
@@ -508,84 +915,99 @@ folder_tree_new (EMFolderTree *emft, EMFolderTreeModel *model)
selection = gtk_tree_view_get_selection ((GtkTreeView *) tree);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
- gtk_tree_selection_set_select_function(selection, emft_select_func, emft, NULL);
+ gtk_tree_selection_set_select_function (
+ selection, (GtkTreeSelectionFunc)
+ emft_select_func, NULL, NULL);
gtk_tree_view_set_headers_visible ((GtkTreeView *) tree, FALSE);
gtk_tree_view_set_search_column((GtkTreeView *)tree, COL_STRING_DISPLAY_NAME);
- gtk_tree_view_set_enable_search((GtkTreeView *)tree, side_bar_search);
return (GtkTreeView *) tree;
}
static void
-em_folder_tree_construct (EMFolderTree *emft, EMFolderTreeModel *model)
+folder_tree_copy_expanded_cb (GtkTreeView *unused,
+ GtkTreePath *path,
+ GtkTreeView *tree_view)
+{
+ gtk_tree_view_expand_row (tree_view, path, FALSE);
+}
+
+static void
+folder_tree_copy_selection_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GtkTreeView *tree_view)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
GtkTreeSelection *selection;
- GtkWidget *scrolled;
- scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN);
+ selection = gtk_tree_view_get_selection (tree_view);
+ gtk_tree_selection_select_path (selection, path);
+
+ /* Center the tree view on the selected path. */
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.0);
+}
- priv->model = model;
- priv->treeview = folder_tree_new (emft, model);
- gtk_widget_show ((GtkWidget *) priv->treeview);
+static void
+folder_tree_copy_state (EMFolderTree *emft)
+{
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
- g_signal_connect (priv->treeview, "row-expanded", G_CALLBACK (emft_tree_row_expanded), emft);
- g_signal_connect (priv->treeview, "test-collapse-row", G_CALLBACK (emft_tree_test_collapse_row), emft);
- g_signal_connect (priv->treeview, "row-activated", G_CALLBACK (emft_tree_row_activated), emft);
- g_signal_connect (priv->treeview, "button-press-event", G_CALLBACK (emft_tree_button_press), emft);
- g_signal_connect (priv->treeview, "key-press-event", G_CALLBACK (emft_tree_user_event), emft);
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
- selection = gtk_tree_view_get_selection ((GtkTreeView *) priv->treeview);
- g_signal_connect (selection, "changed", G_CALLBACK (emft_tree_selection_changed), emft);
+ selection = em_folder_tree_model_get_selection (
+ EM_FOLDER_TREE_MODEL (model));
+ if (selection == NULL)
+ return;
- gtk_container_add ((GtkContainer *) scrolled, (GtkWidget *) priv->treeview);
- gtk_widget_show (scrolled);
+ gtk_tree_view_map_expanded_rows (
+ tree_view, (GtkTreeViewMappingFunc)
+ folder_tree_copy_expanded_cb, emft);
- gtk_box_pack_start ((GtkBox *) emft, scrolled, TRUE, TRUE, 0);
+ gtk_tree_selection_selected_foreach (
+ selection, (GtkTreeSelectionForeachFunc)
+ folder_tree_copy_selection_cb, emft);
}
-GtkWidget *
-em_folder_tree_new (void)
+static void
+em_folder_tree_construct (EMFolderTree *emft)
{
- EMFolderTreeModel *model;
- EMFolderTree *emft;
-
- model = em_folder_tree_model_new (e_get_user_data_dir ());
- emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
- g_object_unref (model);
-
- return (GtkWidget *) emft;
+ folder_tree_new (emft);
+ folder_tree_copy_state (emft);
+ gtk_widget_show (GTK_WIDGET (emft));
}
/* NOTE: Removes and frees the selected uri structure */
static void
emft_select_uri(EMFolderTree *emft, GtkTreePath *path, struct _selected_uri *u)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
- selection = gtk_tree_view_get_selection(priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
gtk_tree_selection_select_path(selection, path);
if (!priv->cursor_set) {
- gtk_tree_view_set_cursor (priv->treeview, path, NULL, FALSE);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
priv->cursor_set = TRUE;
}
- gtk_tree_view_scroll_to_cell (priv->treeview, path, NULL, TRUE, 0.8f, 0.0f);
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.8f, 0.0f);
g_hash_table_remove(priv->select_uris_table, u->key);
priv->select_uris = g_slist_remove(priv->select_uris, u);
- emft_free_select_uri((gpointer)u, NULL);
+ emft_free_select_uri(u);
}
static void
-emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft)
+emft_expand_node (const gchar *key, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
struct _EMFolderTreeModelStoreInfo *si;
GtkTreeRowReference *row;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
GtkTreePath *path;
EAccount *account;
CamelStore *store;
@@ -603,7 +1025,10 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
memcpy (uid, key, n);
uid[n] = '\0';
- if ((account = mail_config_get_account_by_uid (uid)) && account->enabled) {
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if ((account = e_get_account_by_uid (uid)) && account->enabled) {
CamelException ex;
camel_exception_init (&ex);
@@ -618,7 +1043,7 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
camel_object_ref (store);
} else if (!strcmp (uid, "local")) {
- if (!(store = mail_component_peek_local_store (NULL)))
+ if (!(store = e_mail_local_get_store ()))
return;
camel_object_ref (store);
@@ -626,7 +1051,9 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
return;
}
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
+ si = em_folder_tree_model_lookup_store_info (
+ EM_FOLDER_TREE_MODEL (model), store);
+ if (si == NULL) {
camel_object_unref (store);
return;
}
@@ -640,7 +1067,7 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
row = si->row;
path = gtk_tree_row_reference_get_path (row);
- gtk_tree_view_expand_to_path (priv->treeview, path);
+ gtk_tree_view_expand_to_path (tree_view, path);
u = g_hash_table_lookup(emft->priv->select_uris_table, key);
if (u)
@@ -652,15 +1079,17 @@ emft_expand_node (EMFolderTreeModel *model, const gchar *key, EMFolderTree *emft
static void
emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTreeIter *iter, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
struct _EMFolderTreeModelStoreInfo *si;
+ GtkTreeView *tree_view;
gboolean is_store;
CamelStore *store;
EAccount *account;
gchar *full_name;
gchar *key;
struct _selected_uri *u;
- gboolean is_expanded;
+
+ tree_view = GTK_TREE_VIEW (emft);
gtk_tree_model_get ((GtkTreeModel *) model, iter,
COL_STRING_FULL_NAME, &full_name,
@@ -668,8 +1097,8 @@ emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTree
COL_BOOL_IS_STORE, &is_store,
-1);
- si = g_hash_table_lookup (model->store_hash, store);
- if ((account = mail_config_get_account_by_name (si->display_name))) {
+ si = em_folder_tree_model_lookup_store_info (model, store);
+ if ((account = e_get_account_by_name (si->display_name))) {
key = g_strdup_printf ("%s/%s", account->uid, full_name ? full_name : "");
} else if (CAMEL_IS_VEE_STORE (store)) {
/* vfolder store */
@@ -679,21 +1108,14 @@ emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTree
key = g_strdup_printf ("local/%s", full_name ? full_name : "");
}
- is_expanded = em_folder_tree_model_get_expanded (model, key);
u = g_hash_table_lookup(priv->select_uris_table, key);
- if (is_expanded || u) {
- if (is_expanded) {
- gtk_tree_view_expand_to_path (priv->treeview, tree_path);
- gtk_tree_view_expand_row (priv->treeview, tree_path, FALSE);
- } else {
- gchar *c = strrchr (key, '/');
+ if (u) {
+ gchar *c = strrchr (key, '/');
- *c = '\0';
- emft_expand_node (model, key, emft);
- }
+ *c = '\0';
+ emft_expand_node (key, emft);
- if (u)
- emft_select_uri(emft, tree_path, u);
+ emft_select_uri(emft, tree_path, u);
}
g_free (full_name);
@@ -701,21 +1123,25 @@ emft_maybe_expand_row (EMFolderTreeModel *model, GtkTreePath *tree_path, GtkTree
}
GtkWidget *
-em_folder_tree_new_with_model (EMFolderTreeModel *model)
+em_folder_tree_new (void)
{
EMFolderTree *emft;
+ GtkTreeModel *model;
AtkObject *a11y;
emft = g_object_new (EM_TYPE_FOLDER_TREE, NULL);
- em_folder_tree_construct (emft, model);
- g_object_ref (model);
+ em_folder_tree_construct (emft);
- em_folder_tree_model_expand_foreach (model, (EMFTModelExpandFunc)emft_expand_node, emft);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
- emft->priv->loading_row_id = g_signal_connect (model, "loading-row", G_CALLBACK (emft_maybe_expand_row), emft);
- emft->priv->loaded_row_id = g_signal_connect (model, "loaded-row", G_CALLBACK (emft_maybe_expand_row), emft);
+ emft->priv->loading_row_id = g_signal_connect (
+ model, "loading-row",
+ G_CALLBACK (emft_maybe_expand_row), emft);
+ emft->priv->loaded_row_id = g_signal_connect (
+ model, "loaded-row",
+ G_CALLBACK (emft_maybe_expand_row), emft);
- a11y = gtk_widget_get_accessible (GTK_WIDGET (emft->priv->treeview));
+ a11y = gtk_widget_get_accessible (GTK_WIDGET (emft));
atk_object_set_name (a11y, _("Mail Folder Tree"));
return (GtkWidget *) emft;
@@ -724,7 +1150,7 @@ em_folder_tree_new_with_model (EMFolderTreeModel *model)
static void
tree_drag_begin (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreePath *path;
@@ -744,8 +1170,9 @@ tree_drag_begin (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
static void
tree_drag_data_delete(GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
gchar *full_name = NULL;
+ GtkTreeModel *model;
GtkTreePath *src_path;
gboolean is_store;
CamelStore *store;
@@ -755,13 +1182,16 @@ tree_drag_data_delete(GtkWidget *widget, GdkDragContext *context, EMFolderTree *
if (!priv->drag_row || (src_path = gtk_tree_row_reference_get_path (priv->drag_row)))
return;
- if (!gtk_tree_model_get_iter((GtkTreeModel *)priv->model, &iter, src_path))
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
+
+ if (!gtk_tree_model_get_iter (model, &iter, src_path))
goto fail;
- gtk_tree_model_get((GtkTreeModel *)priv->model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_FULL_NAME, &full_name,
- COL_BOOL_IS_STORE, &is_store, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_BOOL_IS_STORE, &is_store, -1);
if (is_store)
goto fail;
@@ -778,8 +1208,9 @@ fail:
static void
tree_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection, guint info, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
gchar *full_name = NULL, *uri = NULL;
+ GtkTreeModel *model;
GtkTreePath *src_path;
CamelFolder *folder;
CamelStore *store;
@@ -789,13 +1220,16 @@ tree_drag_data_get(GtkWidget *widget, GdkDragContext *context, GtkSelectionData
if (!priv->drag_row || !(src_path = gtk_tree_row_reference_get_path(priv->drag_row)))
return;
- if (!gtk_tree_model_get_iter((GtkTreeModel *)priv->model, &iter, src_path))
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
+
+ if (!gtk_tree_model_get_iter (model, &iter, src_path))
goto fail;
- gtk_tree_model_get((GtkTreeModel *)priv->model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_FULL_NAME, &full_name,
- COL_STRING_URI, &uri, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_STRING_URI, &uri, -1);
/* make sure user isn't trying to drag on a placeholder row */
if (full_name == NULL)
@@ -995,8 +1429,9 @@ emft_drop_popup_free(EPopup *ep, GSList *items, gpointer data)
static void
tree_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection, guint info, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
GtkTreeViewDropPosition pos;
+ GtkTreeModel *model;
+ GtkTreeView *tree_view;
GtkTreePath *dest_path;
struct _DragDataReceivedAsync *m;
gboolean is_store;
@@ -1005,7 +1440,10 @@ tree_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint
gchar *full_name;
gint i;
- if (!gtk_tree_view_get_dest_row_at_pos (priv->treeview, x, y, &dest_path, &pos))
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &dest_path, &pos))
return;
/* this means we are receiving no data */
@@ -1014,15 +1452,16 @@ tree_drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint
return;
}
- if (!gtk_tree_model_get_iter((GtkTreeModel *)priv->model, &iter, dest_path)) {
+ if (!gtk_tree_model_get_iter (model, &iter, dest_path)) {
gtk_drag_finish(context, FALSE, FALSE, GDK_CURRENT_TIME);
return;
}
- gtk_tree_model_get((GtkTreeModel *)priv->model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_BOOL_IS_STORE, &is_store,
- COL_STRING_FULL_NAME, &full_name, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &store,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_STRING_FULL_NAME, &full_name, -1);
/* make sure user isn't try to drop on a placeholder row */
if (full_name == NULL && !is_store) {
@@ -1080,27 +1519,32 @@ is_special_local_folder (const gchar *name)
static GdkAtom
emft_drop_target(EMFolderTree *emft, GdkDragContext *context, GtkTreePath *path)
{
- struct _EMFolderTreePrivate *p = emft->priv;
+ EMFolderTreePrivate *p = emft->priv;
gchar *full_name = NULL, *uri = NULL, *src_uri = NULL;
CamelStore *local, *sstore, *dstore;
GdkAtom atom = GDK_NONE;
gboolean is_store;
+ GtkTreeModel *model;
GtkTreeIter iter;
GList *targets;
guint32 flags = 0;
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emft));
+
/* This is a bit of a mess, but should handle all the cases properly */
- if (!gtk_tree_model_get_iter((GtkTreeModel *)p->model, &iter, path))
+ if (!gtk_tree_model_get_iter (model, &iter, path))
return GDK_NONE;
- gtk_tree_model_get((GtkTreeModel *)p->model, &iter, COL_BOOL_IS_STORE, &is_store,
- COL_STRING_FULL_NAME, &full_name,
- COL_UINT_FLAGS, &flags,
- COL_POINTER_CAMEL_STORE, &dstore,
- COL_STRING_URI, &uri, -1);
+ gtk_tree_model_get (
+ model, &iter,
+ COL_BOOL_IS_STORE, &is_store,
+ COL_STRING_FULL_NAME, &full_name,
+ COL_UINT_FLAGS, &flags,
+ COL_POINTER_CAMEL_STORE, &dstore,
+ COL_STRING_URI, &uri, -1);
- local = mail_component_peek_local_store (NULL);
+ local = e_mail_local_get_store ();
targets = context->targets;
@@ -1142,10 +1586,11 @@ emft_drop_target(EMFolderTree *emft, GdkDragContext *context, GtkTreePath *path)
GtkTreePath *src_path = gtk_tree_row_reference_get_path(p->drag_row);
if (src_path) {
- if (gtk_tree_model_get_iter((GtkTreeModel *)p->model, &iter, src_path))
- gtk_tree_model_get((GtkTreeModel *)p->model, &iter,
- COL_POINTER_CAMEL_STORE, &sstore,
- COL_STRING_URI, &src_uri, -1);
+ if (gtk_tree_model_get_iter (model, &iter, src_path))
+ gtk_tree_model_get (
+ model, &iter,
+ COL_POINTER_CAMEL_STORE, &sstore,
+ COL_STRING_URI, &src_uri, -1);
/* can't dnd onto itself or below itself - bad things happen,
no point dragging to where we were either */
@@ -1276,12 +1721,15 @@ emft_drop_target(EMFolderTree *emft, GdkDragContext *context, GtkTreePath *path)
static gboolean
tree_drag_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
GtkTreeViewColumn *column;
+ GtkTreeView *tree_view;
gint cell_x, cell_y;
GtkTreePath *path;
GdkAtom target;
+ tree_view = GTK_TREE_VIEW (emft);
+
if (priv->autoscroll_id != 0) {
g_source_remove (priv->autoscroll_id);
priv->autoscroll_id = 0;
@@ -1295,7 +1743,7 @@ tree_drag_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guin
priv->autoexpand_id = 0;
}
- if (!gtk_tree_view_get_path_at_pos (priv->treeview, x, y, &path, &column, &cell_x, &cell_y))
+ if (!gtk_tree_view_get_path_at_pos (tree_view, x, y, &path, &column, &cell_x, &cell_y))
return FALSE;
target = emft_drop_target(emft, context, path);
@@ -1309,7 +1757,7 @@ tree_drag_drop (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guin
static void
tree_drag_end (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
if (priv->drag_row) {
gtk_tree_row_reference_free (priv->drag_row);
@@ -1322,7 +1770,10 @@ tree_drag_end (GtkWidget *widget, GdkDragContext *context, EMFolderTree *emft)
static void
tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
+ GtkTreeView *tree_view;
+
+ tree_view = GTK_TREE_VIEW (emft);
if (priv->autoscroll_id != 0) {
g_source_remove (priv->autoscroll_id);
@@ -1337,7 +1788,7 @@ tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, EMFolde
priv->autoexpand_id = 0;
}
- gtk_tree_view_set_drag_dest_row(emft->priv->treeview, NULL, GTK_TREE_VIEW_DROP_BEFORE);
+ gtk_tree_view_set_drag_dest_row(tree_view, NULL, GTK_TREE_VIEW_DROP_BEFORE);
}
#define SCROLL_EDGE_SIZE 15
@@ -1345,19 +1796,20 @@ tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, EMFolde
static gboolean
tree_autoscroll (EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
GtkAdjustment *vadjustment;
+ GtkTreeView *tree_view;
GdkRectangle rect;
GdkWindow *window;
gint offset, y;
gfloat value;
/* get the y pointer position relative to the treeview */
- window = gtk_tree_view_get_bin_window (priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ window = gtk_tree_view_get_bin_window (tree_view);
gdk_window_get_pointer (window, NULL, &y, NULL);
/* rect is in coorinates relative to the scrolled window relative to the treeview */
- gtk_tree_view_get_visible_rect (priv->treeview, &rect);
+ gtk_tree_view_get_visible_rect (tree_view, &rect);
/* move y into the same coordinate system as rect */
y += rect.y;
@@ -1369,7 +1821,7 @@ tree_autoscroll (EMFolderTree *emft)
return TRUE;
}
- vadjustment = gtk_tree_view_get_vadjustment (priv->treeview);
+ vadjustment = gtk_tree_view_get_vadjustment (tree_view);
value = CLAMP (vadjustment->value + offset, 0.0, vadjustment->upper - vadjustment->page_size);
gtk_adjustment_set_value (vadjustment, value);
@@ -1380,11 +1832,13 @@ tree_autoscroll (EMFolderTree *emft)
static gboolean
tree_autoexpand (EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
+ GtkTreeView *tree_view;
GtkTreePath *path;
+ tree_view = GTK_TREE_VIEW (emft);
path = gtk_tree_row_reference_get_path (priv->autoexpand_row);
- gtk_tree_view_expand_row (priv->treeview, path, FALSE);
+ gtk_tree_view_expand_row (tree_view, path, FALSE);
gtk_tree_path_free (path);
return TRUE;
@@ -1393,16 +1847,20 @@ tree_autoexpand (EMFolderTree *emft)
static gboolean
tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeModel *model = (GtkTreeModel *) priv->model;
+ EMFolderTreePrivate *priv = emft->priv;
GtkTreeViewDropPosition pos;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
GdkDragAction action = 0;
GtkTreePath *path;
GtkTreeIter iter;
GdkAtom target;
gint i;
- if (!gtk_tree_view_get_dest_row_at_pos(priv->treeview, x, y, &path, &pos))
+ tree_view = GTK_TREE_VIEW (emft);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (!gtk_tree_view_get_dest_row_at_pos(tree_view, x, y, &path, &pos))
return FALSE;
if (priv->autoscroll_id == 0)
@@ -1410,7 +1868,7 @@ tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, gu
gtk_tree_model_get_iter (model, &iter, path);
- if (gtk_tree_model_iter_has_child (model, &iter) && !gtk_tree_view_row_expanded (priv->treeview, path)) {
+ if (gtk_tree_model_iter_has_child (model, &iter) && !gtk_tree_view_row_expanded (tree_view, path)) {
if (priv->autoexpand_id != 0) {
GtkTreePath *autoexpand_path;
@@ -1446,10 +1904,10 @@ tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, gu
action = context->suggested_action;
if (action == GDK_ACTION_COPY && (context->actions & GDK_ACTION_MOVE))
action = GDK_ACTION_MOVE;
- gtk_tree_view_set_drag_dest_row(priv->treeview, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
+ gtk_tree_view_set_drag_dest_row(tree_view, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
break;
default:
- gtk_tree_view_set_drag_dest_row(priv->treeview, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
+ gtk_tree_view_set_drag_dest_row(tree_view, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER);
action = context->suggested_action;
break;
}
@@ -1468,12 +1926,15 @@ tree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, gu
void
em_folder_tree_enable_drag_and_drop (EMFolderTree *emft)
{
- struct _EMFolderTreePrivate *priv;
+ EMFolderTreePrivate *priv;
+ GtkTreeView *tree_view;
static gint setup = 0;
gint i;
g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+ tree_view = GTK_TREE_VIEW (emft);
+
priv = emft->priv;
if (!setup) {
for (i=0; i<NUM_DRAG_TYPES; i++)
@@ -1485,35 +1946,35 @@ em_folder_tree_enable_drag_and_drop (EMFolderTree *emft)
setup = 1;
}
- gtk_drag_source_set((GtkWidget *)priv->treeview, GDK_BUTTON1_MASK, drag_types, NUM_DRAG_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
- gtk_drag_dest_set((GtkWidget *)priv->treeview, GTK_DEST_DEFAULT_ALL, drop_types, NUM_DROP_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
+ gtk_drag_source_set((GtkWidget *)tree_view, GDK_BUTTON1_MASK, drag_types, NUM_DRAG_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
+ gtk_drag_dest_set((GtkWidget *)tree_view, GTK_DEST_DEFAULT_ALL, drop_types, NUM_DROP_TYPES, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
- g_signal_connect (priv->treeview, "drag-begin", G_CALLBACK (tree_drag_begin), emft);
- g_signal_connect (priv->treeview, "drag-data-delete", G_CALLBACK (tree_drag_data_delete), emft);
- g_signal_connect (priv->treeview, "drag-data-get", G_CALLBACK (tree_drag_data_get), emft);
- g_signal_connect (priv->treeview, "drag-data-received", G_CALLBACK (tree_drag_data_received), emft);
- g_signal_connect (priv->treeview, "drag-drop", G_CALLBACK (tree_drag_drop), emft);
- g_signal_connect (priv->treeview, "drag-end", G_CALLBACK (tree_drag_end), emft);
- g_signal_connect (priv->treeview, "drag-leave", G_CALLBACK (tree_drag_leave), emft);
- g_signal_connect (priv->treeview, "drag-motion", G_CALLBACK (tree_drag_motion), emft);
+ g_signal_connect (tree_view, "drag-begin", G_CALLBACK (tree_drag_begin), emft);
+ g_signal_connect (tree_view, "drag-data-delete", G_CALLBACK (tree_drag_data_delete), emft);
+ g_signal_connect (tree_view, "drag-data-get", G_CALLBACK (tree_drag_data_get), emft);
+ g_signal_connect (tree_view, "drag-data-received", G_CALLBACK (tree_drag_data_received), emft);
+ g_signal_connect (tree_view, "drag-drop", G_CALLBACK (tree_drag_drop), emft);
+ g_signal_connect (tree_view, "drag-end", G_CALLBACK (tree_drag_end), emft);
+ g_signal_connect (tree_view, "drag-leave", G_CALLBACK (tree_drag_leave), emft);
+ g_signal_connect (tree_view, "drag-motion", G_CALLBACK (tree_drag_motion), emft);
}
void
-em_folder_tree_set_multiselect (EMFolderTree *tree, gboolean mode)
+em_folder_tree_set_excluded (EMFolderTree *emft, guint32 flags)
{
- GtkTreeSelection *sel = gtk_tree_view_get_selection ((GtkTreeView *) tree->priv->treeview);
-
- tree->priv->do_multiselect = mode;
- gtk_tree_selection_set_mode (sel, mode ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE);
-}
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
-void em_folder_tree_set_excluded(EMFolderTree *emft, guint32 flags)
-{
emft->priv->excluded = flags;
}
-void em_folder_tree_set_excluded_func(EMFolderTree *emft, EMFTExcludeFunc exclude, gpointer data)
+void
+em_folder_tree_set_excluded_func (EMFolderTree *emft,
+ EMFTExcludeFunc exclude,
+ gpointer data)
{
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+ g_return_if_fail (exclude != NULL);
+
emft->priv->excluded_func = exclude;
emft->priv->excluded_data = data;
}
@@ -1521,10 +1982,14 @@ void em_folder_tree_set_excluded_func(EMFolderTree *emft, EMFTExcludeFunc exclud
GList *
em_folder_tree_get_selected_uris (EMFolderTree *emft)
{
- GtkTreeSelection *selection = gtk_tree_view_get_selection (emft->priv->treeview);
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
GList *list = NULL, *rows, *l;
GSList *sl;
- GtkTreeModel *model;
+
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
/* at first, add lost uris */
for (sl = emft->priv->select_uris; sl; sl = g_slist_next(sl))
@@ -1561,31 +2026,22 @@ get_selected_uris_path_iterate (GtkTreeModel *model, GtkTreePath *treepath, GtkT
GList *
em_folder_tree_get_selected_paths (EMFolderTree *emft)
{
- GtkTreeSelection *selection = gtk_tree_view_get_selection (emft->priv->treeview);
+ GtkTreeSelection *selection;
+ GtkTreeView *tree_view;
GList *list = NULL;
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
gtk_tree_selection_selected_foreach (selection, get_selected_uris_path_iterate, &list);
return list;
}
-static void
-emft_clear_selected_list(EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- g_slist_foreach(priv->select_uris, emft_free_select_uri, emft);
- g_slist_free(priv->select_uris);
- g_hash_table_destroy(priv->select_uris_table);
- priv->select_uris = NULL;
- priv->select_uris_table = g_hash_table_new(g_str_hash, g_str_equal);
- priv->cursor_set = FALSE;
-}
-
void
em_folder_tree_set_selected_list (EMFolderTree *emft, GList *list, gboolean expand_only)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
gint id = 0;
/* FIXME: need to remove any currently selected stuff? */
@@ -1638,8 +2094,7 @@ em_folder_tree_set_selected_list (EMFolderTree *emft, GList *list, gboolean expa
end = strrchr(expand_key, '/');
do {
- emft_expand_node(priv->model, expand_key, emft);
- em_folder_tree_model_set_expanded(priv->model, expand_key, TRUE);
+ emft_expand_node(expand_key, emft);
*end = 0;
end = strrchr(expand_key, '/');
} while (end);
@@ -1671,680 +2126,15 @@ dump_fi (CamelFolderInfo *fi, gint depth)
}
#endif
-struct _EMFolderTreeGetFolderInfo {
- MailMsg base;
-
- /* input data */
- GtkTreeRowReference *root;
- EMFolderTree *emft;
- CamelStore *store;
- guint32 flags;
- gchar *top;
-
- /* output data */
- CamelFolderInfo *fi;
-};
-
-static gchar *
-emft_get_folder_info__desc (struct _EMFolderTreeGetFolderInfo *m)
-{
- gchar *ret, *name;
-
- name = camel_service_get_name((CamelService *)m->store, TRUE);
- ret = g_strdup_printf(_("Scanning folders in \"%s\""), name);
- g_free(name);
- return ret;
-}
-
-static void
-emft_get_folder_info__exec (struct _EMFolderTreeGetFolderInfo *m)
-{
- guint32 flags = m->flags | CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
-
- m->fi = camel_store_get_folder_info (m->store, m->top, flags, &m->base.ex);
-}
-
-static void
-emft_get_folder_info__done (struct _EMFolderTreeGetFolderInfo *m)
-{
- struct _EMFolderTreePrivate *priv = m->emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
- GtkTreeIter root, iter, titer;
- CamelFolderInfo *fi;
- GtkTreeStore *model;
- GtkTreePath *path;
- gboolean is_store;
-
- /* check that we haven't been destroyed */
- if (priv->treeview == NULL)
- return;
-
- /* check that our parent folder hasn't been deleted/unsubscribed */
- if (!gtk_tree_row_reference_valid (m->root))
- return;
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, m->store))) {
- /* store has been removed in the interim - do nothing */
- return;
- }
-
- model = (GtkTreeStore *) gtk_tree_view_get_model (priv->treeview);
-
- path = gtk_tree_row_reference_get_path (m->root);
- gtk_tree_model_get_iter ((GtkTreeModel *) model, &root, path);
-
- /* if we had an error, then we need to re-set the load subdirs state and collapse the node */
- if (!m->fi && camel_exception_is_set(&m->base.ex)) {
- gtk_tree_store_set(model, &root, COL_BOOL_LOAD_SUBDIRS, TRUE, -1);
- gtk_tree_view_collapse_row (priv->treeview, path);
- gtk_tree_path_free (path);
- return;
- }
-
- gtk_tree_path_free (path);
-
- /* make sure we still need to load the tree subfolders... */
- gtk_tree_model_get ((GtkTreeModel *) model, &root,
- COL_BOOL_IS_STORE, &is_store,
- -1);
-
- /* get the first child (which will be a dummy node) */
- gtk_tree_model_iter_children ((GtkTreeModel *) model, &iter, &root);
-
- /* Traverse to the last valid iter */
- titer = iter;
- while (gtk_tree_model_iter_next((GtkTreeModel *) model, &iter))
- titer = iter; /* Preserve the last valid iter */
-
- iter = titer;
-
- /* FIXME: camel's IMAP code is totally on crack here, @top's
- * folder info should be @fi and fi->child should be what we
- * want to fill our tree with... *sigh* */
- if (m->top && m->fi && !strcmp (m->fi->full_name, m->top)) {
- if (!(fi = m->fi->child))
- fi = m->fi->next;
- } else
- fi = m->fi;
-
- if (fi == NULL) {
- /* no children afterall... remove the "Loading..." placeholder node */
- emft_update_model_expanded_state (priv, &root, FALSE);
-
- gtk_tree_store_remove (model, &iter);
-
- if (is_store) {
- path = gtk_tree_model_get_path ((GtkTreeModel *) model, &root);
- gtk_tree_view_collapse_row (priv->treeview, path);
- emft_queue_save_state (m->emft);
- gtk_tree_path_free (path);
- return;
- }
- } else {
- gint fully_loaded = (m->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? TRUE : FALSE;
-
- do {
- gboolean known = g_hash_table_lookup (si->full_hash, fi->full_name) != NULL;
-
- if (!known)
- em_folder_tree_model_set_folder_info (priv->model, &iter, si, fi, fully_loaded);
-
- if ((fi = fi->next) != NULL && !known)
- gtk_tree_store_append (model, &iter, &root);
- } while (fi != NULL);
- }
-
- gtk_tree_store_set (model, &root, COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
- emft_queue_save_state (m->emft);
-}
-
-static void
-emft_get_folder_info__free (struct _EMFolderTreeGetFolderInfo *m)
-{
- camel_store_free_folder_info (m->store, m->fi);
-
- gtk_tree_row_reference_free (m->root);
- g_object_unref(m->emft);
- camel_object_unref (m->store);
- g_free (m->top);
-}
-
-static MailMsgInfo get_folder_info_info = {
- sizeof (struct _EMFolderTreeGetFolderInfo),
- (MailMsgDescFunc) emft_get_folder_info__desc,
- (MailMsgExecFunc) emft_get_folder_info__exec,
- (MailMsgDoneFunc) emft_get_folder_info__done,
- (MailMsgFreeFunc) emft_get_folder_info__free
-};
-
-static void
-emft_update_model_expanded_state (struct _EMFolderTreePrivate *priv, GtkTreeIter *iter, gboolean expanded)
-{
- struct _EMFolderTreeModelStoreInfo *si;
- gboolean is_store;
- CamelStore *store;
- EAccount *account;
- gchar *full_name;
- gchar *key;
-
- gtk_tree_model_get ((GtkTreeModel *) priv->model, iter,
- COL_STRING_FULL_NAME, &full_name,
- COL_POINTER_CAMEL_STORE, &store,
- COL_BOOL_IS_STORE, &is_store,
- -1);
-
- si = g_hash_table_lookup (priv->model->store_hash, store);
- if ((account = mail_config_get_account_by_name (si->display_name))) {
- key = g_strdup_printf ("%s/%s", account->uid, full_name ? full_name : "");
- } else if (CAMEL_IS_VEE_STORE (store)) {
- /* vfolder store */
- key = g_strdup_printf ("vfolder/%s", full_name ? full_name : "");
- } else {
- /* local store */
- key = g_strdup_printf ("local/%s", full_name ? full_name : "");
- }
-
- em_folder_tree_model_set_expanded (priv->model, key, expanded);
- g_free (full_name);
- g_free (key);
-}
-
-static void
-emft_tree_row_expanded (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_path, EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeGetFolderInfo *m;
- GtkTreeModel *model;
- CamelStore *store;
- gchar *full_name;
- gboolean load;
-
- model = gtk_tree_view_get_model (treeview);
-
- gtk_tree_model_get (model, root,
- COL_STRING_FULL_NAME, &full_name,
- COL_POINTER_CAMEL_STORE, &store,
- COL_BOOL_LOAD_SUBDIRS, &load,
- -1);
-
- emft_update_model_expanded_state (priv, root, TRUE);
-
- if (!load) {
- emft_queue_save_state (emft);
- g_free (full_name);
- return;
- }
-
- gtk_tree_store_set ((GtkTreeStore *)model, root, COL_BOOL_LOAD_SUBDIRS, FALSE, -1);
-
- m = mail_msg_new (&get_folder_info_info);
- m->root = gtk_tree_row_reference_new (model, tree_path);
- camel_object_ref (store);
- m->store = store;
- m->emft = emft;
- g_object_ref(emft);
- m->top = full_name;
- m->flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST;
-
- mail_msg_unordered_push (m);
-}
-
-static gboolean
-emft_tree_test_collapse_row (GtkTreeView *treeview, GtkTreeIter *root, GtkTreePath *tree_path, EMFolderTree *emft)
-{
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter cursor;
-
- selection = gtk_tree_view_get_selection (treeview);
- if (gtk_tree_selection_get_selected (selection, &model, &cursor)) {
- /* select the collapsed node IFF it is a parent of the currently selected folder */
- if (gtk_tree_store_is_ancestor ((GtkTreeStore *) model, root, &cursor))
- gtk_tree_view_set_cursor (treeview, tree_path, NULL, FALSE);
- }
-
- emft_update_model_expanded_state (emft->priv, root, FALSE);
- emft_queue_save_state (emft);
-
- return FALSE;
-}
-
-static void
-emft_tree_row_activated (GtkTreeView *treeview, GtkTreePath *tree_path, GtkTreeViewColumn *column, EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeModel *model = (GtkTreeModel *) priv->model;
- gchar *full_name, *uri;
- GtkTreeIter iter;
- guint32 flags;
-
- if (!emft_select_func(NULL, model, tree_path, FALSE, emft))
- return;
-
- if (!gtk_tree_model_get_iter (model, &iter, tree_path))
- return;
-
- gtk_tree_model_get (model, &iter, COL_STRING_FULL_NAME, &full_name,
- COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags, -1);
-
- emft_clear_selected_list(emft);
-
- g_signal_emit (emft, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
- g_signal_emit (emft, signals[FOLDER_ACTIVATED], 0, full_name, uri);
-
- g_free(full_name);
- g_free(uri);
-}
-
-#if 0
-static void
-emft_popup_view (GtkWidget *item, EMFolderTree *emft)
-{
-
-}
-
-static void
-emft_popup_open_new (GtkWidget *item, EMFolderTree *emft)
-{
-}
-#endif
-
-static void
-emft_popup_copy(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolderInfo *fi = NULL;
-
- /* FIXME: use async apis */
- if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL)
- em_folder_utils_copy_folder(fi, FALSE);
-}
-
-static void
-emft_popup_move(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolderInfo *fi = NULL;
-
- /* FIXME: use async apis */
- if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL)
- em_folder_utils_copy_folder(fi, TRUE);
-}
-
-static void
-emft_popup_new_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolderInfo *fi;
-
- if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL) {
- em_folder_utils_create_folder (fi, emft, NULL);
- camel_folder_info_free(fi);
- }
-}
-
-static void
-selfunc (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
- struct _emft_selection_data *dat = (struct _emft_selection_data *) data;
-
- dat->model = model;
- if (!dat->set)
- *(dat->iter) = *iter;
- dat->set = TRUE;
-}
-
-static gboolean
-emft_selection_get_selected (GtkTreeSelection *selection, GtkTreeModel **model, GtkTreeIter *iter)
-{
- struct _emft_selection_data dat = { NULL, iter, FALSE };
-
- if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_MULTIPLE) {
- gtk_tree_selection_selected_foreach (selection, selfunc, &dat);
- if (model)
- *model = dat.model;
- return dat.set;
- } else {
- return gtk_tree_selection_get_selected (selection, model, iter);
- }
-}
-
-static void
-emft_popup_delete_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- em_folder_utils_delete_folder(folder);
- }
-}
-
-static void
-emft_popup_rename_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- em_folder_utils_rename_folder(folder);
- }
-}
-
-static void
-emft_popup_refresh_folder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- EMEvent *e = em_event_peek();
- EMEventTargetFolder *t = em_event_target_new_folder(e, folder->full_name, 0);
- e_event_emit((EEvent *)e, "folder.refresh", (EEventTarget *)t);
- mail_refresh_folder(folder, NULL, NULL);
- }
-}
-
-static void
-emft_popup_flush_outbox (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- mail_send ();
-}
-
-static void
-emft_popup_empty_trash (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- em_utils_empty_trash (data);
-}
-
-static void
-emft_popup_properties (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- gchar *uri;
-
- selection = gtk_tree_view_get_selection (priv->treeview);
- if (!emft_selection_get_selected (selection, &model, &iter))
- return;
-
- gtk_tree_model_get (model, &iter, COL_STRING_URI, &uri, -1);
- em_folder_properties_show (NULL, NULL, uri);
- g_free (uri);
-}
-
-static void
-emft_popup_uvfolder (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderTree *emft = data;
- CamelFolder *folder;
-
- if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
- gchar *meta = camel_object_meta_get(folder, "vfolder:unread");
- if (!meta || strcmp(meta, "false") == 0)
- camel_object_meta_set(folder, "vfolder:unread", "true");
- else
- camel_object_meta_set(folder, "vfolder:unread", "false");
- camel_object_state_write (folder);
- g_free (meta);
- }
-}
-
-static EPopupItem emft_popup_items[] = {
-#if 0
- { E_POPUP_ITEM, "00.emc.00", N_("_View"), emft_popup_view, NULL, NULL, EM_POPUP_FOLDER_SELECT },
- { E_POPUP_ITEM, "00.emc.01", N_("Open in _New Window"), emft_popup_open_new, NULL, NULL, EM_POPUP_FOLDER_SELECT },
-
- { E_POPUP_BAR, "10.emc" },
-#endif
- /* FIXME: need to disable for nochildren folders */
- { E_POPUP_ITEM, (gchar *) "10.emc.00", (gchar *) N_("_New Folder..."), emft_popup_new_folder, NULL, (gchar *) "folder-new", 0, EM_POPUP_FOLDER_INFERIORS },
-
- { E_POPUP_ITEM, (gchar *) "10.emc.05", (gchar *) N_("_Copy..."), emft_popup_copy, NULL, (gchar *) "folder-copy", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT },
- { E_POPUP_ITEM, (gchar *) "10.emc.06", (gchar *) N_("_Move..."), emft_popup_move, NULL, (gchar *) "folder-move", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_DELETE },
-
- /* FIXME: need to disable for undeletable folders */
- { E_POPUP_BAR, (gchar *) "20.emc" },
- { E_POPUP_ITEM, (gchar *) "20.emc.01", (gchar *) N_("_Delete"), emft_popup_delete_folder, NULL, (gchar *) "edit-delete", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_DELETE },
-
- { E_POPUP_BAR, (gchar *) "30.emc" },
- { E_POPUP_ITEM, (gchar *) "30.emc.02", (gchar *) N_("_Rename..."), emft_popup_rename_folder, NULL, NULL, 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_DELETE },
- { E_POPUP_ITEM, (gchar *) "30.emc.03", (gchar *) N_("Re_fresh"), emft_popup_refresh_folder, NULL, (gchar *) "view-refresh", EM_POPUP_FOLDER_NONSTATIC, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT},
- { E_POPUP_ITEM, (gchar *) "30.emc.04", (gchar *) N_("Fl_ush Outbox"), emft_popup_flush_outbox, NULL, (gchar *) "mail-send", EM_POPUP_FOLDER_OUTBOX, 0 },
-
- { E_POPUP_BAR, (gchar *) "99.emc" },
- { E_POPUP_ITEM, (gchar *) "99.emc.00", (gchar *) N_("_Properties"), emft_popup_properties, NULL, (gchar *) "document-properties", 0, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT }
-};
-static EPopupItem trash_popup_item = {E_POPUP_ITEM, (gchar *) "30.emc.05", (gchar *) N_("_Empty Trash"), emft_popup_empty_trash,NULL,NULL, 1, EM_POPUP_FOLDER_FOLDER|EM_POPUP_FOLDER_SELECT};
-
-static void
-emft_popup_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static gboolean
-emft_popup (EMFolderTree *emft, GdkEvent *event)
-{
- GtkTreeView *treeview;
- GtkTreeSelection *selection;
- CamelStore *local, *store;
- EMPopupTargetFolder *target;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GSList *menus = NULL;
- guint32 info_flags = 0;
- guint32 flags = 0;
- guint32 folder_type_flags = 0;
- gboolean isstore;
- gchar *uri, *full_name;
- GtkMenu *menu;
- EMPopup *emp;
- CamelFolder *selfolder = NULL;
- gint i;
-
- treeview = emft->priv->treeview;
-
- /* this centralises working out when the user's done something */
- emft_tree_user_event(treeview, (GdkEvent *)event, emft);
-
- /* FIXME: we really need the folderinfo to build a proper menu */
- selection = gtk_tree_view_get_selection (treeview);
- if (!emft_selection_get_selected (selection, &model, &iter))
- return FALSE;
-
- gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_URI, &uri, COL_STRING_FULL_NAME, &full_name,
- COL_BOOL_IS_STORE, &isstore, COL_UINT_FLAGS, &folder_type_flags, -1);
-
- /* Stores have full_name == NULL, otherwise its just a placeholder */
- /* NB: This is kind of messy */
- if (!isstore && full_name == NULL) {
- g_free (uri);
- return FALSE;
- }
-
- /* TODO: em_popup_target_folder_new? */
- if (isstore) {
- flags |= EM_POPUP_FOLDER_STORE;
- } else {
- flags |= EM_POPUP_FOLDER_FOLDER;
-
- local = mail_component_peek_local_store (NULL);
-
- /* don't allow deletion of special local folders */
- if (!(store == local && is_special_local_folder (full_name)))
- flags |= EM_POPUP_FOLDER_DELETE;
-
- /* hack for vTrash/vJunk */
- if (!strcmp (full_name, CAMEL_VTRASH_NAME) || !strcmp (full_name, CAMEL_VJUNK_NAME))
- info_flags |= CAMEL_FOLDER_VIRTUAL | CAMEL_FOLDER_NOINFERIORS;
-
- selfolder = em_folder_tree_get_selected_folder (emft);
-
- if (folder_type_flags & CAMEL_FOLDER_SYSTEM)
- flags &= ~EM_POPUP_FOLDER_DELETE;
-
- if (em_utils_folder_is_outbox (selfolder, NULL))
- info_flags |= CAMEL_FOLDER_TYPE_OUTBOX;
- }
-
- /** @HookPoint-EMPopup: Folder Tree Context Menu
- * @Id: org.gnome.evolution.mail.foldertree.popup
- * @Class: org.gnome.evolution.mail.popup:1.0
- * @Target: EMPopupTargetFolder
- *
- * This is the context menu shown on the folder tree.
- */
- emp = em_popup_new ("org.gnome.evolution.mail.foldertree.popup");
-
- /* FIXME: pass valid fi->flags here */
- target = em_popup_target_new_folder (emp, uri, info_flags, flags);
-
- for (i = 0; i < sizeof (emft_popup_items) / sizeof (emft_popup_items[0]); i++)
- menus = g_slist_prepend (menus, &emft_popup_items[i]);
-
- if ((folder_type_flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_TRASH)
- menus = g_slist_prepend (menus, &trash_popup_item);
- if (!isstore && strstr(uri, "vfolder")) {
- /* This is a vfolder, so lets add hacked up menu item. */
- static EPopupItem *item = NULL;
- gchar *meta = camel_object_meta_get (selfolder, "vfolder:unread");
-
- if (!item)
- item = g_malloc0(sizeof(*item));
- if (meta && (strcmp (meta, "true") == 0))
- item->type = E_POPUP_TOGGLE | E_POPUP_ACTIVE;
- else
- item->type = E_POPUP_TOGGLE & ~E_POPUP_ACTIVE;
- item->path = (gchar *) "99.emc.99";
- item->label = _("_Unread Search Folder");
- item->activate = emft_popup_uvfolder;
- item->visible = EM_POPUP_FOLDER_SELECT;
- item->user_data = NULL;
- menus = g_slist_prepend (menus, item);
- g_free (meta);
- }
-
- e_popup_add_items ((EPopup *)emp, menus, NULL, emft_popup_free, emft);
-
- menu = e_popup_create_menu_once ((EPopup *)emp, (EPopupTarget *)target, 0);
-
- if (event == NULL || event->type == GDK_KEY_PRESS) {
- /* FIXME: menu pos function */
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
- } else {
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button.button, event->button.time);
- }
-
- g_free (full_name);
- g_free (uri);
-
- return TRUE;
-}
-
-static gboolean
-emft_popup_menu (GtkWidget *widget)
-{
- return emft_popup (EM_FOLDER_TREE (widget), NULL);
-}
-
-static gboolean
-emft_tree_button_press (GtkTreeView *treeview, GdkEventButton *event, EMFolderTree *emft)
-{
- GtkTreeSelection *selection;
- GtkTreePath *tree_path;
-
- /* this centralises working out when the user's done something */
- emft_tree_user_event(treeview, (GdkEvent *)event, emft);
-
- if (event->button != 3 && !(event->button == 1 && event->type == GDK_2BUTTON_PRESS))
- return FALSE;
-
- if (!gtk_tree_view_get_path_at_pos (treeview, (gint) event->x, (gint) event->y, &tree_path, NULL, NULL, NULL))
- return FALSE;
-
- /* select/focus the row that was right-clicked or double-clicked */
- selection = gtk_tree_view_get_selection (treeview);
- gtk_tree_selection_select_path(selection, tree_path);
- gtk_tree_view_set_cursor (treeview, tree_path, NULL, FALSE);
-
- if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
- if (emft->priv->skip_double_click) {
- return FALSE;
- }
- emft_tree_row_activated (treeview, tree_path, NULL, emft);
- gtk_tree_path_free (tree_path);
- return TRUE;
- }
-
- gtk_tree_path_free (tree_path);
-
- return emft_popup (emft, (GdkEvent *)event);
-}
-
-/* This is called for keyboard and mouse events, it seems the only way
- * we know the user has done something to the selection as opposed to
- * code or initialisation processes */
-static gboolean
-emft_tree_user_event (GtkTreeView *treeview, GdkEvent *e, EMFolderTree *emft)
-{
- if (e && e->type == GDK_KEY_PRESS && (e->key.keyval == GDK_space || e->key.keyval == '.' || e->key.keyval == ',' || e->key.keyval == '[' || e->key.keyval == ']')) {
- g_signal_emit (emft, signals [HIDDEN_KEY_EVENT], 0, e);
-
- return TRUE;
- }
- if (!emft->priv->do_multiselect)
- emft_clear_selected_list(emft);
-
- emft->priv->cursor_set = TRUE;
-
- return FALSE;
-}
-
-static void
-emft_tree_selection_changed (GtkTreeSelection *selection, EMFolderTree *emft)
-{
- gchar *full_name, *uri;
- GtkTreeModel *model;
- GtkTreeIter iter;
- guint32 flags;
- guint unread = 0;
- guint old_unread = 0;
-
- if (!emft_selection_get_selected (selection, &model, &iter)) {
- em_folder_tree_model_set_selected (emft->priv->model, NULL);
- g_signal_emit (emft, signals[FOLDER_SELECTED], 0, NULL, NULL, 0);
- emft_queue_save_state (emft);
- return;
- }
-
- gtk_tree_model_get (
- model, &iter,
- COL_STRING_FULL_NAME, &full_name,
- COL_STRING_URI, &uri, COL_UINT_FLAGS, &flags,
- COL_UINT_UNREAD, &unread, COL_UINT_UNREAD_LAST_SEL,
- &old_unread, -1);
-
- /* Sync unread counts to distinguish new incoming mail. */
- if (unread != old_unread)
- gtk_tree_store_set (
- GTK_TREE_STORE (model), &iter,
- COL_UINT_UNREAD_LAST_SEL, unread, -1);
-
- g_signal_emit (emft, signals[FOLDER_SELECTED], 0, full_name, uri, flags);
- g_free(uri);
- g_free(full_name);
-}
-
void
-em_folder_tree_set_selected (EMFolderTree *emft, const gchar *uri, gboolean expand_only)
+em_folder_tree_set_selected (EMFolderTree *emft,
+ const gchar *uri,
+ gboolean expand_only)
{
GList *l = NULL;
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+
if (uri && uri[0])
l = g_list_append(l, (gpointer)uri);
@@ -2355,16 +2145,18 @@ em_folder_tree_set_selected (EMFolderTree *emft, const gchar *uri, gboolean expa
void
em_folder_tree_select_next_path (EMFolderTree *emft, gboolean skip_read_folders)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter, parent, child;
GtkTreePath *current_path, *path = NULL;
guint unread = 0;
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
g_return_if_fail (EM_IS_FOLDER_TREE (emft));
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection(tree_view);
if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
current_path = gtk_tree_model_get_path (model, &iter);
@@ -2399,16 +2191,16 @@ em_folder_tree_select_next_path (EMFolderTree *emft, gboolean skip_read_folders)
}
if (path) {
- if (!gtk_tree_view_row_expanded (emft->priv->treeview, path))
- gtk_tree_view_expand_to_path (emft->priv->treeview, path);
+ if (!gtk_tree_view_row_expanded (tree_view, path))
+ gtk_tree_view_expand_to_path (tree_view, path);
gtk_tree_selection_select_path(selection, path);
if (!priv->cursor_set) {
- gtk_tree_view_set_cursor (priv->treeview, path, NULL, FALSE);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
priv->cursor_set = TRUE;
}
- gtk_tree_view_scroll_to_cell (priv->treeview, path, NULL, TRUE, 0.5f, 0.0f);
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5f, 0.0f);
}
return;
}
@@ -2434,16 +2226,18 @@ get_last_child (GtkTreeModel *model, GtkTreeIter *iter)
void
em_folder_tree_select_prev_path (EMFolderTree *emft, gboolean skip_read_folders)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter, child;
GtkTreePath *path = NULL, *current_path = NULL;
guint unread = 0;
- struct _EMFolderTreePrivate *priv = emft->priv;
+ EMFolderTreePrivate *priv = emft->priv;
g_return_if_fail (EM_IS_FOLDER_TREE (emft));
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
if (gtk_tree_selection_get_selected(selection, &model, &iter)){
@@ -2477,17 +2271,17 @@ em_folder_tree_select_prev_path (EMFolderTree *emft, gboolean skip_read_folders)
}
if (path) {
- if (!gtk_tree_view_row_expanded (priv->treeview, path)) {
- gtk_tree_view_expand_to_path (priv->treeview, path);
+ if (!gtk_tree_view_row_expanded (tree_view, path)) {
+ gtk_tree_view_expand_to_path (tree_view, path);
}
gtk_tree_selection_select_path(selection, path);
if (!priv->cursor_set) {
- gtk_tree_view_set_cursor (priv->treeview, path, NULL, FALSE);
+ gtk_tree_view_set_cursor (tree_view, path, NULL, FALSE);
priv->cursor_set = TRUE;
}
- gtk_tree_view_scroll_to_cell (priv->treeview, path, NULL, TRUE, 0.5f, 0.0f);
+ gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5f, 0.0f);
}
return;
}
@@ -2495,6 +2289,7 @@ em_folder_tree_select_prev_path (EMFolderTree *emft, gboolean skip_read_folders)
gchar *
em_folder_tree_get_selected_uri (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2502,9 +2297,13 @@ em_folder_tree_get_selected_uri (EMFolderTree *emft)
g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- gtk_tree_model_get(model, &iter, COL_STRING_URI, &uri, -1);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COL_STRING_URI, &uri, -1);
return uri;
}
@@ -2512,6 +2311,7 @@ em_folder_tree_get_selected_uri (EMFolderTree *emft)
gchar *
em_folder_tree_get_selected_path (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2519,9 +2319,13 @@ em_folder_tree_get_selected_path (EMFolderTree *emft)
g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
- if (gtk_tree_selection_get_selected(selection, &model, &iter))
- gtk_tree_model_get(model, &iter, COL_STRING_FULL_NAME, &name, -1);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COL_STRING_FULL_NAME, &name, -1);
return name;
}
@@ -2529,6 +2333,7 @@ em_folder_tree_get_selected_path (EMFolderTree *emft)
CamelFolder *
em_folder_tree_get_selected_folder (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2541,7 +2346,9 @@ em_folder_tree_get_selected_folder (EMFolderTree *emft)
camel_exception_init (&ex);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
if (gtk_tree_selection_get_selected(selection, &model, &iter))
gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
COL_STRING_FULL_NAME, &full_name, -1);
@@ -2557,6 +2364,7 @@ em_folder_tree_get_selected_folder (EMFolderTree *emft)
CamelFolderInfo *
em_folder_tree_get_selected_folder_info (EMFolderTree *emft)
{
+ GtkTreeView *tree_view;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2569,7 +2377,9 @@ em_folder_tree_get_selected_folder_info (EMFolderTree *emft)
camel_exception_init (&ex);
- selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ tree_view = GTK_TREE_VIEW (emft);
+ selection = gtk_tree_view_get_selection (tree_view);
+
if (gtk_tree_selection_get_selected(selection, &model, &iter))
gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
COL_STRING_FULL_NAME, &full_name,
@@ -2598,54 +2408,6 @@ em_folder_tree_get_selected_folder_info (EMFolderTree *emft)
return fi;
}
-EMFolderTreeModel *
-em_folder_tree_get_model (EMFolderTree *emft)
-{
- g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
-
- return emft->priv->model;
-}
-
-EMFolderTreeModelStoreInfo *
-em_folder_tree_get_model_storeinfo (EMFolderTree *emft, CamelStore *store)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
- g_return_val_if_reached (NULL);
- }
- return si;
-}
-
-static gboolean
-emft_save_state (EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- em_folder_tree_model_save_state (priv->model);
- priv->save_state_id = 0;
-
- return FALSE;
-}
-
-static void
-emft_queue_save_state (EMFolderTree *emft)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
-
- if (priv->save_state_id != 0)
- return;
-
- priv->save_state_id = g_timeout_add_seconds (1, (GSourceFunc) emft_save_state, emft);
-}
-
-GtkWidget *
-em_folder_tree_get_tree_view (EMFolderTree *emft)
-{
- return (GtkWidget *)emft->priv->treeview;
-}
-
void
em_folder_tree_set_skip_double_click (EMFolderTree *emft, gboolean skip)
{
diff --git a/mail/em-folder-tree.h b/mail/em-folder-tree.h
index e8b607151c..74b79d37ee 100644
--- a/mail/em-folder-tree.h
+++ b/mail/em-folder-tree.h
@@ -21,25 +21,37 @@
*
*/
-#ifndef __EM_FOLDER_TREE_H__
-#define __EM_FOLDER_TREE_H__
+#ifndef EM_FOLDER_TREE_H
+#define EM_FOLDER_TREE_H
#include <gtk/gtk.h>
#include <camel/camel-store.h>
-
-#include "mail/em-folder-tree-model.h"
+#include <mail/em-folder-tree-model.h>
+
+/* Standard GObject macros */
+#define EM_TYPE_FOLDER_TREE \
+ (em_folder_tree_get_type ())
+#define EM_FOLDER_TREE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_TYPE_FOLDER_TREE, EMFolderTree))
+#define EM_FOLDER_TREE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_TYPE_FOLDER_TREE, EMFolderTreeClass))
+#define EM_IS_FOLDER_TREE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_TYPE_FOLDER_TREE))
+#define EM_IS_FOLDER_TREE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_TYPE_FOLDER_TREE))
+#define EM_FOLDER_TREE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_TYPE_FOLDER_TREE, EMFolderTreeClass))
G_BEGIN_DECLS
-#define EM_TYPE_FOLDER_TREE (em_folder_tree_get_type ())
-#define EM_FOLDER_TREE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_TYPE_FOLDER_TREE, EMFolderTree))
-#define EM_FOLDER_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EM_TYPE_FOLDER_TREE, EMFolderTreeClass))
-#define EM_IS_FOLDER_TREE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_TYPE_FOLDER_TREE))
-#define EM_IS_FOLDER_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EM_TYPE_FOLDER_TREE))
-#define EM_FOLDER_TREE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EM_TYPE_FOLDER_TREE, EMFolderTreeClass))
-
typedef struct _EMFolderTree EMFolderTree;
typedef struct _EMFolderTreeClass EMFolderTreeClass;
+typedef struct _EMFolderTreePrivate EMFolderTreePrivate;
/* not sure this api is the best, but its the easiest to implement and will cover what we need */
#define EMFT_EXCLUDE_NOSELECT CAMEL_FOLDER_NOSELECT
@@ -51,28 +63,29 @@ typedef struct _EMFolderTreeClass EMFolderTreeClass;
typedef gboolean (*EMFTExcludeFunc)(EMFolderTree *emft, GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
struct _EMFolderTree {
- GtkVBox parent_object;
-
- struct _EMFolderTreePrivate *priv;
+ GtkTreeView parent_object;
+ EMFolderTreePrivate *priv;
};
struct _EMFolderTreeClass {
- GtkVBoxClass parent_class;
+ GtkTreeViewClass parent_class;
/* signals */
- void (* folder_activated) (EMFolderTree *emft, const gchar *full_name, const gchar *uri);
- void (* folder_selected) (EMFolderTree *emft, const gchar *full_name, const gchar *uri, guint32 flags);
- void (* hidden_key_event) (EMFolderTree *emft, GdkEvent *event);
+ void (*folder_activated) (EMFolderTree *emft,
+ const gchar *full_name,
+ const gchar *uri);
+ void (*folder_selected) (EMFolderTree *emft,
+ const gchar *full_name,
+ const gchar *uri,
+ guint32 flags);
+ void (*popup_event) (EMFolderTree *emft);
};
-GType em_folder_tree_get_type (void);
-
-GtkWidget *em_folder_tree_new (void);
-GtkWidget *em_folder_tree_new_with_model (EMFolderTreeModel *model);
+GType em_folder_tree_get_type (void);
+GtkWidget * em_folder_tree_new (void);
void em_folder_tree_enable_drag_and_drop (EMFolderTree *emft);
-void em_folder_tree_set_multiselect (EMFolderTree *emft, gboolean mode);
void em_folder_tree_set_excluded(EMFolderTree *emft, guint32 flags);
void em_folder_tree_set_excluded_func(EMFolderTree *emft, EMFTExcludeFunc exclude, gpointer data);
@@ -88,13 +101,9 @@ gchar *em_folder_tree_get_selected_path (EMFolderTree *emft);
CamelFolder *em_folder_tree_get_selected_folder (EMFolderTree *emft);
CamelFolderInfo *em_folder_tree_get_selected_folder_info (EMFolderTree *emft);
-EMFolderTreeModel *em_folder_tree_get_model (EMFolderTree *emft);
-EMFolderTreeModelStoreInfo *em_folder_tree_get_model_storeinfo (EMFolderTree *emft, CamelStore *store);
-
gboolean em_folder_tree_create_folder (EMFolderTree *emft, const gchar *full_name, const gchar *uri);
-GtkWidget * em_folder_tree_get_tree_view (EMFolderTree *emft);
void em_folder_tree_set_skip_double_click (EMFolderTree *emft, gboolean skip);
G_END_DECLS
-#endif /* __EM_FOLDER_TREE_H__ */
+#endif /* EM_FOLDER_TREE_H */
diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c
index 7a23cb5f0c..904e3908ce 100644
--- a/mail/em-folder-utils.c
+++ b/mail/em-folder-utils.c
@@ -57,7 +57,6 @@
#include "mail-ops.h"
#include "mail-tools.h"
#include "mail-config.h"
-#include "mail-component.h"
#include "mail-vfolder.h"
#include "mail-folder-cache.h"
@@ -70,6 +69,9 @@
#include "em-folder-selection.h"
#include "em-folder-properties.h"
+#include "e-mail-local.h"
+#include "e-mail-store.h"
+
#define d(x)
extern CamelSession *session;
@@ -268,6 +270,7 @@ emfu_copy_folder_selected (const gchar *uri, gpointer data)
{
struct _copy_folder_data *cfd = data;
CamelStore *fromstore = NULL, *tostore = NULL;
+ CamelStore *local_store;
const gchar *tobase = NULL;
CamelException ex;
CamelURL *url;
@@ -279,13 +282,15 @@ emfu_copy_folder_selected (const gchar *uri, gpointer data)
camel_exception_init (&ex);
+ local_store = e_mail_local_get_store ();
+
if (!(fromstore = camel_session_get_store (session, cfd->fi->uri, &ex))) {
e_error_run(NULL,
cfd->delete?"mail:no-move-folder-notexist":"mail:no-copy-folder-notexist", cfd->fi->full_name, uri, ex.desc, NULL);
goto fail;
}
- if (cfd->delete && fromstore == mail_component_peek_local_store (NULL) && emfu_is_special_local_folder (cfd->fi->full_name)) {
+ if (cfd->delete && fromstore == local_store && emfu_is_special_local_folder (cfd->fi->full_name)) {
GtkWidget *w = e_error_new (NULL,
"mail:no-rename-special-folder", cfd->fi->full_name, NULL);
em_utils_show_error_silent (w);
@@ -351,17 +356,22 @@ emfu_copy_folder_exclude(EMFolderTree *tree, GtkTreeModel *model, GtkTreeIter *i
/* FIXME: this interface references the folderinfo without copying it */
/* FIXME: these functions must be documented */
void
-em_folder_utils_copy_folder(CamelFolderInfo *folderinfo, gint delete)
+em_folder_utils_copy_folder (CamelFolderInfo *folderinfo,
+ gint delete)
{
struct _copy_folder_data *cfd;
+ g_return_if_fail (folderinfo != NULL);
+
cfd = g_malloc (sizeof (*cfd));
cfd->fi = folderinfo;
cfd->delete = delete;
- em_select_folder (NULL, _("Select folder"), delete?_("_Move"):_("C_opy"),
- NULL, emfu_copy_folder_exclude,
- emfu_copy_folder_selected, cfd);
+ em_select_folder (
+ _("Select folder"),
+ delete ? _("_Move") : _("C_opy"),
+ NULL, emfu_copy_folder_exclude,
+ emfu_copy_folder_selected, cfd);
}
static void
@@ -397,13 +407,13 @@ emfu_delete_response (GtkWidget *dialog, gint response, gpointer data)
void
em_folder_utils_delete_folder (CamelFolder *folder)
{
- CamelStore *local;
+ CamelStore *local_store;
GtkWidget *dialog;
gint flags = 0;
- local = mail_component_peek_local_store (NULL);
+ local_store = e_mail_local_get_store ();
- if (folder->parent_store == local && emfu_is_special_local_folder (folder->full_name)) {
+ if (folder->parent_store == local_store && emfu_is_special_local_folder (folder->full_name)) {
dialog = e_error_new (NULL, "mail:no-delete-special-folder", folder->full_name, NULL);
em_utils_show_error_silent (dialog);
return;
@@ -432,14 +442,14 @@ em_folder_utils_rename_folder (CamelFolder *folder)
{
gchar *prompt, *new_name;
const gchar *p;
- CamelStore *local;
+ CamelStore *local_store;
gboolean done = FALSE;
gsize base_len;
- local = mail_component_peek_local_store (NULL);
+ local_store = e_mail_local_get_store ();
/* don't allow user to rename one of the special local folders */
- if (folder->parent_store == local && emfu_is_special_local_folder (folder->full_name)) {
+ if (folder->parent_store == local_store && emfu_is_special_local_folder (folder->full_name)) {
e_error_run(NULL,
"mail:no-rename-special-folder", folder->full_name, NULL);
return;
@@ -627,6 +637,7 @@ static void
emfu_popup_new_folder_response (EMFolderSelector *emfs, gint response, gpointer data)
{
EMFolderTreeModelStoreInfo *si;
+ GtkTreeModel *model;
const gchar *uri, *path;
CamelException ex;
CamelStore *store;
@@ -650,7 +661,10 @@ emfu_popup_new_folder_response (EMFolderSelector *emfs, gint response, gpointer
return;
}
- if (!(si = em_folder_tree_get_model_storeinfo (emfs->emft, store))) {
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (emfs->emft));
+ si = em_folder_tree_model_lookup_store_info (
+ EM_FOLDER_TREE_MODEL (model), store);
+ if (si == NULL) {
camel_object_unref (store);
g_return_if_reached();
}
@@ -686,13 +700,11 @@ void
em_folder_utils_create_folder (CamelFolderInfo *folderinfo, EMFolderTree *emft, GtkWindow *parent)
{
EMFolderTree *folder_tree;
- EMFolderTreeModel *model;
GtkWidget *dialog;
- model = mail_component_peek_tree_model (mail_component_peek ());
- folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model);
+ folder_tree = (EMFolderTree *) em_folder_tree_new ();
- dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:"));
+ dialog = em_folder_selector_create_new (folder_tree, 0, _("Create Folder"), _("Specify where to create the folder:"));
if (folderinfo != NULL)
em_folder_selector_set_selected ((EMFolderSelector *) dialog, folderinfo->uri);
if (parent) {
@@ -705,6 +717,72 @@ em_folder_utils_create_folder (CamelFolderInfo *folderinfo, EMFolderTree *emft,
gtk_widget_show (dialog);
}
+struct _folder_unsub_t {
+ MailMsg base;
+ gchar *folder_uri;
+};
+
+static gchar *
+emfu_unsubscribe_folder__desc (struct _folder_unsub_t *msg)
+{
+ return g_strdup_printf (
+ _("Unsubscribing from folder \"%s\""), msg->folder_uri);
+}
+
+static void
+emfu_unsubscribe_folder__exec (struct _folder_unsub_t *msg)
+{
+ CamelStore *store;
+ CamelURL *url;
+ const gchar *path = NULL;
+ gint url_flags;
+
+ store = camel_session_get_store (
+ session, msg->folder_uri, &msg->base.ex);
+ if (store == NULL)
+ return;
+
+ url = camel_url_new (msg->folder_uri, NULL);
+ url_flags = CAMEL_SERVICE (store)->provider->url_flags;
+
+ if (url_flags & CAMEL_URL_FRAGMENT_IS_PATH)
+ path = url->fragment;
+ else if (url->path != NULL && *url->path != '\0')
+ path = url->path + 1;
+
+ if (path != NULL)
+ camel_store_unsubscribe_folder (store, path, &msg->base.ex);
+
+ camel_url_free (url);
+}
+
+static void
+emfu_unsubscribe_folder__free (struct _folder_unsub_t *msg)
+{
+ g_free (msg->folder_uri);
+}
+
+static MailMsgInfo unsubscribe_info = {
+ sizeof (struct _folder_unsub_t),
+ (MailMsgDescFunc) emfu_unsubscribe_folder__desc,
+ (MailMsgExecFunc) emfu_unsubscribe_folder__exec,
+ (MailMsgDoneFunc) NULL,
+ (MailMsgFreeFunc) emfu_unsubscribe_folder__free
+};
+
+void
+em_folder_utils_unsubscribe_folder (const gchar *folder_uri)
+{
+ struct _folder_unsub_t *unsub;
+
+ g_return_if_fail (folder_uri != NULL);
+
+ unsub = mail_msg_new (&unsubscribe_info);
+ unsub->folder_uri = g_strdup (folder_uri);
+
+ mail_msg_unordered_push (unsub);
+}
+
const gchar *
em_folder_utils_get_icon_name (guint32 flags)
{
diff --git a/mail/em-folder-utils.h b/mail/em-folder-utils.h
index d0c5e986c6..d0db789b96 100644
--- a/mail/em-folder-utils.h
+++ b/mail/em-folder-utils.h
@@ -24,7 +24,7 @@
#ifndef EM_FOLDER_UTILS_H
#define EM_FOLDER_UTILS_H
-#include <glib.h>
+#include <gtk/gtk.h>
#include <camel/camel-folder.h>
#include <camel/camel-store.h>
#include <mail/em-folder-tree.h>
@@ -41,14 +41,14 @@ gint em_folder_utils_copy_folders (CamelStore *fromstore,
* most rely on the wrong data. */
void em_folder_utils_copy_folder (CamelFolderInfo *folderinfo,
- gint delete);
-
+ gboolean delete);
void em_folder_utils_delete_folder (CamelFolder *folder);
void em_folder_utils_rename_folder (CamelFolder *folder);
-
void em_folder_utils_create_folder (CamelFolderInfo *folderinfo,
- EMFolderTree * emft,
+ EMFolderTree *emft,
GtkWindow *parent);
+void em_folder_utils_unsubscribe_folder
+ (const gchar *folder_uri);
const gchar * em_folder_utils_get_icon_name (guint32 flags);
diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c
index 3025031909..26ebac670f 100644
--- a/mail/em-folder-view.c
+++ b/mail/em-folder-view.c
@@ -27,6 +27,7 @@
#include <sys/stat.h>
#include <unistd.h>
+#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gdk/gdkkeysyms.h>
@@ -54,13 +55,6 @@
#include <camel/camel-offline-store.h>
#include <camel/camel-vee-store.h>
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <bonobo/bonobo-ui-util.h>
-
#include <gtkhtml/gtkhtml.h>
#include <gtkhtml/gtkhtml-embedded.h>
#include <gtkhtml/gtkhtml-stream.h>
@@ -71,10 +65,8 @@
#include "menus/gal-view-etable.h"
#include "menus/gal-view-factory-etable.h"
#include "menus/gal-view-instance.h"
-#include "menus/gal-view-menus.h"
#include "misc/e-charset-picker.h"
-#include <misc/e-filter-bar.h>
#include <misc/e-spinner.h>
#include "e-util/e-error.h"
@@ -84,6 +76,7 @@
#include "e-util/e-profile-event.h"
#include "e-util/e-util-private.h"
#include "e-util/e-util-labels.h"
+#include "shell/e-shell.h"
#include "filter/filter-rule.h"
@@ -94,109 +87,76 @@
#include "em-folder-browser.h"
#include "em-mailer-prefs.h"
#include "em-folder-browser.h"
-#include "em-message-browser.h"
#include "message-list.h"
#include "em-utils.h"
#include "em-composer-utils.h"
#include "em-menu.h"
#include "em-event.h"
+#include "e-mail-shell-backend.h"
#include "mail-mt.h"
#include "mail-ops.h"
#include "mail-config.h"
#include "mail-autofilter.h"
#include "mail-vfolder.h"
-#include "mail-component.h"
#include "mail-tools.h"
-#include "evolution-shell-component-utils.h" /* Pixmap stuff, sigh */
-
#ifdef HAVE_XFREE
#include <X11/XF86keysym.h>
#endif
-static void emfv_list_message_selected(MessageList *ml, const gchar *uid, EMFolderView *emfv);
-static void emfv_list_built(MessageList *ml, EMFolderView *emfv);
-static gint emfv_list_right_click(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, EMFolderView *emfv);
-static void emfv_list_double_click(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, EMFolderView *emfv);
-static gint emfv_list_key_press(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *ev, EMFolderView *emfv);
-static void emfv_list_selection_change(ETree *tree, EMFolderView *emfv);
-
-static void emfv_format_link_clicked(EMFormatHTMLDisplay *efhd, const gchar *uri, EMFolderView *);
-static gint emfv_format_popup_event(EMFormatHTMLDisplay *efhd, GdkEventButton *event, const gchar *uri, CamelMimePart *part, EMFolderView *);
-
-static void emfv_enable_menus(EMFolderView *emfv);
-
-static void emfv_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri);
-static void emfv_set_folder_uri(EMFolderView *emfv, const gchar *uri);
-static void emfv_set_message(EMFolderView *emfv, const gchar *uid, gint nomarkseen);
-static void emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint state);
-
-static void emfv_message_reply(EMFolderView *emfv, gint mode);
-static void vfolder_type_current (EMFolderView *emfv, gint type);
-static void filter_type_current (EMFolderView *emfv, gint type);
-
-static void emfv_setting_setup(EMFolderView *emfv);
-
-static void emfv_on_url_cb(GObject *emitter, const gchar *url, EMFolderView *emfv);
-static void emfv_on_url(EMFolderView *emfv, const gchar *uri, const gchar *nice_uri);
-
-static void emfv_set_seen (EMFolderView *emfv, const gchar *uid);
-static gboolean emfv_on_html_button_released_cb (GtkHTML *html, GdkEventButton *button, EMFolderView *emfv);
-static gboolean emfv_popup_menu (GtkWidget *widget);
-
/* this is added to emfv->enable_map in :init() */
static const EMFolderViewEnable emfv_enable_map[] = {
{ "EditCut", EM_POPUP_SELECT_MANY },
{ "EditCopy", EM_FOLDER_VIEW_SELECT_SELECTION },
{ "EditPaste", EM_POPUP_SELECT_FOLDER },
- { "SelectAllText", EM_POPUP_SELECT_ONE },
+// { "SelectAllText", EM_POPUP_SELECT_ONE },
/* FIXME: should these be single-selection? */
{ "MailNext", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_NEXT_MSG },
- { "MailNextFlagged", EM_POPUP_SELECT_MANY },
- { "MailNextUnread", EM_POPUP_SELECT_MANY },
- { "MailNextThread", EM_POPUP_SELECT_MANY },
+// { "MailNextFlagged", EM_POPUP_SELECT_MANY },
+// { "MailNextUnread", EM_POPUP_SELECT_MANY },
+// { "MailNextThread", EM_POPUP_SELECT_MANY },
{ "MailPrevious", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_PREV_MSG },
- { "MailPreviousFlagged", EM_POPUP_SELECT_MANY },
- { "MailPreviousUnread", EM_POPUP_SELECT_MANY },
+// { "MailPreviousFlagged", EM_POPUP_SELECT_MANY },
+// { "MailPreviousUnread", EM_POPUP_SELECT_MANY },
{ "AddSenderToAddressbook", EM_POPUP_SELECT_ADD_SENDER },
- { "MessageApplyFilters", EM_POPUP_SELECT_MANY },
- { "MessageFilterJunk", EM_POPUP_SELECT_MANY },
- { "MessageCopy", EM_POPUP_SELECT_MANY },
- { "MessageDelete", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_DELETE },
- { "MessageDeleteKey", EM_POPUP_SELECT_MANY},
- { "MessageForward", EM_POPUP_SELECT_MANY },
- { "MessageForwardAttached", EM_POPUP_SELECT_MANY },
- { "MessageForwardInline", EM_POPUP_SELECT_ONE },
- { "MessageForwardQuoted", EM_POPUP_SELECT_ONE },
- { "MessageRedirect", EM_POPUP_SELECT_ONE },
- { "MessageMarkAsRead", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_READ },
- { "MessageMarkAsUnRead", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_UNREAD },
- { "MessageMarkAsImportant", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_IMPORTANT },
- { "MessageMarkAsUnimportant", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_UNIMPORTANT },
- { "MessageMarkAsJunk", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_JUNK },
- { "MessageMarkAsNotJunk", EM_POPUP_SELECT_MANY},
+// { "MessageApplyFilters", EM_POPUP_SELECT_MANY },
+// { "MessageFilterJunk", EM_POPUP_SELECT_MANY },
+// { "MessageCopy", EM_POPUP_SELECT_MANY },
+// { "MessageDelete", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_DELETE },
+// { "MessageDeleteKey", EM_POPUP_SELECT_MANY},
+// { "MessageForward", EM_POPUP_SELECT_MANY },
+// { "MessageForwardAttached", EM_POPUP_SELECT_MANY },
+// { "MessageForwardInline", EM_POPUP_SELECT_ONE },
+// { "MessageForwardQuoted", EM_POPUP_SELECT_ONE },
+// { "MessageRedirect", EM_POPUP_SELECT_ONE },
+// { "MessageMarkAsRead", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_READ },
+// { "MessageMarkAsUnRead", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_UNREAD },
+// { "MessageMarkAsImportant", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_IMPORTANT },
+// { "MessageMarkAsUnimportant", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_MARK_UNIMPORTANT },
+// { "MessageMarkAsJunk", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_JUNK },
+// { "MessageMarkAsNotJunk", EM_POPUP_SELECT_MANY},
{ "MessageFollowUpFlag", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_FLAG_FOLLOWUP },
{ "MessageFollowUpComplete", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_FLAG_COMPLETED },
{ "MessageFollowUpClear", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_FLAG_CLEAR },
- { "MessageMove", EM_POPUP_SELECT_MANY },
- { "MessageOpen", EM_POPUP_SELECT_MANY },
- { "MessageReplyAll", EM_POPUP_SELECT_ONE },
- { "MessageReplyList", EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST },
- { "MessageReplySender", EM_POPUP_SELECT_ONE },
- { "MessageEdit", EM_POPUP_SELECT_ONE },
- { "MessageSaveAs", EM_POPUP_SELECT_MANY },
+// { "MessageMove", EM_POPUP_SELECT_MANY },
+// { "MessageOpen", EM_POPUP_SELECT_MANY },
+// { "MessageReplyAll", EM_POPUP_SELECT_ONE },
+// { "MessageReplyList", EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST },
+// { "MessageReplySender", EM_POPUP_SELECT_ONE },
+// { "MessageEdit", EM_POPUP_SELECT_ONE },
+// { "MessageSaveAs", EM_POPUP_SELECT_MANY },
{ "MessageSearch", EM_POPUP_SELECT_ONE| EM_FOLDER_VIEW_PREVIEW_PRESENT },
- { "MessageUndelete", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_UNDELETE },
- { "PrintMessage", EM_POPUP_SELECT_ONE },
- { "PrintPreviewMessage", EM_POPUP_SELECT_ONE },
+// { "MessageUndelete", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_UNDELETE },
+// { "PrintMessage", EM_POPUP_SELECT_ONE },
+// { "PrintPreviewMessage", EM_POPUP_SELECT_ONE },
- { "TextZoomIn", EM_POPUP_SELECT_ONE },
- { "TextZoomOut", EM_POPUP_SELECT_ONE },
- { "TextZoomReset", EM_POPUP_SELECT_ONE },
+// { "TextZoomIn", EM_POPUP_SELECT_ONE },
+// { "TextZoomOut", EM_POPUP_SELECT_ONE },
+// { "TextZoomReset", EM_POPUP_SELECT_ONE },
{ "ToolsFilterMailingList", EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST},
{ "ToolsFilterRecipient", EM_POPUP_SELECT_ONE },
@@ -207,11 +167,11 @@ static const EMFolderViewEnable emfv_enable_map[] = {
{ "ToolsVFolderSender", EM_POPUP_SELECT_ONE },
{ "ToolsVFolderSubject", EM_POPUP_SELECT_ONE },
- { "ViewLoadImages", EM_POPUP_SELECT_ONE },
- { "ViewSource", EM_POPUP_SELECT_ONE },
+// { "ViewLoadImages", EM_POPUP_SELECT_ONE },
+// { "ViewSource", EM_POPUP_SELECT_ONE },
- /* always enabled */
- { "MailStop", 0 },
+// /* always enabled */
+// { "MailStop", 0 },
{ NULL },
};
@@ -225,9 +185,6 @@ struct _EMFolderViewPrivate {
GtkWidget *invisible;
gchar *selection_uri;
- GalViewInstance *view_instance;
- GalViewMenus *view_menus;
-
gchar *selected_uid;
};
@@ -244,147 +201,55 @@ extern CamelSession *session;
static guint signals[LAST_SIGNAL];
-static void emfv_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint time_stamp, EMFolderView *emfv);
-static void emfv_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, EMFolderView *emfv);
-
-#ifdef ENABLE_PROFILING
-static void
-emfv_format_complete(EMFormat *emf, EMFolderView *emfv)
-{
- e_profile_event_emit("goto.done", emf->uid?emf->uid:"", 0);
-}
-#endif
-
static void
emfv_init(GObject *o)
{
EMFolderView *emfv = (EMFolderView *)o;
struct _EMFolderViewPrivate *p;
- gtk_box_set_homogeneous (GTK_BOX (emfv), FALSE);
-
- p = emfv->priv = g_malloc0(sizeof(struct _EMFolderViewPrivate));
-
- emfv->statusbar_active = TRUE;
- emfv->list_active = FALSE;
-
- emfv->ui_files = g_slist_append(NULL,
- g_build_filename (EVOLUTION_UIDIR,
- "evolution-mail-message.xml",
- NULL));
-
- emfv->ui_app_name = "evolution-mail";
+// gtk_box_set_homogeneous (GTK_BOX (emfv), FALSE);
+//
+// p = emfv->priv = g_malloc0(sizeof(struct _EMFolderViewPrivate));
+//
+// emfv->statusbar_active = TRUE;
+// emfv->list_active = FALSE;
+//
+// emfv->ui_files = g_slist_append(NULL,
+// g_build_filename (EVOLUTION_UIDIR,
+// "evolution-mail-message.xml",
+// NULL));
+//
+// emfv->ui_app_name = "evolution-mail";
emfv->enable_map = g_slist_prepend(NULL, (gpointer)emfv_enable_map);
- emfv->list = (MessageList *)message_list_new();
- g_signal_connect(emfv->list, "message_selected", G_CALLBACK(emfv_list_message_selected), emfv);
- g_signal_connect(emfv->list, "message_list_built", G_CALLBACK(emfv_list_built), emfv);
-
- /* FIXME: should this hang off message-list instead? */
- g_signal_connect(emfv->list->tree, "right_click", G_CALLBACK(emfv_list_right_click), emfv);
- g_signal_connect(emfv->list->tree, "double_click", G_CALLBACK(emfv_list_double_click), emfv);
- g_signal_connect(emfv->list->tree, "key_press", G_CALLBACK(emfv_list_key_press), emfv);
- g_signal_connect(emfv->list->tree, "selection_change", G_CALLBACK(emfv_list_selection_change), emfv);
-
- emfv->preview = (EMFormatHTMLDisplay *)em_format_html_display_new();
- /* FIXME: set_session should NOT be called here. Should it be a constructor attribute? */
- em_format_set_session ((EMFormat *) emfv->preview, session);
- g_signal_connect(emfv->preview, "link_clicked", G_CALLBACK(emfv_format_link_clicked), emfv);
+// emfv->list = (MessageList *)message_list_new();
+// g_signal_connect(emfv->list, "message_selected", G_CALLBACK(emfv_list_message_selected), emfv);
+// g_signal_connect(emfv->list, "message_list_built", G_CALLBACK(emfv_list_built), emfv);
+//
+// /* FIXME: should this hang off message-list instead? */
+// g_signal_connect(emfv->list->tree, "right_click", G_CALLBACK(emfv_list_right_click), emfv);
+// g_signal_connect(emfv->list->tree, "double_click", G_CALLBACK(emfv_list_double_click), emfv);
+// g_signal_connect(emfv->list->tree, "key_press", G_CALLBACK(emfv_list_key_press), emfv);
+// g_signal_connect(emfv->list->tree, "selection_change", G_CALLBACK(emfv_list_selection_change), emfv);
+//
+// emfv->preview = (EMFormatHTMLDisplay *)em_format_html_display_new();
+// /* FIXME: set_session should NOT be called here. Should it be a constructor attribute? */
+// em_format_set_session ((EMFormat *) emfv->preview, session);
+// g_signal_connect(emfv->preview, "link_clicked", G_CALLBACK(emfv_format_link_clicked), emfv);
g_signal_connect(emfv->preview, "popup_event", G_CALLBACK(emfv_format_popup_event), emfv);
- g_signal_connect (emfv->preview, "on_url", G_CALLBACK (emfv_on_url_cb), emfv);
- g_signal_connect (((EMFormatHTML *)emfv->preview)->html, "button-release-event", G_CALLBACK (emfv_on_html_button_released_cb), emfv);
-#ifdef ENABLE_PROFILING
- g_signal_connect(emfv->preview, "complete", G_CALLBACK (emfv_format_complete), emfv);
-#endif
- p->invisible = gtk_invisible_new();
- g_signal_connect(p->invisible, "selection_get", G_CALLBACK(emfv_selection_get), emfv);
- g_signal_connect(p->invisible, "selection_clear_event", G_CALLBACK(emfv_selection_clear_event), emfv);
- gtk_selection_add_target(p->invisible, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 0);
- gtk_selection_add_target(p->invisible, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 1);
+// g_signal_connect (emfv->preview, "on_url", G_CALLBACK (emfv_on_url_cb), emfv);
+// g_signal_connect (((EMFormatHTML *)emfv->preview)->html, "button-release-event", G_CALLBACK (emfv_on_html_button_released_cb), emfv);
+//#ifdef ENABLE_PROFILING
+// g_signal_connect(emfv->preview, "complete", G_CALLBACK (emfv_format_complete), emfv);
+//#endif
+// p->invisible = gtk_invisible_new();
+// g_signal_connect(p->invisible, "selection_get", G_CALLBACK(emfv_selection_get), emfv);
+// g_signal_connect(p->invisible, "selection_clear_event", G_CALLBACK(emfv_selection_clear_event), emfv);
+// gtk_selection_add_target(p->invisible, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 0);
+// gtk_selection_add_target(p->invisible, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 1);
emfv->async = mail_async_event_new();
-
- emfv_setting_setup(emfv);
-}
-
-static void
-free_one_ui_file (gpointer data,
- gpointer user_data)
-{
- g_free (data);
-}
-
-static void
-emfv_finalise(GObject *o)
-{
- EMFolderView *emfv = (EMFolderView *)o;
- struct _EMFolderViewPrivate *p = emfv->priv;
-
- g_slist_foreach (emfv->ui_files, free_one_ui_file, NULL);
- g_slist_free(emfv->ui_files);
- g_slist_free(emfv->enable_map);
-
- g_free(p);
-
- ((GObjectClass *)emfv_parent)->finalize(o);
-}
-
-static void
-emfv_destroy (GtkObject *o)
-{
- EMFolderView *emfv = (EMFolderView *) o;
- struct _EMFolderViewPrivate *p = emfv->priv;
-
- p->destroyed = TRUE;
-
- if (emfv->list && emfv->list->seen_id) {
- g_source_remove(emfv->list->seen_id);
- emfv->list->seen_id = 0;
- }
-
- if (p->setting_notify_id) {
- GConfClient *gconf = gconf_client_get_default();
-
- gconf_client_notify_remove(gconf, p->setting_notify_id);
- p->setting_notify_id = 0;
- g_object_unref(gconf);
- }
-
- if (emfv->folder) {
- camel_object_unref(emfv->folder);
- g_free(emfv->folder_uri);
- emfv->folder = NULL;
- emfv->folder_uri = NULL;
- }
-
- if (emfv->async) {
- mail_async_event_destroy(emfv->async);
- emfv->async = NULL;
- }
-
- if (p->invisible) {
- gtk_object_destroy((GtkObject *)p->invisible);
- p->invisible = NULL;
- }
-
- if (p->selected_id != 0) {
- g_source_remove(p->selected_id);
- p->selected_id = 0;
- }
-
- g_free(p->selected_uid);
- p->selected_uid = NULL;
-
- g_free (emfv->displayed_uid);
- emfv->displayed_uid = NULL;
-
- emfv->preview = NULL;
- emfv->list = NULL;
- emfv->preview_active = FALSE;
- emfv->uic = NULL;
-
- ((GtkObjectClass *) emfv_parent)->destroy (o);
}
static void
@@ -403,7 +268,7 @@ emfv_class_init(GObjectClass *klass)
((EMFolderViewClass *)klass)->set_message = emfv_set_message;
((EMFolderViewClass *)klass)->activate = emfv_activate;
- ((EMFolderViewClass *)klass)->on_url = emfv_on_url;
+// ((EMFolderViewClass *)klass)->on_url = emfv_on_url;
signals[EMFV_ON_URL] = g_signal_new ("on-url",
G_OBJECT_CLASS_TYPE (klass),
@@ -433,1080 +298,33 @@ emfv_class_init(GObjectClass *klass)
0);
}
-GType
-em_folder_view_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFolderViewClass),
- NULL, NULL,
- (GClassInitFunc)emfv_class_init,
- NULL, NULL,
- sizeof(EMFolderView), 0,
- (GInstanceInitFunc)emfv_init
- };
- emfv_parent = g_type_class_ref(gtk_vbox_get_type());
- type = g_type_register_static(gtk_vbox_get_type(), "EMFolderView", &info, 0);
- }
-
- return type;
-}
-
-GtkWidget *em_folder_view_new(void)
-{
- EMFolderView *emfv = g_object_new(em_folder_view_get_type(), NULL);
-
- return (GtkWidget *)emfv;
-}
-
-/* flag all selected messages. Return number flagged */
-/* FIXME: Should this be part of message-list instead? */
-gint
-em_folder_view_mark_selected(EMFolderView *emfv, guint32 mask, guint32 set)
-{
- GPtrArray *uids;
- gint i;
-
- if (emfv->folder == NULL)
- return 0;
-
- uids = message_list_get_selected(emfv->list);
- if (!CAMEL_IS_VEE_FOLDER(emfv->folder))
- camel_folder_freeze(emfv->folder);
-
- for (i=0; i<uids->len; i++)
- camel_folder_set_message_flags(emfv->folder, uids->pdata[i], mask, set);
-
- message_list_free_uids(emfv->list, uids);
- if (!CAMEL_IS_VEE_FOLDER(emfv->folder))
- camel_folder_thaw(emfv->folder);
-
- return i;
-}
-
-/* should this be elsewhere/take a uid list? */
-gint
-em_folder_view_open_selected(EMFolderView *emfv)
-{
- GPtrArray *uids, *views;
- gint i = 0;
-
- uids = message_list_get_selected(emfv->list);
-
- if (uids->len >= 10) {
- gchar *num = g_strdup_printf("%d", uids->len);
- gint doit;
-
- doit = em_utils_prompt_user((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)emfv),
- "/apps/evolution/mail/prompts/open_many",
- "mail:ask-open-many", num, NULL);
- g_free(num);
- if (!doit) {
- message_list_free_uids(emfv->list, uids);
- return 0;
- }
- }
-
- if (em_utils_folder_is_drafts(emfv->folder, emfv->folder_uri)
- || em_utils_folder_is_templates(emfv->folder, emfv->folder_uri)
- || em_utils_folder_is_outbox(emfv->folder, emfv->folder_uri)) {
- em_utils_edit_messages(emfv->folder, uids, TRUE);
- return uids->len;
- }
-
- /* for vfolders we need to edit the *original*, not the vfolder copy */
- views = g_ptr_array_new();
- for (i=0;i<uids->len;i++) {
- if (camel_object_is((CamelObject *)emfv->folder, camel_vee_folder_get_type())) {
- CamelVeeMessageInfo *vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info(emfv->folder, uids->pdata[i]);
-
- if (vinfo) {
- gchar *uid;
- /* TODO: get_location shouldn't strdup the uid */
- CamelFolder *f = camel_vee_folder_get_location((CamelVeeFolder *)emfv->folder, vinfo, &uid);
- gchar *uri = mail_tools_folder_to_url(f);
-
- if (em_utils_folder_is_drafts(f, uri) || em_utils_folder_is_outbox(f, uri)) {
- GPtrArray *edits = g_ptr_array_new();
-
- g_ptr_array_add(edits, uid);
- em_utils_edit_messages(f, edits, TRUE);
- } else {
- g_free(uid);
- g_ptr_array_add(views, g_strdup(uids->pdata[i]));
- }
- g_free(uri);
- }
- } else {
- g_ptr_array_add(views, g_strdup(uids->pdata[i]));
- }
- }
-
- /* TODO: have an em_utils_open_messages call? */
- for (i=0; i<views->len; i++) {
- EMMessageBrowser *emmb;
-
- emmb = (EMMessageBrowser *)em_message_browser_window_new();
- message_list_set_threaded(((EMFolderView *)emmb)->list, emfv->list->threaded);
- /* always keep actual message in a list view, even it doesn't belong to the filter anymore */
- message_list_ensure_message (((EMFolderView *)emmb)->list, views->pdata[i]);
- message_list_set_search (((EMFolderView *)emmb)->list, emfv->list->search);
- em_folder_view_set_hide_deleted((EMFolderView *)emmb, emfv->hide_deleted);
- /* FIXME: session needs to be passed easier than this */
- em_format_set_session((EMFormat *)((EMFolderView *)emmb)->preview, ((EMFormat *)emfv->preview)->session);
- em_folder_view_set_folder((EMFolderView *)emmb, emfv->folder, emfv->folder_uri);
- em_folder_view_set_message((EMFolderView *)emmb, views->pdata[i], FALSE);
- gtk_widget_show(emmb->window);
- /* TODO: this loads the message twice (!) */
- em_utils_handle_receipt (emfv->folder, uids->pdata[i], NULL);
- g_free(views->pdata[i]);
- }
- g_ptr_array_free(views, TRUE);
-
- message_list_free_uids(emfv->list, uids);
-
- return i;
-}
-
-/* ******************************************************************************** */
-static void
-emfv_list_display_view(GalViewInstance *instance, GalView *view, EMFolderView *emfv)
-{
- if (GAL_IS_VIEW_ETABLE(view))
- gal_view_etable_attach_tree(GAL_VIEW_ETABLE(view), emfv->list->tree);
-}
-
-static void
-emfv_setup_view_instance(EMFolderView *emfv)
-{
- static GalViewCollection *collection = NULL;
- struct _EMFolderViewPrivate *p = emfv->priv;
- gboolean outgoing, show_wide=FALSE;
- gchar *id;
-
- g_return_if_fail (emfv->folder);
- g_return_if_fail (emfv->folder_uri);
-
- if (collection == NULL) {
- ETableSpecification *spec;
- GalViewFactory *factory;
- const gchar *evolution_dir;
- gchar *dir;
- gchar *galviewsmaildir;
- gchar *etspecfile;
-
- collection = gal_view_collection_new ();
-
- gal_view_collection_set_title (collection, _("Mail"));
-
- evolution_dir = mail_component_peek_base_directory (mail_component_peek ());
- galviewsmaildir = g_build_filename (EVOLUTION_GALVIEWSDIR,
- "mail",
- NULL);
- dir = g_build_filename (evolution_dir, "views", NULL);
- gal_view_collection_set_storage_directories (collection, galviewsmaildir, dir);
- g_free (dir);
- g_free (galviewsmaildir);
-
- spec = e_table_specification_new ();
- etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
- "message-list.etspec",
- NULL);
- if (!e_table_specification_load_from_file (spec, etspecfile))
- g_error ("Unable to load ETable specification file "
- "for mail");
- g_free (etspecfile);
-
- factory = gal_view_factory_etable_new (spec);
- g_object_unref (spec);
- gal_view_collection_add_factory (collection, factory);
- g_object_unref (factory);
-
- gal_view_collection_load (collection);
- }
-
- if (p->view_instance) {
- g_object_unref(p->view_instance);
- p->view_instance = NULL;
- }
-
- if (p->view_menus) {
- g_object_unref(p->view_menus);
- p->view_menus = NULL;
- }
-
- /* TODO: should this go through mail-config api? */
- id = mail_config_folder_to_safe_url (emfv->folder);
- p->view_instance = gal_view_instance_new (collection, id);
-
- show_wide = emfv->list_active ? em_folder_browser_get_wide ((EMFolderBrowser *) emfv):FALSE;
- if (show_wide) {
- gchar *safe_id, *filename;
-
- /* Force to use the wide view */
- g_free (p->view_instance->custom_filename);
- g_free (p->view_instance->current_view_filename);
- safe_id = g_strdup (id);
- e_filename_make_safe (safe_id);
- filename = g_strdup_printf ("custom_wide_view-%s.xml", safe_id);
- p->view_instance->custom_filename = g_build_filename (collection->local_dir, filename, NULL);
- g_free (filename);
- filename = g_strdup_printf ("current_wide_view-%s.xml", safe_id);
- p->view_instance->current_view_filename = g_build_filename (collection->local_dir, filename, NULL);
- g_free (filename);
- g_free (safe_id);
- }
- g_free (id);
-
- outgoing = em_utils_folder_is_drafts (emfv->folder, emfv->folder_uri)
- || em_utils_folder_is_sent (emfv->folder, emfv->folder_uri)
- || em_utils_folder_is_outbox (emfv->folder, emfv->folder_uri);
-
- if (outgoing) {
- if (show_wide)
- gal_view_instance_set_default_view(p->view_instance, "Wide_View_Sent");
- else
- gal_view_instance_set_default_view(p->view_instance, "As_Sent_Folder");
- } else if (show_wide) {
- gal_view_instance_set_default_view(p->view_instance, "Wide_View_Normal");
- }
-
- gal_view_instance_load(p->view_instance);
-
- if (!gal_view_instance_exists(p->view_instance)) {
- struct stat st;
- gchar *path;
-
- path = mail_config_folder_to_cachename (emfv->folder, "et-header-");
- if (path && g_stat (path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) {
- ETableSpecification *spec;
- ETableState *state;
- GalView *view;
- gchar *etspecfile;
-
- spec = e_table_specification_new ();
- etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
- "message-list.etspec",
- NULL);
- e_table_specification_load_from_file (spec, etspecfile);
- g_free (etspecfile);
- view = gal_view_etable_new (spec, "");
- g_object_unref (spec);
-
- state = e_table_state_new ();
- e_table_state_load_from_file (state, path);
- gal_view_etable_set_state (GAL_VIEW_ETABLE (view), state);
- g_object_unref (state);
-
- gal_view_instance_set_custom_view(p->view_instance, view);
- g_object_unref (view);
- }
-
- g_free (path);
- }
-
- g_signal_connect(p->view_instance, "display_view", G_CALLBACK(emfv_list_display_view), emfv);
- emfv_list_display_view(p->view_instance, gal_view_instance_get_current_view(p->view_instance), emfv);
-
- if (emfv->list_active && emfv->uic) {
- p->view_menus = gal_view_menus_new(p->view_instance);
- gal_view_menus_apply(p->view_menus, emfv->uic, NULL);
- }
-}
-
-void em_folder_view_setup_view_instance (EMFolderView *emfv)
-{
- emfv_setup_view_instance (emfv);
-}
-
-/* ********************************************************************** */
-
-static void
-emfv_set_folder(EMFolderView *emfv, CamelFolder *folder, const gchar *uri)
-{
- gint isout = (folder && uri
- && (em_utils_folder_is_drafts(folder, uri)
- || em_utils_folder_is_sent(folder, uri)
- || em_utils_folder_is_outbox(folder, uri)));
-
- if (folder == emfv->folder)
- return;
-
- if (emfv->priv->selected_id)
- g_source_remove(emfv->priv->selected_id);
-
- if (emfv->preview)
- em_format_format ((EMFormat *) emfv->preview, NULL, NULL, NULL);
-
- message_list_set_folder(emfv->list, folder, uri, isout);
- g_free(emfv->folder_uri);
- emfv->folder_uri = uri ? g_strdup(uri):NULL;
-
- if (emfv->folder) {
- emfv->hide_deleted = emfv->list->hidedeleted; /* <- a bit nasty but makes it track the display better */
- mail_sync_folder (emfv->folder, NULL, NULL);
- camel_object_unref(emfv->folder);
- }
-
- emfv->folder = folder;
- if (folder) {
- /* We need to set this up to get the right view options for the message-list,
- * even if we're not showing it */
- emfv_setup_view_instance(emfv);
- camel_object_ref(folder);
- }
-
- emfv_enable_menus(emfv);
-
- /* TODO: should probably be called after all processing, not just this class's impl */
- g_signal_emit(emfv, signals[EMFV_LOADED], 0);
-}
-
-static void
-emfv_got_folder(gchar *uri, CamelFolder *folder, gpointer data)
-{
- EMFolderView *emfv = data;
-
- em_folder_view_set_folder(emfv, folder, uri);
-}
-
-static void
-emfv_set_folder_uri(EMFolderView *emfv, const gchar *uri)
-{
- mail_get_folder(uri, 0, emfv_got_folder, emfv, mail_msg_fast_ordered_push);
-}
-
-static void
-emfv_set_message(EMFolderView *emfv, const gchar *uid, gint nomarkseen)
-{
- e_profile_event_emit("goto.uid", uid?uid:"<none>", 0);
-
- /* This could possible race with other set messages, but likelyhood is small */
- emfv->priv->nomarkseen = nomarkseen;
- message_list_select_uid(emfv->list, uid);
- /* force an update, since we may not get an updated event if we select the same uid */
- emfv_list_message_selected(emfv->list, uid, emfv);
-}
-
-/* ********************************************************************** */
-
-static void
-emfv_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint time_stamp, EMFolderView *emfv)
-{
- struct _EMFolderViewPrivate *p = emfv->priv;
-
- if (p->selection_uri == NULL)
- return;
-
- gtk_selection_data_set(data, data->target, 8, (guchar *)p->selection_uri, strlen(p->selection_uri));
-}
-
-static void
-emfv_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, EMFolderView *emfv)
-{
-#if 0 /* do i care? */
- struct _EMFolderViewPrivate *p = emfv->priv;
-
- g_free(p->selection_uri);
- p->selection_uri = NULL;
-#endif
-}
+//static void
+//emfv_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint time_stamp, EMFolderView *emfv)
+//{
+// struct _EMFolderViewPrivate *p = emfv->priv;
+//
+// if (p->selection_uri == NULL)
+// return;
+//
+// gtk_selection_data_set(data, data->target, 8, (guchar *)p->selection_uri, strlen(p->selection_uri));
+//}
+
+//static void
+//emfv_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, EMFolderView *emfv)
+//{
+//#if 0 /* do i care? */
+// struct _EMFolderViewPrivate *p = emfv->priv;
+//
+// g_free(p->selection_uri);
+// p->selection_uri = NULL;
+//#endif
+//}
/* ********************************************************************** */
/* Popup menu
In many cases these are the functions called by the bonobo callbacks too */
-static void
-emfv_popup_open(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_open_selected(emfv);
-}
-
-static void
-emfv_popup_edit (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- if (!em_utils_check_user_can_send_mail((GtkWidget *)emfv))
- return;
-
- uids = message_list_get_selected(emfv->list);
- em_utils_edit_messages (emfv->folder, uids, FALSE);
-}
-
-static void
-emfv_popup_saveas(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- uids = message_list_get_selected(emfv->list);
- em_utils_save_messages((GtkWidget *)emfv, emfv->folder, uids);
-}
-
-static void
-emfv_view_load_images(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->preview)
- em_format_html_load_http((EMFormatHTML *)emfv->preview);
-}
-
-static void
-emfv_popup_print(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_print(emfv, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
-}
-
-static void
-emfv_popup_copy_text(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- gtk_html_copy (((EMFormatHTML *)emfv->preview)->html);
-}
-
-static void
-emfv_popup_source(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- EMMessageBrowser *emmb;
- GPtrArray *uids;
-
- uids = message_list_get_selected(emfv->list);
-
- emmb = (EMMessageBrowser *)em_message_browser_window_new();
- em_format_set_session((EMFormat *)((EMFolderView *)emmb)->preview, ((EMFormat *)emfv->preview)->session);
- message_list_ensure_message (((EMFolderView *)emmb)->list, uids->pdata[0]);
- em_folder_view_set_folder((EMFolderView *)emmb, emfv->folder, emfv->folder_uri);
- em_format_set_mode((EMFormat *)((EMFolderView *)emmb)->preview, EM_FORMAT_SOURCE);
- em_folder_view_set_message((EMFolderView *)emmb, uids->pdata[0], FALSE);
- gtk_widget_show(emmb->window);
-
- message_list_free_uids(emfv->list, uids);
-}
-
-static void
-emfv_mail_compose(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (!em_utils_check_user_can_send_mail((GtkWidget *)emfv))
- return;
-
- em_utils_compose_new_message(emfv->folder_uri);
-}
-
-static void
-emfv_popup_reply_sender(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- emfv_message_reply(emfv, REPLY_MODE_SENDER);
-}
-
-static void
-emfv_popup_reply_list(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- emfv_message_reply(emfv, REPLY_MODE_LIST);
-}
-
-static void
-emfv_popup_reply_all(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- emfv_message_reply(emfv, REPLY_MODE_ALL);
-}
-
-static void
-emfv_popup_forward(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- if (!em_utils_check_user_can_send_mail((GtkWidget *)emfv))
- return;
-
- uids = message_list_get_selected(emfv->list);
- em_utils_forward_messages (emfv->folder, uids, emfv->folder_uri);
-}
-
-static void
-emfv_popup_flag_followup(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids = message_list_get_selected(emfv->list);
-
- em_utils_flag_for_followup((GtkWidget *)emfv, emfv->folder, uids);
-}
-
-static void
-emfv_popup_flag_completed(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- uids = message_list_get_selected(emfv->list);
- em_utils_flag_for_followup_completed((GtkWidget *)emfv, emfv->folder, uids);
-
- if (emfv->preview)
- em_format_redraw (EM_FORMAT (emfv->preview));
-}
-
-static void
-emfv_popup_flag_clear(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids = message_list_get_selected(emfv->list);
-
- em_utils_flag_for_followup_clear((GtkWidget *)emfv, emfv->folder, uids);
-
- if (emfv->preview)
- em_format_redraw (EM_FORMAT (emfv->preview));
-}
-
-static void
-emfv_popup_mark_read(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
-}
-
-static void
-emfv_popup_mark_unread(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED, 0);
-
- if (emfv->list->seen_id) {
- g_source_remove(emfv->list->seen_id);
- emfv->list->seen_id = 0;
- }
-}
-
-static void
-emfv_popup_mark_important(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_FLAGGED);
-}
-
-static void
-emfv_popup_mark_unimportant(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_FLAGGED, 0);
-}
-
-static void
-emfv_select_next_message (EMFolderView *emfv, gint count, gboolean always_can_previous)
-{
- if (emfv && count == 1) {
- if (!message_list_select (emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0) && (emfv->hide_deleted || always_can_previous))
- message_list_select (emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0);
- }
-}
-
-static void
-emfv_popup_mark_junk (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- gint count;
-
- count = em_folder_view_mark_selected(emfv,
- CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN,
- CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_JUNK_LEARN);
-
- emfv_select_next_message (emfv, count, TRUE);
-}
-
-static void
-emfv_popup_mark_nojunk (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- gint count;
-
- count = em_folder_view_mark_selected(emfv,
- CAMEL_MESSAGE_JUNK|CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN,
- CAMEL_MESSAGE_NOTJUNK|CAMEL_MESSAGE_JUNK_LEARN);
-
- emfv_select_next_message (emfv, count, TRUE);
-}
-
-#define DelInVFolderCheckName "DelInVFolderCheck"
-#define DelInVFolderKey "/apps/evolution/mail/prompts/delete_in_vfolder"
-
-static void
-emfv_delete_msg_response (GtkWidget *dialog, gint response, gpointer data)
-{
- if (response == GTK_RESPONSE_OK) {
- EMFolderView *emfv = data;
- gint count;
- GPtrArray *uids;
-
- if (dialog) {
- GList *children, *l;
- GtkWidget *check = NULL;
-
- children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox));
- for (l = children; l; l = l->next) {
- if (GTK_IS_ALIGNMENT (l->data)) {
- check = gtk_bin_get_child (GTK_BIN (l->data));
-
- if (check && GTK_IS_CHECK_BUTTON (check) &&
- !strcmp (gtk_widget_get_name (check), DelInVFolderCheckName))
- break;
-
- check = NULL;
- }
- }
-
- if (check) {
- GConfClient *gconf = gconf_client_get_default ();
- gconf_client_set_bool (gconf, DelInVFolderKey, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check)), NULL);
- g_object_unref (gconf);
- }
-
- g_list_free (children);
- }
-
- uids = message_list_get_selected(emfv->list);
- if (!CAMEL_IS_VEE_FOLDER(emfv->folder))
- camel_folder_freeze(emfv->folder);
-
- for (count=0; count < uids->len; count++) {
- if (camel_folder_get_message_flags (emfv->folder, uids->pdata[count]) & CAMEL_MESSAGE_USER_NOT_DELETABLE) {
- if (emfv->preview_active) {
- GtkHTMLStream *hstream = gtk_html_begin(((EMFormatHTML *)emfv->preview)->html);
-
- gtk_html_stream_printf(hstream, "<h2>%s</h2><p>%s</p>",
- _("Mail Deletion Failed"),
- _("You do not have sufficient permissions to delete this mail."));
- gtk_html_stream_close(hstream, GTK_HTML_STREAM_OK);
- } else {
- GtkWidget *w = e_error_new (NULL, "mail:no-delete-permission", "", NULL);
- em_utils_show_error_silent (w);
- }
-
- count = -1;
- break;
- } else
- camel_folder_set_message_flags(emfv->folder, uids->pdata[count], CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED );
- }
-
- message_list_free_uids(emfv->list, uids);
- if (!CAMEL_IS_VEE_FOLDER(emfv->folder))
- camel_folder_thaw(emfv->folder);
-
- emfv_select_next_message (emfv, count, FALSE);
- }
-
- if (dialog)
- gtk_widget_destroy (dialog);
-}
-
-static void
-emfv_popup_delete (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GConfClient *gconf = gconf_client_get_default ();
-
- if (emfv->folder && emfv->folder->parent_store && CAMEL_IS_VEE_STORE (emfv->folder->parent_store)
- && !gconf_client_get_bool (gconf, DelInVFolderKey, NULL)) {
- GtkWidget *dialog, *checkbox, *align;
-
- dialog = e_error_new (NULL, "mail:ask-delete-vfolder-msg", emfv->folder->full_name, NULL);
- g_signal_connect (dialog, "response", G_CALLBACK (emfv_delete_msg_response), emfv);
- checkbox = gtk_check_button_new_with_label (_("Do not ask me again."));
- gtk_widget_set_name (checkbox, DelInVFolderCheckName);
- align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
- gtk_container_add (GTK_CONTAINER (align), checkbox);
- gtk_widget_show (checkbox);
- gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox), align, TRUE, TRUE, 6);
- gtk_widget_show (align);
- gtk_widget_show (dialog);
- } else {
- emfv_delete_msg_response (NULL, GTK_RESPONSE_OK, emfv);
- }
-
- g_object_unref (gconf);
-}
-#undef DelInVFolderCheckName
-#undef DelInVFolderKey
-
-static void
-emfv_popup_undelete(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- em_folder_view_mark_selected(emfv, CAMEL_MESSAGE_DELETED, 0);
-}
-
-struct _move_data {
- EMFolderView *emfv;
- GPtrArray *uids;
- gint delete;
-};
-
-static gchar *default_xfer_messages_uri = NULL;
-
-static void
-emfv_popup_move_cb(const gchar *uri, gpointer data)
-{
- struct _move_data *d = data;
-
- if (uri) {
- g_free (default_xfer_messages_uri);
- default_xfer_messages_uri = g_strdup (uri);
- mail_transfer_messages(d->emfv->folder, d->uids, d->delete, uri, 0, NULL, NULL);
- } else
- em_utils_uids_free(d->uids);
-
- g_object_unref(d->emfv);
- g_free(d);
-}
-
-static void
-emfv_popup_move(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- struct _move_data *d;
-
- d = g_malloc(sizeof(*d));
- d->emfv = emfv;
- g_object_ref(emfv);
- d->uids = message_list_get_selected(emfv->list);
- d->delete = TRUE;
-
- em_select_folder ((GtkWindow *) emfv, _("Select folder"), _("_Move"), default_xfer_messages_uri, NULL, emfv_popup_move_cb, d);
-}
-
-static void
-emfv_popup_copy(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- struct _move_data *d;
-
- d = g_malloc(sizeof(*d));
- d->emfv = emfv;
- g_object_ref(emfv);
- d->uids = message_list_get_selected(emfv->list);
- d->delete = FALSE;
-
- em_select_folder ((GtkWindow *) emfv, _("Select folder"), _("C_opy"), default_xfer_messages_uri, NULL, emfv_popup_move_cb, d);
-}
-
-static void
-emfv_set_label (EMFolderView *emfv, const gchar *label)
-{
- GPtrArray *uids = message_list_get_selected (emfv->list);
- gint i;
-
- for (i = 0; i < uids->len; i++)
- camel_folder_set_message_user_flag (emfv->folder, uids->pdata[i], label, TRUE);
-
- message_list_free_uids (emfv->list, uids);
-}
-
-static void
-emfv_unset_label (EMFolderView *emfv, const gchar *label)
-{
- GPtrArray *uids = message_list_get_selected (emfv->list);
- gint i;
-
- for (i = 0; i < uids->len; i++) {
- camel_folder_set_message_user_flag (emfv->folder, uids->pdata[i], label, FALSE);
- camel_folder_set_message_user_tag (emfv->folder, uids->pdata[i], "label", NULL);
- }
-
- message_list_free_uids (emfv->list, uids);
-}
-
-static void
-emfv_popup_label_clear(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GSList *l;
- EUtilLabel *label;
-
- for (l = mail_config_get_labels (); l; l = l->next) {
- label = l->data;
- emfv_unset_label(emfv, label->tag);
- }
-}
-
-static void
-emfv_popup_label_set(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
-
- if (pitem->type & E_POPUP_ACTIVE)
- emfv_set_label (emfv, pitem->user_data);
- else
- emfv_unset_label (emfv, pitem->user_data);
-}
-
-static void
-emfv_popup_label_new (EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- gchar *tag = e_util_labels_add_with_dlg (NULL, NULL);
-
- if (tag) {
- emfv_set_label (emfv, tag);
- g_free (tag);
- }
-}
-
-static void
-emfv_popup_add_sender(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids = message_list_get_selected(emfv->list);
- CamelMessageInfo *info;
- const gchar *addr;
-
- if (uids->len == 1
- && (info = camel_folder_get_message_info(emfv->folder, uids->pdata[0])) != NULL
- && (addr = camel_message_info_from(info)) != NULL
- && addr[0] != 0)
- em_utils_add_address((GtkWidget *)emfv, addr);
-
- em_utils_uids_free(uids);
-}
-
-static void
-emfv_popup_apply_filters(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids = message_list_get_selected(emfv->list);
-
- mail_filter_on_demand(emfv->folder, uids);
-}
-
-static void
-emfv_popup_filter_junk(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids = message_list_get_selected(emfv->list);
-
- mail_filter_junk(emfv->folder, uids);
-}
-
-/* filter callbacks, this will eventually be a wizard, see
- filter_type_current/vfolder_type_current for implementation */
-
-#define EMFV_POPUP_AUTO_TYPE(autotype, name, type) \
-static void \
-name(EPopup *ep, EPopupItem *item, gpointer data) \
-{ \
- EMFolderView *emfv = data; \
- autotype(emfv, type); \
-}
-
-EMFV_POPUP_AUTO_TYPE(vfolder_type_current, emfv_popup_vfolder_subject, AUTO_SUBJECT)
-EMFV_POPUP_AUTO_TYPE(vfolder_type_current, emfv_popup_vfolder_sender, AUTO_FROM)
-EMFV_POPUP_AUTO_TYPE(vfolder_type_current, emfv_popup_vfolder_recipients, AUTO_TO)
-EMFV_POPUP_AUTO_TYPE(vfolder_type_current, emfv_popup_vfolder_mlist, AUTO_MLIST)
-
-EMFV_POPUP_AUTO_TYPE(filter_type_current, emfv_popup_filter_subject, AUTO_SUBJECT)
-EMFV_POPUP_AUTO_TYPE(filter_type_current, emfv_popup_filter_sender, AUTO_FROM)
-EMFV_POPUP_AUTO_TYPE(filter_type_current, emfv_popup_filter_recipients, AUTO_TO)
-EMFV_POPUP_AUTO_TYPE(filter_type_current, emfv_popup_filter_mlist, AUTO_MLIST)
-
-/* TODO: Move some of these to be 'standard' menu's */
-
-static EPopupItem emfv_popup_items[] = {
- { E_POPUP_ITEM, (gchar *) "00.emfv.00", (gchar *) N_("_Copy"), emfv_popup_copy_text, NULL, (gchar *) "edit-copy", EM_FOLDER_VIEW_SELECT_DISPLAY|EM_FOLDER_VIEW_SELECT_SELECTION },
-
- { E_POPUP_BAR, (gchar *) "10.emfv", NULL, NULL, NULL, NULL },
-
- { E_POPUP_ITEM, (gchar *) "10.emfv.00", (gchar *) N_("_Reply to Sender"), emfv_popup_reply_sender, NULL, (gchar *) "mail-reply-sender", EM_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "10.emfv.01", (gchar *) N_("Reply to _All"), emfv_popup_reply_all, NULL, (gchar *) "mail-reply-all", EM_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "10.emfv.02", (gchar *) N_("_Forward"), emfv_popup_forward, NULL, (gchar *) "mail-forward", EM_POPUP_SELECT_MANY },
-
- { E_POPUP_BAR, (gchar *) "20.emfv", NULL, NULL, NULL, NULL },
- /* EM_POPUP_EDIT was used here. This is changed to EM_POPUP_SELECT_ONE as Edit-as-new-messaeg need not be restricted to Sent-Items folder alone */
- { E_POPUP_ITEM, (gchar *) "20.emfv.00", (gchar *) N_("_Edit as New Message..."), emfv_popup_edit, NULL, NULL, EM_POPUP_SELECT_ONE },
- { E_POPUP_ITEM, (gchar *) "20.emfv.01", (gchar *) N_("_Save As..."), emfv_popup_saveas, NULL, (gchar *) "document-save-as", EM_POPUP_SELECT_MANY },
- { E_POPUP_ITEM, (gchar *) "20.emfv.02", (gchar *) N_("_Print..."), emfv_popup_print, NULL, (gchar *) "document-print", EM_POPUP_SELECT_ONE },
-
- { E_POPUP_BAR, (gchar *) "40.emfv", NULL, NULL, NULL, NULL },
- { E_POPUP_ITEM, (gchar *) "40.emfv.00", (gchar *) N_("_Delete"), emfv_popup_delete, NULL, (gchar *) "edit-delete", EM_POPUP_SELECT_DELETE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "40.emfv.01", (gchar *) N_("U_ndelete"), emfv_popup_undelete, NULL, NULL, EM_POPUP_SELECT_UNDELETE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "40.emfv.02", (gchar *) N_("_Move to Folder..."), emfv_popup_move, NULL, (gchar *) "mail-move", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "40.emfv.03", (gchar *) N_("_Copy to Folder..."), emfv_popup_copy, NULL, (gchar *) "mail-copy", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
-
- { E_POPUP_BAR, (gchar *) "50.emfv", NULL, NULL, NULL, NULL },
- { E_POPUP_ITEM, (gchar *) "50.emfv.00", (gchar *) N_("Mar_k as Read"), emfv_popup_mark_read, NULL, (gchar *) "mail-mark-read", EM_POPUP_SELECT_MARK_READ|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "50.emfv.01", (gchar *) N_("Mark as _Unread"), emfv_popup_mark_unread, NULL, (gchar *) "mail-mark-unread", EM_POPUP_SELECT_MARK_UNREAD|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "50.emfv.02", (gchar *) N_("Mark as _Important"), emfv_popup_mark_important, NULL, (gchar *) "mail-mark-important", EM_POPUP_SELECT_MARK_IMPORTANT|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "50.emfv.03", (gchar *) N_("Mark as Un_important"), emfv_popup_mark_unimportant, NULL, NULL, EM_POPUP_SELECT_MARK_UNIMPORTANT|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "50.emfv.04", (gchar *) N_("Mark as _Junk"), emfv_popup_mark_junk, NULL, (gchar *) "mail-mark-junk", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY|EM_POPUP_SELECT_JUNK },
- { E_POPUP_ITEM, (gchar *) "50.emfv.05", (gchar *) N_("Mark as _Not Junk"), emfv_popup_mark_nojunk, NULL, (gchar *) "mail-mark-notjunk", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY|EM_POPUP_SELECT_NOT_JUNK },
- { E_POPUP_ITEM, (gchar *) "50.emfv.06", (gchar *) N_("Mark for Follo_w Up..."), emfv_popup_flag_followup, NULL, (gchar *) "stock_mail-flag-for-followup", EM_POPUP_SELECT_FLAG_FOLLOWUP|EM_FOLDER_VIEW_SELECT_LISTONLY },
-
- { E_POPUP_SUBMENU, (gchar *) "60.label.00", (gchar *) N_("_Label"), NULL, NULL, NULL, EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "60.label.00/00.label", (gchar *) N_("_None"), emfv_popup_label_clear, NULL, NULL, EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_BAR, (gchar *) "60.label.00/00.label.00", NULL, NULL, NULL, NULL },
- { E_POPUP_BAR, (gchar *) "60.label.00/01.label", NULL, NULL, NULL, NULL },
- { E_POPUP_ITEM, (gchar *) "60.label.00/01.label.00", (gchar *) N_("_New Label"), emfv_popup_label_new, NULL, NULL, EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
-
- { E_POPUP_BAR, (gchar *) "70.emfv.06", NULL, NULL, NULL, NULL },
-
- { E_POPUP_ITEM, (gchar *) "70.emfv.07", (gchar *) N_("Fla_g Completed"), emfv_popup_flag_completed, NULL, (gchar *) "stock_mail-flag-for-followup-done", EM_POPUP_SELECT_FLAG_COMPLETED|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "70.emfv.08", (gchar *) N_("Cl_ear Flag"), emfv_popup_flag_clear, NULL, NULL, EM_POPUP_SELECT_FLAG_CLEAR|EM_FOLDER_VIEW_SELECT_LISTONLY },
-
- { E_POPUP_BAR, (gchar *) "90.filter", NULL, NULL, NULL, NULL },
- { E_POPUP_SUBMENU, (gchar *) "90.filter.00", (gchar *) N_("Crea_te Rule From Message"), NULL, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- /* Translators: The following strings are used while creating a new search folder, to specify what parameter the search folder would be based on. */
- { E_POPUP_ITEM, (gchar *) "90.filter.00/00.00", (gchar *) N_("Search Folder based on _Subject"), emfv_popup_vfolder_subject, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/00.01", (gchar *) N_("Search Folder based on Se_nder"), emfv_popup_vfolder_sender, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/00.02", (gchar *) N_("Search Folder based on _Recipients"), emfv_popup_vfolder_recipients, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/00.03", (gchar *) N_("Search Folder based on Mailing _List"),
- emfv_popup_vfolder_mlist, NULL, NULL, EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST|EM_FOLDER_VIEW_SELECT_LISTONLY },
-
- { E_POPUP_BAR, (gchar *) "90.filter.00/10", NULL, NULL, NULL, NULL },
- /* Translators: The following strings are used while creating a new message filter, to specify what parameter the filter would be based on. */
- { E_POPUP_ITEM, (gchar *) "90.filter.00/10.00", (gchar *) N_("Filter based on Sub_ject"), emfv_popup_filter_subject, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/10.01", (gchar *) N_("Filter based on Sen_der"), emfv_popup_filter_sender, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/10.02", (gchar *) N_("Filter based on Re_cipients"), emfv_popup_filter_recipients, NULL, NULL, EM_POPUP_SELECT_ONE|EM_FOLDER_VIEW_SELECT_LISTONLY },
- { E_POPUP_ITEM, (gchar *) "90.filter.00/10.03", (gchar *) N_("Filter based on _Mailing List"),
- emfv_popup_filter_mlist, NULL, NULL, EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST|EM_FOLDER_VIEW_SELECT_LISTONLY },
-};
-
-static enum _e_popup_t
-emfv_popup_labels_get_state_for_tag (EMFolderView *emfv, GPtrArray *uids, const gchar *label_tag)
-{
- enum _e_popup_t state = 0;
- gint i;
- gboolean exists = FALSE, not_exists = FALSE;
-
- g_return_val_if_fail (emfv != 0, state);
- g_return_val_if_fail (label_tag != NULL, state);
-
- for (i = 0; i < uids->len && (!exists || !not_exists); i++) {
- if (camel_folder_get_message_user_flag (emfv->folder, uids->pdata[i], label_tag))
- exists = TRUE;
- else {
- const gchar *label = e_util_labels_get_new_tag (camel_folder_get_message_user_tag (emfv->folder, uids->pdata[i], "label"));
-
- /* backward compatibility... */
- if (label && !strcmp (label, label_tag))
- exists = TRUE;
- else
- not_exists = TRUE;
- }
- }
-
- if (exists && not_exists)
- state = E_POPUP_INCONSISTENT;
- else if (exists)
- state = E_POPUP_ACTIVE;
-
- return state;
-}
-
-static void
-emfv_popup_labels_free(EPopup *ep, GSList *l, gpointer data)
-{
- while (l) {
- GSList *n = l->next;
- EPopupItem *item = l->data;
-
- g_free(item->path);
- g_free(item);
-
- g_slist_free_1(l);
- l = n;
- }
-}
-
-static void
-emfv_popup_items_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static void
-emfv_popup(EMFolderView *emfv, GdkEvent *event, gint on_display)
-{
- GSList *menus = NULL, *l, *label_list = NULL;
- GtkMenu *menu;
- EMPopup *emp;
- EMPopupTargetSelect *target;
- gint i;
-
- /** @HookPoint-EMPopup: Message List Context Menu
- * @Id: org.gnome.evolution.mail.folderview.popup.select
- * @Type: EMPopup
- * @Target: EMPopupTargetSelect
- *
- * This is the context menu shown on the message list or over a message.
- */
- emp = em_popup_new("org.gnome.evolution.mail.folderview.popup");
- target = em_folder_view_get_popup_target(emfv, emp, on_display);
-
- for (i=0;i<sizeof(emfv_popup_items)/sizeof(emfv_popup_items[0]);i++)
- menus = g_slist_prepend(menus, &emfv_popup_items[i]);
-
- e_popup_add_items((EPopup *)emp, menus, NULL, emfv_popup_items_free, emfv);
-
- i = 1;
- if (!on_display) {
- GPtrArray *uids = message_list_get_selected (emfv->list);
-
- for (l = mail_config_get_labels (); l; l = l->next) {
- EPopupItem *item;
- EUtilLabel *label = l->data;
- GdkPixmap *pixmap;
- GdkColor colour;
- GdkGC *gc;
-
- item = g_malloc0(sizeof(*item));
- item->type = E_POPUP_TOGGLE | emfv_popup_labels_get_state_for_tag (emfv, uids, label->tag);
- item->path = g_strdup_printf("60.label.00/00.label.%02d", i++);
- item->label = label->name;
- item->activate = emfv_popup_label_set;
- item->user_data = label->tag;
-
- item->visible = EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY;
-
- gdk_color_parse (label->colour, &colour);
- gdk_colormap_alloc_color(gdk_colormap_get_system(), &colour, FALSE, TRUE);
-
- pixmap = gdk_pixmap_new(((GtkWidget *)emfv)->window, 16, 16, -1);
- gc = gdk_gc_new(((GtkWidget *)emfv)->window);
- gdk_gc_set_foreground(gc, &colour);
- gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, 16, 16);
- g_object_unref(gc);
-
- item->image = gtk_image_new_from_pixmap(pixmap, NULL);
- gtk_widget_show(item->image);
-
- label_list = g_slist_prepend(label_list, item);
- }
-
- message_list_free_uids (emfv->list, uids);
- }
-
- e_popup_add_items((EPopup *)emp, label_list, NULL, emfv_popup_labels_free, emfv);
-
- menu = e_popup_create_menu_once((EPopup *)emp, (EPopupTarget *)target, 0);
-
- if (event == NULL || event->type == GDK_KEY_PRESS) {
- /* FIXME: menu pos function */
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 0, event ? event->key.time : gtk_get_current_event_time());
- } else {
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event->button.button, event->button.time);
- }
-}
-
/* ********************************************************************** */
/* Bonobo menu's */
@@ -1519,57 +337,6 @@ from(BonoboUIComponent *uid, gpointer data, const gchar *path) \
to(NULL, NULL, data); \
}
-EMFV_MAP_CALLBACK(emfv_add_sender_addressbook, emfv_popup_add_sender)
-EMFV_MAP_CALLBACK(emfv_message_apply_filters, emfv_popup_apply_filters)
-EMFV_MAP_CALLBACK(emfv_message_filter_junk, emfv_popup_filter_junk)
-EMFV_MAP_CALLBACK(emfv_message_copy, emfv_popup_copy)
-EMFV_MAP_CALLBACK(emfv_message_move, emfv_popup_move)
-EMFV_MAP_CALLBACK(emfv_message_forward, emfv_popup_forward)
-EMFV_MAP_CALLBACK(emfv_message_reply_all, emfv_popup_reply_all)
-EMFV_MAP_CALLBACK(emfv_message_reply_list, emfv_popup_reply_list)
-EMFV_MAP_CALLBACK(emfv_message_reply_sender, emfv_popup_reply_sender)
-EMFV_MAP_CALLBACK(emfv_message_mark_read, emfv_popup_mark_read)
-EMFV_MAP_CALLBACK(emfv_message_mark_unread, emfv_popup_mark_unread)
-EMFV_MAP_CALLBACK(emfv_message_mark_important, emfv_popup_mark_important)
-EMFV_MAP_CALLBACK(emfv_message_mark_unimportant, emfv_popup_mark_unimportant)
-EMFV_MAP_CALLBACK(emfv_message_mark_junk, emfv_popup_mark_junk)
-EMFV_MAP_CALLBACK(emfv_message_mark_nojunk, emfv_popup_mark_nojunk)
-EMFV_MAP_CALLBACK(emfv_message_delete, emfv_popup_delete)
-EMFV_MAP_CALLBACK(emfv_message_undelete, emfv_popup_undelete)
-EMFV_MAP_CALLBACK(emfv_message_followup_flag, emfv_popup_flag_followup)
-EMFV_MAP_CALLBACK(emfv_message_followup_clear, emfv_popup_flag_clear)
-EMFV_MAP_CALLBACK(emfv_message_followup_completed, emfv_popup_flag_completed)
-EMFV_MAP_CALLBACK(emfv_message_open, emfv_popup_open)
-EMFV_MAP_CALLBACK(emfv_message_edit, emfv_popup_edit)
-EMFV_MAP_CALLBACK(emfv_message_saveas, emfv_popup_saveas)
-EMFV_MAP_CALLBACK(emfv_print_message, emfv_popup_print)
-EMFV_MAP_CALLBACK(emfv_message_source, emfv_popup_source)
-
-static void
-emfv_empty_trash(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- em_utils_empty_trash (gtk_widget_get_toplevel ((GtkWidget *) emfv));
-}
-
-static void
-prepare_offline(gpointer key, gpointer value, gpointer data)
-{
- CamelService *service = key;
-
- if (CAMEL_IS_DISCO_STORE(service)
- || CAMEL_IS_OFFLINE_STORE(service)) {
- mail_store_prepare_offline((CamelStore *)service);
- }
-}
-
-static void
-emfv_prepare_offline(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- mail_component_stores_foreach(mail_component_peek(), prepare_offline, NULL);
-}
-
static void
emfv_edit_cut(BonoboUIComponent *uid, gpointer data, const gchar *path)
{
@@ -1600,646 +367,83 @@ emfv_edit_paste(BonoboUIComponent *uid, gpointer data, const gchar *path)
message_list_paste(emfv->list);
}
-static void
-emfv_select_all_text(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
- gboolean selected;
-
- gtk_html_select_all (((EMFormatHTML *)emfv->preview)->html);
- selected = gtk_html_command (((EMFormatHTML *)emfv->preview)->html, "is-selection-active");
- bonobo_ui_component_set_prop(emfv->uic, "/commands/EditCopy", "sensitive", selected?"1":"0", NULL);
-
-}
-
-static void
-emfv_mail_next(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- e_profile_event_emit("goto.next", "", 0);
-
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT, 0, 0);
-}
-
-static void
-emfv_mail_next_flagged(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT|MESSAGE_LIST_SELECT_WRAP, CAMEL_MESSAGE_FLAGGED, CAMEL_MESSAGE_FLAGGED);
-}
-
-static void
-emfv_mail_next_unread(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- gtk_widget_grab_focus((GtkWidget *) emfv->list);
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_NEXT|MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
-}
-
-static void
-emfv_mail_next_thread(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select_next_thread(emfv->list);
-}
-
-static void
-emfv_mail_previous(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0);
-}
-
-static void
-emfv_mail_previous_flagged(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS|MESSAGE_LIST_SELECT_WRAP, CAMEL_MESSAGE_FLAGGED, CAMEL_MESSAGE_FLAGGED);
-}
-
-static void
-emfv_mail_previous_unread(BonoboUIComponent *uid, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- gtk_widget_grab_focus((GtkWidget *) emfv->list);
- message_list_select(emfv->list, MESSAGE_LIST_SELECT_PREVIOUS|MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
-}
-
-static void
-emfv_message_forward_attached (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv))
- return;
-
- uids = message_list_get_selected (emfv->list);
- em_utils_forward_attached (emfv->folder, uids, emfv->folder_uri);
-}
-
-static void
-emfv_message_forward_inline (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv))
- return;
-
- uids = message_list_get_selected (emfv->list);
- em_utils_forward_inline (emfv->folder, uids, emfv->folder_uri);
-}
-
-static void
-emfv_message_forward_quoted (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
- GPtrArray *uids;
-
- if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv))
- return;
-
- uids = message_list_get_selected (emfv->list);
- em_utils_forward_quoted (emfv->folder, uids, emfv->folder_uri);
-}
-
-static void
-emfv_message_redirect (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->list->cursor_uid == NULL)
- return;
-
- if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv))
- return;
-
- em_utils_redirect_message_by_uid (emfv->folder, emfv->list->cursor_uid);
-}
-
-static gboolean
-html_contains_nonwhitespace (const gchar *html, gint len)
-{
- const gchar *p;
- gunichar c = 0;
-
- if (!html || len<=0)
- return FALSE;
-
- p = html;
-
- while (p && p - html < len) {
- c = g_utf8_get_char (p);
- if (!c)
- break;
-
- if (c == '<') {
- /* skip until next '>' */
- while (c = g_utf8_get_char (p), c && c != '>' && p - html < len)
- p = g_utf8_next_char (p);
- if (!c)
- break;
- }else if (c == '&') {
- /* sequence '&nbsp;' is a space */
- if (g_ascii_strncasecmp (p, "&nbsp;", 6) == 0)
- p = p + 5;
- else
- break;
- }else if (!g_unichar_isspace (c)) {
- break;
- }
-
- p = g_utf8_next_char (p);
- }
-
- return p - html < len - 1 && c != 0;
-}
-
-static void
-emfv_message_reply(EMFolderView *emfv, gint mode)
-{
- gchar *html = NULL;
- gint len;
-
- if (emfv->list->cursor_uid == NULL)
- return;
-
- if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv))
- return;
-
- if (gtk_html_command(((EMFormatHTML *)emfv->preview)->html, "is-selection-active")
- && (html = gtk_html_get_selection_html (((EMFormatHTML *)emfv->preview)->html, &len))
- && len && html[0] && html_contains_nonwhitespace (html, len)) {
- CamelMimeMessage *msg, *src;
- struct _camel_header_raw *header;
-
- src = (CamelMimeMessage *)((EMFormat *)emfv->preview)->message;
- msg = camel_mime_message_new();
-
- /* need to strip content- headers */
- header = ((CamelMimePart *)src)->headers;
- while (header) {
- if (g_ascii_strncasecmp(header->name, "content-", 8) != 0)
- camel_medium_add_header((CamelMedium *)msg, header->name, header->value);
- header = header->next;
- }
- camel_mime_part_set_encoding((CamelMimePart *)msg, CAMEL_TRANSFER_ENCODING_8BIT);
- camel_mime_part_set_content((CamelMimePart *)msg,
- html, len, "text/html");
- em_utils_reply_to_message (emfv->folder, emfv->list->cursor_uid, msg, mode, NULL);
- camel_object_unref(msg);
- } else {
- em_utils_reply_to_message (emfv->folder, emfv->list->cursor_uid, NULL, mode, (EMFormat *)emfv->preview);
- }
-
- g_free (html);
-}
-
-static void
-emfv_message_search(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- em_folder_view_show_search_bar (emfv);
-}
-
-static void
-emfv_print_preview_message(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- em_folder_view_print(emfv, GTK_PRINT_OPERATION_ACTION_PREVIEW);
-}
-
-static void
-emfv_text_zoom_in(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->preview)
- em_format_html_display_zoom_in(emfv->preview);
-}
-
-static void
-emfv_text_zoom_out(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->preview)
- em_format_html_display_zoom_out(emfv->preview);
-}
-
-static void
-emfv_text_zoom_reset(BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->preview)
- em_format_html_display_zoom_reset(emfv->preview);
-}
-
-/* ********************************************************************** */
-
-struct _filter_data {
- const gchar *source;
- gchar *uri;
- gint type;
-};
-
-static void
-filter_data_free (struct _filter_data *fdata)
-{
- g_free (fdata->uri);
- g_free (fdata);
-}
-
-static void
-filter_type_got_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, gpointer user_data)
-{
- struct _filter_data *data = user_data;
-
- if (msg)
- filter_gui_add_from_message (msg, data->source, data->type);
-
- filter_data_free (data);
-}
-
-static void
-filter_type_uid (CamelFolder *folder, const gchar *uid, const gchar *source, gint type)
-{
- struct _filter_data *data;
-
- data = g_malloc0 (sizeof (*data));
- data->type = type;
- data->source = source;
-
- mail_get_message (folder, uid, filter_type_got_message, data, mail_msg_unordered_push);
-}
-
-static void
-filter_type_current (EMFolderView *emfv, gint type)
-{
- const gchar *source;
- GPtrArray *uids;
-
- if (em_utils_folder_is_sent (emfv->folder, emfv->folder_uri)
- || em_utils_folder_is_outbox (emfv->folder, emfv->folder_uri))
- source = FILTER_SOURCE_OUTGOING;
- else
- source = FILTER_SOURCE_INCOMING;
-
- uids = message_list_get_selected (emfv->list);
-
- if (uids->len == 1)
- filter_type_uid (emfv->folder, (gchar *) uids->pdata[0], source, type);
-
- em_utils_uids_free (uids);
-}
-
-EMFV_MAP_CALLBACK(emfv_tools_filter_subject, emfv_popup_filter_subject)
-EMFV_MAP_CALLBACK(emfv_tools_filter_sender, emfv_popup_filter_sender)
-EMFV_MAP_CALLBACK(emfv_tools_filter_recipient, emfv_popup_filter_recipients)
-EMFV_MAP_CALLBACK(emfv_tools_filter_mlist, emfv_popup_filter_mlist)
-
-static void
-vfolder_type_got_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, gpointer user_data)
-{
- struct _filter_data *data = user_data;
-
- if (msg)
- vfolder_gui_add_from_message (msg, data->type, data->uri);
-
- filter_data_free (data);
-}
-
-static void
-emp_uri_popup_vfolder_sender(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
- CamelURL *url;
- CamelInternetAddress *addr;
-
- url = camel_url_new(t->uri, NULL);
- if (url == NULL) {
- g_warning("cannot parse url '%s'", t->uri);
- return;
- }
-
- if (url->path && url->path[0]) {
- /* ensures vfolder is running */
- vfolder_load_storage ();
-
- addr = camel_internet_address_new ();
- camel_address_decode (CAMEL_ADDRESS (addr), url->path);
- vfolder_gui_add_from_address (addr, AUTO_FROM, emfv->folder_uri);
- camel_object_unref (addr);
- }
-
- camel_url_free(url);
-
-}
-
-static void
-emp_uri_popup_vfolder_recipient(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
- CamelURL *url;
- CamelInternetAddress *addr;
-
- url = camel_url_new(t->uri, NULL);
- if (url == NULL) {
- g_warning("cannot parse url '%s'", t->uri);
- return;
- }
-
- if (url->path && url->path[0]) {
- /* ensures vfolder is running */
- vfolder_load_storage ();
-
- addr = camel_internet_address_new ();
- camel_address_decode (CAMEL_ADDRESS (addr), url->path);
- vfolder_gui_add_from_address (addr, AUTO_TO, emfv->folder_uri);
- camel_object_unref (addr);
- }
-
- camel_url_free(url);
-}
-
-static void
-vfolder_type_uid (CamelFolder *folder, const gchar *uid, const gchar *uri, gint type)
-{
- struct _filter_data *data;
-
- data = g_malloc0 (sizeof (*data));
- data->type = type;
- data->uri = g_strdup (uri);
-
- mail_get_message (folder, uid, vfolder_type_got_message, data, mail_msg_unordered_push);
-}
-
-static void
-vfolder_type_current (EMFolderView *emfv, gint type)
-{
- GPtrArray *uids;
-
- uids = message_list_get_selected (emfv->list);
-
- if (uids->len == 1) {
- /* ensures vfolder is running */
- vfolder_load_storage ();
-
- vfolder_type_uid (emfv->folder, (gchar *) uids->pdata[0], emfv->folder_uri, type);
- }
-
- em_utils_uids_free (uids);
-}
-
-EMFV_MAP_CALLBACK(emfv_tools_vfolder_subject, emfv_popup_vfolder_subject)
-EMFV_MAP_CALLBACK(emfv_tools_vfolder_sender, emfv_popup_vfolder_sender)
-EMFV_MAP_CALLBACK(emfv_tools_vfolder_recipient, emfv_popup_vfolder_recipients)
-EMFV_MAP_CALLBACK(emfv_tools_vfolder_mlist, emfv_popup_vfolder_mlist)
+//static void
+//emp_uri_popup_vfolder_sender(EPopup *ep, EPopupItem *pitem, gpointer data)
+//{
+// EMFolderView *emfv = data;
+// EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
+// CamelURL *url;
+// CamelInternetAddress *addr;
+//
+// url = camel_url_new(t->uri, NULL);
+// if (url == NULL) {
+// g_warning("cannot parse url '%s'", t->uri);
+// return;
+// }
+//
+// if (url->path && url->path[0]) {
+// /* ensures vfolder is running */
+// vfolder_load_storage ();
+//
+// addr = camel_internet_address_new ();
+// camel_address_decode (CAMEL_ADDRESS (addr), url->path);
+// vfolder_gui_add_from_address (addr, AUTO_FROM, emfv->folder_uri);
+// camel_object_unref (addr);
+// }
+//
+// camel_url_free(url);
+//
+//}
+
+//static void
+//emp_uri_popup_vfolder_recipient(EPopup *ep, EPopupItem *pitem, gpointer data)
+//{
+// EMFolderView *emfv = data;
+// EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
+// CamelURL *url;
+// CamelInternetAddress *addr;
+//
+// url = camel_url_new(t->uri, NULL);
+// if (url == NULL) {
+// g_warning("cannot parse url '%s'", t->uri);
+// return;
+// }
+//
+// if (url->path && url->path[0]) {
+// /* ensures vfolder is running */
+// vfolder_load_storage ();
+//
+// addr = camel_internet_address_new ();
+// camel_address_decode (CAMEL_ADDRESS (addr), url->path);
+// vfolder_gui_add_from_address (addr, AUTO_TO, emfv->folder_uri);
+// camel_object_unref (addr);
+// }
+//
+// camel_url_free(url);
+//}
/* ********************************************************************** */
static BonoboUIVerb emfv_message_verbs[] = {
- BONOBO_UI_UNSAFE_VERB ("EmptyTrash", emfv_empty_trash),
- BONOBO_UI_UNSAFE_VERB ("PrepareForOffline", emfv_prepare_offline),
BONOBO_UI_UNSAFE_VERB ("EditCut", emfv_edit_cut),
BONOBO_UI_UNSAFE_VERB ("EditCopy", emfv_edit_copy),
BONOBO_UI_UNSAFE_VERB ("EditPaste", emfv_edit_paste),
- BONOBO_UI_UNSAFE_VERB ("SelectAllText", emfv_select_all_text),
-
- BONOBO_UI_UNSAFE_VERB ("MailNext", emfv_mail_next),
- BONOBO_UI_UNSAFE_VERB ("MailNextFlagged", emfv_mail_next_flagged),
- BONOBO_UI_UNSAFE_VERB ("MailNextUnread", emfv_mail_next_unread),
- BONOBO_UI_UNSAFE_VERB ("MailNextThread", emfv_mail_next_thread),
- BONOBO_UI_UNSAFE_VERB ("MailPrevious", emfv_mail_previous),
- BONOBO_UI_UNSAFE_VERB ("MailPreviousFlagged", emfv_mail_previous_flagged),
- BONOBO_UI_UNSAFE_VERB ("MailPreviousUnread", emfv_mail_previous_unread),
-
- BONOBO_UI_UNSAFE_VERB ("AddSenderToAddressbook", emfv_add_sender_addressbook),
-
- BONOBO_UI_UNSAFE_VERB ("MessageApplyFilters", emfv_message_apply_filters),
- BONOBO_UI_UNSAFE_VERB ("MessageFilterJunk", emfv_message_filter_junk),
- BONOBO_UI_UNSAFE_VERB ("MessageCopy", emfv_message_copy),
- BONOBO_UI_UNSAFE_VERB ("MessageDelete", emfv_message_delete),
- BONOBO_UI_UNSAFE_VERB ("MessageDeleteKey", emfv_message_delete),
- BONOBO_UI_UNSAFE_VERB ("MessageForward", emfv_message_forward),
- BONOBO_UI_UNSAFE_VERB ("MessageForwardAttached", emfv_message_forward_attached),
- BONOBO_UI_UNSAFE_VERB ("MessageForwardInline", emfv_message_forward_inline),
- BONOBO_UI_UNSAFE_VERB ("MessageForwardQuoted", emfv_message_forward_quoted),
- BONOBO_UI_UNSAFE_VERB ("MessageRedirect", emfv_message_redirect),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsRead", emfv_message_mark_read),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsUnRead", emfv_message_mark_unread),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsImportant", emfv_message_mark_important),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsUnimportant", emfv_message_mark_unimportant),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsJunk", emfv_message_mark_junk),
- BONOBO_UI_UNSAFE_VERB ("MessageMarkAsNotJunk", emfv_message_mark_nojunk),
- BONOBO_UI_UNSAFE_VERB ("MessageFollowUpFlag", emfv_message_followup_flag),
- BONOBO_UI_UNSAFE_VERB ("MessageFollowUpComplete", emfv_message_followup_completed),
- BONOBO_UI_UNSAFE_VERB ("MessageFollowUpClear", emfv_message_followup_clear),
- BONOBO_UI_UNSAFE_VERB ("MessageMove", emfv_message_move),
- BONOBO_UI_UNSAFE_VERB ("MessageOpen", emfv_message_open),
- BONOBO_UI_UNSAFE_VERB ("MessageReplyAll", emfv_message_reply_all),
- BONOBO_UI_UNSAFE_VERB ("MessageReplyList", emfv_message_reply_list),
- BONOBO_UI_UNSAFE_VERB ("MessageReplySender", emfv_message_reply_sender),
- BONOBO_UI_UNSAFE_VERB ("MessageEdit", emfv_message_edit),
- BONOBO_UI_UNSAFE_VERB ("MessageSaveAs", emfv_message_saveas),
- BONOBO_UI_UNSAFE_VERB ("MessageSearch", emfv_message_search),
- BONOBO_UI_UNSAFE_VERB ("MessageUndelete", emfv_message_undelete),
-
- BONOBO_UI_UNSAFE_VERB ("PrintMessage", emfv_print_message),
- BONOBO_UI_UNSAFE_VERB ("PrintPreviewMessage", emfv_print_preview_message),
-
- BONOBO_UI_UNSAFE_VERB ("TextZoomIn", emfv_text_zoom_in),
- BONOBO_UI_UNSAFE_VERB ("TextZoomOut", emfv_text_zoom_out),
- BONOBO_UI_UNSAFE_VERB ("TextZoomReset", emfv_text_zoom_reset),
-
- BONOBO_UI_UNSAFE_VERB ("ViewSource", emfv_message_source),
-
- BONOBO_UI_UNSAFE_VERB ("MailCompose", emfv_mail_compose),
-
- /* TODO: This stuff should just be 1 item that runs a wizard */
- BONOBO_UI_UNSAFE_VERB ("ToolsFilterMailingList", emfv_tools_filter_mlist),
- BONOBO_UI_UNSAFE_VERB ("ToolsFilterRecipient", emfv_tools_filter_recipient),
- BONOBO_UI_UNSAFE_VERB ("ToolsFilterSender", emfv_tools_filter_sender),
- BONOBO_UI_UNSAFE_VERB ("ToolsFilterSubject", emfv_tools_filter_subject),
- BONOBO_UI_UNSAFE_VERB ("ToolsVFolderMailingList", emfv_tools_vfolder_mlist),
- BONOBO_UI_UNSAFE_VERB ("ToolsVFolderRecipient", emfv_tools_vfolder_recipient),
- BONOBO_UI_UNSAFE_VERB ("ToolsVFolderSender", emfv_tools_vfolder_sender),
- BONOBO_UI_UNSAFE_VERB ("ToolsVFolderSubject", emfv_tools_vfolder_subject),
-
- BONOBO_UI_UNSAFE_VERB ("ViewLoadImages", emfv_view_load_images),
- /* ViewHeaders stuff is a radio */
- /* CaretMode is a toggle */
-
- BONOBO_UI_VERB_END
-};
-static EPixmap emfv_message_pixmaps[] = {
-
- E_PIXMAP ("/commands/EditCopy", "edit-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/EditCut", "edit-cut", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/EditPaste", "edit-paste", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MailCompose", "mail-message-new", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageApplyFilters", "stock_mail-filters-apply", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageCopy", "mail-copy", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageDelete", "user-trash", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageFilterJunk", "mail-mark-junk", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageFollowUpFlag", "stock_mail-flag-for-followup", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageForward", "mail-forward", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAsImportant", "mail-mark-important", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAsJunk", "mail-mark-junk", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAsNotJunk", "mail-mark-notjunk", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAsRead", "mail-mark-read", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMarkAsUnRead", "mail-mark-unread", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageMove", "mail-move", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageReplyAll", "mail-reply-all", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageReplySender", "mail-reply-sender", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageSaveAs", "document-save-as", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/MessageSearch", "edit-find", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/PrintMessage", "document-print", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/PrintPreviewMessage", "document-print-preview", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TextZoomIn", "zoom-in", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TextZoomOut", "zoom-out", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/TextZoomReset", "zoom-original", GTK_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ViewLoadImages", "image-x-generic", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP ("/menu/MessagePlaceholder/Message/MessageNavigation/GoTo", "go-jump", GTK_ICON_SIZE_MENU),
-
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageReplySender", "mail-reply-sender", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageReplyAll", "mail-reply-all", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageForward", "mail-forward", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/PrintMessage", "document-print", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageMove", "mail-move", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageCopy", "mail-copy", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageDelete", "edit-delete", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageMarkAsJunk", "mail-mark-junk", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageMarkAsNotJunk", "mail-mark-notjunk", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailNextButtons/MailNext", "go-next", GTK_ICON_SIZE_LARGE_TOOLBAR),
- E_PIXMAP ("/Toolbar/MailNextButtons/MailPrevious", "go-previous", GTK_ICON_SIZE_LARGE_TOOLBAR),
-
- E_PIXMAP_END
-};
-
-static void
-emfv_enable_menus(EMFolderView *emfv)
-{
- guint32 disable_mask;
- GString *name;
- GSList *l;
+// BONOBO_UI_UNSAFE_VERB ("SelectAllText", emfv_select_all_text),
- if (emfv->uic == NULL)
- return;
+// BONOBO_UI_UNSAFE_VERB ("MessageDelete", emfv_message_delete),
+// BONOBO_UI_UNSAFE_VERB ("MessageDeleteKey", emfv_message_delete),
+// BONOBO_UI_UNSAFE_VERB ("MessageOpen", emfv_message_open),
+// BONOBO_UI_UNSAFE_VERB ("MessageSearch", emfv_message_search),
- {
- if (emfv->menu && emfv->folder) {
- EMMenuTargetSelect *t;
-
- t = em_menu_target_new_select(emfv->menu, emfv->folder, emfv->folder_uri, message_list_get_selected(emfv->list));
- t->target.widget = GTK_WIDGET (emfv);
- e_menu_update_target((EMenu *)emfv->menu, t);
- }
- }
+// BONOBO_UI_UNSAFE_VERB ("ViewSource", emfv_message_source),
- if (emfv->folder) {
- EMPopup *emp = em_popup_new("dummy");
- EMPopupTargetSelect *t;
-
- t = em_folder_view_get_popup_target(emfv, emp, FALSE);
- disable_mask = t->target.mask;
- e_popup_target_free((EPopup *)emp, t);
- g_object_unref(emp);
- } else {
- disable_mask = ~0;
- }
-
- name = g_string_new("");
- for (l = emfv->enable_map; l; l = l->next) {
- EMFolderViewEnable *map = l->data;
- gint i;
-
- for (i=0;map[i].name;i++) {
- gint state = (map[i].mask & disable_mask) == 0;
-
- g_string_printf(name, "/commands/%s", map[i].name);
- bonobo_ui_component_set_prop(emfv->uic, name->str, "sensitive", state?"1":"0", NULL);
- }
- }
-
- g_string_free(name, TRUE);
-}
-
-static void
-emfv_view_mode(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- EMFolderView *emfv = data;
- gint i;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- /* TODO: I don't like this stuff much, is there any way we can move listening for such events
- elsehwere? Probably not I guess, unless there's a EMFolderViewContainer for bonobo usage
- of a folder view */
-
- i = state[0] != '0';
-
- em_format_set_mode((EMFormat *)emfv->preview, i);
-
- if (EM_FOLDER_VIEW_GET_CLASS (emfv)->update_message_style) {
- GConfClient *gconf = mail_config_get_gconf_client ();
-
- gconf_client_set_int (gconf, "/apps/evolution/mail/display/message_style", i, NULL);
- }
-}
-
-static void
-emfv_caret_mode(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- EMFolderView *emfv = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- em_format_html_display_set_caret_mode(emfv->preview, state[0] != '0');
-
- gconf_client_set_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/display/caret_mode", state[0] != '0', NULL);
-}
-
-static void
-emfv_charset_changed(BonoboUIComponent *uic, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data)
-{
- EMFolderView *emfv = data;
-
- if (type != Bonobo_UIComponent_STATE_CHANGED)
- return;
-
- /* menu items begin with "Charset-" = 8 characters */
- if (state[0] != '0' && strlen(path) > 8) {
- path += 8;
- /* default charset used in mail view */
- if (!strcmp(path, _("Default")))
- path = NULL;
-
- em_format_set_charset((EMFormat *)emfv->preview, path);
- }
-}
+ BONOBO_UI_VERB_END
+};
static void
emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint act)
{
- struct _EMFolderViewPrivate *p = emfv->priv;
if (act) {
em_format_mode_t style;
@@ -2252,27 +456,25 @@ emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint act)
bonobo_ui_util_set_ui(uic, PREFIX, (gchar *)l->data, emfv->ui_app_name, NULL);
bonobo_ui_component_add_verb_list_with_data(uic, emfv_message_verbs, emfv);
- e_pixmaps_update(uic, emfv_message_pixmaps);
-
/* must do plugin menu's after main ones because of bonobo bustedness */
if (emfv->menu)
e_menu_activate((EMenu *)emfv->menu, uic, act);
- state = emfv->preview->caret_mode;
- bonobo_ui_component_set_prop(uic, "/commands/CaretMode", "state", state?"1":"0", NULL);
- bonobo_ui_component_add_listener(uic, "CaretMode", emfv_caret_mode, emfv);
+// state = emfv->preview->caret_mode;
+// bonobo_ui_component_set_prop(uic, "/commands/CaretMode", "state", state?"1":"0", NULL);
+// bonobo_ui_component_add_listener(uic, "CaretMode", emfv_caret_mode, emfv);
- style = ((EMFormat *)emfv->preview)->mode?EM_FORMAT_ALLHEADERS:EM_FORMAT_NORMAL;
- if (style)
- bonobo_ui_component_set_prop(uic, "/commands/ViewFullHeaders", "state", "1", NULL);
- bonobo_ui_component_add_listener(uic, "ViewFullHeaders", emfv_view_mode, emfv);
- em_format_set_mode((EMFormat *)emfv->preview, style);
+// style = ((EMFormat *)emfv->preview)->mode?EM_FORMAT_ALLHEADERS:EM_FORMAT_NORMAL;
+// if (style)
+// bonobo_ui_component_set_prop(uic, "/commands/ViewFullHeaders", "state", "1", NULL);
+// bonobo_ui_component_add_listener(uic, "ViewFullHeaders", emfv_view_mode, emfv);
+// em_format_set_mode((EMFormat *)emfv->preview, style);
if (emfv->folder)
bonobo_ui_component_set_prop(uic, "/commands/MessageEdit", "sensitive", "0", NULL);
- /* default charset used in mail view */
- e_charset_picker_bonobo_ui_populate (uic, "/menu/View", _("Default"), emfv_charset_changed, emfv);
+// /* default charset used in mail view */
+// e_charset_picker_bonobo_ui_populate (uic, "/menu/View", _("Default"), emfv_charset_changed, emfv);
emfv_enable_menus(emfv);
if (emfv->statusbar_active)
@@ -2291,16 +493,6 @@ emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint act)
for (v = &emfv_message_verbs[0]; v->cname; v++)
bonobo_ui_component_remove_verb(uic, v->cname);
- if (p->view_instance) {
- g_object_unref(p->view_instance);
- p->view_instance = NULL;
- }
-
- if (p->view_menus) {
- g_object_unref(p->view_menus);
- p->view_menus = NULL;
- }
-
if (emfv->folder)
mail_sync_folder(emfv->folder, NULL, NULL);
@@ -2308,37 +500,6 @@ emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, gint act)
}
}
-gint
-em_folder_view_print (EMFolderView *emfv, GtkPrintOperationAction action)
-{
- EMFormatHTMLPrint *efhp;
- GPtrArray *uids;
-
- if (emfv->folder == NULL)
- return 0;
-
- uids = message_list_get_selected (emfv->list);
- if (uids->len != 1)
- goto exit;
-
- efhp = em_format_html_print_new (
- (EMFormatHTML *) emfv->preview, action);
- em_format_set_session (
- (EMFormat *) efhp,
- ((EMFormat *) emfv->preview)->session);
- em_format_merge_handler ((EMFormat *) efhp,
- (EMFormat *) emfv->preview);
-
- em_format_html_print_message (
- efhp, emfv->folder, uids->pdata[0]);
- g_object_unref (efhp);
-
-exit:
- message_list_free_uids (emfv->list, uids);
-
- return 0;
-}
-
EMPopupTargetSelect *
em_folder_view_get_popup_target(EMFolderView *emfv, EMPopup *emp, gint on_display)
{
@@ -2381,18 +542,6 @@ em_folder_view_get_popup_target(EMFolderView *emfv, EMPopup *emp, gint on_displa
}
void
-em_folder_view_set_statusbar (EMFolderView *emfv, gboolean statusbar)
-{
- g_return_if_fail (emfv);
-
- emfv->statusbar_active = statusbar;
-
- if (statusbar && emfv->uic)
- bonobo_ui_component_set_translate (emfv->uic, "/",
- "<status><item name=\"main\"/></status>", NULL);
-}
-
-void
em_folder_view_set_hide_deleted(EMFolderView *emfv, gboolean status)
{
if (emfv->folder && (emfv->folder->folder_flags & CAMEL_FOLDER_IS_TRASH))
@@ -2441,6 +590,7 @@ emfv_list_done_message_selected(CamelFolder *folder, const gchar *uid, CamelMime
EMFolderView *emfv = data;
EMEvent *eme;
EMEventTargetMessage *target;
+ EShell *shell;
if (emfv->preview == NULL) {
emfv->priv->nomarkseen = FALSE;
@@ -2452,7 +602,8 @@ emfv_list_done_message_selected(CamelFolder *folder, const gchar *uid, CamelMime
e_profile_event_emit("goto.loaded", emfv->displayed_uid, 0);
- mail_indicate_new_mail (FALSE);
+ shell = e_shell_backend_get_shell (mail_shell_backend);
+ e_shell_event (shell, "mail-icon", "evolution-mail");
/** @Event: message.reading
* @Title: Viewing a message
@@ -2535,100 +686,6 @@ emfv_message_selected_timeout(gpointer data)
return FALSE;
}
-static void
-emfv_list_message_selected(MessageList *ml, const gchar *uid, EMFolderView *emfv)
-{
- e_profile_event_emit("goto.listuid", uid, 0);
-
- if (emfv->preview_active) {
- if (emfv->priv->selected_id != 0)
- g_source_remove(emfv->priv->selected_id);
-
- emfv->priv->selected_id = g_timeout_add(100, emfv_message_selected_timeout, emfv);
-
- g_free(emfv->priv->selected_uid);
- emfv->priv->selected_uid = g_strdup(uid);
- }
-
- emfv_enable_menus(emfv);
-
- g_signal_emit(emfv, signals[EMFV_CHANGED], 0);
-}
-
-static void
-emfv_list_built(MessageList *ml, EMFolderView *emfv)
-{
- if (!emfv->priv->destroyed) {
- emfv_enable_menus(emfv);
- g_signal_emit(emfv, signals[EMFV_LOADED], 0);
- }
-}
-
-static void
-emfv_list_double_click(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, EMFolderView *emfv)
-{
- /* Ignore double-clicks on columns that handle thier own state */
- if (MESSAGE_LIST_COLUMN_IS_ACTIVE (col))
- return;
-
- em_folder_view_open_selected(emfv);
-}
-
-static gint
-emfv_list_right_click(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, EMFolderView *emfv)
-{
- emfv_popup(emfv, event, FALSE);
-
- return TRUE;
-}
-
-static gint
-emfv_list_key_press(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *ev, EMFolderView *emfv)
-{
- GPtrArray *uids;
- gint i;
- guint32 flags;
-
- if ((ev->key.state & GDK_CONTROL_MASK) != 0)
- return FALSE;
-
- switch (ev->key.keyval) {
- case GDK_Return:
- case GDK_KP_Enter:
- case GDK_ISO_Enter:
- em_folder_view_open_selected(emfv);
- break;
-#ifdef HAVE_XFREE
- case XF86XK_Reply:
- emfv_message_reply(emfv, REPLY_MODE_ALL);
- break;
- case XF86XK_MailForward:
- uids = message_list_get_selected(emfv->list);
- em_utils_forward_messages (emfv->folder, uids, emfv->folder_uri);
- break;
-#endif /* HAVE_XFREE */
- case '!':
- uids = message_list_get_selected(emfv->list);
-
- camel_folder_freeze(emfv->folder);
- for (i = 0; i < uids->len; i++) {
- flags = camel_folder_get_message_flags(emfv->folder, uids->pdata[i]) ^ CAMEL_MESSAGE_FLAGGED;
- if (flags & CAMEL_MESSAGE_FLAGGED)
- flags &= ~CAMEL_MESSAGE_DELETED;
- camel_folder_set_message_flags(emfv->folder, uids->pdata[i],
- CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_DELETED, flags);
- }
- camel_folder_thaw(emfv->folder);
-
- message_list_free_uids(emfv->list, uids);
- break;
- default:
- return FALSE;
- }
-
- return TRUE;
-}
-
static gboolean
emfv_popup_menu (GtkWidget *widget)
{
@@ -2649,53 +706,25 @@ emfv_popup_menu (GtkWidget *widget)
return TRUE;
}
-static void
-emfv_list_selection_change(ETree *tree, EMFolderView *emfv)
-{
- /* we can't just listen to the message-list message selected thing, since we dont get them
- in all cases. blah */
- g_signal_emit(emfv, signals[EMFV_CHANGED], 0);
-}
-
-static void
-emfv_format_link_clicked(EMFormatHTMLDisplay *efhd, const gchar *uri, EMFolderView *emfv)
-{
- if (!strncmp (uri, "##", 2))
- return;
-
- if (!g_ascii_strncasecmp (uri, "mailto:", 7)) {
- em_utils_compose_new_message_with_mailto (uri, emfv->folder_uri);
- } else if (*uri == '#') {
- gtk_html_jump_to_anchor (((EMFormatHTML *) efhd)->html, uri + 1);
- } else if (!g_ascii_strncasecmp (uri, "thismessage:", 12)) {
- /* ignore */
- } else if (!g_ascii_strncasecmp (uri, "cid:", 4)) {
- /* ignore */
- } else {
- /* FIXME Pass a parent window. */
- e_show_uri (NULL, uri);
- }
-}
-
-static void
-emp_uri_popup_link_copy(EPopup *ep, EPopupItem *pitem, gpointer data)
-{
- EMFolderView *emfv = data;
- struct _EMFolderViewPrivate *p = emfv->priv;
-
- g_free(p->selection_uri);
- p->selection_uri = g_strdup(pitem->user_data);
-
- gtk_selection_owner_set(p->invisible, GDK_SELECTION_PRIMARY, gtk_get_current_event_time());
- gtk_selection_owner_set(p->invisible, GDK_SELECTION_CLIPBOARD, gtk_get_current_event_time());
-}
+//static void
+//emp_uri_popup_link_copy(EPopup *ep, EPopupItem *pitem, gpointer data)
+//{
+// EMFolderView *emfv = data;
+// struct _EMFolderViewPrivate *p = emfv->priv;
+//
+// g_free(p->selection_uri);
+// p->selection_uri = em_utils_url_unescape_amp(pitem->user_data);
+//
+// gtk_selection_owner_set(p->invisible, GDK_SELECTION_PRIMARY, gtk_get_current_event_time());
+// gtk_selection_owner_set(p->invisible, GDK_SELECTION_CLIPBOARD, gtk_get_current_event_time());
+//}
static EPopupItem emfv_uri_popups[] = {
- { E_POPUP_ITEM, (gchar *) "00.uri.15", (gchar *) N_("_Copy Link Location"), emp_uri_popup_link_copy, NULL, (gchar *) "edit-copy", EM_POPUP_URI_NOT_MAILTO },
+// { E_POPUP_ITEM, (gchar *) "00.uri.15", (gchar *) N_("_Copy Link Location"), emp_uri_popup_link_copy, NULL, (gchar *) "edit-copy", EM_POPUP_URI_NOT_MAILTO },
- { E_POPUP_SUBMENU, (gchar *) "99.uri.00", (gchar *) N_("Create _Search Folder"), NULL, NULL, NULL, EM_POPUP_URI_MAILTO },
- { E_POPUP_ITEM, (gchar *) "99.uri.00/00.10", (gchar *) N_("_From this Address"), emp_uri_popup_vfolder_sender, NULL, NULL, EM_POPUP_URI_MAILTO },
- { E_POPUP_ITEM, (gchar *) "99.uri.00/00.00", (gchar *) N_("_To this Address"), emp_uri_popup_vfolder_recipient, NULL, NULL, EM_POPUP_URI_MAILTO },
+// { E_POPUP_SUBMENU, (gchar *) "99.uri.00", (gchar *) N_("Create _Search Folder"), NULL, NULL, NULL, EM_POPUP_URI_MAILTO },
+// { E_POPUP_ITEM, (gchar *) "99.uri.00/00.10", (gchar *) N_("_From this Address"), emp_uri_popup_vfolder_sender, NULL, NULL, EM_POPUP_URI_MAILTO },
+// { E_POPUP_ITEM, (gchar *) "99.uri.00/00.00", (gchar *) N_("_To this Address"), emp_uri_popup_vfolder_recipient, NULL, NULL, EM_POPUP_URI_MAILTO },
};
static void
@@ -2914,43 +943,17 @@ emfv_set_seen(EMFolderView *emfv, const gchar *uid)
/* keep these two tables in sync */
enum {
- EMFV_ANIMATE_IMAGES = 1,
- EMFV_CHARSET,
- EMFV_CITATION_COLOUR,
- EMFV_CITATION_MARK,
- EMFV_CARET_MODE,
- EMFV_MESSAGE_STYLE,
- EMFV_MARK_SEEN,
- EMFV_MARK_SEEN_TIMEOUT,
- EMFV_LOAD_HTTP,
+ EMFV_CHARSET = 1,
EMFV_HEADERS,
- EMFV_SHOW_PREVIEW,
EMFV_SHOW_DELETED,
- EMFV_THREAD_LIST,
- EMFV_PANED_SIZE,
- EMFV_SENDER_PHOTO,
- EMFV_PHOTO_LOCAL,
EMFV_SETTINGS /* last, for loop count */
};
/* IF these get too long, update key field */
static const gchar * const emfv_display_keys[] = {
- "animate_images",
"charset",
- "citation_colour",
- "mark_citations",
- "caret_mode",
- "message_style",
- "mark_seen",
- "mark_seen_timeout",
- "load_http_images",
"headers",
- "show_preview",
"show_deleted",
- "thread_list",
- "paned_size",
- "sender_photo",
- "photo_local",
};
static GHashTable *emfv_setting_key;
@@ -2970,49 +973,9 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold
g_return_if_fail (tkey != NULL);
switch(GPOINTER_TO_INT(g_hash_table_lookup(emfv_setting_key, tkey+1))) {
- case EMFV_ANIMATE_IMAGES:
- em_format_html_display_set_animate(emfv->preview, gconf_value_get_bool (value));
- break;
case EMFV_CHARSET:
em_format_set_default_charset((EMFormat *)emfv->preview, gconf_value_get_string (value));
break;
- case EMFV_CITATION_COLOUR: {
- const gchar *s;
- GdkColor colour;
- guint32 rgb;
-
- s = gconf_value_get_string (value);
- gdk_color_parse(s?s:"#737373", &colour);
- rgb = ((colour.red & 0xff00) << 8) | (colour.green & 0xff00) | ((colour.blue & 0xff00) >> 8);
- em_format_html_set_mark_citations((EMFormatHTML *)emfv->preview,
- ((EMFormatHTML *)emfv->preview)->mark_citations, rgb);
- break; }
- case EMFV_CITATION_MARK:
- em_format_html_set_mark_citations((EMFormatHTML *)emfv->preview,
- gconf_value_get_bool (value),
- ((EMFormatHTML *)emfv->preview)->citation_colour);
- break;
- case EMFV_CARET_MODE:
- em_format_html_display_set_caret_mode(emfv->preview, gconf_value_get_bool (value));
- break;
- case EMFV_MESSAGE_STYLE:
- if (EM_FOLDER_VIEW_GET_CLASS (emfv)->update_message_style) {
- gint style = gconf_value_get_int (value);
-
- if (style < EM_FORMAT_NORMAL || style > EM_FORMAT_SOURCE)
- style = EM_FORMAT_NORMAL;
- em_format_set_mode((EMFormat *)emfv->preview, style);
- }
- break;
- case EMFV_MARK_SEEN:
- emfv->mark_seen = gconf_value_get_bool (value);
- break;
- case EMFV_MARK_SEEN_TIMEOUT:
- emfv->mark_seen_timeout = gconf_value_get_int (value);
- break;
- case EMFV_LOAD_HTTP:
- em_format_html_set_load_http((EMFormatHTML *)emfv->preview, gconf_value_get_int(value));
- break;
case EMFV_HEADERS: {
GSList *header_config_list, *p;
EMFormat *emf = (EMFormat *)emfv->preview;
@@ -3037,45 +1000,6 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold
if (emf->message)
em_format_redraw(emf);
break; }
- case EMFV_SENDER_PHOTO: {
- EMFormat *emf = (EMFormat *)emfv->preview;
-
- emf->show_photo = gconf_value_get_bool (value);
- if (emf->message)
- em_format_redraw(emf);
-
- break; }
- case EMFV_PHOTO_LOCAL: {
- EMFormat *emf = (EMFormat *)emfv->preview;
-
- emf->photo_local = gconf_value_get_bool (value);
-
- break; }
- case EMFV_SHOW_PREVIEW: {
- gboolean state_gconf, state_camel;
- gchar *ret;
-
- /* If emfv->folder hasn't been initialized, do nothing */
- if (!emfv->folder)
- return;
-
- state_gconf = gconf_value_get_bool (value);
- if (state_gconf == FALSE)
- emfv_enable_menus (emfv);
-
- if ((ret = camel_object_meta_get (emfv->folder, "evolution:show_preview"))) {
- state_camel = (ret[0] != '0');
- g_free (ret);
- if (state_gconf == state_camel)
- return;
- }
-
- if (camel_object_meta_set (emfv->folder, "evolution:show_preview", state_gconf ? "1" : "0"))
- camel_object_state_write (emfv->folder);
- if (emfv->list_active)
- em_folder_browser_show_preview ((EMFolderBrowser *)emfv, state_gconf);
- bonobo_ui_component_set_prop (emfv->uic, "/commands/ViewPreview", "state", state_gconf ? "1" : "0", NULL);
- break; }
case EMFV_SHOW_DELETED: {
gboolean state;
@@ -3086,155 +1010,5 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold
if (emfv->uic)
bonobo_ui_component_set_prop (emfv->uic, "/commands/HideDeleted", "state", state ? "0" : "1", NULL);
break; }
- case EMFV_THREAD_LIST: {
- gboolean state_gconf, state_camel;
- gchar *ret;
-
- /* If emfv->folder or emfv->list hasn't been initialized, do nothing */
- if (!emfv->folder || !emfv->list)
- return;
-
- state_gconf = gconf_value_get_bool (value);
- if ((ret = camel_object_meta_get (emfv->folder, "evolution:thread_list"))) {
- state_camel = (ret[0] != '0');
- g_free (ret);
- if (state_gconf == state_camel)
- return;
- }
-
- if (camel_object_meta_set (emfv->folder, "evolution:thread_list", state_gconf ? "1" : "0"))
- camel_object_state_write (emfv->folder);
- message_list_set_threaded (emfv->list, state_gconf);
- bonobo_ui_component_set_prop (emfv->uic, "/commands/ViewThreaded", "state", state_gconf ? "1" : "0", NULL);
- break; }
- case EMFV_PANED_SIZE: {
- EMFolderBrowser *emfb = (EMFolderBrowser *)emfv;
- gint paned_size;
-
- if (!emfv->list_active || !emfb->vpane || !emfv->preview_active)
- return;
-
- paned_size = gconf_value_get_int (value);
- if (paned_size == gtk_paned_get_position (GTK_PANED (emfb->vpane)))
- return;
-
- gtk_paned_set_position (GTK_PANED (emfb->vpane), paned_size);
- break; }
- }
-}
-
-static void
-emfv_setting_setup(EMFolderView *emfv)
-{
- GConfClient *gconf = gconf_client_get_default();
- GConfEntry *entry;
- GError *err = NULL;
- gint i;
- gchar key[64];
-
- if (emfv_setting_key == NULL) {
- emfv_setting_key = g_hash_table_new(g_str_hash, g_str_equal);
- for (i=1;i<EMFV_SETTINGS;i++)
- g_hash_table_insert(emfv_setting_key, (gpointer)emfv_display_keys[i-1], GINT_TO_POINTER(i));
- }
-
- gconf_client_add_dir(gconf, "/apps/evolution/mail/display", GCONF_CLIENT_PRELOAD_NONE, NULL);
-
- for (i=1;err == NULL && i<EMFV_SETTINGS;i++) {
- sprintf(key, "/apps/evolution/mail/display/%s", emfv_display_keys[i-1]);
- entry = gconf_client_get_entry(gconf, key, NULL, TRUE, &err);
- if (entry) {
- emfv_setting_notify(gconf, 0, entry, emfv);
- gconf_entry_free(entry);
- }
- }
-
- if (err) {
- g_warning("Could not load display settings: %s", err->message);
- g_error_free(err);
}
-
- emfv->priv->setting_notify_id = gconf_client_notify_add(gconf, "/apps/evolution/mail/display",
- (GConfClientNotifyFunc)emfv_setting_notify,
- emfv, NULL, NULL);
- g_object_unref(gconf);
-}
-
-static void
-emfv_on_url (EMFolderView *emfv, const gchar *uri, const gchar *nice_uri)
-{
- if (emfv->statusbar_active) {
- if (emfv->uic) {
- bonobo_ui_component_set_status (emfv->uic, nice_uri, NULL);
- /* Make sure the node keeps existing if nice_url == NULL */
- if (!nice_uri)
- bonobo_ui_component_set_translate (
- emfv->uic, "/", "<status><item name=\"main\"/></status>", NULL);
- }
- }
-}
-
-static void
-emfv_on_url_cb (GObject *emitter, const gchar *url, EMFolderView *emfv)
-{
- gchar *nice_url = NULL;
-
- if (url) {
- if (strncmp (url, "mailto:", 7) == 0) {
- CamelInternetAddress *cia = camel_internet_address_new();
- CamelURL *curl;
- gchar *addr;
-
- curl = camel_url_new(url, NULL);
- camel_address_decode((CamelAddress *)cia, curl->path);
- addr = camel_address_format((CamelAddress *)cia);
- nice_url = g_strdup_printf (_("Click to mail %s"), addr&&addr[0]?addr:(url + 7));
- g_free(addr);
- camel_url_free(curl);
- camel_object_unref(cia);
- } else if (strncmp (url, "callto:", 7) == 0 || strncmp (url, "h323:", 5) == 0 || strncmp (url, "sip:", 4) == 0) {
- CamelInternetAddress *cia = camel_internet_address_new();
- CamelURL *curl;
- gchar *addr;
-
- curl = camel_url_new(url, NULL);
- camel_address_decode((CamelAddress *)cia, curl->path);
- addr = camel_address_format((CamelAddress *)cia);
- nice_url = g_strdup_printf (_("Click to call %s"), addr&&addr[0]?addr:(url + 7));
- g_free(addr);
- camel_url_free(curl);
- camel_object_unref(cia);
- } else if (!strncmp (url, "##", 2)) {
- nice_url = g_strdup (_("Click to hide/unhide addresses"));
- } else
- nice_url = g_strdup_printf (_("Click to open %s"), url);
- }
-
- g_signal_emit (emfv, signals[EMFV_ON_URL], 0, url, nice_url);
-
- g_free (nice_url);
-}
-
-static gboolean
-emfv_on_html_button_released_cb (GtkHTML *html, GdkEventButton *button, EMFolderView *emfv)
-{
- gboolean selected;
-
- selected = gtk_html_command (html, "is-selection-active");
- bonobo_ui_component_set_prop(emfv->uic, "/commands/EditCopy", "sensitive", selected?"1":"0", NULL);
-
- return FALSE;
-}
-
-void
-em_folder_view_show_search_bar (EMFolderView *emfv)
-{
- EMFolderViewClass *class;
-
- g_return_if_fail (EM_IS_FOLDER_VIEW (emfv));
-
- class = EM_FOLDER_VIEW_GET_CLASS (emfv);
- g_return_if_fail (class->show_search_bar != NULL);
-
- class->show_search_bar (emfv);
}
diff --git a/mail/em-folder-view.h b/mail/em-folder-view.h
index bb25f390ea..2c276914c0 100644
--- a/mail/em-folder-view.h
+++ b/mail/em-folder-view.h
@@ -143,6 +143,9 @@ GtkWidget *em_folder_view_new(void);
#define em_folder_view_set_folder_uri(emfv, uri) EM_FOLDER_VIEW_GET_CLASS (emfv)->set_folder_uri((emfv), (uri))
#define em_folder_view_set_message(emfv, uid, nomarkseen) EM_FOLDER_VIEW_GET_CLASS (emfv)->set_message((emfv), (uid), (nomarkseen))
+void em_folder_view_select_next_message(EMFolderView *emfv, gint count, gboolean always_can_previous);
+void em_folder_view_message_reply(EMFolderView *emfv, gint mode);
+
EMPopupTargetSelect *em_folder_view_get_popup_target(EMFolderView *emfv, EMPopup *emp, gint on_display);
gint em_folder_view_mark_selected(EMFolderView *emfv, guint32 mask, guint32 set);
diff --git a/mail/em-format-hook.h b/mail/em-format-hook.h
index 8312404451..e0560f4994 100644
--- a/mail/em-format-hook.h
+++ b/mail/em-format-hook.h
@@ -28,7 +28,7 @@
#include "libedataserver/e-msgport.h"
#include "e-util/e-plugin.h"
-#include "mail/em-format.h"
+#include "em-format/em-format.h"
G_BEGIN_DECLS
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index 48595582da..375eadafe2 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -73,12 +73,12 @@
#include "mail-config.h"
+#include "e-mail-display.h"
#include "e-mail-attachment-bar.h"
#include "em-format-html-display.h"
#include "em-icon-stream.h"
#include "em-utils.h"
#include "em-popup.h"
-#include "e-icon-entry.h"
#include "widgets/misc/e-attachment-button.h"
#include "widgets/misc/e-attachment-view.h"
@@ -94,17 +94,53 @@
#define d(x)
+#define EM_FORMAT_HTML_DISPLAY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplayPrivate))
+
struct _EMFormatHTMLDisplayPrivate {
GtkWidget *attachment_view; /* weak reference */
};
-static gint efhd_html_button_press_event (GtkWidget *widget, GdkEventButton *event, EMFormatHTMLDisplay *efh);
-static void efhd_html_link_clicked (GtkHTML *html, const gchar *url, EMFormatHTMLDisplay *efhd);
-static void efhd_html_on_url (GtkHTML *html, const gchar *url, EMFormatHTMLDisplay *efhd);
+struct _smime_pobject {
+ EMFormatHTMLPObject object;
+
+ gint signature;
+ CamelCipherValidity *valid;
+ GtkWidget *widget;
+};
+
+/* TODO: move the dialogue elsehwere */
+/* FIXME: also in em-format-html.c */
+static const struct {
+ const gchar *icon, *shortdesc, *description;
+} smime_sign_table[5] = {
+ { "stock_signature-bad", N_("Unsigned"), N_("This message is not signed. There is no guarantee that this message is authentic.") },
+ { "stock_signature-ok", N_("Valid signature"), N_("This message is signed and is valid meaning that it is very likely that this message is authentic.") },
+ { "stock_signature-bad", N_("Invalid signature"), N_("The signature of this message cannot be verified, it may have been altered in transit.") },
+ { "stock_signature", N_("Valid signature, but cannot verify sender"), N_("This message is signed with a valid signature, but the sender of the message cannot be verified.") },
+ { "stock_signature-bad", N_("Signature exists, but need public key"), N_("This message is signed with a signature, but there is no corresponding public key.") },
+
+};
+
+static const struct {
+ const gchar *icon, *shortdesc, *description;
+} smime_encrypt_table[4] = {
+ { "stock_lock-broken", N_("Unencrypted"), N_("This message is not encrypted. Its content may be viewed in transit across the Internet.") },
+ { "stock_lock-ok", N_("Encrypted, weak"), N_("This message is encrypted, but with a weak encryption algorithm. It would be difficult, but not impossible for an outsider to view the content of this message in a practical amount of time.") },
+ { "stock_lock-ok", N_("Encrypted"), N_("This message is encrypted. It would be difficult for an outsider to view the content of this message.") },
+ { "stock_lock-ok", N_("Encrypted, strong"), N_("This message is encrypted, with a strong encryption algorithm. It would be very difficult for an outsider to view the content of this message in a practical amount of time.") },
+};
+
+static const gchar *smime_sign_colour[5] = {
+ "", " bgcolor=\"#88bb88\"", " bgcolor=\"#bb8888\"", " bgcolor=\"#e8d122\"",""
+};
static void efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri);
static gboolean efhd_attachment_image(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
static void efhd_message_add_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info);
+static gboolean efhd_attachment_button (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
+static gboolean efhd_attachment_optional (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *object);
struct _attach_puri {
EMFormatPURI puri;
@@ -117,7 +153,6 @@ struct _attach_puri {
GtkWidget *forward, *down;
/* currently no way to correlate this data to the frame :( */
GtkHTML *frame;
- CamelStream *output;
guint shown:1;
/* Embedded Frame */
@@ -140,463 +175,14 @@ struct _attach_puri {
camel_cipher_validity_encrypt_t encrypt;
};
-static void efhd_iframe_created(GtkHTML *html, GtkHTML *iframe, EMFormatHTMLDisplay *efh);
-/*static void efhd_url_requested(GtkHTML *html, const gchar *url, GtkHTMLStream *handle, EMFormatHTMLDisplay *efh);
- static gboolean efhd_object_requested(GtkHTML *html, GtkHTMLEmbedded *eb, EMFormatHTMLDisplay *efh);*/
-
static void efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info);
-static const EMFormatHandler *efhd_find_handler(EMFormat *emf, const gchar *mime_type);
-static void efhd_format_clone(EMFormat *, CamelFolder *folder, const gchar *, CamelMimeMessage *msg, EMFormat *);
-static void efhd_format_error(EMFormat *emf, CamelStream *stream, const gchar *txt);
-static void efhd_format_source(EMFormat *, CamelStream *, CamelMimePart *);
-static void efhd_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, const gchar *, const EMFormatHandler *);
-static void efhd_format_optional(EMFormat *, CamelStream *, CamelMimePart *, CamelStream *);
-static void efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid);
-
static void efhd_builtin_init(EMFormatHTMLDisplayClass *efhc);
-enum {
- EFHD_LINK_CLICKED,
- EFHD_POPUP_EVENT,
- EFHD_ON_URL,
- EFHD_LAST_SIGNAL
-};
-
-static guint efhd_signals[EFHD_LAST_SIGNAL] = { 0 };
-
-static EMFormatHTMLClass *efhd_parent;
-static EMFormatClass *efhd_format_class;
-
-static void
-efhd_gtkhtml_realise(GtkHTML *html, EMFormatHTMLDisplay *efhd)
-{
- GtkStyle *style;
-
- /* FIXME: does this have to be re-done every time we draw? */
-
- /* My favorite thing to do... muck around with colors so we respect people's stupid themes.
- However, we only do this if we are rendering to the screen -- we ignore the theme
- when we are printing. */
- style = gtk_widget_get_style((GtkWidget *)html);
- if (style) {
- gint state = GTK_WIDGET_STATE(html);
- gushort r, g, b;
-
- r = style->fg[state].red >> 8;
- g = style->fg[state].green >> 8;
- b = style->fg[state].blue >> 8;
-
- efhd->formathtml.header_colour = ((r<<16) | (g<< 8) | b) & 0xffffff;
-
- r = style->bg[state].red >> 8;
- g = style->bg[state].green >> 8;
- b = style->bg[state].blue >> 8;
-
- efhd->formathtml.body_colour = ((r<<16) | (g<< 8) | b) & 0xffffff;
-
- r = style->dark[state].red >> 8;
- g = style->dark[state].green >> 8;
- b = style->dark[state].blue >> 8;
-
- efhd->formathtml.frame_colour = ((r<<16) | (g<< 8) | b) & 0xffffff;
-
- r = style->base[GTK_STATE_NORMAL].red >> 8;
- g = style->base[GTK_STATE_NORMAL].green >> 8;
- b = style->base[GTK_STATE_NORMAL].blue >> 8;
-
- efhd->formathtml.content_colour = ((r<<16) | (g<< 8) | b) & 0xffffff;
-
- r = style->text[state].red >> 8;
- g = style->text[state].green >> 8;
- b = style->text[state].blue >> 8;
-
- efhd->formathtml.text_colour = ((r<<16) | (g<< 8) | b) & 0xffffff;
-#undef DARKER
- }
-}
-
-static void
-efhd_gtkhtml_style_set(GtkHTML *html, GtkStyle *old, EMFormatHTMLDisplay *efhd)
-{
- efhd_gtkhtml_realise(html, efhd);
- em_format_redraw((EMFormat *)efhd);
-}
-
-static void
-efhd_init(GObject *o)
-{
- EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)o;
-#define efh ((EMFormatHTML *)efhd)
-
- efhd->priv = g_malloc0(sizeof(*efhd->priv));
-
- g_signal_connect(efh->html, "realize", G_CALLBACK(efhd_gtkhtml_realise), o);
- g_signal_connect(efh->html, "style-set", G_CALLBACK(efhd_gtkhtml_style_set), o);
- /* we want to convert url's etc */
- efh->text_html_flags |= CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES;
-#undef efh
-
- efhd->nobar = getenv("EVOLUTION_NO_BAR") != NULL;
-}
-
-static void
-efhd_finalise(GObject *o)
-{
- EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)o;
-
- /* check pending stuff */
-
- g_free(efhd->priv);
-
- ((GObjectClass *)efhd_parent)->finalize(o);
-}
-
-static gboolean
-efhd_bool_accumulator(GSignalInvocationHint *ihint, GValue *out, const GValue *in, gpointer data)
-{
- gboolean val = g_value_get_boolean(in);
-
- g_value_set_boolean(out, val);
-
- return !val;
-}
-
-static void
-efhd_class_init(GObjectClass *klass)
-{
- ((EMFormatClass *)klass)->find_handler = efhd_find_handler;
- ((EMFormatClass *)klass)->format_clone = efhd_format_clone;
- ((EMFormatClass *)klass)->format_error = efhd_format_error;
- ((EMFormatClass *)klass)->format_source = efhd_format_source;
- ((EMFormatClass *)klass)->format_attachment = efhd_format_attachment;
- ((EMFormatClass *)klass)->format_optional = efhd_format_optional;
- ((EMFormatClass *)klass)->format_secure = efhd_format_secure;
-
- klass->finalize = efhd_finalise;
-
- efhd_signals[EFHD_LINK_CLICKED] =
- g_signal_new("link_clicked",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(EMFormatHTMLDisplayClass, link_clicked),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
-
- efhd_signals[EFHD_POPUP_EVENT] =
- g_signal_new("popup_event",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(EMFormatHTMLDisplayClass, popup_event),
- efhd_bool_accumulator, NULL,
- e_marshal_BOOLEAN__BOXED_POINTER_POINTER,
- G_TYPE_BOOLEAN, 3,
- GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE,
- G_TYPE_POINTER, G_TYPE_POINTER);
-
- efhd_signals[EFHD_ON_URL] =
- g_signal_new("on_url",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(EMFormatHTMLDisplayClass, on_url),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- efhd_builtin_init((EMFormatHTMLDisplayClass *)klass);
-}
-
-GType
-em_format_html_display_get_type (void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFormatHTMLDisplayClass),
- NULL, NULL,
- (GClassInitFunc)efhd_class_init,
- NULL, NULL,
- sizeof(EMFormatHTMLDisplay), 0,
- (GInstanceInitFunc)efhd_init
- };
- efhd_parent = g_type_class_ref(em_format_html_get_type());
- efhd_format_class = g_type_class_ref(em_format_get_type());
- type = g_type_register_static(em_format_html_get_type(), "EMFormatHTMLDisplay", &info, 0);
- }
-
- return type;
-}
-
-static gboolean
-efhd_scroll_event(GtkWidget *w, GdkEventScroll *event, EMFormatHTMLDisplay *efhd)
-{
- if(event->state & GDK_CONTROL_MASK)
- {
- if(event->direction == GDK_SCROLL_UP)
- {
- gtk_html_zoom_in (efhd->formathtml.html);
- }
- else if(event->direction == GDK_SCROLL_DOWN)
- {
- gtk_html_zoom_out (efhd->formathtml.html);
- }
- return TRUE;
- }
- return FALSE;
-}
-
-EMFormatHTMLDisplay *em_format_html_display_new(void)
-{
- EMFormatHTMLDisplay *efhd;
-
- efhd = g_object_new(em_format_html_display_get_type(), 0);
-
- g_signal_connect(efhd->formathtml.html, "iframe_created", G_CALLBACK(efhd_iframe_created), efhd);
- g_signal_connect(efhd->formathtml.html, "link_clicked", G_CALLBACK(efhd_html_link_clicked), efhd);
- g_signal_connect(efhd->formathtml.html, "on_url", G_CALLBACK(efhd_html_on_url), efhd);
- g_signal_connect(efhd->formathtml.html, "button_press_event", G_CALLBACK(efhd_html_button_press_event), efhd);
- g_signal_connect(efhd->formathtml.html,"scroll_event", G_CALLBACK(efhd_scroll_event), efhd);
-
- return efhd;
-}
-
-void em_format_html_display_goto_anchor(EMFormatHTMLDisplay *efhd, const gchar *name)
-{
- printf("FIXME: go to anchor '%s'\n", name);
-}
-
-void em_format_html_display_set_animate(EMFormatHTMLDisplay *efhd, gboolean state)
-{
- efhd->animate = state;
- gtk_html_set_animate(((EMFormatHTML *)efhd)->html, state);
-}
-
-void em_format_html_display_set_caret_mode(EMFormatHTMLDisplay *efhd, gboolean state)
-{
- efhd->caret_mode = state;
- gtk_html_set_caret_mode(((EMFormatHTML *)efhd)->html, state);
-}
-
-void
-em_format_html_display_cut (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_cut (((EMFormatHTML *) efhd)->html);
-}
-
-void
-em_format_html_display_copy (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_copy (((EMFormatHTML *) efhd)->html);
-}
-
-void
-em_format_html_display_paste (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_paste (((EMFormatHTML *) efhd)->html, FALSE);
-}
-
-void
-em_format_html_display_zoom_in (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_zoom_in (((EMFormatHTML *) efhd)->html);
-}
-
-void
-em_format_html_display_zoom_out (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_zoom_out (((EMFormatHTML *) efhd)->html);
-}
-
-void
-em_format_html_display_zoom_reset (EMFormatHTMLDisplay *efhd)
-{
- gtk_html_zoom_reset (((EMFormatHTML *) efhd)->html);
-}
-
-/* ********************************************************************** */
-
-static void
-efhd_iframe_created(GtkHTML *html, GtkHTML *iframe, EMFormatHTMLDisplay *efh)
-{
- d(printf("Iframe created %p ... \n", iframe));
-
- g_signal_connect(iframe, "button_press_event", G_CALLBACK (efhd_html_button_press_event), efh);
-
- return;
-}
-
-static void
-efhd_get_uri_puri (GtkWidget *html, GdkEventButton *event, EMFormatHTMLDisplay *efhd, gchar **uri, EMFormatPURI **puri)
-{
- gchar *url, *img_url;
-
- g_return_if_fail (html != NULL);
- g_return_if_fail (GTK_IS_HTML (html));
- g_return_if_fail (efhd != NULL);
-
- if (event) {
- url = gtk_html_get_url_at (GTK_HTML (html), event->x, event->y);
- img_url = gtk_html_get_image_src_at (GTK_HTML (html), event->x, event->y);
- } else {
- url = gtk_html_get_cursor_url (GTK_HTML (html));
- img_url = gtk_html_get_cursor_image_src (GTK_HTML (html));
- }
-
- if (img_url) {
- if (!(strstr (img_url, "://") || g_ascii_strncasecmp (img_url, "cid:", 4) == 0)) {
- gchar *u = g_filename_to_uri (img_url, NULL, NULL);
- g_free (img_url);
- img_url = u;
- }
- }
-
- if (puri) {
- if (url)
- *puri = em_format_find_puri ((EMFormat *)efhd, url);
-
- if (!*puri && img_url)
- *puri = em_format_find_puri ((EMFormat *)efhd, img_url);
- }
-
- if (uri) {
- *uri = NULL;
- if (img_url && g_ascii_strncasecmp (img_url, "cid:", 4) != 0) {
- if (url)
- *uri = g_strdup_printf ("%s\n%s", url, img_url);
- else {
- *uri = img_url;
- img_url = NULL;
- }
- } else {
- *uri = url;
- url = NULL;
- }
- }
-
- g_free (url);
- g_free (img_url);
-}
-
-static gint
-efhd_html_button_press_event (GtkWidget *widget, GdkEventButton *event, EMFormatHTMLDisplay *efhd)
-{
- gchar *uri = NULL;
- EMFormatPURI *puri = NULL;
- gboolean res = FALSE;
-
- if (event->button != 3)
- return FALSE;
-
- d(printf("popup button pressed\n"));
-
- efhd_get_uri_puri (widget, event, efhd, &uri, &puri);
-
- if (uri && !strncmp (uri, "##", 2)) {
- g_free (uri);
- return TRUE;
- }
-
- g_signal_emit((GtkObject *)efhd, efhd_signals[EFHD_POPUP_EVENT], 0, event, uri, puri?puri->part:NULL, &res);
-
- g_free (uri);
-
- return res;
-}
-
-gboolean
-em_format_html_display_popup_menu (EMFormatHTMLDisplay *efhd)
-{
- GtkHTML *html;
- gchar *uri = NULL;
- EMFormatPURI *puri = NULL;
- gboolean res = FALSE;
-
- html = efhd->formathtml.html;
-
- efhd_get_uri_puri (GTK_WIDGET (html), NULL, efhd, &uri, &puri);
-
- g_signal_emit ((GtkObject *)efhd, efhd_signals[EFHD_POPUP_EVENT], 0, NULL, uri, puri?puri->part:NULL, &res);
-
- g_free (uri);
-
- return res;
-}
-
-static void
-efhd_html_link_clicked (GtkHTML *html, const gchar *url, EMFormatHTMLDisplay *efhd)
-{
- d(printf("link clicked event '%s'\n", url));
- if (url && !strncmp(url, "##", 2)) {
- if (!strcmp (url, "##TO##"))
- if (!(((EMFormatHTML *) efhd)->header_wrap_flags & EM_FORMAT_HTML_HEADER_TO))
- ((EMFormatHTML *) efhd)->header_wrap_flags |= EM_FORMAT_HTML_HEADER_TO;
- else
- ((EMFormatHTML *) efhd)->header_wrap_flags &= ~EM_FORMAT_HTML_HEADER_TO;
- else if (!strcmp (url, "##CC##"))
- if (!(((EMFormatHTML *) efhd)->header_wrap_flags & EM_FORMAT_HTML_HEADER_CC))
- ((EMFormatHTML *) efhd)->header_wrap_flags |= EM_FORMAT_HTML_HEADER_CC;
- else
- ((EMFormatHTML *) efhd)->header_wrap_flags &= ~EM_FORMAT_HTML_HEADER_CC;
- else if (!strcmp (url, "##BCC##")) {
- if (!(((EMFormatHTML *) efhd)->header_wrap_flags & EM_FORMAT_HTML_HEADER_BCC))
- ((EMFormatHTML *) efhd)->header_wrap_flags |= EM_FORMAT_HTML_HEADER_BCC;
- else
- ((EMFormatHTML *) efhd)->header_wrap_flags &= ~EM_FORMAT_HTML_HEADER_BCC;
- }
- em_format_redraw((EMFormat *)efhd);
- } else
- g_signal_emit((GObject *)efhd, efhd_signals[EFHD_LINK_CLICKED], 0, url);
-}
+static gpointer parent_class;
static void
-efhd_html_on_url (GtkHTML *html, const gchar *url, EMFormatHTMLDisplay *efhd)
-{
- d(printf("on_url event '%s'\n", url));
-
- g_signal_emit((GObject *)efhd, efhd_signals[EFHD_ON_URL], 0, url);
-}
-
-/* ********************************************************************** */
-
-/* TODO: move the dialogue elsehwere */
-/* FIXME: also in em-format-html.c */
-static const struct {
- const gchar *icon, *shortdesc, *description;
-} smime_sign_table[5] = {
- { "stock_signature-bad", N_("Unsigned"), N_("This message is not signed. There is no guarantee that this message is authentic.") },
- { "stock_signature-ok", N_("Valid signature"), N_("This message is signed and is valid meaning that it is very likely that this message is authentic.") },
- { "stock_signature-bad", N_("Invalid signature"), N_("The signature of this message cannot be verified, it may have been altered in transit.") },
- { "stock_signature", N_("Valid signature, but cannot verify sender"), N_("This message is signed with a valid signature, but the sender of the message cannot be verified.") },
- { "stock_signature-bad", N_("Signature exists, but need public key"), N_("This message is signed with a signature, but there is no corresponding public key.") },
-
-};
-
-static const struct {
- const gchar *icon, *shortdesc, *description;
-} smime_encrypt_table[4] = {
- { "stock_lock-broken", N_("Unencrypted"), N_("This message is not encrypted. Its content may be viewed in transit across the Internet.") },
- { "stock_lock-ok", N_("Encrypted, weak"), N_("This message is encrypted, but with a weak encryption algorithm. It would be difficult, but not impossible for an outsider to view the content of this message in a practical amount of time.") },
- { "stock_lock-ok", N_("Encrypted"), N_("This message is encrypted. It would be difficult for an outsider to view the content of this message.") },
- { "stock_lock-ok", N_("Encrypted, strong"), N_("This message is encrypted, with a strong encryption algorithm. It would be very difficult for an outsider to view the content of this message in a practical amount of time.") },
-};
-
-static const gchar *smime_sign_colour[5] = {
- "", " bgcolor=\"#88bb88\"", " bgcolor=\"#bb8888\"", " bgcolor=\"#e8d122\"",""
-};
-
-struct _smime_pobject {
- EMFormatHTMLPObject object;
-
- gint signature;
- CamelCipherValidity *valid;
- GtkWidget *widget;
-};
-
-static void
-efhd_xpkcs7mime_free(EMFormatHTMLPObject *o)
+efhd_xpkcs7mime_free (EMFormatHTMLPObject *o)
{
struct _smime_pobject *po = (struct _smime_pobject *)o;
@@ -606,21 +192,18 @@ efhd_xpkcs7mime_free(EMFormatHTMLPObject *o)
}
static void
-efhd_xpkcs7mime_info_response(GtkWidget *w, guint button, struct _smime_pobject *po)
+efhd_xpkcs7mime_info_response (GtkWidget *widget,
+ guint button,
+ struct _smime_pobject *po)
{
- gtk_widget_destroy(w);
+ gtk_widget_destroy (widget);
po->widget = NULL;
}
#ifdef HAVE_NSS
static void
-efhd_xpkcs7mime_viewcert_foad(GtkWidget *w, guint button, struct _smime_pobject *po)
-{
- gtk_widget_destroy(w);
-}
-
-static void
-efhd_xpkcs7mime_viewcert_clicked(GtkWidget *button, struct _smime_pobject *po)
+efhd_xpkcs7mime_viewcert_clicked (GtkWidget *button,
+ struct _smime_pobject *po)
{
CamelCipherCertInfo *info = g_object_get_data((GObject *)button, "e-cert-info");
ECertDB *db = e_cert_db_peek();
@@ -637,7 +220,7 @@ efhd_xpkcs7mime_viewcert_clicked(GtkWidget *button, struct _smime_pobject *po)
/* oddly enough certificate_viewer_show doesn't ... */
gtk_widget_show(w);
- g_signal_connect(w, "response", G_CALLBACK(efhd_xpkcs7mime_viewcert_foad), po);
+ g_signal_connect(w, "response", G_CALLBACK(gtk_widget_destroy), NULL);
if (w && po->widget)
gtk_window_set_transient_for((GtkWindow *)w, (GtkWindow *)po->widget);
@@ -650,7 +233,9 @@ efhd_xpkcs7mime_viewcert_clicked(GtkWidget *button, struct _smime_pobject *po)
#endif
static void
-efhd_xpkcs7mime_add_cert_table(GtkWidget *vbox, CamelDList *certlist, struct _smime_pobject *po)
+efhd_xpkcs7mime_add_cert_table (GtkWidget *vbox,
+ CamelDList *certlist,
+ struct _smime_pobject *po)
{
CamelCipherCertInfo *info = (CamelCipherCertInfo *)certlist->head;
GtkTable *table = (GtkTable *)gtk_table_new(camel_dlist_length(certlist), 2, FALSE);
@@ -709,7 +294,8 @@ efhd_xpkcs7mime_add_cert_table(GtkWidget *vbox, CamelDList *certlist, struct _sm
}
static void
-efhd_xpkcs7mime_validity_clicked(GtkWidget *button, EMFormatHTMLPObject *pobject)
+efhd_xpkcs7mime_validity_clicked (GtkWidget *button,
+ EMFormatHTMLPObject *pobject)
{
struct _smime_pobject *po = (struct _smime_pobject *)pobject;
GladeXML *xml;
@@ -720,10 +306,9 @@ efhd_xpkcs7mime_validity_clicked(GtkWidget *button, EMFormatHTMLPObject *pobject
/* FIXME: window raise? */
return;
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-dialogs.glade",
- NULL);
- xml = glade_xml_new(gladefile, "message_security_dialog", NULL);
+ gladefile = g_build_filename (
+ EVOLUTION_GLADEDIR, "mail-dialogs.glade", NULL);
+ xml = glade_xml_new (gladefile, "message_security_dialog", NULL);
g_free (gladefile);
po->widget = glade_xml_get_widget(xml, "message_security_dialog");
@@ -799,9 +384,12 @@ efhd_xpkcs7mime_validity_clicked(GtkWidget *button, EMFormatHTMLPObject *pobject
}
static gboolean
-efhd_xpkcs7mime_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject)
+efhd_xpkcs7mime_button (EMFormatHTML *efh,
+ GtkHTMLEmbedded *eb,
+ EMFormatHTMLPObject *pobject)
{
- GtkWidget *icon, *button;
+ GtkWidget *container;
+ GtkWidget *widget;
struct _smime_pobject *po = (struct _smime_pobject *)pobject;
const gchar *icon_name;
@@ -811,25 +399,171 @@ efhd_xpkcs7mime_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje
else
icon_name = smime_encrypt_table[po->valid->encrypt.status].icon;
- icon = gtk_image_new_from_icon_name (
- icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR);
- gtk_widget_show(icon);
+ container = GTK_WIDGET (eb);
- button = gtk_button_new();
- g_signal_connect(button, "clicked", G_CALLBACK(efhd_xpkcs7mime_validity_clicked), pobject);
+ widget = gtk_button_new ();
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (efhd_xpkcs7mime_validity_clicked), pobject);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
- gtk_container_add((GtkContainer *)button, icon);
- gtk_widget_show(button);
- gtk_container_add((GtkContainer *)eb, button);
+ container = widget;
+
+ widget = gtk_image_new_from_icon_name (
+ icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
return TRUE;
}
static void
-efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
+efhd_format_clone (EMFormat *emf,
+ CamelFolder *folder,
+ const gchar *uid,
+ CamelMimeMessage *msg,
+ EMFormat *src)
+{
+ if (emf != src)
+ EM_FORMAT_HTML (emf)->header_wrap_flags = 0;
+
+ /* Chain up to parent's format_clone() method. */
+ EM_FORMAT_CLASS (parent_class)->
+ format_clone (emf, folder, uid, msg, src);
+}
+
+static void
+efhd_format_attachment (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part,
+ const gchar *mime_type,
+ const EMFormatHandler *handle)
+{
+ gchar *classid, *text, *html;
+ struct _attach_puri *info;
+
+ classid = g_strdup_printf ("attachment%s", emf->part_id->str);
+ info = (struct _attach_puri *) em_format_add_puri (
+ emf, sizeof (*info), classid, part, efhd_attachment_frame);
+ em_format_html_add_pobject (
+ EM_FORMAT_HTML (emf), sizeof (EMFormatHTMLPObject),
+ classid, part, efhd_attachment_button);
+ info->handle = handle;
+ info->shown = em_format_is_inline (
+ emf, info->puri.part_id, info->puri.part, handle);
+ info->snoop_mime_type = emf->snoop_mime_type;
+ info->attachment = e_attachment_new ();
+ e_attachment_set_mime_part (info->attachment, info->puri.part);
+
+ if (emf->valid) {
+ info->sign = emf->valid->sign.status;
+ info->encrypt = emf->valid->encrypt.status;
+ }
+
+ camel_stream_write_string (
+ stream, EM_FORMAT_HTML_VPAD
+ "<table cellspacing=0 cellpadding=0><tr><td>"
+ "<table width=10 cellspacing=0 cellpadding=0>"
+ "<tr><td></td></tr></table></td>");
+
+ camel_stream_printf (
+ stream, "<td><object classid=\"%s\"></object></td>", classid);
+
+ camel_stream_write_string (
+ stream, "<td><table width=3 cellspacing=0 cellpadding=0>"
+ "<tr><td></td></tr></table></td><td><font size=-1>");
+
+ /* output some info about it */
+ /* FIXME: should we look up mime_type from object again? */
+ text = em_format_describe_part (part, mime_type);
+ html = camel_text_to_html (
+ text, EM_FORMAT_HTML (emf)->text_html_flags &
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
+ camel_stream_write_string (stream, html);
+ g_free (html);
+ g_free (text);
+
+ camel_stream_write_string (
+ stream, "</font></td></tr><tr></table>\n"
+ EM_FORMAT_HTML_VPAD);
+
+ if (handle && info->shown)
+ handle->handler (emf, stream, part, handle);
+
+ g_free (classid);
+}
+
+static void
+efhd_format_optional (EMFormat *emf,
+ CamelStream *fstream,
+ CamelMimePart *part,
+ CamelStream *mstream)
{
- /* Note: We call EMFormatClass directly, not EMFormatHTML, our parent */
- efhd_format_class->format_secure(emf, stream, part, valid);
+ gchar *classid, *html;
+ struct _attach_puri *info;
+ CamelStream *stream;
+
+ if (CAMEL_IS_STREAM_FILTER (fstream) && ((CamelStreamFilter *) fstream)->source)
+ stream = ((CamelStreamFilter *) fstream)->source;
+ else
+ stream = fstream;
+
+ classid = g_strdup_printf ("optional%s", emf->part_id->str);
+ info = (struct _attach_puri *) em_format_add_puri (
+ emf, sizeof (*info), classid, part, efhd_attachment_frame);
+ em_format_html_add_pobject (
+ EM_FORMAT_HTML (emf), sizeof (EMFormatHTMLPObject),
+ classid, part, efhd_attachment_optional);
+ info->handle = em_format_find_handler (emf, "text/plain");
+ info->shown = FALSE;
+ info->snoop_mime_type = "text/plain";
+ info->attachment = e_attachment_new ();
+ e_attachment_set_mime_part (info->attachment, info->puri.part);
+ info->mstream = (CamelStreamMem *) mstream;
+ if (emf->valid) {
+ info->sign = emf->valid->sign.status;
+ info->encrypt = emf->valid->encrypt.status;
+ }
+
+ camel_stream_write_string (
+ stream, EM_FORMAT_HTML_VPAD
+ "<table cellspacing=0 cellpadding=0><tr><td>"
+ "<h3><font size=-1 color=red>");
+
+ html = camel_text_to_html (
+ _("Evolution cannot render this email as it is too "
+ "large to process. You can view it unformatted or "
+ "with an external text editor."),
+ EM_FORMAT_HTML (emf)->text_html_flags &
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
+ camel_stream_write_string (stream, html);
+ camel_stream_write_string (
+ stream, "</font></h3></td></tr></table>\n");
+ camel_stream_write_string (
+ stream, "<table cellspacing=0 cellpadding=0><tr>");
+ camel_stream_printf (
+ stream, "<td><object classid=\"%s\"></object>"
+ "</td></tr></table>", classid);
+
+ g_free(html);
+
+ camel_stream_write_string (
+ stream, EM_FORMAT_HTML_VPAD);
+
+ g_free (classid);
+}
+
+static void
+efhd_format_secure (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part,
+ CamelCipherValidity *valid)
+{
+ EMFormatClass *format_class;
+
+ format_class = g_type_class_peek (EM_TYPE_FORMAT);
+ format_class->format_secure (emf, stream, part, valid);
if (emf->valid == valid
&& (valid->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE
@@ -837,24 +571,45 @@ efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Came
gchar *classid;
struct _smime_pobject *pobj;
- camel_stream_printf (stream, "<table border=0 width=\"100%%\" cellpadding=3 cellspacing=0%s><tr>",
- smime_sign_colour[valid->sign.status]);
-
- classid = g_strdup_printf("smime:///em-format-html/%s/icon/signed", emf->part_id->str);
- pobj = (struct _smime_pobject *)em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(*pobj), classid, part, efhd_xpkcs7mime_button);
+ camel_stream_printf (
+ stream, "<table border=0 width=\"100%%\" "
+ "cellpadding=3 cellspacing=0%s><tr>",
+ smime_sign_colour[valid->sign.status]);
+
+ classid = g_strdup_printf (
+ "smime:///em-format-html/%s/icon/signed",
+ emf->part_id->str);
+ pobj = (struct _smime_pobject *) em_format_html_add_pobject (
+ EM_FORMAT_HTML (emf), sizeof (*pobj),
+ classid, part, efhd_xpkcs7mime_button);
pobj->valid = camel_cipher_validity_clone(valid);
pobj->object.free = efhd_xpkcs7mime_free;
- camel_stream_printf(stream, "<td valign=center><object classid=\"%s\"></object></td><td width=100%% valign=center>", classid);
- g_free(classid);
+ camel_stream_printf (
+ stream, "<td valign=center><object classid=\"%s\">"
+ "</object></td><td width=100%% valign=center>",
+ classid);
+ g_free (classid);
+
if (valid->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE) {
- camel_stream_printf (stream, "%s", _(smime_sign_table[valid->sign.status].shortdesc));
+ const gchar *desc;
+ gint status;
+
+ status = valid->sign.status;
+ desc = smime_sign_table[status].shortdesc;
+ camel_stream_printf (stream, "%s", gettext (desc));
}
if (valid->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE) {
+ const gchar *desc;
+ gint status;
+
if (valid->sign.status != CAMEL_CIPHER_VALIDITY_SIGN_NONE) {
camel_stream_printf (stream, "<br>");
}
- camel_stream_printf (stream, "%s", _(smime_encrypt_table[valid->encrypt.status].shortdesc));
+
+ status = valid->encrypt.status;
+ desc = smime_encrypt_table[status].shortdesc;
+ camel_stream_printf (stream, "%s", gettext (desc));
}
camel_stream_printf(stream, "</td></tr></table>");
@@ -862,6 +617,80 @@ efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, Came
}
static void
+efhd_class_init (EMFormatHTMLDisplayClass *class)
+{
+ EMFormatClass *format_class;
+ EMFormatHTMLClass *format_html_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFormatHTMLDisplayPrivate));
+
+ format_class = EM_FORMAT_CLASS (class);
+ format_class->format_clone = efhd_format_clone;
+ format_class->format_attachment = efhd_format_attachment;
+ format_class->format_optional = efhd_format_optional;
+ format_class->format_secure = efhd_format_secure;
+
+ format_html_class = EM_FORMAT_HTML_CLASS (class);
+ format_html_class->html_widget_type = E_TYPE_MAIL_DISPLAY;
+
+ efhd_builtin_init (class);
+}
+
+static void
+efhd_init (EMFormatHTMLDisplay *efhd)
+{
+ GtkHTML *html;
+
+ html = EM_FORMAT_HTML (efhd)->html;
+
+ efhd->priv = EM_FORMAT_HTML_DISPLAY_GET_PRIVATE (efhd);
+
+ e_mail_display_set_formatter (
+ E_MAIL_DISPLAY (html), EM_FORMAT_HTML (efhd));
+
+ /* we want to convert url's etc */
+ EM_FORMAT_HTML (efhd)->text_html_flags |=
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES;
+}
+
+GType
+em_format_html_display_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFormatHTMLDisplayClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) efhd_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFormatHTMLDisplay),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) efhd_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ EM_TYPE_FORMAT_HTML, "EMFormatHTMLDisplay",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+EMFormatHTMLDisplay *
+em_format_html_display_new (void)
+{
+ return g_object_new (EM_TYPE_FORMAT_HTML_DISPLAY, NULL);
+}
+
+/* ********************************************************************** */
+
+static void
efhd_image(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFormatHandler *handle)
{
gchar *classid;
@@ -924,20 +753,6 @@ efhd_builtin_init(EMFormatHTMLDisplayClass *efhc)
em_format_class_add_handler((EMFormatClass *)efhc, &type_builtin_table[i]);
}
-static const EMFormatHandler *
-efhd_find_handler(EMFormat *emf, const gchar *mime_type)
-{
- return ((EMFormatClass *) efhd_parent)->find_handler (emf, mime_type);
-}
-
-static void efhd_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *src)
-{
- if (emf != src)
- ((EMFormatHTML *) emf)->header_wrap_flags = 0;
-
- ((EMFormatClass *)efhd_parent)->format_clone(emf, folder, uid, msg, src);
-}
-
static void
efhd_write_image(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
{
@@ -949,7 +764,8 @@ efhd_write_image(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
camel_stream_close(stream);
}
-static void efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
+static void
+efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
{
const gchar *flag, *comp, *due;
time_t date;
@@ -1008,17 +824,6 @@ static void efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePar
camel_stream_printf(stream, "</td></tr></table>");
}
-/* TODO: if these aren't going to do anything should remove */
-static void efhd_format_error(EMFormat *emf, CamelStream *stream, const gchar *txt)
-{
- ((EMFormatClass *)efhd_parent)->format_error(emf, stream, txt);
-}
-
-static void efhd_format_source(EMFormat *emf, CamelStream *stream, CamelMimePart *part)
-{
- ((EMFormatClass *)efhd_parent)->format_source(emf, stream, part);
-}
-
/* ********************************************************************** */
/* Checks on the widget whether it can be processed, based on the state of EMFormatHTML.
@@ -1446,38 +1251,35 @@ efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje
return TRUE;
}
-/* not used currently */
-/* frame source callback */
static void
-efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
+efhd_attachment_frame (EMFormat *emf,
+ CamelStream *stream,
+ EMFormatPURI *puri)
{
struct _attach_puri *info = (struct _attach_puri *)puri;
- if (info->shown) {
- d(printf("writing to frame content, handler is '%s'\n", info->handle->mime_type));
- info->handle->handler(emf, stream, info->puri.part, info->handle);
- camel_stream_close(stream);
- } else {
- /* FIXME: this is leaked if the object is closed without showing it
- NB: need a virtual puri_free method? */
- info->output = stream;
- camel_object_ref(stream);
- }
+ if (info->shown)
+ info->handle->handler (
+ emf, stream, info->puri.part, info->handle);
+
+ camel_stream_close (stream);
}
static void
efhd_bar_resize (EMFormatHTML *efh,
GtkAllocation *event)
{
- EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) efh;
+ EMFormatHTMLDisplayPrivate *priv;
GtkWidget *widget;
gint width;
+ priv = EM_FORMAT_HTML_DISPLAY_GET_PRIVATE (efh);
+
widget = GTK_WIDGET (efh->html);
width = widget->allocation.width - 12;
if (width > 0) {
- widget = efhd->priv->attachment_view;
+ widget = priv->attachment_view;
gtk_widget_set_size_request (widget, width, -1);
}
}
@@ -1487,12 +1289,18 @@ efhd_add_bar (EMFormatHTML *efh,
GtkHTMLEmbedded *eb,
EMFormatHTMLPObject *pobject)
{
- EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) efh;
+ EMFormatHTMLDisplayPrivate *priv;
GtkWidget *widget;
+ /* XXX See note in efhd_message_add_bar(). */
+ if (!EM_IS_FORMAT_HTML_DISPLAY (efh))
+ return FALSE;
+
+ priv = EM_FORMAT_HTML_DISPLAY_GET_PRIVATE (efh);
+
widget = e_mail_attachment_bar_new ();
gtk_container_add (GTK_CONTAINER (eb), widget);
- efhd->priv->attachment_view = widget;
+ priv->attachment_view = widget;
gtk_widget_hide (widget);
g_signal_connect_swapped (
@@ -1510,8 +1318,12 @@ efhd_message_add_bar (EMFormat *emf,
{
const gchar *classid = "attachment-bar";
+ /* XXX Apparently this installs the callback for -all-
+ * EMFormatHTML subclasses, not just this subclass.
+ * Bad idea. So we have to filter out other types
+ * in the callback. */
em_format_html_add_pobject (
- (EMFormatHTML *) emf,
+ EM_FORMAT_HTML (emf),
sizeof (EMFormatHTMLPObject),
classid, part, efhd_add_bar);
@@ -1520,63 +1332,6 @@ efhd_message_add_bar (EMFormat *emf,
}
static void
-efhd_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const gchar *mime_type, const EMFormatHandler *handle)
-{
- gchar *classid, *text, *html;
- struct _attach_puri *info;
-
- classid = g_strdup_printf ("attachment%s", emf->part_id->str);
- info = (struct _attach_puri *)em_format_add_puri (
- emf, sizeof (*info), classid, part, efhd_attachment_frame);
- em_format_html_add_pobject (
- (EMFormatHTML *) emf, sizeof (EMFormatHTMLPObject),
- classid, part, efhd_attachment_button);
- info->handle = handle;
- info->shown = em_format_is_inline (
- emf, info->puri.part_id, info->puri.part, handle);
- info->snoop_mime_type = emf->snoop_mime_type;
- info->attachment = e_attachment_new ();
- e_attachment_set_mime_part (info->attachment, info->puri.part);
-
- if (emf->valid) {
- info->sign = emf->valid->sign.status;
- info->encrypt = emf->valid->encrypt.status;
- }
-
- camel_stream_write_string (
- stream, EM_FORMAT_HTML_VPAD
- "<table cellspacing=0 cellpadding=0><tr><td>"
- "<table width=10 cellspacing=0 cellpadding=0>"
- "<tr><td></td></tr></table></td>");
-
- camel_stream_printf (
- stream, "<td><object classid=\"%s\"></object></td>", classid);
-
- camel_stream_write_string (
- stream, "<td><table width=3 cellspacing=0 cellpadding=0>"
- "<tr><td></td></tr></table></td><td><font size=-1>");
-
- /* output some info about it */
- /* FIXME: should we look up mime_type from object again? */
- text = em_format_describe_part (part, mime_type);
- html = camel_text_to_html (
- text, ((EMFormatHTML *)emf)->text_html_flags &
- CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
- camel_stream_write_string (stream, html);
- g_free (html);
- g_free (text);
-
- camel_stream_write_string (
- stream, "</font></td></tr><tr></table>\n"
- EM_FORMAT_HTML_VPAD);
-
- if (handle && info->shown)
- handle->handler(emf, stream, part, handle);
-
- g_free(classid);
-}
-
-static void
efhd_optional_button_show (GtkWidget *widget, GtkWidget *w)
{
GtkWidget *label = g_object_get_data (G_OBJECT (widget), "text-label");
@@ -1689,50 +1444,3 @@ efhd_attachment_optional(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPOb
return TRUE;
}
-static void
-efhd_format_optional(EMFormat *emf, CamelStream *fstream, CamelMimePart *part, CamelStream *mstream)
-{
- gchar *classid, *html;
- struct _attach_puri *info;
- CamelStream *stream;
-
- if (CAMEL_IS_STREAM_FILTER (fstream) && ((CamelStreamFilter *) fstream)->source)
- stream = ((CamelStreamFilter *) fstream)->source;
- else
- stream = fstream;
-
- classid = g_strdup_printf("optional%s", emf->part_id->str);
- info = (struct _attach_puri *)em_format_add_puri(emf, sizeof(*info), classid, part, efhd_attachment_frame);
- em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_attachment_optional);
- info->handle = em_format_find_handler(emf, "text/plain");
- info->shown = FALSE;
- info->snoop_mime_type = "text/plain";
- info->attachment = e_attachment_new ();
- e_attachment_set_mime_part (info->attachment, info->puri.part);
- info->mstream = (CamelStreamMem *)mstream;
- if (emf->valid) {
- info->sign = emf->valid->sign.status;
- info->encrypt = emf->valid->encrypt.status;
- }
-
- camel_stream_write_string(stream,
- EM_FORMAT_HTML_VPAD
- "<table cellspacing=0 cellpadding=0><tr><td><h3><font size=-1 color=red>");
-
- html = camel_text_to_html(_("Evolution cannot render this email as it is too large to process. You can view it unformatted or with an external text editor."), ((EMFormatHTML *)emf)->text_html_flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
- camel_stream_write_string(stream, html);
- camel_stream_write_string(stream,
- "</font></h3></td></tr></table>\n");
- camel_stream_write_string(stream,
- "<table cellspacing=0 cellpadding=0>"
- "<tr>");
- camel_stream_printf(stream, "<td><object classid=\"%s\"></object></td></tr></table>", classid);
-
- g_free(html);
-
- camel_stream_write_string(stream,
-/* "</font></h2></td></tr></table>\n" */
- EM_FORMAT_HTML_VPAD);
-
- g_free(classid);
-}
diff --git a/mail/em-format-html-display.h b/mail/em-format-html-display.h
index d85809f0b0..4626598cb5 100644
--- a/mail/em-format-html-display.h
+++ b/mail/em-format-html-display.h
@@ -53,70 +53,20 @@ typedef struct _EMFormatHTMLDisplayClass EMFormatHTMLDisplayClass;
typedef struct _EMFormatHTMLDisplayPrivate EMFormatHTMLDisplayPrivate;
struct _EMFormatHTMLDisplay {
- EMFormatHTML formathtml;
-
+ EMFormatHTML parent;
EMFormatHTMLDisplayPrivate *priv;
struct _ESearchingTokenizer *search_tok;
-
- guint animate:1;
- guint caret_mode:1;
- guint nobar:1;
};
-#define EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY (0)
-#define EM_FORMAT_HTML_DISPLAY_SEARCH_SECONDARY (1)
-#define EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE (1<<8)
-
struct _EMFormatHTMLDisplayClass {
- EMFormatHTMLClass formathtml_class;
-
- /* a link clicked normally */
- void (*link_clicked)(EMFormatHTMLDisplay *efhd, const gchar *uri);
- /* a part or a link button pressed event */
- gint (*popup_event)(EMFormatHTMLDisplay *efhd, GdkEventButton *event, const gchar *uri, CamelMimePart *part);
- /* the mouse is over a link */
- void (*on_url)(EMFormatHTMLDisplay *efhd, const gchar *uri);
+ EMFormatHTMLClass parent_class;
};
GType em_format_html_display_get_type (void);
EMFormatHTMLDisplay *
em_format_html_display_new (void);
-void em_format_html_display_goto_anchor
- (EMFormatHTMLDisplay *efhd,
- const gchar *name);
-
-void em_format_html_display_set_animate
- (EMFormatHTMLDisplay *efhd,
- gboolean state);
-void em_format_html_display_set_caret_mode
- (EMFormatHTMLDisplay *efhd,
- gboolean state);
-
-void em_format_html_display_set_search
- (EMFormatHTMLDisplay *efhd,
- gint type,
- GSList *strings);
-void em_format_html_display_search (EMFormatHTMLDisplay *efhd);
-void em_format_html_display_search_with
- (EMFormatHTMLDisplay *efhd,
- gchar *word);
-void em_format_html_display_search_close
- (EMFormatHTMLDisplay *efhd);
-
-void em_format_html_display_cut (EMFormatHTMLDisplay *efhd);
-void em_format_html_display_copy (EMFormatHTMLDisplay *efhd);
-void em_format_html_display_paste (EMFormatHTMLDisplay *efhd);
-
-void em_format_html_display_zoom_in (EMFormatHTMLDisplay *efhd);
-void em_format_html_display_zoom_out (EMFormatHTMLDisplay *efhd);
-void em_format_html_display_zoom_reset
- (EMFormatHTMLDisplay *efhd);
-
-gboolean em_format_html_display_popup_menu
- (EMFormatHTMLDisplay *efhd);
-
G_END_DECLS
#endif /* EM_FORMAT_HTML_DISPLAY_H */
diff --git a/mail/em-format-html-print.c b/mail/em-format-html-print.c
index c5c99bcab1..773bc04b0d 100644
--- a/mail/em-format-html-print.c
+++ b/mail/em-format-html-print.c
@@ -38,22 +38,27 @@
static gpointer parent_class = NULL;
static void
-efhp_finalize (GObject *o)
+efhp_finalize (GObject *object)
{
- EMFormatHTMLPrint *efhp = (EMFormatHTMLPrint *)o;
+ EMFormatHTMLPrint *efhp = (EMFormatHTMLPrint *)object;
gtk_widget_destroy (efhp->window);
if (efhp->source != NULL)
g_object_unref (efhp->source);
- ((GObjectClass *) parent_class)->finalize (o);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
-efhp_class_init (GObjectClass *class)
+efhp_class_init (EMFormatHTMLPrintClass *class)
{
+ GObjectClass *object_class;
+
parent_class = g_type_class_peek_parent (class);
- class->finalize = efhp_finalize;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = efhp_finalize;
}
static void
@@ -93,7 +98,7 @@ em_format_html_print_get_type (void)
};
type = g_type_register_static (
- em_format_html_get_type (), "EMFormatHTMLPrint",
+ EM_TYPE_FORMAT_HTML, "EMFormatHTMLPrint",
&type_info, 0);
}
@@ -101,7 +106,8 @@ em_format_html_print_get_type (void)
}
EMFormatHTMLPrint *
-em_format_html_print_new (EMFormatHTML *source, GtkPrintOperationAction action)
+em_format_html_print_new (EMFormatHTML *source,
+ GtkPrintOperationAction action)
{
EMFormatHTMLPrint *efhp;
@@ -210,9 +216,7 @@ emfhp_got_message (CamelFolder *folder, const gchar *uid,
return;
}
- if (efhp->source != NULL)
- ((EMFormatHTML *)efhp)->load_http =
- efhp->source->load_http_now;
+ em_format_html_load_images (EM_FORMAT_HTML (efhp));
g_signal_connect (
efhp, "complete", G_CALLBACK (emfhp_complete), efhp);
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index d769127705..31c4cf0e88 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -48,7 +48,6 @@
#include "e-util/e-util.h"
#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-embedded.h>
#include <gtkhtml/gtkhtml-stream.h>
#include <glib/gi18n.h>
@@ -74,7 +73,6 @@
#include <libedataserver/e-msgport.h>
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-mt.h"
@@ -84,6 +82,10 @@
#define d(x)
+#define EM_FORMAT_HTML_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EM_TYPE_FORMAT_HTML, EMFormatHTMLPrivate))
+
#define EFM_MESSAGE_START_ANAME "evolution#message#start"
#define EFH_MESSAGE_START "<A name=\"" EFM_MESSAGE_START_ANAME "\"></A>"
@@ -104,6 +106,27 @@ struct _EMFormatHTMLPrivate {
EDList pending_jobs;
GMutex *lock;
+
+ GdkColor colors[EM_FORMAT_HTML_NUM_COLOR_TYPES];
+ MailConfigHTTPMode image_loading_policy;
+
+ guint load_images_now : 1;
+ guint only_local_photos : 1;
+ guint show_sender_photo : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_BODY_COLOR,
+ PROP_CITATION_COLOR,
+ PROP_CONTENT_COLOR,
+ PROP_FRAME_COLOR,
+ PROP_HEADER_COLOR,
+ PROP_IMAGE_LOADING_POLICY,
+ PROP_MARK_CITATIONS,
+ PROP_ONLY_LOCAL_PHOTOS,
+ PROP_SHOW_SENDER_PHOTO,
+ PROP_TEXT_COLOR
};
static void efh_url_requested(GtkHTML *html, const gchar *url, GtkHTMLStream *handle, EMFormatHTML *efh);
@@ -112,67 +135,243 @@ static void efh_gtkhtml_destroy(GtkHTML *html, EMFormatHTML *efh);
static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info);
-static void efh_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *emfsource);
-static void efh_format_error(EMFormat *emf, CamelStream *stream, const gchar *txt);
-static void efh_format_source(EMFormat *, CamelStream *, CamelMimePart *);
-static void efh_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, const gchar *, const EMFormatHandler *);
static void efh_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid);
-static gboolean efh_busy(EMFormat *);
static void efh_builtin_init(EMFormatHTMLClass *efhc);
static void efh_write_image(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri);
-static EMFormatClass *efh_parent;
+static gpointer parent_class;
static CamelDataCache *emfh_http_cache;
#define EMFH_HTTP_CACHE_PATH "http"
+/* Sigh, this is so we have a cancellable, async rendering thread */
+struct _format_msg {
+ MailMsg base;
+
+ EMFormatHTML *format;
+ EMFormat *format_source;
+ EMHTMLStream *estream;
+ CamelFolder *folder;
+ gchar *uid;
+ CamelMimeMessage *message;
+};
+
+static gchar *
+efh_format_desc (struct _format_msg *m)
+{
+ return g_strdup(_("Formatting message"));
+}
+
static void
-efh_free_cache(struct _EMFormatHTMLCache *efhc)
+efh_format_exec (struct _format_msg *m)
{
- if (efhc->textmp)
- camel_object_unref(efhc->textmp);
- g_free(efhc);
+ struct _EMFormatHTMLJob *job;
+ struct _EMFormatPURITree *puri_level;
+ gint cancelled = FALSE;
+ CamelURL *base;
+
+ if (m->format->html == NULL)
+ return;
+
+ camel_stream_printf (
+ (CamelStream *)m->estream,
+ "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n"
+ "<head>\n<meta name=\"generator\" content=\"Evolution Mail Component\">\n</head>\n"
+ "<body bgcolor =\"#%06x\" text=\"#%06x\" marginwidth=6 marginheight=6>\n",
+ e_color_to_value (
+ &m->format->priv->colors[
+ EM_FORMAT_HTML_COLOR_BODY]),
+ e_color_to_value (
+ &m->format->priv->colors[
+ EM_FORMAT_HTML_COLOR_HEADER]));
+
+ /* <insert top-header stuff here> */
+
+ if (((EMFormat *)m->format)->mode == EM_FORMAT_SOURCE) {
+ em_format_format_source((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message);
+ } else {
+ const EMFormatHandler *handle;
+
+ handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/prefix");
+ if (handle)
+ handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
+ handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/rfc822");
+ if (handle)
+ handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
+ }
+
+ camel_stream_flush((CamelStream *)m->estream);
+
+ puri_level = ((EMFormat *)m->format)->pending_uri_level;
+ base = ((EMFormat *)m->format)->base;
+
+ do {
+ /* now dispatch any added tasks ... */
+ g_mutex_lock(m->format->priv->lock);
+ while ((job = (struct _EMFormatHTMLJob *)e_dlist_remhead(&m->format->priv->pending_jobs))) {
+ g_mutex_unlock(m->format->priv->lock);
+
+ /* This is an implicit check to see if the gtkhtml has been destroyed */
+ if (!cancelled)
+ cancelled = m->format->html == NULL;
+
+ /* Now do an explicit check for user cancellation */
+ if (!cancelled)
+ cancelled = camel_operation_cancel_check(NULL);
+
+ /* call jobs even if cancelled, so they can clean up resources */
+ ((EMFormat *)m->format)->pending_uri_level = job->puri_level;
+ if (job->base)
+ ((EMFormat *)m->format)->base = job->base;
+ job->callback(job, cancelled);
+ ((EMFormat *)m->format)->base = base;
+
+ /* clean up the job */
+ camel_object_unref(job->stream);
+ if (job->base)
+ camel_url_free(job->base);
+ g_free(job);
+
+ g_mutex_lock(m->format->priv->lock);
+ }
+ g_mutex_unlock(m->format->priv->lock);
+
+ if (m->estream) {
+ /* Closing this base stream can queue more jobs, so we need
+ to check the list again after we've finished */
+ d(printf("out of jobs, closing root stream\n"));
+ camel_stream_write_string((CamelStream *)m->estream, "</body>\n</html>\n");
+ camel_stream_close((CamelStream *)m->estream);
+ camel_object_unref(m->estream);
+ m->estream = NULL;
+ }
+
+ /* e_dlist_empty is atomic and doesn't need locking */
+ } while (!e_dlist_empty(&m->format->priv->pending_jobs));
+
+ d(printf("out of jobs, done\n"));
+
+ ((EMFormat *)m->format)->pending_uri_level = puri_level;
}
static void
-efh_init(GObject *o)
+efh_format_done (struct _format_msg *m)
{
- EMFormatHTML *efh = (EMFormatHTML *)o;
+ d(printf("formatting finished\n"));
- efh->priv = g_malloc0(sizeof(*efh->priv));
+ m->format->priv->format_id = -1;
+ m->format->priv->load_images_now = FALSE;
+ m->format->state = EM_FORMAT_HTML_STATE_NONE;
+ g_signal_emit_by_name(m->format, "complete");
+}
- e_dlist_init(&efh->pending_object_list);
- e_dlist_init(&efh->priv->pending_jobs);
- efh->priv->lock = g_mutex_new();
- efh->priv->format_id = -1;
- efh->priv->text_inline_parts = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) efh_free_cache);
+static void
+efh_format_free (struct _format_msg *m)
+{
+ d(printf("formatter freed\n"));
+ g_object_unref(m->format);
+ if (m->estream) {
+ camel_stream_close((CamelStream *)m->estream);
+ camel_object_unref(m->estream);
+ }
+ if (m->folder)
+ camel_object_unref(m->folder);
+ g_free(m->uid);
+ if (m->message)
+ camel_object_unref(m->message);
+ if (m->format_source)
+ g_object_unref(m->format_source);
+}
- efh->html = (GtkHTML *)gtk_html_new();
- gtk_html_set_blocking(efh->html, FALSE);
- gtk_html_set_caret_first_focus_anchor (efh->html, EFM_MESSAGE_START_ANAME);
- g_object_ref_sink(efh->html);
-
- gtk_html_set_default_content_type(efh->html, "text/html; charset=utf-8");
- gtk_html_set_editable(efh->html, FALSE);
-
- g_signal_connect(efh->html, "destroy", G_CALLBACK(efh_gtkhtml_destroy), efh);
- g_signal_connect(efh->html, "url_requested", G_CALLBACK(efh_url_requested), efh);
- g_signal_connect(efh->html, "object_requested", G_CALLBACK(efh_object_requested), efh);
-
- efh->body_colour = 0xeeeeee;
- efh->header_colour = 0xeeeeee;
- efh->text_colour = 0;
- efh->frame_colour = 0x3f3f3f;
- efh->content_colour = 0xffffff;
- efh->text_html_flags = CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES
- | CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
- efh->show_icon = TRUE;
- efh->state = EM_FORMAT_HTML_STATE_NONE;
+static MailMsgInfo efh_format_info = {
+ sizeof (struct _format_msg),
+ (MailMsgDescFunc) efh_format_desc,
+ (MailMsgExecFunc) efh_format_exec,
+ (MailMsgDoneFunc) efh_format_done,
+ (MailMsgFreeFunc) efh_format_free
+};
+
+static gboolean
+efh_format_timeout(struct _format_msg *m)
+{
+ GtkHTMLStream *hstream;
+ EMFormatHTML *efh = m->format;
+ struct _EMFormatHTMLPrivate *p = efh->priv;
+
+ if (m->format->html == NULL) {
+ mail_msg_unref(m);
+ return FALSE;
+ }
+
+ d(printf("timeout called ...\n"));
+ if (p->format_id != -1) {
+ d(printf(" still waiting for cancellation to take effect, waiting ...\n"));
+ return TRUE;
+ }
+
+ g_return_val_if_fail (e_dlist_empty(&p->pending_jobs), FALSE);
+
+ d(printf(" ready to go, firing off format thread\n"));
+
+ /* call super-class to kick it off */
+ EM_FORMAT_CLASS (parent_class)->format_clone (
+ EM_FORMAT (efh), m->folder, m->uid,
+ m->message, m->format_source);
+ em_format_html_clear_pobject(m->format);
+
+ /* FIXME: method off EMFormat? */
+ if (((EMFormat *)efh)->valid) {
+ camel_cipher_validity_free(((EMFormat *)efh)->valid);
+ ((EMFormat *)efh)->valid = NULL;
+ ((EMFormat *)efh)->valid_parent = NULL;
+ }
+
+ if (m->message == NULL) {
+ hstream = gtk_html_begin(efh->html);
+ gtk_html_stream_close(hstream, GTK_HTML_STREAM_OK);
+ mail_msg_unref(m);
+ p->last_part = NULL;
+ } else {
+ efh->state = EM_FORMAT_HTML_STATE_RENDERING;
+
+ if (p->last_part != m->message) {
+ hstream = gtk_html_begin (efh->html);
+ gtk_html_stream_printf (hstream, "<h5>%s</h5>", _("Formatting Message..."));
+ gtk_html_stream_close (hstream, GTK_HTML_STREAM_OK);
+ }
+
+ hstream = NULL;
+ m->estream = (EMHTMLStream *)em_html_stream_new(efh->html, hstream);
+
+ if (p->last_part == m->message) {
+ em_html_stream_set_flags (m->estream,
+ GTK_HTML_BEGIN_KEEP_SCROLL | GTK_HTML_BEGIN_KEEP_IMAGES
+ | GTK_HTML_BEGIN_BLOCK_UPDATES | GTK_HTML_BEGIN_BLOCK_IMAGES);
+ } else {
+ /* clear cache of inline-scanned text parts */
+ g_hash_table_remove_all(p->text_inline_parts);
+
+ p->last_part = m->message;
+ }
+
+ efh->priv->format_id = m->base.seq;
+ mail_msg_unordered_push (m);
+ }
+
+ efh->priv->format_timeout_id = 0;
+ efh->priv->format_timeout_msg = NULL;
+
+ return FALSE;
+}
+
+static void
+efh_free_cache(struct _EMFormatHTMLCache *efhc)
+{
+ if (efhc->textmp)
+ camel_object_unref(efhc->textmp);
+ g_free(efhc);
}
static void
@@ -189,8 +388,8 @@ efh_gtkhtml_destroy(GtkHTML *html, EMFormatHTML *efh)
if (efh->priv->format_id != -1)
mail_msg_cancel(efh->priv->format_id);
- if (efh->html) {
- g_object_unref(efh->html);
+ if (efh->html != NULL) {
+ g_object_unref (efh->html);
efh->html = NULL;
}
}
@@ -208,122 +407,719 @@ efh_insert_cache(EMFormatHTML *efh, const gchar *partid)
}
static void
-efh_finalise(GObject *o)
+efh_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_BODY_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_BODY,
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_CITATION_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_CITATION,
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_CONTENT_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_CONTENT,
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_FRAME_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_FRAME,
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_HEADER_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_HEADER,
+ g_value_get_boxed (value));
+ return;
+
+ case PROP_IMAGE_LOADING_POLICY:
+ em_format_html_set_image_loading_policy (
+ EM_FORMAT_HTML (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_MARK_CITATIONS:
+ em_format_html_set_mark_citations (
+ EM_FORMAT_HTML (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_ONLY_LOCAL_PHOTOS:
+ em_format_html_set_only_local_photos (
+ EM_FORMAT_HTML (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SHOW_SENDER_PHOTO:
+ em_format_html_set_show_sender_photo (
+ EM_FORMAT_HTML (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_TEXT_COLOR:
+ em_format_html_set_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_TEXT,
+ g_value_get_boxed (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+efh_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdkColor color;
+
+ switch (property_id) {
+ case PROP_BODY_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_BODY,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_CITATION_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_CITATION,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_CONTENT_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_CONTENT,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_FRAME_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_FRAME,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_HEADER_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_HEADER,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+
+ case PROP_IMAGE_LOADING_POLICY:
+ g_value_set_int (
+ value,
+ em_format_html_get_image_loading_policy (
+ EM_FORMAT_HTML (object)));
+ return;
+
+ case PROP_MARK_CITATIONS:
+ g_value_set_boolean (
+ value, em_format_html_get_mark_citations (
+ EM_FORMAT_HTML (object)));
+ return;
+
+ case PROP_ONLY_LOCAL_PHOTOS:
+ g_value_set_boolean (
+ value, em_format_html_get_only_local_photos (
+ EM_FORMAT_HTML (object)));
+ return;
+
+ case PROP_SHOW_SENDER_PHOTO:
+ g_value_set_boolean (
+ value, em_format_html_get_show_sender_photo (
+ EM_FORMAT_HTML (object)));
+ return;
+
+ case PROP_TEXT_COLOR:
+ em_format_html_get_color (
+ EM_FORMAT_HTML (object),
+ EM_FORMAT_HTML_COLOR_TEXT,
+ &color);
+ g_value_set_boxed (value, &color);
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+efh_finalize (GObject *object)
{
- EMFormatHTML *efh = (EMFormatHTML *)o;
+ EMFormatHTML *efh = EM_FORMAT_HTML (object);
/* FIXME: check for leaked stuff */
- em_format_html_clear_pobject(efh);
+ em_format_html_clear_pobject (efh);
+ efh_gtkhtml_destroy (efh->html, efh);
+
+ g_hash_table_destroy (efh->priv->text_inline_parts);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+efh_format_clone (EMFormat *emf,
+ CamelFolder *folder,
+ const gchar *uid,
+ CamelMimeMessage *msg,
+ EMFormat *emfsource)
+{
+ EMFormatHTML *efh = EM_FORMAT_HTML (emf);
+ struct _format_msg *m;
- efh_gtkhtml_destroy(efh->html, efh);
+ /* How to sub-class ? Might need to adjust api ... */
- g_hash_table_destroy(efh->priv->text_inline_parts);
+ if (efh->html == NULL)
+ return;
+
+ d(printf("efh_format called\n"));
+ if (efh->priv->format_timeout_id != 0) {
+ d(printf(" timeout for last still active, removing ...\n"));
+ g_source_remove(efh->priv->format_timeout_id);
+ efh->priv->format_timeout_id = 0;
+ mail_msg_unref(efh->priv->format_timeout_msg);
+ efh->priv->format_timeout_msg = NULL;
+ }
- g_free(efh->priv);
+ if (emfsource != NULL)
+ g_object_ref (emfsource);
- ((GObjectClass *)efh_parent)->finalize(o);
+ if (folder != NULL)
+ camel_object_ref (folder);
+
+ if (msg != NULL)
+ camel_object_ref (msg);
+
+ m = mail_msg_new (&efh_format_info);
+ m->format = g_object_ref (emf);
+ m->format_source = emfsource;
+ m->folder = folder;
+ m->uid = g_strdup (uid);
+ m->message = msg;
+
+ if (efh->priv->format_id == -1) {
+ d(printf(" idle, forcing format\n"));
+ efh_format_timeout (m);
+ } else {
+ d(printf(" still busy, cancelling and queuing wait\n"));
+ /* cancel and poll for completion */
+ mail_msg_cancel (efh->priv->format_id);
+ efh->priv->format_timeout_msg = m;
+ efh->priv->format_timeout_id = g_timeout_add (
+ 100, (GSourceFunc) efh_format_timeout, m);
+ }
}
static void
-efh_base_init(EMFormatHTMLClass *efhklass)
+efh_format_error (EMFormat *emf,
+ CamelStream *stream,
+ const gchar *txt)
{
- efh_builtin_init(efhklass);
+ gchar *html;
+
+ html = camel_text_to_html (
+ txt, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
+ camel_stream_printf (
+ stream, "<em><font color=\"red\">%s</font></em><br>", html);
+ g_free (html);
}
static void
-efh_class_init(GObjectClass *klass)
+efh_format_source (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part)
{
- ((EMFormatClass *)klass)->format_clone = efh_format_clone;
- ((EMFormatClass *)klass)->format_error = efh_format_error;
- ((EMFormatClass *)klass)->format_source = efh_format_source;
- ((EMFormatClass *)klass)->format_attachment = efh_format_attachment;
- ((EMFormatClass *)klass)->format_secure = efh_format_secure;
- ((EMFormatClass *)klass)->busy = efh_busy;
-
- klass->finalize = efh_finalise;
+ CamelStreamFilter *filtered_stream;
+ CamelMimeFilter *filter;
+ CamelDataWrapper *dw = (CamelDataWrapper *) part;
+
+ filtered_stream = camel_stream_filter_new_with_stream (stream);
+
+ filter = camel_mime_filter_tohtml_new (
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES |
+ CAMEL_MIME_FILTER_TOHTML_PRESERVE_8BIT, 0);
+ camel_stream_filter_add (filtered_stream, filter);
+ camel_object_unref (filter);
+
+ camel_stream_write_string (stream, "<table><tr><td><tt>");
+ em_format_format_text (emf, (CamelStream *) filtered_stream, dw);
+ camel_object_unref (filtered_stream);
+
+ camel_stream_write_string(stream, "</tt></td></tr></table>");
+}
+
+static void
+efh_format_attachment (EMFormat *emf,
+ CamelStream *stream,
+ CamelMimePart *part,
+ const gchar *mime_type,
+ const EMFormatHandler *handle)
+{
+ gchar *text, *html;
+
+ /* we display all inlined attachments only */
+
+ /* this could probably be cleaned up ... */
+ camel_stream_write_string (
+ stream,
+ "<table border=1 cellspacing=0 cellpadding=0><tr><td>"
+ "<table width=10 cellspacing=0 cellpadding=0>"
+ "<tr><td></td></tr></table></td>"
+ "<td><table width=3 cellspacing=0 cellpadding=0>"
+ "<tr><td></td></tr></table></td><td><font size=-1>\n");
+
+ /* output some info about it */
+ text = em_format_describe_part(part, mime_type);
+ html = camel_text_to_html (
+ text, ((EMFormatHTML *)emf)->text_html_flags &
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
+ camel_stream_write_string (stream, html);
+ g_free (html);
+ g_free (text);
+
+ camel_stream_write_string (stream, "</font></td></tr><tr></table>");
+
+ if (handle && em_format_is_inline (emf, emf->part_id->str, part, handle))
+ handle->handler (emf, stream, part, handle);
+}
+
+static gboolean
+efh_busy (EMFormat *emf)
+{
+ EMFormatHTMLPrivate *priv;
+
+ priv = EM_FORMAT_HTML_GET_PRIVATE (emf);
+
+ return (priv->format_id != -1);
+}
+static void
+efh_base_init (EMFormatHTMLClass *class)
+{
+ efh_builtin_init (class);
+}
+
+static void
+efh_class_init (EMFormatHTMLClass *class)
+{
+ GObjectClass *object_class;
+ EMFormatClass *format_class;
+ gchar *pathname;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EMFormatHTMLPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = efh_set_property;
+ object_class->get_property = efh_get_property;
+ object_class->finalize = efh_finalize;
+
+ format_class = EM_FORMAT_CLASS (class);
+ format_class->format_clone = efh_format_clone;
+ format_class->format_error = efh_format_error;
+ format_class->format_source = efh_format_source;
+ format_class->format_attachment = efh_format_attachment;
+ format_class->format_secure = efh_format_secure;
+ format_class->busy = efh_busy;
+
+ class->html_widget_type = GTK_TYPE_HTML;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_BODY_COLOR,
+ g_param_spec_boxed (
+ "body-color",
+ "Body Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CITATION_COLOR,
+ g_param_spec_boxed (
+ "citation-color",
+ "Citation Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CONTENT_COLOR,
+ g_param_spec_boxed (
+ "content-color",
+ "Content Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FRAME_COLOR,
+ g_param_spec_boxed (
+ "frame-color",
+ "Frame Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HEADER_COLOR,
+ g_param_spec_boxed (
+ "header-color",
+ "Header Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ /* FIXME Make this a proper enum property. */
+ g_object_class_install_property (
+ object_class,
+ PROP_IMAGE_LOADING_POLICY,
+ g_param_spec_int (
+ "image-loading-policy",
+ "Image Loading Policy",
+ NULL,
+ 0,
+ G_MAXINT,
+ MAIL_CONFIG_HTTP_ALWAYS,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MARK_CITATIONS,
+ g_param_spec_boolean (
+ "mark-citations",
+ "Mark Citations",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ONLY_LOCAL_PHOTOS,
+ g_param_spec_boolean (
+ "only-local-photos",
+ "Only Local Photos",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_SENDER_PHOTO,
+ g_param_spec_boolean (
+ "show-sender-photo",
+ "Show Sender Photo",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TEXT_COLOR,
+ g_param_spec_boxed (
+ "text-color",
+ "Text Color",
+ NULL,
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ /* cache expiry - 2 hour access, 1 day max */
+ pathname = g_build_filename (
+ e_get_user_data_dir (), "cache", NULL);
+ emfh_http_cache = camel_data_cache_new (pathname, 0, NULL);
+ if (emfh_http_cache) {
+ camel_data_cache_set_expire_age(emfh_http_cache, 24*60*60);
+ camel_data_cache_set_expire_access(emfh_http_cache, 2*60*60);
+ }
+ g_free (pathname);
+}
+
+static void
+efh_init (EMFormatHTML *efh,
+ EMFormatHTMLClass *class)
+{
+ GtkHTML *html;
+ GdkColor *color;
+
+ efh->priv = EM_FORMAT_HTML_GET_PRIVATE (efh);
+
+ e_dlist_init(&efh->pending_object_list);
+ e_dlist_init(&efh->priv->pending_jobs);
+ efh->priv->lock = g_mutex_new();
+ efh->priv->format_id = -1;
+ efh->priv->text_inline_parts = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) efh_free_cache);
+
+ html = g_object_new (class->html_widget_type, NULL);
+ efh->html = g_object_ref_sink (html);
+
+ gtk_html_set_blocking (html, FALSE);
+ gtk_html_set_caret_first_focus_anchor (html, EFM_MESSAGE_START_ANAME);
+ gtk_html_set_default_content_type (html, "text/html; charset=utf-8");
+ gtk_html_set_editable (html, FALSE);
+
+ g_signal_connect (
+ html, "url-requested",
+ G_CALLBACK (efh_url_requested), efh);
+ g_signal_connect (
+ html, "object-requested",
+ G_CALLBACK (efh_object_requested), efh);
+
+ color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_BODY];
+ gdk_color_parse ("#eeeeee", color);
+
+ color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_CONTENT];
+ gdk_color_parse ("#ffffff", color);
+
+ color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_FRAME];
+ gdk_color_parse ("#3f3f3f", color);
+
+ color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_HEADER];
+ gdk_color_parse ("#eeeeee", color);
+
+ color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_TEXT];
+ gdk_color_parse ("#000000", color);
+
+ efh->text_html_flags =
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_NL |
+ CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES |
+ CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
+ efh->show_icon = TRUE;
+ efh->state = EM_FORMAT_HTML_STATE_NONE;
+
+ g_signal_connect_swapped (
+ efh, "notify::mark-citations",
+ G_CALLBACK (em_format_redraw), NULL);
}
GType
-em_format_html_get_type(void)
+em_format_html_get_type (void)
{
static GType type = 0;
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFormatHTMLClass),
- (GBaseInitFunc)efh_base_init, NULL,
- (GClassInitFunc)efh_class_init,
- NULL, NULL,
- sizeof(EMFormatHTML), 0,
- (GInstanceInitFunc)efh_init
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EMFormatHTMLClass),
+ (GBaseInitFunc) efh_base_init,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) efh_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EMFormatHTML),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) efh_init,
+ NULL /* value_table */
};
- const gchar *base_directory = e_get_user_data_dir ();
- gchar *path;
-
- /* Trigger creation of mail component. */
- mail_component_peek ();
- efh_parent = g_type_class_ref(em_format_get_type());
- type = g_type_register_static(em_format_get_type(), "EMFormatHTML", &info, 0);
-
- /* cache expiry - 2 hour access, 1 day max */
- path = alloca(strlen(base_directory)+16);
- sprintf(path, "%s/cache", base_directory);
- emfh_http_cache = camel_data_cache_new(path, 0, NULL);
- if (emfh_http_cache) {
- camel_data_cache_set_expire_age(emfh_http_cache, 24*60*60);
- camel_data_cache_set_expire_access(emfh_http_cache, 2*60*60);
- }
+ type = g_type_register_static (
+ em_format_get_type(), "EMFormatHTML",
+ &type_info, G_TYPE_FLAG_ABSTRACT);
}
return type;
}
-EMFormatHTML *em_format_html_new(void)
+void
+em_format_html_load_images (EMFormatHTML *efh)
{
- EMFormatHTML *efh;
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
- efh = g_object_new(em_format_html_get_type(), NULL);
+ if (efh->priv->image_loading_policy == MAIL_CONFIG_HTTP_ALWAYS)
+ return;
- return efh;
+ /* This will remain set while we're still
+ * rendering the same message, then it wont be. */
+ efh->priv->load_images_now = TRUE;
+ em_format_redraw (EM_FORMAT (efh));
}
-/* force loading of http images */
-void em_format_html_load_http(EMFormatHTML *emfh)
+void
+em_format_html_get_color (EMFormatHTML *efh,
+ EMFormatHTMLColorType type,
+ GdkColor *color)
{
- if (emfh->load_http == MAIL_CONFIG_HTTP_ALWAYS)
- return;
+ GdkColor *format_color;
- /* This will remain set while we're still rendering the same message, then it wont be */
- emfh->load_http_now = TRUE;
- d(printf("redrawing with images forced on\n"));
- em_format_redraw((EMFormat *)emfh);
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
+ g_return_if_fail (type < EM_FORMAT_HTML_NUM_COLOR_TYPES);
+ g_return_if_fail (color != NULL);
+
+ format_color = &efh->priv->colors[type];
+
+ color->red = format_color->red;
+ color->green = format_color->green;
+ color->blue = format_color->blue;
}
void
-em_format_html_set_load_http(EMFormatHTML *emfh, gint style)
+em_format_html_set_color (EMFormatHTML *efh,
+ EMFormatHTMLColorType type,
+ const GdkColor *color)
{
- if (emfh->load_http != style) {
- emfh->load_http = style;
- em_format_redraw((EMFormat *)emfh);
+ GdkColor *format_color;
+ const gchar *property_name;
+
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
+ g_return_if_fail (type < EM_FORMAT_HTML_NUM_COLOR_TYPES);
+ g_return_if_fail (color != NULL);
+
+ format_color = &efh->priv->colors[type];
+
+ if (gdk_color_equal (color, format_color))
+ return;
+
+ format_color->red = color->red;
+ format_color->green = color->green;
+ format_color->blue = color->blue;
+
+ switch (type) {
+ case EM_FORMAT_HTML_COLOR_BODY:
+ property_name = "body-color";
+ break;
+ case EM_FORMAT_HTML_COLOR_CITATION:
+ property_name = "citation-color";
+ break;
+ case EM_FORMAT_HTML_COLOR_CONTENT:
+ property_name = "content-color";
+ break;
+ case EM_FORMAT_HTML_COLOR_FRAME:
+ property_name = "frame-color";
+ break;
+ case EM_FORMAT_HTML_COLOR_HEADER:
+ property_name = "header-color";
+ break;
+ case EM_FORMAT_HTML_COLOR_TEXT:
+ property_name = "text-color";
+ break;
+ default:
+ g_return_if_reached ();
}
+
+ g_object_notify (G_OBJECT (efh), property_name);
+}
+
+MailConfigHTTPMode
+em_format_html_get_image_loading_policy (EMFormatHTML *efh)
+{
+ g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), 0);
+
+ return efh->priv->image_loading_policy;
}
void
-em_format_html_set_mark_citations(EMFormatHTML *emfh, gint state, guint32 citation_colour)
+em_format_html_set_image_loading_policy (EMFormatHTML *efh,
+ MailConfigHTTPMode policy)
{
- if (emfh->mark_citations ^ state || emfh->citation_colour != citation_colour) {
- emfh->mark_citations = state;
- emfh->citation_colour = citation_colour;
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
- if (state)
- emfh->text_html_flags |= CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
- else
- emfh->text_html_flags &= ~CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
+ if (policy == efh->priv->image_loading_policy)
+ return;
- em_format_redraw((EMFormat *)emfh);
- }
+ efh->priv->image_loading_policy = policy;
+
+ g_object_notify (G_OBJECT (efh), "image-loading-policy");
+}
+
+gboolean
+em_format_html_get_mark_citations (EMFormatHTML *efh)
+{
+ guint32 flags;
+
+ g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), FALSE);
+
+ flags = efh->text_html_flags;
+
+ return ((flags & CAMEL_MIME_FILTER_TOHTML_MARK_CITATION) != 0);
+}
+
+void
+em_format_html_set_mark_citations (EMFormatHTML *efh,
+ gboolean mark_citations)
+{
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
+
+ if (mark_citations)
+ efh->text_html_flags |=
+ CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
+ efh->text_html_flags &=
+ ~CAMEL_MIME_FILTER_TOHTML_MARK_CITATION;
+
+ g_object_notify (G_OBJECT (efh), "mark-citations");
+}
+
+gboolean
+em_format_html_get_only_local_photos (EMFormatHTML *efh)
+{
+ g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), FALSE);
+
+ return efh->priv->only_local_photos;
+}
+
+void
+em_format_html_set_only_local_photos (EMFormatHTML *efh,
+ gboolean only_local_photos)
+{
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
+
+ efh->priv->only_local_photos = only_local_photos;
+
+ g_object_notify (G_OBJECT (efh), "only-local-photos");
+}
+
+gboolean
+em_format_html_get_show_sender_photo (EMFormatHTML *efh)
+{
+ g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), FALSE);
+
+ return efh->priv->show_sender_photo;
+}
+
+void
+em_format_html_set_show_sender_photo (EMFormatHTML *efh,
+ gboolean show_sender_photo)
+{
+ g_return_if_fail (EM_IS_FORMAT_HTML (efh));
+
+ efh->priv->show_sender_photo = show_sender_photo;
+
+ g_object_notify (G_OBJECT (efh), "show-sender-photo");
}
CamelMimePart *
@@ -481,12 +1277,15 @@ static void emfh_gethttp(struct _EMFormatHTMLJob *job, gint cancelled)
instream = cistream = camel_data_cache_get(emfh_http_cache, EMFH_HTTP_CACHE_PATH, job->u.uri, NULL);
if (instream == NULL) {
+ MailConfigHTTPMode policy;
gchar *proxy;
- if (!(job->format->load_http_now
- || job->format->load_http == MAIL_CONFIG_HTTP_ALWAYS
- || (job->format->load_http == MAIL_CONFIG_HTTP_SOMETIMES
- && em_utils_in_addressbook((CamelInternetAddress *)camel_mime_message_get_from(job->format->format.message), FALSE)))) {
+ policy = em_format_html_get_image_loading_policy (job->format);
+
+ if (!(job->format->priv->load_images_now
+ || policy == MAIL_CONFIG_HTTP_ALWAYS
+ || (policy == MAIL_CONFIG_HTTP_SOMETIMES
+ && em_utils_in_addressbook((CamelInternetAddress *)camel_mime_message_get_from(job->format->parent.message), FALSE)))) {
/* TODO: Ideally we would put the http requests into another queue and only send them out
if the user selects 'load images', when they do. The problem is how to maintain this
state with multiple renderings, and how to adjust the thread dispatch/setup routine to handle it */
@@ -675,7 +1474,11 @@ static const gchar *smime_sign_colour[4] = {
static void
efh_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
{
- efh_parent->format_secure(emf, stream, part, valid);
+ EMFormatClass *format_class;
+
+ format_class = EM_FORMAT_GET_CLASS (emf);
+ g_return_if_fail (format_class->format_secure != NULL);
+ format_class->format_secure (emf, stream, part, valid);
/* To explain, if the validity is the same, then we are the
base validity and now have a combined sign/encrypt validity
@@ -729,6 +1532,7 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
CamelContentType *type;
const gchar *format;
guint32 flags;
+ guint32 rgb;
gint i, count, len;
struct _EMFormatHTMLCache *efhc;
@@ -785,8 +1589,10 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
camel_content_type_unref(ct);
}
+ rgb = e_color_to_value (
+ &efh->priv->colors[EM_FORMAT_HTML_COLOR_CITATION]);
filtered_stream = camel_stream_filter_new_with_stream(stream);
- html_filter = camel_mime_filter_tohtml_new(flags, efh->citation_colour);
+ html_filter = camel_mime_filter_tohtml_new(flags, rgb);
camel_stream_filter_add(filtered_stream, html_filter);
camel_object_unref(html_filter);
@@ -802,9 +1608,17 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo
type = camel_mime_part_get_content_type(newpart);
if (camel_content_type_is (type, "text", "*") && !camel_content_type_is(type, "text", "calendar")) {
- camel_stream_printf (stream,
- "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n",
- efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff);
+ camel_stream_printf (
+ stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n",
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_FRAME]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_CONTENT]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_TEXT]));
camel_stream_write_string(stream, "<tt>\n" EFH_MESSAGE_START);
em_format_format_text((EMFormat *)efh, (CamelStream *)filtered_stream, (CamelDataWrapper *)newpart);
camel_stream_flush((CamelStream *)filtered_stream);
@@ -842,9 +1656,17 @@ efh_text_enriched(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, E
camel_stream_filter_add(filtered_stream, enriched);
camel_object_unref(enriched);
- camel_stream_printf (stream,
- "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n" EFH_MESSAGE_START,
- efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff);
+ camel_stream_printf (
+ stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n" EFH_MESSAGE_START,
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_FRAME]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_CONTENT]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_TEXT]));
em_format_format_text((EMFormat *)efh, (CamelStream *)filtered_stream, (CamelDataWrapper *)part);
@@ -879,10 +1701,18 @@ efh_text_html(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFor
EMFormatPURI *puri;
gchar *cid = NULL;
- camel_stream_printf (stream,
- "<div style=\"border: solid #%06x 1px; background-color: #%06x; color: #%06x;\">\n"
- "<!-- text/html -->\n" EFH_MESSAGE_START,
- efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff);
+ camel_stream_printf (
+ stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; color: #%06x;\">\n"
+ "<!-- text/html -->\n" EFH_MESSAGE_START,
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_FRAME]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_CONTENT]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_TEXT]));
/* TODO: perhaps we don't need to calculate this anymore now base is handled better */
/* calculate our own location string so add_puri doesn't do it
@@ -1019,9 +1849,17 @@ efh_message_deliverystatus(EMFormatHTML *efh, CamelStream *stream, CamelMimePart
guint32 rgb = 0x737373;
/* Yuck, this is copied from efh_text_plain */
- camel_stream_printf (stream,
- "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n",
- efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff);
+ camel_stream_printf (
+ stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n",
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_FRAME]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_CONTENT]),
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_TEXT]));
filtered_stream = camel_stream_filter_new_with_stream(stream);
html_filter = camel_mime_filter_tohtml_new(efh->text_html_flags, rgb);
@@ -1213,284 +2051,17 @@ static EMFormatHandler type_builtin_table[] = {
static void
efh_builtin_init(EMFormatHTMLClass *efhc)
{
- gint i;
-
- for (i=0;i<sizeof(type_builtin_table)/sizeof(type_builtin_table[0]);i++)
- em_format_class_add_handler((EMFormatClass *)efhc, &type_builtin_table[i]);
-}
-
-/* ********************************************************************** */
-
-/* Sigh, this is so we have a cancellable, async rendering thread */
-struct _format_msg {
- MailMsg base;
-
- EMFormatHTML *format;
- EMFormat *format_source;
- EMHTMLStream *estream;
- CamelFolder *folder;
- gchar *uid;
- CamelMimeMessage *message;
-};
-
-static gchar *
-efh_format_desc (struct _format_msg *m)
-{
- return g_strdup(_("Formatting message"));
-}
-
-static void
-efh_format_exec (struct _format_msg *m)
-{
- struct _EMFormatHTMLJob *job;
- struct _EMFormatPURITree *puri_level;
- gint cancelled = FALSE;
- CamelURL *base;
-
- if (m->format->html == NULL)
- return;
-
- camel_stream_printf((CamelStream *)m->estream,
- "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n"
- "<head>\n<meta name=\"generator\" content=\"Evolution Mail Component\">\n</head>\n"
- "<body bgcolor =\"#%06x\" text=\"#%06x\" marginwidth=6 marginheight=6>\n",
- m->format->body_colour & 0xffffff,
- m->format->header_colour & 0xffffff);
-
- /* <insert top-header stuff here> */
-
- if (((EMFormat *)m->format)->mode == EM_FORMAT_SOURCE) {
- em_format_format_source((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message);
- } else {
- const EMFormatHandler *handle;
-
- handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/prefix");
- if (handle)
- handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
- handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/rfc822");
- if (handle)
- handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
- handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/post-header-closure");
- if (handle && !((EMFormat *)m->format)->print)
- handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
-
- }
-
- camel_stream_flush((CamelStream *)m->estream);
-
- puri_level = ((EMFormat *)m->format)->pending_uri_level;
- base = ((EMFormat *)m->format)->base;
-
- do {
- /* now dispatch any added tasks ... */
- g_mutex_lock(m->format->priv->lock);
- while ((job = (struct _EMFormatHTMLJob *)e_dlist_remhead(&m->format->priv->pending_jobs))) {
- g_mutex_unlock(m->format->priv->lock);
-
- /* This is an implicit check to see if the gtkhtml has been destroyed */
- if (!cancelled)
- cancelled = m->format->html == NULL;
-
- /* Now do an explicit check for user cancellation */
- if (!cancelled)
- cancelled = camel_operation_cancel_check(NULL);
-
- /* call jobs even if cancelled, so they can clean up resources */
- ((EMFormat *)m->format)->pending_uri_level = job->puri_level;
- if (job->base)
- ((EMFormat *)m->format)->base = job->base;
- job->callback(job, cancelled);
- ((EMFormat *)m->format)->base = base;
-
- /* clean up the job */
- camel_object_unref(job->stream);
- if (job->base)
- camel_url_free(job->base);
- g_free(job);
-
- g_mutex_lock(m->format->priv->lock);
- }
- g_mutex_unlock(m->format->priv->lock);
-
- if (m->estream) {
- /* Closing this base stream can queue more jobs, so we need
- to check the list again after we've finished */
- d(printf("out of jobs, closing root stream\n"));
- camel_stream_write_string((CamelStream *)m->estream, "</body>\n</html>\n");
- camel_stream_close((CamelStream *)m->estream);
- camel_object_unref(m->estream);
- m->estream = NULL;
- }
-
- /* e_dlist_empty is atomic and doesn't need locking */
- } while (!e_dlist_empty(&m->format->priv->pending_jobs));
-
- d(printf("out of jobs, done\n"));
-
- ((EMFormat *)m->format)->pending_uri_level = puri_level;
-}
-
-static void
-efh_format_done (struct _format_msg *m)
-{
- d(printf("formatting finished\n"));
-
- m->format->load_http_now = FALSE;
- m->format->priv->format_id = -1;
- m->format->state = EM_FORMAT_HTML_STATE_NONE;
- g_signal_emit_by_name(m->format, "complete");
-}
-
-static void
-efh_format_free (struct _format_msg *m)
-{
- d(printf("formatter freed\n"));
- g_object_unref(m->format);
- if (m->estream) {
- camel_stream_close((CamelStream *)m->estream);
- camel_object_unref(m->estream);
- }
- if (m->folder)
- camel_object_unref(m->folder);
- g_free(m->uid);
- if (m->message)
- camel_object_unref(m->message);
- if (m->format_source)
- g_object_unref(m->format_source);
-}
-
-static MailMsgInfo efh_format_info = {
- sizeof (struct _format_msg),
- (MailMsgDescFunc) efh_format_desc,
- (MailMsgExecFunc) efh_format_exec,
- (MailMsgDoneFunc) efh_format_done,
- (MailMsgFreeFunc) efh_format_free
-};
-
-static gboolean
-efh_format_timeout(struct _format_msg *m)
-{
- GtkHTMLStream *hstream;
- EMFormatHTML *efh = m->format;
- struct _EMFormatHTMLPrivate *p = efh->priv;
-
- if (m->format->html == NULL) {
- mail_msg_unref(m);
- return FALSE;
- }
-
- d(printf("timeout called ...\n"));
- if (p->format_id != -1) {
- d(printf(" still waiting for cancellation to take effect, waiting ...\n"));
- return TRUE;
- }
-
- g_return_val_if_fail (e_dlist_empty(&p->pending_jobs), FALSE);
-
- d(printf(" ready to go, firing off format thread\n"));
-
- /* call super-class to kick it off */
- efh_parent->format_clone((EMFormat *)efh, m->folder, m->uid, m->message, m->format_source);
- em_format_html_clear_pobject(m->format);
-
- /* FIXME: method off EMFormat? */
- if (((EMFormat *)efh)->valid) {
- camel_cipher_validity_free(((EMFormat *)efh)->valid);
- ((EMFormat *)efh)->valid = NULL;
- ((EMFormat *)efh)->valid_parent = NULL;
- }
-
- if (m->message == NULL) {
- hstream = gtk_html_begin(efh->html);
- gtk_html_stream_close(hstream, GTK_HTML_STREAM_OK);
- mail_msg_unref(m);
- p->last_part = NULL;
- } else {
- efh->state = EM_FORMAT_HTML_STATE_RENDERING;
-
- if (p->last_part != m->message) {
- hstream = gtk_html_begin (efh->html);
- gtk_html_stream_printf (hstream, "<h5>%s</h5>", _("Formatting Message..."));
- gtk_html_stream_close (hstream, GTK_HTML_STREAM_OK);
- }
-
- hstream = NULL;
- m->estream = (EMHTMLStream *)em_html_stream_new(efh->html, hstream);
-
- if (p->last_part == m->message) {
- em_html_stream_set_flags (m->estream,
- GTK_HTML_BEGIN_KEEP_SCROLL | GTK_HTML_BEGIN_KEEP_IMAGES
- | GTK_HTML_BEGIN_BLOCK_UPDATES | GTK_HTML_BEGIN_BLOCK_IMAGES);
- } else {
- /* clear cache of inline-scanned text parts */
- g_hash_table_remove_all(p->text_inline_parts);
-
- p->last_part = m->message;
- }
-
- efh->priv->format_id = m->base.seq;
- mail_msg_unordered_push (m);
- }
-
- efh->priv->format_timeout_id = 0;
- efh->priv->format_timeout_msg = NULL;
-
- return FALSE;
-}
-
-static void efh_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *emfsource)
-{
- EMFormatHTML *efh = (EMFormatHTML *)emf;
- struct _format_msg *m;
-
- /* How to sub-class ? Might need to adjust api ... */
-
- if (efh->html == NULL)
- return;
-
- d(printf("efh_format called\n"));
- if (efh->priv->format_timeout_id != 0) {
- d(printf(" timeout for last still active, removing ...\n"));
- g_source_remove(efh->priv->format_timeout_id);
- efh->priv->format_timeout_id = 0;
- mail_msg_unref(efh->priv->format_timeout_msg);
- efh->priv->format_timeout_msg = NULL;
- }
+ EMFormatClass *efc;
+ gint ii;
- m = mail_msg_new(&efh_format_info);
- m->format = (EMFormatHTML *)emf;
- g_object_ref(emf);
- m->format_source = emfsource;
- if (emfsource)
- g_object_ref(emfsource);
- m->folder = folder;
- if (folder)
- camel_object_ref(folder);
- m->uid = g_strdup(uid);
- m->message = msg;
- if (msg)
- camel_object_ref(msg);
+ efc = (EMFormatClass *) efhc;
- if (efh->priv->format_id == -1) {
- d(printf(" idle, forcing format\n"));
- efh_format_timeout(m);
- } else {
- d(printf(" still busy, cancelling and queuing wait\n"));
- /* cancel and poll for completion */
- mail_msg_cancel(efh->priv->format_id);
- efh->priv->format_timeout_msg = m;
- efh->priv->format_timeout_id = g_timeout_add(100, (GSourceFunc)efh_format_timeout, m);
- }
+ for (ii = 0; ii < G_N_ELEMENTS (type_builtin_table); ii++)
+ em_format_class_add_handler (
+ efc, &type_builtin_table[ii]);
}
-static void efh_format_error(EMFormat *emf, CamelStream *stream, const gchar *txt)
-{
- gchar *html;
-
- html = camel_text_to_html (txt, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL|CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
- camel_stream_printf(stream, "<em><font color=\"red\">%s</font></em><br>", html);
- g_free(html);
-}
+/* ********************************************************************** */
static void
efh_format_text_header (EMFormatHTML *emfh, CamelStream *stream, const gchar *label, const gchar *value, guint32 flags)
@@ -1856,10 +2427,12 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part)
charset = camel_iconv_charset_name(charset);
if (!efh->simple_headers)
- camel_stream_printf(stream,
- "<font color=\"#%06x\">\n"
- "<table cellpadding=\"0\" width=\"100%%\">",
- efh->header_colour & 0xffffff);
+ camel_stream_printf (
+ stream, "<font color=\"#%06x\">\n"
+ "<table cellpadding=\"0\" width=\"100%%\">",
+ e_color_to_value (
+ &efh->priv->colors[
+ EM_FORMAT_HTML_COLOR_HEADER]));
hdr_charset = emf->charset ? emf->charset : emf->default_charset;
@@ -1941,7 +2514,8 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part)
face = !g_ascii_strcasecmp (h->name, "Face");
while (header) {
- if (emf->show_photo && !photo_name && !g_ascii_strcasecmp (header->name, "From"))
+ if (em_format_html_get_show_sender_photo (efh) &&
+ !photo_name && !g_ascii_strcasecmp (header->name, "From"))
photo_name = header->value;
if (!mailer_shown && mailer && (!g_ascii_strcasecmp (header->name, "X-Mailer") ||
@@ -1999,10 +2573,12 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part)
if (photo_name) {
gchar *classid;
CamelMimePart *photopart;
+ gboolean only_local_photo;
cia = camel_internet_address_new();
camel_address_decode((CamelAddress *) cia, (const gchar *) photo_name);
- photopart = em_utils_contact_photo (cia, emf->photo_local);
+ only_local_photo = em_format_html_get_only_local_photos (efh);
+ photopart = em_utils_contact_photo (cia, only_local_photo);
if (photopart) {
contact_has_photo = TRUE;
@@ -2060,7 +2636,8 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part)
}
}
-static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
+static void
+efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
{
const EMFormatHandler *handle;
@@ -2092,57 +2669,3 @@ static void efh_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart
emf->valid = save;
emf->valid_parent = save_parent;
}
-
-static void efh_format_source(EMFormat *emf, CamelStream *stream, CamelMimePart *part)
-{
- CamelStreamFilter *filtered_stream;
- CamelMimeFilter *html_filter;
- CamelDataWrapper *dw = (CamelDataWrapper *)part;
-
- filtered_stream = camel_stream_filter_new_with_stream ((CamelStream *) stream);
- html_filter = camel_mime_filter_tohtml_new (CAMEL_MIME_FILTER_TOHTML_CONVERT_NL
- | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES
- | CAMEL_MIME_FILTER_TOHTML_PRESERVE_8BIT, 0);
- camel_stream_filter_add(filtered_stream, html_filter);
- camel_object_unref(html_filter);
-
- camel_stream_write_string((CamelStream *)stream, "<table><tr><td><tt>");
- em_format_format_text(emf, (CamelStream *)filtered_stream, dw);
- camel_object_unref(filtered_stream);
-
- camel_stream_write_string(stream, "</tt></td></tr></table>");
-}
-
-static void
-efh_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const gchar *mime_type, const EMFormatHandler *handle)
-{
- gchar *text, *html;
-
- /* we display all inlined attachments only */
-
- /* this could probably be cleaned up ... */
- camel_stream_write_string(stream,
- "<table border=1 cellspacing=0 cellpadding=0><tr><td>"
- "<table width=10 cellspacing=0 cellpadding=0>"
- "<tr><td></td></tr></table></td>"
- "<td><table width=3 cellspacing=0 cellpadding=0>"
- "<tr><td></td></tr></table></td><td><font size=-1>\n");
-
- /* output some info about it */
- text = em_format_describe_part(part, mime_type);
- html = camel_text_to_html(text, ((EMFormatHTML *)emf)->text_html_flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
- camel_stream_write_string(stream, html);
- g_free(html);
- g_free(text);
-
- camel_stream_write_string(stream, "</font></td></tr><tr></table>");
-
- if (handle && em_format_is_inline(emf, emf->part_id->str, part, handle))
- handle->handler(emf, stream, part, handle);
-}
-
-static gboolean
-efh_busy(EMFormat *emf)
-{
- return (((EMFormatHTML *)emf)->priv->format_id != -1);
-}
diff --git a/mail/em-format-html.h b/mail/em-format-html.h
index 81a6811de5..4f9c0b209b 100644
--- a/mail/em-format-html.h
+++ b/mail/em-format-html.h
@@ -22,13 +22,13 @@
*/
/*
- Concrete class for formatting mails to html
+ Abstract class for formatting mails to html
*/
#ifndef EM_FORMAT_HTML_H
#define EM_FORMAT_HTML_H
-#include <mail/em-format.h>
+#include <em-format/em-format.h>
#include <mail/mail-config.h>
#include <camel/camel-medium.h>
#include <camel/camel-mime-part.h>
@@ -73,6 +73,16 @@ typedef enum {
EM_FORMAT_HTML_STATE_RENDERING
} EMFormatHTMLState;
+typedef enum {
+ EM_FORMAT_HTML_COLOR_BODY, /* header area background */
+ EM_FORMAT_HTML_COLOR_CITATION, /* citation font color */
+ EM_FORMAT_HTML_COLOR_CONTENT, /* message area background */
+ EM_FORMAT_HTML_COLOR_FRAME, /* frame around message area */
+ EM_FORMAT_HTML_COLOR_HEADER, /* header font color */
+ EM_FORMAT_HTML_COLOR_TEXT, /* message font color */
+ EM_FORMAT_HTML_NUM_COLOR_TYPES
+} EMFormatHTMLColorType;
+
/* A HTMLJob will be executed in another thread, in sequence.
It's job is to write to its stream, close it if successful,
then exit. */
@@ -196,8 +206,7 @@ struct _EMFormatHTMLPObject {
* multipart/related objects and inline images.
**/
struct _EMFormatHTML {
- EMFormat format;
-
+ EMFormat parent;
EMFormatHTMLPrivate *priv;
GtkHTML *html;
@@ -207,15 +216,6 @@ struct _EMFormatHTML {
GSList *headers;
guint32 text_html_flags; /* default flags for text to html conversion */
- guint32 body_colour; /* header box colour */
- guint32 header_colour;
- guint32 text_colour;
- guint32 frame_colour;
- guint32 content_colour;
- guint32 citation_colour;
- guint load_http:2;
- guint load_http_now:1;
- guint mark_citations:1;
guint simple_headers:1; /* simple header format, no box/table */
guint hide_headers:1; /* no headers at all */
guint show_icon:1; /* show an icon when the sender used Evo */
@@ -225,19 +225,40 @@ struct _EMFormatHTML {
};
struct _EMFormatHTMLClass {
- EMFormatClass format_class;
+ EMFormatClass parent_class;
+
+ GType html_widget_type;
};
GType em_format_html_get_type (void);
-EMFormatHTML * em_format_html_new (void);
-void em_format_html_load_http (EMFormatHTML *efh);
-
-void em_format_html_set_load_http (EMFormatHTML *efh,
- gint style);
+void em_format_html_load_images (EMFormatHTML *efh);
+void em_format_html_get_color (EMFormatHTML *efh,
+ EMFormatHTMLColorType type,
+ GdkColor *color);
+void em_format_html_set_color (EMFormatHTML *efh,
+ EMFormatHTMLColorType type,
+ const GdkColor *color);
+MailConfigHTTPMode
+ em_format_html_get_image_loading_policy
+ (EMFormatHTML *efh);
+void em_format_html_set_image_loading_policy
+ (EMFormatHTML *efh,
+ MailConfigHTTPMode policy);
+gboolean em_format_html_get_mark_citations
+ (EMFormatHTML *efh);
void em_format_html_set_mark_citations
(EMFormatHTML *efh,
- gint state,
- guint32 citation_colour);
+ gboolean mark_citations);
+gboolean em_format_html_get_only_local_photos
+ (EMFormatHTML *efh);
+void em_format_html_set_only_local_photos
+ (EMFormatHTML *efh,
+ gboolean only_local_photos);
+gboolean em_format_html_get_show_sender_photo
+ (EMFormatHTML *efh);
+void em_format_html_set_show_sender_photo
+ (EMFormatHTML *efh,
+ gboolean show_sender_photo);
/* retrieves a pseudo-part icon wrapper for a file */
CamelMimePart * em_format_html_file_part (EMFormatHTML *efh,
@@ -261,7 +282,6 @@ EMFormatHTMLPObject *
void em_format_html_remove_pobject (EMFormatHTML *efh,
EMFormatHTMLPObject *pobject);
void em_format_html_clear_pobject (EMFormatHTML *efh);
-
EMFormatHTMLJob *
em_format_html_job_new (EMFormatHTML *efh,
void (*callback)(EMFormatHTMLJob *job, gint cancelled),
diff --git a/mail/em-format-quote.c b/mail/em-format-quote.c
deleted file mode 100644
index af8616a981..0000000000
--- a/mail/em-format-quote.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- *
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include <camel/camel-iconv.h>
-#include <camel/camel-stream.h>
-#include <camel/camel-stream-filter.h>
-#include <camel/camel-mime-filter-tohtml.h>
-#include <camel/camel-mime-filter-enriched.h>
-#include <camel/camel-string-utils.h>
-#include <camel/camel-mime-message.h>
-#include <camel/camel-url.h>
-
-#include <glib/gi18n.h>
-#include <gconf/gconf-client.h>
-
-#include "em-stripsig-filter.h"
-#include "em-format-quote.h"
-#include "mail-config.h"
-
-struct _EMFormatQuotePrivate {
- gint dummy;
-};
-
-static void emfq_format_clone(EMFormat *, CamelFolder *, const gchar *, CamelMimeMessage *, EMFormat *);
-static void emfq_format_error(EMFormat *emf, CamelStream *stream, const gchar *txt);
-static void emfq_format_message(EMFormat *, CamelStream *, CamelMimePart *, const EMFormatHandler *);
-static void emfq_format_source(EMFormat *, CamelStream *, CamelMimePart *);
-static void emfq_format_attachment(EMFormat *, CamelStream *, CamelMimePart *, const gchar *, const EMFormatHandler *);
-
-static void emfq_builtin_init(EMFormatQuoteClass *efhc);
-
-static EMFormatClass *emfq_parent;
-
-static void
-emfq_init(GObject *o)
-{
- EMFormatQuote *emfq =(EMFormatQuote *) o;
-
- emfq->priv = g_malloc0(sizeof(*emfq->priv));
-
- /* we want to convert url's etc */
- emfq->text_html_flags = CAMEL_MIME_FILTER_TOHTML_PRE | CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS
- | CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES;
-}
-
-static void
-emfq_finalise(GObject *o)
-{
- EMFormatQuote *emfq =(EMFormatQuote *) o;
-
- if (emfq->stream)
- camel_object_unref(emfq->stream);
- g_free(emfq->credits);
- g_free(emfq->priv);
-
- ((GObjectClass *) emfq_parent)->finalize(o);
-}
-
-static void
-emfq_base_init(EMFormatQuoteClass *emfqklass)
-{
- emfq_builtin_init(emfqklass);
-}
-
-static void
-emfq_class_init(GObjectClass *klass)
-{
- ((EMFormatClass *) klass)->format_clone = emfq_format_clone;
- ((EMFormatClass *) klass)->format_error = emfq_format_error;
- ((EMFormatClass *) klass)->format_source = emfq_format_source;
- ((EMFormatClass *) klass)->format_attachment = emfq_format_attachment;
-
- klass->finalize = emfq_finalise;
-}
-
-GType
-em_format_quote_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFormatQuoteClass),
- (GBaseInitFunc)emfq_base_init, NULL,
- (GClassInitFunc)emfq_class_init,
- NULL, NULL,
- sizeof(EMFormatQuote), 0,
- (GInstanceInitFunc) emfq_init
- };
-
- emfq_parent = g_type_class_ref(em_format_get_type());
- type = g_type_register_static(em_format_get_type(), "EMFormatQuote", &info, 0);
- }
-
- return type;
-}
-
-EMFormatQuote *
-em_format_quote_new(const gchar *credits, CamelStream *stream, guint32 flags)
-{
- EMFormatQuote *emfq;
-
- emfq = (EMFormatQuote *)g_object_new(em_format_quote_get_type(), NULL);
-
- emfq->credits = g_strdup(credits);
- emfq->stream = stream;
- camel_object_ref(stream);
- emfq->flags = flags;
-
- return emfq;
-}
-
-static void
-emfq_format_empty_line(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- camel_stream_printf(stream, "<br>\n");
-}
-
-static void
-emfq_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *src)
-{
- EMFormatQuote *emfq = (EMFormatQuote *) emf;
- const EMFormatHandler *handle;
-
- ((EMFormatClass *)emfq_parent)->format_clone(emf, folder, uid, msg, src);
-
- camel_stream_reset(emfq->stream);
- if (gconf_client_get_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/composer/top_signature", NULL))
- emfq_format_empty_line(emf, emfq->stream, (CamelMimePart *)msg, NULL);
- handle = em_format_find_handler(emf, "x-evolution/message/prefix");
- if (handle)
- handle->handler(emf, emfq->stream, (CamelMimePart *)msg, handle);
- handle = em_format_find_handler(emf, "x-evolution/message/rfc822");
- if (handle)
- handle->handler(emf, emfq->stream, (CamelMimePart *)msg, handle);
-
- camel_stream_flush(emfq->stream);
-
- g_signal_emit_by_name(emf, "complete");
-}
-
-static void
-emfq_format_error(EMFormat *emf, CamelStream *stream, const gchar *txt)
-{
- /* FIXME: should we even bother writing error text for quoting? probably not... */
-}
-
-static void
-emfq_format_text_header (EMFormatQuote *emfq, CamelStream *stream, const gchar *label, const gchar *value, guint32 flags, gint is_html)
-{
- const gchar *html;
- gchar *mhtml = NULL;
-
- if (value == NULL)
- return;
-
- while (*value == ' ')
- value++;
-
- if (!is_html)
- html = mhtml = camel_text_to_html (value, 0, 0);
- else
- html = value;
-
- if (flags & EM_FORMAT_HEADER_BOLD)
- camel_stream_printf (stream, "<b>%s</b>: %s<br>", label, html);
- else
- camel_stream_printf (stream, "%s: %s<br>", label, html);
-
- g_free (mhtml);
-}
-
-static const gchar *addrspec_hdrs[] = {
- "Sender", "From", "Reply-To", "To", "Cc", "Bcc",
- "Resent-Sender", "Resent-from", "Resent-Reply-To",
- "Resent-To", "Resent-cc", "Resent-Bcc", NULL
-};
-
-#if 0
-/* FIXME: include Sender and Resent-* headers too? */
-/* For Translators only: The following strings are used in the header table in the preview pane */
-static gchar *i18n_hdrs[] = {
- N_("From"), N_("Reply-To"), N_("To"), N_("Cc"), N_("Bcc")
-};
-#endif
-
-static void
-emfq_format_address (GString *out, struct _camel_header_address *a)
-{
- guint32 flags = CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES;
- gchar *name, *mailto, *addr;
-
- while (a) {
- if (a->name)
- name = camel_text_to_html (a->name, flags, 0);
- else
- name = NULL;
-
- switch (a->type) {
- case CAMEL_HEADER_ADDRESS_NAME:
- if (name && *name) {
- gchar *real, *mailaddr;
-
- g_string_append_printf (out, "%s &lt;", name);
- /* rfc2368 for mailto syntax and url encoding extras */
- if ((real = camel_header_encode_phrase ((guchar *)a->name))) {
- mailaddr = g_strdup_printf ("%s <%s>", real, a->v.addr);
- g_free (real);
- mailto = camel_url_encode (mailaddr, "?=&()");
- g_free (mailaddr);
- } else {
- mailto = camel_url_encode (a->v.addr, "?=&()");
- }
- } else {
- mailto = camel_url_encode (a->v.addr, "?=&()");
- }
- addr = camel_text_to_html (a->v.addr, flags, 0);
- g_string_append_printf (out, "<a href=\"mailto:%s\">%s</a>", mailto, addr);
- g_free (mailto);
- g_free (addr);
-
- if (name && *name)
- g_string_append (out, "&gt;");
- break;
- case CAMEL_HEADER_ADDRESS_GROUP:
- g_string_append_printf (out, "%s: ", name);
- emfq_format_address (out, a->v.members);
- g_string_append_printf (out, ";");
- break;
- default:
- g_warning ("Invalid address type");
- break;
- }
-
- g_free (name);
-
- a = a->next;
- if (a)
- g_string_append (out, ", ");
- }
-}
-
-static void
-canon_header_name (gchar *name)
-{
- gchar *inptr = name;
-
- /* canonicalise the header name... first letter is
- * capitalised and any letter following a '-' also gets
- * capitalised */
-
- if (*inptr >= 'a' && *inptr <= 'z')
- *inptr -= 0x20;
-
- inptr++;
-
- while (*inptr) {
- if (inptr[-1] == '-' && *inptr >= 'a' && *inptr <= 'z')
- *inptr -= 0x20;
- else if (*inptr >= 'A' && *inptr <= 'Z')
- *inptr += 0x20;
-
- inptr++;
- }
-}
-
-static void
-emfq_format_header (EMFormat *emf, CamelStream *stream, CamelMedium *part, const gchar *namein, guint32 flags, const gchar *charset)
-{
- CamelMimeMessage *msg = (CamelMimeMessage *) part;
- EMFormatQuote *emfq = (EMFormatQuote *) emf;
- gchar *name, *buf, *value = NULL;
- const gchar *txt, *label;
- gboolean addrspec = FALSE;
- gint is_html = FALSE;
- gint i;
-
- name = g_alloca (strlen (namein) + 1);
- strcpy (name, namein);
- canon_header_name (name);
-
- for (i = 0; addrspec_hdrs[i]; i++) {
- if (!strcmp (name, addrspec_hdrs[i])) {
- addrspec = TRUE;
- break;
- }
- }
-
- label = _(name);
-
- if (addrspec) {
- struct _camel_header_address *addrs;
- GString *html;
-
- if (!(txt = camel_medium_get_header (part, name)))
- return;
-
- buf = camel_header_unfold (txt);
- if (!(addrs = camel_header_address_decode (txt, emf->charset ? emf->charset : emf->default_charset))) {
- g_free (buf);
- return;
- }
-
- g_free (buf);
-
- html = g_string_new ("");
- emfq_format_address (html, addrs);
- camel_header_address_unref (addrs);
- txt = value = html->str;
- g_string_free (html, FALSE);
- flags |= EM_FORMAT_HEADER_BOLD;
- is_html = TRUE;
- } else if (!strcmp (name, "Subject")) {
- txt = camel_mime_message_get_subject (msg);
- label = _("Subject");
- flags |= EM_FORMAT_HEADER_BOLD;
- } else if (!strcmp (name, "X-Evolution-Mailer")) { /* pseudo-header */
- if (!(txt = camel_medium_get_header (part, "x-mailer")))
- if (!(txt = camel_medium_get_header (part, "user-agent")))
- if (!(txt = camel_medium_get_header (part, "x-newsreader")))
- if (!(txt = camel_medium_get_header (part, "x-mimeole")))
- return;
-
- txt = value = camel_header_format_ctext (txt, charset);
-
- label = _("Mailer");
- flags |= EM_FORMAT_HEADER_BOLD;
- } else if (!strcmp (name, "Date") || !strcmp (name, "Resent-Date")) {
- if (!(txt = camel_medium_get_header (part, name)))
- return;
-
- flags |= EM_FORMAT_HEADER_BOLD;
- } else {
- txt = camel_medium_get_header (part, name);
- buf = camel_header_unfold (txt);
- txt = value = camel_header_decode_string (txt, charset);
- g_free (buf);
- }
-
- emfq_format_text_header (emfq, stream, label, txt, flags, is_html);
-
- g_free (value);
-}
-
-static void
-emfq_format_headers (EMFormatQuote *emfq, CamelStream *stream, CamelMedium *part)
-{
- EMFormat *emf = (EMFormat *) emfq;
- CamelContentType *ct;
- const gchar *charset;
- EMFormatHeader *h;
-
- if (!part)
- return;
-
- ct = camel_mime_part_get_content_type ((CamelMimePart *) part);
- charset = camel_content_type_param (ct, "charset");
- charset = camel_iconv_charset_name (charset);
-
- /* dump selected headers */
- h = (EMFormatHeader *) emf->header_list.head;
- while (h->next) {
- emfq_format_header (emf, stream, part, h->name, h->flags, charset);
- h = h->next;
- }
-
- camel_stream_printf(stream, "<br>\n");
-}
-
-static void
-emfq_format_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- EMFormatQuote *emfq = (EMFormatQuote *) emf;
-
- if (emfq->credits)
- camel_stream_printf(stream, "%s<br>\n", emfq->credits);
-}
-
-static void
-emfq_format_message(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- EMFormatQuote *emfq = (EMFormatQuote *) emf;
-
- if (emfq->flags & EM_FORMAT_QUOTE_CITE)
- camel_stream_printf(stream, "<!--+GtkHTML:<DATA class=\"ClueFlow\" key=\"orig\" value=\"1\">-->\n"
- "<blockquote type=cite>\n");
-
- if (((CamelMimePart *)emf->message) != part) {
- camel_stream_printf(stream, "%s</br>\n", _("-------- Forwarded Message --------"));
- emfq_format_headers (emfq, stream, (CamelMedium *)part);
- } else if (emfq->flags & EM_FORMAT_QUOTE_HEADERS)
- emfq_format_headers (emfq, stream, (CamelMedium *)part);
-
- em_format_part (emf, stream, part);
-
- if (emfq->flags & EM_FORMAT_QUOTE_CITE)
- camel_stream_write_string(stream, "</blockquote><!--+GtkHTML:<DATA class=\"ClueFlow\" clear=\"orig\">-->");
-}
-
-static void
-emfq_format_source(EMFormat *emf, CamelStream *stream, CamelMimePart *part)
-{
- CamelStreamFilter *filtered_stream;
- CamelMimeFilter *html_filter;
-
- filtered_stream = camel_stream_filter_new_with_stream ((CamelStream *) stream);
- html_filter = camel_mime_filter_tohtml_new (CAMEL_MIME_FILTER_TOHTML_CONVERT_NL
- | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES
- | CAMEL_MIME_FILTER_TOHTML_ESCAPE_8BIT, 0);
- camel_stream_filter_add(filtered_stream, html_filter);
- camel_object_unref(html_filter);
-
- em_format_format_text(emf, (CamelStream *)filtered_stream, (CamelDataWrapper *)part);
- camel_object_unref(filtered_stream);
-}
-
-static void
-emfq_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const gchar *mime_type, const EMFormatHandler *handle)
-{
- if (handle && em_format_is_inline(emf, emf->part_id->str, part, handle)) {
- gchar *text, *html;
-
- camel_stream_write_string(stream,
- "<table border=1 cellspacing=0 cellpadding=0><tr><td><font size=-1>\n");
-
- /* output some info about it */
- text = em_format_describe_part(part, mime_type);
- html = camel_text_to_html(text, ((EMFormatQuote *)emf)->text_html_flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0);
- camel_stream_write_string(stream, html);
- g_free(html);
- g_free(text);
-
- camel_stream_write_string(stream, "</font></td></tr></table>");
-
- handle->handler(emf, stream, part, handle);
- }
-}
-
-#include <camel/camel-medium.h>
-#include <camel/camel-mime-part.h>
-#include <camel/camel-multipart.h>
-#include <camel/camel-url.h>
-
-static void
-emfq_text_plain(EMFormatQuote *emfq, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
-{
- CamelStreamFilter *filtered_stream;
- CamelMimeFilter *html_filter;
- CamelMimeFilter *sig_strip;
- CamelContentType *type;
- const gchar *format;
- guint32 rgb = 0x737373, flags;
-
- if (!part)
- return;
-
- flags = emfq->text_html_flags;
-
- /* Check for RFC 2646 flowed text. */
- type = camel_mime_part_get_content_type(part);
- if (camel_content_type_is(type, "text", "plain")
- && (format = camel_content_type_param(type, "format"))
- && !g_ascii_strcasecmp(format, "flowed"))
- flags |= CAMEL_MIME_FILTER_TOHTML_FORMAT_FLOWED;
-
- filtered_stream = camel_stream_filter_new_with_stream(stream);
-
- if (emfq->flags != 0) {
- sig_strip = em_stripsig_filter_new ();
- camel_stream_filter_add (filtered_stream, sig_strip);
- camel_object_unref (sig_strip);
- }
-
- html_filter = camel_mime_filter_tohtml_new(flags, rgb);
- camel_stream_filter_add(filtered_stream, html_filter);
- camel_object_unref(html_filter);
-
- em_format_format_text((EMFormat *)emfq, (CamelStream *)filtered_stream, (CamelDataWrapper *)part);
- camel_stream_flush((CamelStream *)filtered_stream);
- camel_object_unref(filtered_stream);
-}
-
-static void
-emfq_text_enriched(EMFormatQuote *emfq, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
-{
- CamelStreamFilter *filtered_stream;
- CamelMimeFilter *enriched;
- CamelDataWrapper *dw;
- guint32 flags = 0;
-
- dw = camel_medium_get_content_object((CamelMedium *)part);
-
- if (!strcmp(info->mime_type, "text/richtext")) {
- flags = CAMEL_MIME_FILTER_ENRICHED_IS_RICHTEXT;
- camel_stream_write_string(stream, "\n<!-- text/richtext -->\n");
- } else {
- camel_stream_write_string(stream, "\n<!-- text/enriched -->\n");
- }
-
- enriched = camel_mime_filter_enriched_new(flags);
- filtered_stream = camel_stream_filter_new_with_stream (stream);
- camel_stream_filter_add(filtered_stream, enriched);
- camel_object_unref(enriched);
-
- camel_stream_write_string(stream, "<br><hr><br>");
- em_format_format_text((EMFormat *)emfq, (CamelStream *)filtered_stream, (CamelDataWrapper *)part);
- camel_object_unref(filtered_stream);
-}
-
-static void
-emfq_text_html(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
-{
- camel_stream_write_string(stream, "\n<!-- text/html -->\n");
- em_format_format_text(emf, stream, (CamelDataWrapper *)part);
-}
-
-static void
-emfq_ignore(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info)
-{
- /* NOOP */
-}
-
-static EMFormatHandler type_builtin_table[] = {
- { (gchar *) "text/plain", (EMFormatFunc)emfq_text_plain },
- { (gchar *) "text/enriched", (EMFormatFunc)emfq_text_enriched },
- { (gchar *) "text/richtext", (EMFormatFunc)emfq_text_enriched },
- { (gchar *) "text/html", (EMFormatFunc)emfq_text_html },
-/* { (gchar *) "multipart/related",(EMFormatFunc)emfq_multipart_related },*/
- { (gchar *) "message/external-body", (EMFormatFunc)emfq_ignore },
- { (gchar *) "multipart/appledouble", (EMFormatFunc)emfq_ignore },
-
- /* internal evolution types */
- { (gchar *) "x-evolution/evolution-rss-feed", (EMFormatFunc)emfq_text_html },
- { (gchar *) "x-evolution/message/rfc822", (EMFormatFunc)emfq_format_message },
- { (gchar *) "x-evolution/message/prefix", (EMFormatFunc)emfq_format_message_prefix },
-};
-
-static void
-emfq_builtin_init(EMFormatQuoteClass *efhc)
-{
- gint i;
-
- for (i=0;i<sizeof(type_builtin_table)/sizeof(type_builtin_table[0]);i++)
- em_format_class_add_handler((EMFormatClass *)efhc, &type_builtin_table[i]);
-}
diff --git a/mail/em-format-quote.h b/mail/em-format-quote.h
deleted file mode 100644
index be88be5956..0000000000
--- a/mail/em-format-quote.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EM_FORMAT_QUOTE_H
-#define EM_FORMAT_QUOTE_H
-
-#include <camel/camel-stream.h>
-#include "mail/em-format.h"
-
-/* Standard GObject macros */
-#define EM_TYPE_FORMAT_QUOTE \
- (em_format_quote_get_type ())
-#define EM_FORMAT_QUOTE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), EM_TYPE_FORMAT_QUOTE, EMFormatQuote))
-#define EM_FORMAT_QUOTE_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), EM_TYPE_FORMAT_QUOTE, EMFormatQuoteClass))
-#define EM_IS_FORMAT_QUOTE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), EM_TYPE_FORMAT_QUOTE))
-#define EM_IS_FORMAT_QUOTE_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), EM_TYPE_FORMAT_QUOTE))
-#define EM_FORMAT_QUOTE_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), EM_TYPE_FORMAT_QUOTE, EMFormatQuoteClass))
-
-#define EM_FORMAT_QUOTE_CITE (1<<0)
-#define EM_FORMAT_QUOTE_HEADERS (1<<1)
-
-G_BEGIN_DECLS
-
-typedef struct _EMFormatQuote EMFormatQuote;
-typedef struct _EMFormatQuoteClass EMFormatQuoteClass;
-typedef struct _EMFormatQuotePrivate EMFormatQuotePrivate;
-
-struct _EMFormatQuote {
- EMFormat format;
-
- EMFormatQuotePrivate *priv;
-
- gchar *credits;
- CamelStream *stream;
- guint32 flags;
-
- guint32 text_html_flags;
- guint32 citation_colour;
-};
-
-struct _EMFormatQuoteClass {
- EMFormatClass format_class;
-};
-
-GType em_format_quote_get_type (void);
-EMFormatQuote * em_format_quote_new (const gchar *credits,
- CamelStream *stream,
- guint32 flags);
-
-G_END_DECLS
-
-#endif /* EM_FORMAT_QUOTE_H */
diff --git a/mail/em-format.c b/mail/em-format.c
deleted file mode 100644
index 1cc6468e55..0000000000
--- a/mail/em-format.c
+++ /dev/null
@@ -1,1839 +0,0 @@
-/*
- * 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:
- * Michael Zucchi <notzed@ximian.com>
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-
-#include <glib/gi18n.h>
-#include <gio/gio.h>
-
-#include <libedataserver/e-msgport.h>
-#include <camel/camel-url.h>
-#include <camel/camel-stream.h>
-#include <camel/camel-stream-mem.h>
-#include <camel/camel-multipart.h>
-#include <camel/camel-multipart-encrypted.h>
-#include <camel/camel-multipart-signed.h>
-#include <camel/camel-medium.h>
-#include <camel/camel-mime-message.h>
-#include <camel/camel-gpg-context.h>
-#include <camel/camel-smime-context.h>
-#include <camel/camel-string-utils.h>
-#include <camel/camel-stream-filter.h>
-#include <camel/camel-stream-null.h>
-#include <camel/camel-stream-mem.h>
-#include <camel/camel-mime-filter-charset.h>
-#include <camel/camel-mime-filter-windows.h>
-#include <camel/camel-mime-filter-pgp.h>
-
-#include "em-format.h"
-#include "em-utils.h"
-#include "mail-config.h"
-
-#define d(x)
-
-/* Used to cache various data/info for redraws
- The validity stuff could be cached at a higher level but this is easier
- This absolutely relies on the partid being _globally unique_
- This is still kind of yucky, we should maintian a full tree of all this data,
- along with/as part of the puri tree */
-struct _EMFormatCache {
- CamelCipherValidity *valid; /* validity copy */
- CamelMimePart *secured; /* encrypted subpart */
-
- guint state:2; /* inline state */
-
- gchar partid[1];
-};
-
-#define INLINE_UNSET (0)
-#define INLINE_ON (1)
-#define INLINE_OFF (2)
-
-static void emf_builtin_init(EMFormatClass *);
-
-static const EMFormatHandler *emf_find_handler(EMFormat *emf, const gchar *mime_type);
-static void emf_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *emfsource);
-static void emf_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid);
-static gboolean emf_busy(EMFormat *emf);
-enum {
- EMF_COMPLETE,
- EMF_LAST_SIGNAL
-};
-
-extern CamelSession *session;
-
-static guint emf_signals[EMF_LAST_SIGNAL];
-static GObjectClass *emf_parent;
-
-static void
-emf_free_cache(struct _EMFormatCache *efc)
-{
- if (efc->valid)
- camel_cipher_validity_free(efc->valid);
- if (efc->secured)
- camel_object_unref(efc->secured);
- g_free(efc);
-}
-
-static struct _EMFormatCache *
-emf_insert_cache(EMFormat *emf, const gchar *partid)
-{
- struct _EMFormatCache *new;
-
- new = g_malloc0(sizeof(*new)+strlen(partid));
- strcpy(new->partid, partid);
- g_hash_table_insert(emf->inline_table, new->partid, new);
-
- return new;
-}
-
-static void
-emf_init(GObject *o)
-{
- EMFormat *emf = (EMFormat *)o;
-
- emf->inline_table = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) emf_free_cache);
- emf->composer = FALSE;
- emf->print = FALSE;
- emf->show_photo = TRUE;
- emf->photo_local = TRUE;
- e_dlist_init(&emf->header_list);
- em_format_default_headers(emf);
- emf->part_id = g_string_new("");
-}
-
-static void
-emf_finalise(GObject *o)
-{
- EMFormat *emf = (EMFormat *)o;
-
- if (emf->session)
- camel_object_unref(emf->session);
-
- g_hash_table_destroy(emf->inline_table);
-
- em_format_clear_headers(emf);
- camel_cipher_validity_free(emf->valid);
- g_free(emf->charset);
- g_free (emf->default_charset);
- g_string_free(emf->part_id, TRUE);
-
- /* FIXME: check pending jobs */
-
- ((GObjectClass *)emf_parent)->finalize(o);
-}
-
-static void
-emf_base_init(EMFormatClass *emfklass)
-{
- emfklass->type_handlers = g_hash_table_new(g_str_hash, g_str_equal);
- emf_builtin_init(emfklass);
-}
-
-static void
-emf_class_init(GObjectClass *klass)
-{
- ((EMFormatClass *)klass)->type_handlers = g_hash_table_new(g_str_hash, g_str_equal);
- emf_builtin_init((EMFormatClass *)klass);
-
- klass->finalize = emf_finalise;
- ((EMFormatClass *)klass)->find_handler = emf_find_handler;
- ((EMFormatClass *)klass)->format_clone = emf_format_clone;
- ((EMFormatClass *)klass)->format_secure = emf_format_secure;
- ((EMFormatClass *)klass)->busy = emf_busy;
-
- emf_signals[EMF_COMPLETE] =
- g_signal_new("complete",
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EMFormatClass, complete),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-GType
-em_format_get_type(void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof(EMFormatClass),
- (GBaseInitFunc)emf_base_init, NULL,
- (GClassInitFunc)emf_class_init,
- NULL, NULL,
- sizeof(EMFormat), 0,
- (GInstanceInitFunc)emf_init
- };
- emf_parent = g_type_class_ref(G_TYPE_OBJECT);
- type = g_type_register_static(G_TYPE_OBJECT, "EMFormat", &info, 0);
- }
-
- return type;
-}
-
-/**
- * em_format_class_add_handler:
- * @emfc: EMFormatClass
- * @info: Callback information.
- *
- * Add a mime type handler to this class. This is only used by
- * implementing classes. The @info.old pointer will automatically be
- * setup to point to the old hanlder if one was already set. This can
- * be used for overrides a fallback.
- *
- * When a mime type described by @info is encountered, the callback will
- * be invoked. Note that @info may be extended by sub-classes if
- * they require additional context information.
- *
- * Use a mime type of "foo/ *" to insert a fallback handler for type "foo".
- **/
-void
-em_format_class_add_handler(EMFormatClass *emfc, EMFormatHandler *info)
-{
- d(printf("adding format handler to '%s' '%s'\n", g_type_name_from_class((GTypeClass *)emfc), info->mime_type));
- info->old = g_hash_table_lookup(emfc->type_handlers, info->mime_type);
- g_hash_table_insert(emfc->type_handlers, (gpointer) info->mime_type, info);
-}
-
-struct _class_handlers {
- EMFormatClass *old;
- EMFormatClass *new;
-};
-static void
-merge_missing (gpointer key, gpointer value, gpointer userdata)
-{
- struct _class_handlers *classes = (struct _class_handlers *) userdata;
- EMFormatHandler *info, *oldinfo;
-
- oldinfo = (EMFormatHandler *) value;
- info = g_hash_table_lookup (classes->new->type_handlers, key);
- if (!info) {
- /* Might be from a plugin */
- g_hash_table_insert (classes->new->type_handlers, key, value);
- }
-
-}
-
-void
-em_format_merge_handler(EMFormat *new, EMFormat *old)
-{
- EMFormatClass *oldc = (EMFormatClass *)G_OBJECT_GET_CLASS(old);
- EMFormatClass *newc = (EMFormatClass *)G_OBJECT_GET_CLASS(new);
- struct _class_handlers fclasses;
-
- fclasses.old = oldc;
- fclasses.new = newc;
-
- g_hash_table_foreach (oldc->type_handlers, merge_missing, &fclasses);
-
-}
-/**
- * em_format_class_remove_handler:
- * @emfc:
- * @info:
- *
- * Remove a handler. @info must be a value which was previously
- * added.
- **/
-void
-em_format_class_remove_handler(EMFormatClass *emfc, EMFormatHandler *info)
-{
- EMFormatHandler *current;
-
- /* TODO: thread issues? */
-
- current = g_hash_table_lookup(emfc->type_handlers, info->mime_type);
- if (current == info) {
- current = info->old;
- if (current)
- g_hash_table_insert(emfc->type_handlers, (gpointer) current->mime_type, current);
- else
- g_hash_table_remove(emfc->type_handlers, info->mime_type);
- } else {
- while (current && current->old != info)
- current = current->old;
- g_return_if_fail(current != NULL);
- current->old = info->old;
- }
-}
-
-/**
- * em_format_find_handler:
- * @emf:
- * @mime_type:
- *
- * Find a format handler by @mime_type.
- *
- * Return value: NULL if no handler is available.
- **/
-static const EMFormatHandler *
-emf_find_handler(EMFormat *emf, const gchar *mime_type)
-{
- EMFormatClass *emfc = (EMFormatClass *)G_OBJECT_GET_CLASS(emf);
-
- return g_hash_table_lookup(emfc->type_handlers, mime_type);
-}
-
-/**
- * em_format_fallback_handler:
- * @emf:
- * @mime_type:
- *
- * Try to find a format handler based on the major type of the @mime_type.
- *
- * The subtype is replaced with "*" and a lookup performed.
- *
- * Return value:
- **/
-const EMFormatHandler *
-em_format_fallback_handler(EMFormat *emf, const gchar *mime_type)
-{
- gchar *mime, *s;
-
- s = strchr(mime_type, '/');
- if (s == NULL)
- mime = (gchar *)mime_type;
- else {
- gsize len = (s-mime_type)+1;
-
- mime = alloca(len+2);
- strncpy(mime, mime_type, len);
- strcpy(mime+len, "*");
- }
-
- return em_format_find_handler(emf, mime);
-}
-
-/**
- * em_format_add_puri:
- * @emf:
- * @size:
- * @cid: Override the autogenerated content id.
- * @part:
- * @func:
- *
- * Add a pending-uri handler. When formatting parts that reference
- * other parts, a pending-uri (PURI) can be used to track the reference.
- *
- * @size is used to allocate the structure, so that it can be directly
- * subclassed by implementors.
- *
- * @cid can be used to override the key used to retreive the PURI, if NULL,
- * then the content-location and the content-id of the @part are stored
- * as lookup keys for the part.
- *
- * FIXME: This may need a free callback.
- *
- * Return value: A new PURI, with a referenced copy of @part, and the cid
- * always set. The uri will be set if one is available. Clashes
- * are resolved by forgetting the old PURI in the global index.
- **/
-EMFormatPURI *
-em_format_add_puri(EMFormat *emf, gsize size, const gchar *cid, CamelMimePart *part, EMFormatPURIFunc func)
-{
- EMFormatPURI *puri;
- const gchar *tmp;
-
- d(printf("adding puri for part: %s\n", emf->part_id->str));
-
- if (size < sizeof(*puri)) {
- g_warning (
- "size (%" G_GSIZE_FORMAT
- ") less than size of puri\n", size);
- size = sizeof (*puri);
- }
-
- puri = g_malloc0(size);
-
- puri->format = emf;
- puri->func = func;
- puri->use_count = 0;
- puri->cid = g_strdup(cid);
- puri->part_id = g_strdup(emf->part_id->str);
-
- if (part) {
- camel_object_ref(part);
- puri->part = part;
- }
-
- if (part != NULL && cid == NULL) {
- tmp = camel_mime_part_get_content_id(part);
- if (tmp)
- puri->cid = g_strdup_printf("cid:%s", tmp);
- else
- puri->cid = g_strdup_printf("em-no-cid:%s", emf->part_id->str);
-
- d(printf("built cid '%s'\n", puri->cid));
-
- /* not quite same as old behaviour, it also put in the relative uri and a fallback for no parent uri */
- tmp = camel_mime_part_get_content_location(part);
- puri->uri = NULL;
- if (tmp == NULL) {
- /* no location, don't set a uri at all, html parts do this themselves */
- } else {
- if (strchr(tmp, ':') == NULL && emf->base != NULL) {
- CamelURL *uri;
-
- uri = camel_url_new_with_base(emf->base, tmp);
- puri->uri = camel_url_to_string(uri, 0);
- camel_url_free(uri);
- } else {
- puri->uri = g_strdup(tmp);
- }
- }
- }
-
- g_return_val_if_fail (puri->cid != NULL, NULL);
- g_return_val_if_fail (emf->pending_uri_level != NULL, NULL);
- g_return_val_if_fail (emf->pending_uri_table != NULL, NULL);
-
- e_dlist_addtail(&emf->pending_uri_level->uri_list, (EDListNode *)puri);
-
- if (puri->uri)
- g_hash_table_insert(emf->pending_uri_table, puri->uri, puri);
- g_hash_table_insert(emf->pending_uri_table, puri->cid, puri);
-
- return puri;
-}
-
-/**
- * em_format_push_level:
- * @emf:
- *
- * This is used to build a heirarchy of visible PURI objects based on
- * the structure of the message. Used by multipart/alternative formatter.
- *
- * FIXME: This could probably also take a uri so it can automaticall update
- * the base location.
- **/
-void
-em_format_push_level(EMFormat *emf)
-{
- struct _EMFormatPURITree *purilist;
-
- d(printf("em_format_push_level\n"));
- purilist = g_malloc0(sizeof(*purilist));
- e_dlist_init(&purilist->children);
- e_dlist_init(&purilist->uri_list);
- purilist->parent = emf->pending_uri_level;
- if (emf->pending_uri_tree == NULL) {
- emf->pending_uri_tree = purilist;
- } else {
- e_dlist_addtail(&emf->pending_uri_level->children, (EDListNode *)purilist);
- }
- emf->pending_uri_level = purilist;
-}
-
-/**
- * em_format_pull_level:
- * @emf:
- *
- * Drop a level of visibility back to the parent. Note that
- * no PURI values are actually freed.
- **/
-void
-em_format_pull_level(EMFormat *emf)
-{
- d(printf("em_format_pull_level\n"));
- emf->pending_uri_level = emf->pending_uri_level->parent;
-}
-
-/**
- * em_format_find_visible_puri:
- * @emf:
- * @uri:
- *
- * Search for a PURI based on the visibility defined by :push_level()
- * and :pull_level().
- *
- * Return value:
- **/
-EMFormatPURI *
-em_format_find_visible_puri(EMFormat *emf, const gchar *uri)
-{
- EMFormatPURI *pw;
- struct _EMFormatPURITree *ptree;
-
- d(printf("checking for visible uri '%s'\n", uri));
-
- ptree = emf->pending_uri_level;
- while (ptree) {
- pw = (EMFormatPURI *)ptree->uri_list.head;
- while (pw->next) {
- d(printf(" pw->uri = '%s' pw->cid = '%s\n", pw->uri?pw->uri:"", pw->cid));
- if ((pw->uri && !strcmp(pw->uri, uri)) || !strcmp(pw->cid, uri))
- return pw;
- pw = pw->next;
- }
- ptree = ptree->parent;
- }
-
- return NULL;
-}
-
-/**
- * em_format_find_puri:
- * @emf:
- * @uri:
- *
- * Search for a PURI based on a uri. Both the content-id
- * and content-location are checked.
- *
- * Return value:
- **/
-EMFormatPURI *
-
-em_format_find_puri(EMFormat *emf, const gchar *uri)
-{
- return g_hash_table_lookup(emf->pending_uri_table, uri);
-}
-
-static void
-emf_clear_puri_node(struct _EMFormatPURITree *node)
-{
- {
- EMFormatPURI *pw, *pn;
-
- /* clear puri's at this level */
- pw = (EMFormatPURI *)node->uri_list.head;
- pn = pw->next;
- while (pn) {
- d(printf ("freeing pw %p format:%p\n", pw, pw->format));
- if (pw->free)
- pw->free(pw);
- g_free(pw->uri);
- g_free(pw->cid);
- g_free(pw->part_id);
- if (pw->part)
- camel_object_unref(pw->part);
- g_free(pw);
- pw = pn;
- pn = pn->next;
- }
- }
-
- {
- struct _EMFormatPURITree *cw, *cn;
-
- /* clear child nodes */
- cw = (struct _EMFormatPURITree *)node->children.head;
- cn = cw->next;
- while (cn) {
- emf_clear_puri_node(cw);
- cw = cn;
- cn = cn->next;
- }
- }
-
- g_free(node);
-}
-
-/**
- * em_format_clear_puri_tree:
- * @emf:
- *
- * For use by implementors to clear out the message structure
- * data.
- **/
-void
-em_format_clear_puri_tree(EMFormat *emf)
-{
- d(printf("clearing pending uri's\n"));
-
- if (emf->pending_uri_table) {
- g_hash_table_destroy(emf->pending_uri_table);
- emf_clear_puri_node(emf->pending_uri_tree);
- emf->pending_uri_level = NULL;
- emf->pending_uri_tree = NULL;
- }
- emf->pending_uri_table = g_hash_table_new(g_str_hash, g_str_equal);
- em_format_push_level(emf);
-}
-
-/* use mime_type == NULL to force showing as application/octet-stream */
-void
-em_format_part_as(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const gchar *mime_type)
-{
- const EMFormatHandler *handle = NULL;
- const gchar *snoop_save = emf->snoop_mime_type, *tmp;
- CamelURL *base_save = emf->base, *base = NULL;
- gchar *basestr = NULL;
-
- d(printf("format_part_as()\n"));
-
- emf->snoop_mime_type = NULL;
-
- /* RFC 2110, we keep track of content-base, and absolute content-location headers
- This is actually only required for html, but, *shrug* */
- tmp = camel_medium_get_header((CamelMedium *)part, "Content-Base");
- if (tmp == NULL) {
- tmp = camel_mime_part_get_content_location(part);
- if (tmp && strchr(tmp, ':') == NULL)
- tmp = NULL;
- } else {
- tmp = basestr = camel_header_location_decode(tmp);
- }
- d(printf("content-base is '%s'\n", tmp?tmp:"<unset>"));
- if (tmp
- && (base = camel_url_new(tmp, NULL))) {
- emf->base = base;
- d(printf("Setting content base '%s'\n", tmp));
- }
- g_free(basestr);
-
- if (mime_type != NULL) {
- if (g_ascii_strcasecmp(mime_type, "application/octet-stream") == 0) {
- emf->snoop_mime_type = mime_type = em_utils_snoop_type(part);
- if (mime_type == NULL)
- mime_type = "application/octet-stream";
- }
-
- handle = em_format_find_handler(emf, mime_type);
- if (handle == NULL)
- handle = em_format_fallback_handler(emf, mime_type);
-
- if (handle != NULL
- && !em_format_is_attachment(emf, part)) {
- d(printf("running handler for type '%s'\n", mime_type));
- handle->handler(emf, stream, part, handle);
- goto finish;
- }
- d(printf("this type is an attachment? '%s'\n", mime_type));
- } else {
- mime_type = "application/octet-stream";
- }
-
- ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_attachment(emf, stream, part, mime_type, handle);
-finish:
- emf->base = base_save;
- emf->snoop_mime_type = snoop_save;
-
- if (base)
- camel_url_free(base);
-}
-
-void
-em_format_part(EMFormat *emf, CamelStream *stream, CamelMimePart *part)
-{
- gchar *mime_type;
- CamelDataWrapper *dw;
-
- dw = camel_medium_get_content_object((CamelMedium *)part);
- mime_type = camel_data_wrapper_get_mime_type(dw);
- if (mime_type) {
- camel_strdown(mime_type);
- em_format_part_as(emf, stream, part, mime_type);
- g_free(mime_type);
- } else
- em_format_part_as(emf, stream, part, "text/plain");
-}
-
-static void
-emf_clone_inlines(gpointer key, gpointer val, gpointer data)
-{
- struct _EMFormatCache *emfc = val, *new;
-
- new = emf_insert_cache((EMFormat *)data, emfc->partid);
- new->state = emfc->state;
- if (emfc->valid)
- new->valid = camel_cipher_validity_clone(emfc->valid);
- if (emfc->secured)
- camel_object_ref((new->secured = emfc->secured));
-}
-
-static void
-emf_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *emfsource)
-{
- em_format_clear_puri_tree(emf);
-
- if (emf != emfsource) {
- g_hash_table_remove_all(emf->inline_table);
- if (emfsource) {
- struct _EMFormatHeader *h;
-
- /* We clone the current state here */
- g_hash_table_foreach(emfsource->inline_table, emf_clone_inlines, emf);
- emf->mode = emfsource->mode;
- g_free(emf->charset);
- emf->charset = g_strdup(emfsource->charset);
- g_free (emf->default_charset);
- emf->default_charset = g_strdup (emfsource->default_charset);
-
- em_format_clear_headers(emf);
- for (h = (struct _EMFormatHeader *)emfsource->header_list.head; h->next; h = h->next)
- em_format_add_header(emf, h->name, h->flags);
- }
- }
-
- /* what a mess */
- if (folder != emf->folder) {
- if (emf->folder)
- camel_object_unref(emf->folder);
- if (folder)
- camel_object_ref(folder);
- emf->folder = folder;
- }
-
- if (uid != emf->uid) {
- g_free(emf->uid);
- emf->uid = g_strdup(uid);
- }
-
- if (msg != emf->message) {
- if (emf->message)
- camel_object_unref(emf->message);
- if (msg)
- camel_object_ref(msg);
- emf->message = msg;
- }
-
- g_string_truncate(emf->part_id, 0);
- if (folder != NULL)
- /* TODO build some string based on the folder name/location? */
- g_string_append_printf(emf->part_id, ".%p", (gpointer) folder);
- if (uid != NULL)
- g_string_append_printf(emf->part_id, ".%s", uid);
-}
-
-static void
-emf_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
-{
- CamelCipherValidity *save = emf->valid_parent;
- gint len;
-
- /* Note that this also requires support from higher up in the class chain
- - validity needs to be cleared when you start output
- - also needs to be cleared (but saved) whenever you start a new message. */
-
- if (emf->valid == NULL) {
- emf->valid = valid;
- } else {
- camel_dlist_addtail(&emf->valid_parent->children, (CamelDListNode *)valid);
- camel_cipher_validity_envelope(emf->valid_parent, valid);
- }
-
- emf->valid_parent = valid;
-
- len = emf->part_id->len;
- g_string_append_printf(emf->part_id, ".secured");
- em_format_part(emf, stream, part);
- g_string_truncate(emf->part_id, len);
-
- emf->valid_parent = save;
-}
-
-static gboolean
-emf_busy(EMFormat *emf)
-{
- return FALSE;
-}
-
-/**
- * em_format_format_clone:
- * @emf: Mail formatter.
- * @folder: Camel Folder.
- * @uid: Uid of message.
- * @msg: Camel Message.
- * @emfsource: Used as a basis for user-altered layout, e.g. inline viewed
- * attachments.
- *
- * Format a message @msg. If @emfsource is non NULL, then the status of
- * inlined expansion and so forth is copied direction from @emfsource.
- *
- * By passing the same value for @emf and @emfsource, you can perform
- * a display refresh, or it can be used to generate an identical layout,
- * e.g. to print what the user has shown inline.
- **/
-void
-em_format_format_clone (EMFormat *emf,
- CamelFolder *folder,
- const gchar *uid,
- CamelMimeMessage *message,
- EMFormat *source)
-{
- EMFormatClass *class;
-
- g_return_if_fail (EM_IS_FORMAT (emf));
- g_return_if_fail (folder == NULL || CAMEL_IS_FOLDER (folder));
- g_return_if_fail (message == NULL || CAMEL_IS_MIME_MESSAGE (message));
- g_return_if_fail (source == NULL || EM_IS_FORMAT (source));
-
- class = EM_FORMAT_GET_CLASS (emf);
- g_return_if_fail (class->format_clone != NULL);
- class->format_clone (emf, folder, uid, message, source);
-}
-
-void
-em_format_format (EMFormat *emf,
- CamelFolder *folder,
- const gchar *uid,
- CamelMimeMessage *message)
-{
- /* em_format_format_clone() will check the arguments. */
- em_format_format_clone (emf, folder, uid, message, NULL);
-}
-
-void
-em_format_redraw (EMFormat *emf)
-{
- g_return_if_fail (EM_IS_FORMAT (emf));
-
- em_format_format_clone (
- emf, emf->folder, emf->uid, emf->message, emf);
-}
-
-/**
- * em_format_set_session:
- * @emf:
- * @s:
- *
- * Set the CamelSession to be used for signature verification and decryption
- * purposes. If this is not set, then signatures cannot be verified or
- * encrypted messages viewed.
- **/
-void
-em_format_set_session(EMFormat *emf, CamelSession *s)
-{
- if (s)
- camel_object_ref(s);
- if (emf->session)
- camel_object_unref(emf->session);
- emf->session = s;
-}
-
-/**
- * em_format_set_mode:
- * @emf:
- * @type:
- *
- * Set display mode, EM_FORMAT_SOURCE, EM_FORMAT_ALLHEADERS, or
- * EM_FORMAT_NORMAL.
- **/
-void
-em_format_set_mode(EMFormat *emf, em_format_mode_t type)
-{
- if (emf->mode == type)
- return;
-
- emf->mode = type;
-
- /* force redraw if type changed afterwards */
- if (emf->message)
- em_format_redraw(emf);
-}
-
-/**
- * em_format_set_charset:
- * @emf:
- * @charset:
- *
- * set override charset on formatter. message will be redisplayed if
- * required.
- **/
-void
-em_format_set_charset(EMFormat *emf, const gchar *charset)
-{
- if ((emf->charset && charset && g_ascii_strcasecmp(emf->charset, charset) == 0)
- || (emf->charset == NULL && charset == NULL)
- || (emf->charset == charset))
- return;
-
- g_free(emf->charset);
- emf->charset = g_strdup(charset);
-
- if (emf->message)
- em_format_redraw(emf);
-}
-
-/**
- * em_format_set_default_charset:
- * @emf:
- * @charset:
- *
- * Set the fallback, default system charset to use when no other charsets
- * are present. Message will be redisplayed if required (and sometimes redisplayed
- * when it isn't).
- **/
-void
-em_format_set_default_charset(EMFormat *emf, const gchar *charset)
-{
- if ((emf->default_charset && charset && g_ascii_strcasecmp(emf->default_charset, charset) == 0)
- || (emf->default_charset == NULL && charset == NULL)
- || (emf->default_charset == charset))
- return;
-
- g_free(emf->default_charset);
- emf->default_charset = g_strdup(charset);
-
- if (emf->message && emf->charset == NULL)
- em_format_redraw(emf);
-}
-
-/**
- * em_format_clear_headers:
- * @emf:
- *
- * Clear the list of headers to be displayed. This will force all headers to
- * be shown.
- **/
-void
-em_format_clear_headers(EMFormat *emf)
-{
- EMFormatHeader *eh;
-
- while ((eh = (EMFormatHeader *)e_dlist_remhead(&emf->header_list)))
- g_free(eh);
-}
-
-/* note: also copied in em-mailer-prefs.c */
-static const struct {
- const gchar *name;
- guint32 flags;
-} default_headers[] = {
- { N_("From"), EM_FORMAT_HEADER_BOLD },
- { N_("Reply-To"), EM_FORMAT_HEADER_BOLD },
- { N_("To"), EM_FORMAT_HEADER_BOLD },
- { N_("Cc"), EM_FORMAT_HEADER_BOLD },
- { N_("Bcc"), EM_FORMAT_HEADER_BOLD },
- { N_("Subject"), EM_FORMAT_HEADER_BOLD },
- { N_("Date"), EM_FORMAT_HEADER_BOLD },
- { N_("Newsgroups"), EM_FORMAT_HEADER_BOLD },
- { N_("Face"), 0 },
-};
-
-/**
- * em_format_default_headers:
- * @emf:
- *
- * Set the headers to show to the default list.
- *
- * From, Reply-To, To, Cc, Bcc, Subject and Date.
- **/
-void
-em_format_default_headers(EMFormat *emf)
-{
- gint i;
-
- em_format_clear_headers(emf);
- for (i=0; i<sizeof(default_headers)/sizeof(default_headers[0]); i++)
- em_format_add_header(emf, default_headers[i].name, default_headers[i].flags);
-}
-
-/**
- * em_format_add_header:
- * @emf:
- * @name: The name of the header, as it will appear during output.
- * @flags: EM_FORMAT_HEAD_* defines to control display attributes.
- *
- * Add a specific header to show. If any headers are set, they will
- * be displayed in the order set by this function. Certain known
- * headers included in this list will be shown using special
- * formatting routines.
- **/
-void em_format_add_header(EMFormat *emf, const gchar *name, guint32 flags)
-{
- EMFormatHeader *h;
-
- h = g_malloc(sizeof(*h) + strlen(name));
- h->flags = flags;
- strcpy(h->name, name);
- e_dlist_addtail(&emf->header_list, (EDListNode *)h);
-}
-
-/**
- * em_format_is_attachment:
- * @emf:
- * @part: Part to check.
- *
- * Returns true if the part is an attachment.
- *
- * A part is not considered an attachment if it is a
- * multipart, or a text part with no filename. It is used
- * to determine if an attachment header should be displayed for
- * the part.
- *
- * Content-Disposition is not checked.
- *
- * Return value: TRUE/FALSE
- **/
-gint em_format_is_attachment(EMFormat *emf, CamelMimePart *part)
-{
- /*CamelContentType *ct = camel_mime_part_get_content_type(part);*/
- CamelDataWrapper *dw = camel_medium_get_content_object((CamelMedium *)part);
-
- if (!dw)
- return 0;
-
- /*printf("checking is attachment %s/%s\n", ct->type, ct->subtype);*/
- return !(camel_content_type_is (dw->mime_type, "multipart", "*")
- || camel_content_type_is(dw->mime_type, "application", "x-pkcs7-mime")
- || camel_content_type_is(dw->mime_type, "application", "pkcs7-mime")
- || camel_content_type_is(dw->mime_type, "application", "x-inlinepgp-signed")
- || camel_content_type_is(dw->mime_type, "application", "x-inlinepgp-encrypted")
- || camel_content_type_is(dw->mime_type, "x-evolution", "evolution-rss-feed")
- || (camel_content_type_is (dw->mime_type, "text", "*")
- && camel_mime_part_get_filename(part) == NULL));
-}
-
-/**
- * em_format_is_inline:
- * @emf:
- * @part:
- * @partid: format->part_id part id of this part.
- * @handle: handler for this part
- *
- * Returns true if the part should be displayed inline. Any part with
- * a Content-Disposition of inline, or if the @handle has a default
- * inline set, will be shown inline.
- *
- * :set_inline() called on the same part will override any calculated
- * value.
- *
- * Return value:
- **/
-gint em_format_is_inline(EMFormat *emf, const gchar *partid, CamelMimePart *part, const EMFormatHandler *handle)
-{
- struct _EMFormatCache *emfc;
- const gchar *tmp;
-
- if (handle == NULL)
- return FALSE;
-
- emfc = g_hash_table_lookup(emf->inline_table, partid);
- if (emfc && emfc->state != INLINE_UNSET)
- return emfc->state & 1;
-
- /* some types need to override the disposition, e.g. application/x-pkcs7-mime */
- if (handle->flags & EM_FORMAT_HANDLER_INLINE_DISPOSITION)
- return TRUE;
-
- tmp = camel_mime_part_get_disposition(part);
- if (tmp)
- return g_ascii_strcasecmp(tmp, "inline") == 0;
-
- /* otherwise, use the default for this handler type */
- return (handle->flags & EM_FORMAT_HANDLER_INLINE) != 0;
-}
-
-/**
- * em_format_set_inline:
- * @emf:
- * @partid: id of part
- * @state:
- *
- * Force the attachment @part to be expanded or hidden explictly to match
- * @state. This is used only to record the change for a redraw or
- * cloned layout render and does not force a redraw.
- **/
-void em_format_set_inline(EMFormat *emf, const gchar *partid, gint state)
-{
- struct _EMFormatCache *emfc;
-
- emfc = g_hash_table_lookup(emf->inline_table, partid);
- if (emfc == NULL) {
- emfc = emf_insert_cache(emf, partid);
- } else if (emfc->state != INLINE_UNSET && (emfc->state & 1) == state)
- return;
-
- emfc->state = state?INLINE_ON:INLINE_OFF;
-
- if (emf->message)
- em_format_redraw(emf);
-}
-
-void em_format_format_error(EMFormat *emf, CamelStream *stream, const gchar *fmt, ...)
-{
- va_list ap;
- gchar *txt;
-
- va_start(ap, fmt);
- txt = g_strdup_vprintf(fmt, ap);
- ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_error((emf), (stream), (txt));
- g_free(txt);
-}
-
-void
-em_format_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid)
-{
- ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_secure(emf, stream, part, valid);
-
- if (emf->valid_parent == NULL && emf->valid != NULL) {
- camel_cipher_validity_free(emf->valid);
- emf->valid = NULL;
- }
-}
-
-/* should this be virtual? */
-void
-em_format_format_content(EMFormat *emf, CamelStream *stream, CamelMimePart *part)
-{
- CamelDataWrapper *dw = camel_medium_get_content_object((CamelMedium *)part);
-
- if (camel_content_type_is (dw->mime_type, "text", "*"))
- em_format_format_text(emf, stream, (CamelDataWrapper *)part);
- else
- camel_data_wrapper_decode_to_stream(dw, stream);
-}
-
-/**
- * em_format_format_content:
- * @emf:
- * @stream: Where to write the converted text
- * @part: Part whose container is to be formatted
- *
- * Decode/output a part's content to @stream.
- **/
-void
-em_format_format_text(EMFormat *emf, CamelStream *stream, CamelDataWrapper *dw)
-{
- CamelStreamFilter *filter_stream;
- CamelMimeFilterCharset *filter;
- const gchar *charset = NULL;
- CamelMimeFilterWindows *windows = NULL;
- CamelStream *mem_stream = NULL;
- gsize size;
- gsize max;
-
- if (emf->charset) {
- charset = emf->charset;
- } else if (dw->mime_type
- && (charset = camel_content_type_param (dw->mime_type, "charset"))
- && g_ascii_strncasecmp(charset, "iso-8859-", 9) == 0) {
- CamelStream *null;
-
- /* Since a few Windows mailers like to claim they sent
- * out iso-8859-# encoded text when they really sent
- * out windows-cp125#, do some simple sanity checking
- * before we move on... */
-
- null = camel_stream_null_new();
- filter_stream = camel_stream_filter_new_with_stream(null);
- camel_object_unref(null);
-
- windows = (CamelMimeFilterWindows *)camel_mime_filter_windows_new(charset);
- camel_stream_filter_add(filter_stream, (CamelMimeFilter *)windows);
-
- camel_data_wrapper_decode_to_stream(dw, (CamelStream *)filter_stream);
- camel_stream_flush((CamelStream *)filter_stream);
- camel_object_unref(filter_stream);
-
- charset = camel_mime_filter_windows_real_charset (windows);
- } else if (charset == NULL) {
- charset = emf->default_charset;
- }
-
- mem_stream = (CamelStream *)camel_stream_mem_new ();
- filter_stream = camel_stream_filter_new_with_stream(mem_stream);
-
- if ((filter = camel_mime_filter_charset_new_convert(charset, "UTF-8"))) {
- camel_stream_filter_add(filter_stream, (CamelMimeFilter *) filter);
- camel_object_unref(filter);
- }
-
- max = mail_config_get_message_limit();
- size = camel_data_wrapper_decode_to_stream(emf->mode == EM_FORMAT_SOURCE ? (CamelDataWrapper *)dw: camel_medium_get_content_object((CamelMedium *)dw), (CamelStream *)filter_stream);
- camel_stream_flush((CamelStream *)filter_stream);
- camel_object_unref(filter_stream);
- camel_stream_reset (mem_stream);
-
- if (max == -1 || size == -1 || size < (max * 1024) || emf->composer) {
- camel_stream_write_to_stream(mem_stream, (CamelStream *)stream);
- camel_stream_flush((CamelStream *)stream);
- } else {
- ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_optional(emf, stream, (CamelMimePart *)dw, mem_stream);
- }
-
- if (windows)
- camel_object_unref(windows);
-}
-
-/**
- * em_format_describe_part:
- * @part:
- * @mimetype:
- *
- * Generate a simple textual description of a part, @mime_type represents the
- * the content.
- *
- * Return value:
- **/
-gchar *
-em_format_describe_part(CamelMimePart *part, const gchar *mime_type)
-{
- GString *stext;
- const gchar *filename, *description;
- gchar *content_type, *desc;
-
- stext = g_string_new("");
- content_type = g_content_type_from_mime_type (mime_type);
- desc = g_content_type_get_description (content_type ? content_type : mime_type);
- g_free (content_type);
- g_string_append_printf (stext, _("%s attachment"), desc ? desc : mime_type);
- g_free (desc);
- if ((filename = camel_mime_part_get_filename (part)))
- g_string_append_printf(stext, " (%s)", filename);
- if ((description = camel_mime_part_get_description(part)) &&
- (*description != 0) &&
- !(filename && (strcmp(filename, description) == 0)))
- g_string_append_printf(stext, ", \"%s\"", description);
-
- return g_string_free (stext, FALSE);
-}
-
-/* ********************************************************************** */
-
-#ifdef ENABLE_SMIME
-static void
-emf_application_xpkcs7mime(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- CamelCipherContext *context;
- CamelException *ex;
- CamelMimePart *opart;
- CamelCipherValidity *valid;
- struct _EMFormatCache *emfc;
-
- /* should this perhaps run off a key of ".secured" ? */
- emfc = g_hash_table_lookup(emf->inline_table, emf->part_id->str);
- if (emfc && emfc->valid) {
- em_format_format_secure(emf, stream, emfc->secured, camel_cipher_validity_clone(emfc->valid));
- return;
- }
-
- ex = camel_exception_new();
-
- context = camel_smime_context_new(session);
-
- opart = camel_mime_part_new();
- valid = camel_cipher_decrypt(context, part, opart, ex);
- if (valid == NULL) {
- em_format_format_error(emf, stream, "%s", ex->desc?ex->desc:_("Could not parse S/MIME message: Unknown error"));
- em_format_part_as(emf, stream, part, NULL);
- } else {
- if (emfc == NULL)
- emfc = emf_insert_cache(emf, emf->part_id->str);
-
- emfc->valid = camel_cipher_validity_clone(valid);
- camel_object_ref((emfc->secured = opart));
-
- em_format_format_secure(emf, stream, opart, valid);
- }
-
- camel_object_unref(opart);
- camel_object_unref(context);
- camel_exception_free(ex);
-}
-#endif
-
-/* RFC 1740 */
-static void
-emf_multipart_appledouble(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part);
- CamelMimePart *mime_part;
- gint len;
-
- if (!CAMEL_IS_MULTIPART(mp)) {
- em_format_format_source(emf, stream, part);
- return;
- }
-
- mime_part = camel_multipart_get_part(mp, 1);
- if (mime_part) {
- /* try the data fork for something useful, doubtful but who knows */
- len = emf->part_id->len;
- g_string_append_printf(emf->part_id, ".appledouble.1");
- em_format_part(emf, stream, mime_part);
- g_string_truncate(emf->part_id, len);
- } else
- em_format_format_source(emf, stream, part);
-
-}
-
-/* RFC ??? */
-static void
-emf_multipart_mixed(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part);
- gint i, nparts, len;
-
- if (!CAMEL_IS_MULTIPART(mp)) {
- em_format_format_source(emf, stream, part);
- return;
- }
-
- len = emf->part_id->len;
- nparts = camel_multipart_get_number(mp);
- for (i = 0; i < nparts; i++) {
- part = camel_multipart_get_part(mp, i);
- g_string_append_printf(emf->part_id, ".mixed.%d", i);
- em_format_part(emf, stream, part);
- g_string_truncate(emf->part_id, len);
- }
-}
-
-/* RFC 1740 */
-static void
-emf_multipart_alternative(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part);
- gint i, nparts, bestid = 0;
- CamelMimePart *best = NULL;
-
- if (!CAMEL_IS_MULTIPART(mp)) {
- em_format_format_source(emf, stream, part);
- return;
- }
-
- /* as per rfc, find the last part we know how to display */
- nparts = camel_multipart_get_number(mp);
- for (i = 0; i < nparts; i++) {
- CamelContentType *type;
- gchar *mime_type;
-
- /* is it correct to use the passed in *part here? */
- part = camel_multipart_get_part(mp, i);
-
- if (!part)
- continue;
-
- type = camel_mime_part_get_content_type (part);
- mime_type = camel_content_type_simple (type);
-
- camel_strdown (mime_type);
-
- /*if (want_plain && !strcmp (mime_type, "text/plain"))
- return part;*/
-
- if (em_format_find_handler(emf, mime_type)
- || (best == NULL && em_format_fallback_handler(emf, mime_type))) {
- best = part;
- bestid = i;
- }
-
- g_free(mime_type);
- }
-
- if (best) {
- gint len = emf->part_id->len;
-
- g_string_append_printf(emf->part_id, ".alternative.%d", bestid);
- em_format_part(emf, stream, best);
- g_string_truncate(emf->part_id, len);
- } else
- emf_multipart_mixed(emf, stream, part, info);
-}
-
-static void
-emf_multipart_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- CamelCipherContext *context;
- CamelException *ex;
- const gchar *protocol;
- CamelMimePart *opart;
- CamelCipherValidity *valid;
- CamelMultipartEncrypted *mpe;
- struct _EMFormatCache *emfc;
-
- /* should this perhaps run off a key of ".secured" ? */
- emfc = g_hash_table_lookup(emf->inline_table, emf->part_id->str);
- if (emfc && emfc->valid) {
- em_format_format_secure(emf, stream, emfc->secured, camel_cipher_validity_clone(emfc->valid));
- return;
- }
-
- mpe = (CamelMultipartEncrypted*)camel_medium_get_content_object((CamelMedium *)part);
- if (!CAMEL_IS_MULTIPART_ENCRYPTED(mpe)) {
- em_format_format_error(emf, stream, _("Could not parse MIME message. Displaying as source."));
- em_format_format_source(emf, stream, part);
- return;
- }
-
- /* Currently we only handle RFC2015-style PGP encryption. */
- protocol = camel_content_type_param(((CamelDataWrapper *)mpe)->mime_type, "protocol");
- if (!protocol || g_ascii_strcasecmp (protocol, "application/pgp-encrypted") != 0) {
- em_format_format_error(emf, stream, _("Unsupported encryption type for multipart/encrypted"));
- em_format_part_as(emf, stream, part, "multipart/mixed");
- return;
- }
-
- ex = camel_exception_new();
- context = camel_gpg_context_new(emf->session);
- opart = camel_mime_part_new();
- valid = camel_cipher_decrypt(context, part, opart, ex);
- if (valid == NULL) {
- em_format_format_error(emf, stream, ex->desc?_("Could not parse PGP/MIME message"):_("Could not parse PGP/MIME message: Unknown error"));
- if (ex->desc)
- em_format_format_error(emf, stream, "%s", ex->desc);
- em_format_part_as(emf, stream, part, "multipart/mixed");
- } else {
- if (emfc == NULL)
- emfc = emf_insert_cache(emf, emf->part_id->str);
-
- emfc->valid = camel_cipher_validity_clone(valid);
- camel_object_ref((emfc->secured = opart));
-
- em_format_format_secure(emf, stream, opart, valid);
- }
-
- /* TODO: Make sure when we finalise this part, it is zero'd out */
- camel_object_unref(opart);
- camel_object_unref(context);
- camel_exception_free(ex);
-}
-
-static void
-emf_write_related(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
-{
- em_format_format_content(emf, stream, puri->part);
- camel_stream_close(stream);
-}
-
-/* RFC 2387 */
-static void
-emf_multipart_related(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part);
- CamelMimePart *body_part, *display_part = NULL;
- CamelContentType *content_type;
- const gchar *start;
- gint i, nparts, partidlen, displayid = 0;
- gchar *oldpartid;
- struct _EMFormatPURITree *ptree;
- EMFormatPURI *puri, *purin;
-
- if (!CAMEL_IS_MULTIPART(mp)) {
- em_format_format_source(emf, stream, part);
- return;
- }
-
- /* FIXME: put this stuff in a shared function */
- nparts = camel_multipart_get_number(mp);
- content_type = camel_mime_part_get_content_type(part);
- start = camel_content_type_param (content_type, "start");
- if (start && strlen(start)>2) {
- gint len;
- const gchar *cid;
-
- /* strip <>'s */
- len = strlen (start) - 2;
- start++;
-
- for (i=0; i<nparts; i++) {
- body_part = camel_multipart_get_part(mp, i);
- cid = camel_mime_part_get_content_id(body_part);
-
- if (cid && !strncmp(cid, start, len) && strlen(cid) == len) {
- display_part = body_part;
- displayid = i;
- break;
- }
- }
- } else {
- display_part = camel_multipart_get_part(mp, 0);
- }
-
- if (display_part == NULL) {
- emf_multipart_mixed(emf, stream, part, info);
- return;
- }
-
- em_format_push_level(emf);
-
- oldpartid = g_strdup(emf->part_id->str);
- partidlen = emf->part_id->len;
-
- /* queue up the parts for possible inclusion */
- for (i = 0; i < nparts; i++) {
- body_part = camel_multipart_get_part(mp, i);
- if (body_part != display_part) {
- /* set the partid since add_puri uses it */
- g_string_append_printf(emf->part_id, ".related.%d", i);
- puri = em_format_add_puri(emf, sizeof(EMFormatPURI), NULL, body_part, emf_write_related);
- g_string_truncate(emf->part_id, partidlen);
- d(printf(" part '%s' '%s' added\n", puri->uri?puri->uri:"", puri->cid));
- }
- }
-
- g_string_append_printf(emf->part_id, ".related.%d", displayid);
- em_format_part(emf, stream, display_part);
- g_string_truncate(emf->part_id, partidlen);
- camel_stream_flush(stream);
-
- ptree = emf->pending_uri_level;
- puri = (EMFormatPURI *)ptree->uri_list.head;
- purin = puri->next;
- while (purin) {
- if (puri->use_count == 0) {
- d(printf("part '%s' '%s' used '%d'\n", puri->uri?puri->uri:"", puri->cid, puri->use_count));
- if (puri->func == emf_write_related) {
- g_string_printf(emf->part_id, "%s", puri->part_id);
- em_format_part(emf, stream, puri->part);
- } else {
- d(printf("unreferenced uri generated by format code: %s\n", puri->uri?puri->uri:puri->cid));
- }
- }
- puri = purin;
- purin = purin->next;
- }
-
- g_string_printf(emf->part_id, "%s", oldpartid);
- g_free(oldpartid);
-
- em_format_pull_level(emf);
-}
-
-static void
-emf_multipart_signed(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- CamelMimePart *cpart;
- CamelMultipartSigned *mps;
- CamelCipherContext *cipher = NULL;
- struct _EMFormatCache *emfc;
-
- /* should this perhaps run off a key of ".secured" ? */
- emfc = g_hash_table_lookup(emf->inline_table, emf->part_id->str);
- if (emfc && emfc->valid) {
- em_format_format_secure(emf, stream, emfc->secured, camel_cipher_validity_clone(emfc->valid));
- return;
- }
-
- mps = (CamelMultipartSigned *)camel_medium_get_content_object((CamelMedium *)part);
- if (!CAMEL_IS_MULTIPART_SIGNED(mps)
- || (cpart = camel_multipart_get_part((CamelMultipart *)mps, CAMEL_MULTIPART_SIGNED_CONTENT)) == NULL) {
- em_format_format_error(emf, stream, _("Could not parse MIME message. Displaying as source."));
- em_format_format_source(emf, stream, part);
- return;
- }
-
- /* FIXME: Should be done via a plugin interface */
- /* FIXME: duplicated in em-format-html-display.c */
- if (mps->protocol) {
-#ifdef ENABLE_SMIME
- if (g_ascii_strcasecmp("application/x-pkcs7-signature", mps->protocol) == 0
- || g_ascii_strcasecmp("application/pkcs7-signature", mps->protocol) == 0)
- cipher = camel_smime_context_new(emf->session);
- else
-#endif
- if (g_ascii_strcasecmp("application/pgp-signature", mps->protocol) == 0)
- cipher = camel_gpg_context_new(emf->session);
- }
-
- if (cipher == NULL) {
- em_format_format_error(emf, stream, _("Unsupported signature format"));
- em_format_part_as(emf, stream, part, "multipart/mixed");
- } else {
- CamelException *ex = camel_exception_new();
- CamelCipherValidity *valid;
-
- valid = camel_cipher_verify(cipher, part, ex);
- if (valid == NULL) {
- em_format_format_error(emf, stream, ex->desc?_("Error verifying signature"):_("Unknown error verifying signature"));
- if (ex->desc)
- em_format_format_error(emf, stream, "%s", ex->desc);
- em_format_part_as(emf, stream, part, "multipart/mixed");
- } else {
- if (emfc == NULL)
- emfc = emf_insert_cache(emf, emf->part_id->str);
-
- emfc->valid = camel_cipher_validity_clone(valid);
- camel_object_ref((emfc->secured = cpart));
-
- em_format_format_secure(emf, stream, cpart, valid);
- }
-
- camel_exception_free(ex);
- camel_object_unref(cipher);
- }
-}
-
-/* RFC 4155 */
-static void
-emf_application_mbox (EMFormat *emf,
- CamelStream *stream,
- CamelMimePart *mime_part,
- const EMFormatHandler *info)
-{
- const EMFormatHandler *handle;
- CamelMimeParser *parser;
- CamelStream *mem_stream;
- camel_mime_parser_state_t state;
-
- /* Extract messages from the application/mbox part and
- * render them as a flat list of messages. */
-
- /* XXX If the mbox has multiple messages, maybe render them
- * as a multipart/digest so each message can be expanded
- * or collapsed individually.
- *
- * See attachment_handler_mail_x_uid_list() for example. */
-
- /* XXX This is based on em_utils_read_messages_from_stream().
- * Perhaps refactor that function to return an array of
- * messages instead of assuming we want to append them
- * to a folder? */
-
- handle = em_format_find_handler (emf, "x-evolution/message/rfc822");
- g_return_if_fail (handle != NULL);
-
- parser = camel_mime_parser_new ();
- camel_mime_parser_scan_from (parser, TRUE);
-
- mem_stream = camel_stream_mem_new ();
- camel_data_wrapper_decode_to_stream (
- CAMEL_DATA_WRAPPER (mime_part), mem_stream);
- camel_seekable_stream_seek (
- CAMEL_SEEKABLE_STREAM (mem_stream), 0, CAMEL_STREAM_SET);
- camel_mime_parser_init_with_stream (parser, mem_stream);
- camel_object_unref (mem_stream);
-
- /* Extract messages from the mbox. */
- state = camel_mime_parser_step (parser, NULL, NULL);
- while (state == CAMEL_MIME_PARSER_STATE_FROM) {
- CamelMimeMessage *message;
-
- message = camel_mime_message_new ();
- mime_part = CAMEL_MIME_PART (message);
-
- if (camel_mime_part_construct_from_parser (mime_part, parser) == -1) {
- camel_object_unref (message);
- break;
- }
-
- /* Render the message. */
- handle->handler (emf, stream, mime_part, handle);
-
- camel_object_unref (message);
-
- /* Skip past CAMEL_MIME_PARSER_STATE_FROM_END. */
- state = camel_mime_parser_step (parser, NULL, NULL);
-
- state = camel_mime_parser_step (parser, NULL, NULL);
- }
-
- camel_object_unref (parser);
-}
-
-static void
-emf_message_rfc822(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- CamelDataWrapper *dw = camel_medium_get_content_object((CamelMedium *)part);
- const EMFormatHandler *handle;
- gint len;
-
- if (!CAMEL_IS_MIME_MESSAGE(dw)) {
- em_format_format_source(emf, stream, part);
- return;
- }
-
- len = emf->part_id->len;
- g_string_append_printf(emf->part_id, ".rfc822");
-
- handle = em_format_find_handler(emf, "x-evolution/message/rfc822");
- if (handle)
- handle->handler(emf, stream, (CamelMimePart *)dw, handle);
-
- g_string_truncate(emf->part_id, len);
-}
-
-static void
-emf_message_deliverystatus(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
- em_format_format_text(emf, stream, (CamelDataWrapper *)part);
-}
-
-static void
-emf_inlinepgp_signed(EMFormat *emf, CamelStream *stream, CamelMimePart *ipart, EMFormatHandler *info)
-{
- CamelStreamFilter *filtered_stream;
- CamelMimeFilterPgp *pgp_filter;
- CamelContentType *content_type;
- CamelCipherContext *cipher;
- CamelCipherValidity *valid;
- CamelDataWrapper *dw;
- CamelMimePart *opart;
- CamelStream *ostream;
- CamelException *ex;
- gchar *type;
-
- if (!ipart) {
- em_format_format_error(emf, stream, _("Unknown error verifying signature"));
- return;
- }
-
- ex = camel_exception_new();
- cipher = camel_gpg_context_new(emf->session);
- /* Verify the signature of the message */
- valid = camel_cipher_verify(cipher, ipart, ex);
- if (!valid) {
- em_format_format_error(emf, stream, ex->desc?_("Error verifying signature"):_("Unknown error verifying signature"));
- if (ex->desc)
- em_format_format_error(emf, stream, "%s", ex->desc);
- em_format_format_source(emf, stream, ipart);
- /* I think this will loop: em_format_part_as(emf, stream, part, "text/plain"); */
- camel_exception_free(ex);
- camel_object_unref(cipher);
- return;
- }
-
- /* Setup output stream */
- ostream = camel_stream_mem_new();
- filtered_stream = camel_stream_filter_new_with_stream(ostream);
-
- /* Add PGP header / footer filter */
- pgp_filter = (CamelMimeFilterPgp *)camel_mime_filter_pgp_new();
- camel_stream_filter_add(filtered_stream, (CamelMimeFilter *)pgp_filter);
- camel_object_unref(pgp_filter);
-
- /* Pass through the filters that have been setup */
- dw = camel_medium_get_content_object((CamelMedium *)ipart);
- camel_data_wrapper_decode_to_stream(dw, (CamelStream *)filtered_stream);
- camel_stream_flush((CamelStream *)filtered_stream);
- camel_object_unref(filtered_stream);
-
- /* Create a new text/plain MIME part containing the signed content preserving the original part's Content-Type params */
- content_type = camel_mime_part_get_content_type (ipart);
- type = camel_content_type_format (content_type);
- content_type = camel_content_type_decode (type);
- g_free (type);
-
- g_free (content_type->type);
- content_type->type = g_strdup ("text");
- g_free (content_type->subtype);
- content_type->subtype = g_strdup ("plain");
- type = camel_content_type_format (content_type);
- camel_content_type_unref (content_type);
-
- dw = camel_data_wrapper_new ();
- camel_data_wrapper_construct_from_stream (dw, ostream);
- camel_data_wrapper_set_mime_type (dw, type);
- g_free (type);
-
- opart = camel_mime_part_new ();
- camel_medium_set_content_object ((CamelMedium *) opart, dw);
- camel_data_wrapper_set_mime_type_field ((CamelDataWrapper *) opart, dw->mime_type);
-
- /* Pass it off to the real formatter */
- em_format_format_secure(emf, stream, opart, valid);
-
- /* Clean Up */
- camel_object_unref(dw);
- camel_object_unref(opart);
- camel_object_unref(ostream);
- camel_object_unref(cipher);
- camel_exception_free(ex);
-}
-
-static void
-emf_inlinepgp_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *ipart, EMFormatHandler *info)
-{
- CamelCipherContext *cipher;
- CamelCipherValidity *valid;
- CamelException *ex;
- CamelMimePart *opart;
- CamelDataWrapper *dw;
- gchar *mime_type;
-
- cipher = camel_gpg_context_new(emf->session);
- ex = camel_exception_new();
- opart = camel_mime_part_new();
- /* Decrypt the message */
- valid = camel_cipher_decrypt (cipher, ipart, opart, ex);
- if (!valid) {
- em_format_format_error(emf, stream, ex->desc?_("Could not parse PGP message"):_("Could not parse PGP message: Unknown error"));
- if (ex->desc)
- em_format_format_error(emf, stream, "%s", ex->desc);
- em_format_format_source(emf, stream, ipart);
- /* I think this will loop: em_format_part_as(emf, stream, part, "text/plain"); */
- camel_exception_free(ex);
- camel_object_unref(cipher);
- camel_object_unref(opart);
- return;
- }
-
- dw = camel_medium_get_content_object ((CamelMedium *)opart);
- mime_type = camel_data_wrapper_get_mime_type (dw);
-
- /* this ensures to show the 'opart' as inlined, if possible */
- if (mime_type && g_ascii_strcasecmp (mime_type, "application/octet-stream") == 0) {
- const gchar *snoop = em_utils_snoop_type (opart);
-
- if (snoop)
- camel_data_wrapper_set_mime_type (dw, snoop);
- }
-
- g_free (mime_type);
-
- /* Pass it off to the real formatter */
- em_format_format_secure(emf, stream, opart, valid);
-
- /* Clean Up */
- camel_object_unref(opart);
- camel_object_unref (cipher);
- camel_exception_free (ex);
-}
-
-static EMFormatHandler type_builtin_table[] = {
-#ifdef ENABLE_SMIME
- { (gchar *) "application/x-pkcs7-mime", (EMFormatFunc)emf_application_xpkcs7mime, EM_FORMAT_HANDLER_INLINE_DISPOSITION },
-#endif
- { (gchar *) "application/mbox", emf_application_mbox, EM_FORMAT_HANDLER_INLINE },
- { (gchar *) "multipart/alternative", emf_multipart_alternative },
- { (gchar *) "multipart/appledouble", emf_multipart_appledouble },
- { (gchar *) "multipart/encrypted", emf_multipart_encrypted },
- { (gchar *) "multipart/mixed", emf_multipart_mixed },
- { (gchar *) "multipart/signed", emf_multipart_signed },
- { (gchar *) "multipart/related", emf_multipart_related },
- { (gchar *) "multipart/*", emf_multipart_mixed },
- { (gchar *) "message/rfc822", emf_message_rfc822, EM_FORMAT_HANDLER_INLINE },
- { (gchar *) "message/news", emf_message_rfc822, EM_FORMAT_HANDLER_INLINE },
- { (gchar *) "message/delivery-status", emf_message_deliverystatus },
- { (gchar *) "message/*", emf_message_rfc822, EM_FORMAT_HANDLER_INLINE },
-
- /* Insert brokenly-named parts here */
-#ifdef ENABLE_SMIME
- { (gchar *) "application/pkcs7-mime", (EMFormatFunc)emf_application_xpkcs7mime, EM_FORMAT_HANDLER_INLINE_DISPOSITION },
-#endif
-
- /* internal types */
- { (gchar *) "application/x-inlinepgp-signed", (EMFormatFunc)emf_inlinepgp_signed },
- { (gchar *) "application/x-inlinepgp-encrypted", (EMFormatFunc)emf_inlinepgp_encrypted },
-};
-
-static void
-emf_builtin_init(EMFormatClass *klass)
-{
- gint i;
-
- for (i=0;i<sizeof(type_builtin_table)/sizeof(type_builtin_table[0]);i++)
- g_hash_table_insert(klass->type_handlers, (gpointer) type_builtin_table[i].mime_type, &type_builtin_table[i]);
-}
diff --git a/mail/em-format.h b/mail/em-format.h
deleted file mode 100644
index b3af1e8c3c..0000000000
--- a/mail/em-format.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- *
- * 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:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-/*
- Abstract class for formatting mime messages
-*/
-
-#ifndef EM_FORMAT_H
-#define EM_FORMAT_H
-
-#include <glib-object.h>
-#include <camel/camel-url.h>
-#include <camel/camel-folder.h>
-#include <camel/camel-stream.h>
-#include <camel/camel-session.h>
-#include <camel/camel-mime-part.h>
-#include <camel/camel-mime-message.h>
-#include <camel/camel-cipher-context.h>
-#include <libedataserver/e-msgport.h>
-
-/* Standard GObject macros */
-#define EM_TYPE_FORMAT \
- (em_format_get_type ())
-#define EM_FORMAT(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), EM_TYPE_FORMAT, EMFormat))
-#define EM_FORMAT_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), EM_TYPE_FORMAT, EMFormatClass))
-#define EM_IS_FORMAT(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), EM_TYPE_FORMAT))
-#define EM_IS_FORMAT_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), EM_TYPE_FORMAT))
-#define EM_FORMAT_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), EM_TYPE_FORMAT, EMFormatClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EMFormat EMFormat;
-typedef struct _EMFormatClass EMFormatClass;
-typedef struct _EMFormatPrivate EMFormatPrivate;
-
-typedef struct _EMFormatHandler EMFormatHandler;
-typedef struct _EMFormatHeader EMFormatHeader;
-
-typedef void (*EMFormatFunc) (EMFormat *md, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info);
-
-typedef enum _em_format_mode_t {
- EM_FORMAT_NORMAL,
- EM_FORMAT_ALLHEADERS,
- EM_FORMAT_SOURCE
-} em_format_mode_t;
-
-/**
- * struct _EMFormatHandler - MIME type handler.
- *
- * @mime_type: Type this handler handles.
- * @handler: The handler callback.
- * @flags: Handling flags, see enum _em_format_handler_t.
- * @old: The last handler set on this type. Allows overrides to
- * fallback to previous implementation.
- *
- **/
-struct _EMFormatHandler {
- gchar *mime_type;
- EMFormatFunc handler;
- guint32 flags;
-
- struct _EMFormatHandler *old;
-};
-
-/**
- * enum _em_format_handler_t - Format handler flags.
- *
- * @EM_FORMAT_HANDLER_INLINE: This type should be shown expanded
- * inline by default.
- * @EM_FORMAT_HANDLER_INLINE_DISPOSITION: This type should always be
- * shown inline, despite what the Content-Disposition suggests.
- *
- **/
-enum _em_format_handler_t {
- EM_FORMAT_HANDLER_INLINE = 1<<0,
- EM_FORMAT_HANDLER_INLINE_DISPOSITION = 1<<1
-};
-
-typedef struct _EMFormatPURI EMFormatPURI;
-typedef void (*EMFormatPURIFunc)(EMFormat *md, CamelStream *stream, EMFormatPURI *puri);
-
-/**
- * struct _EMFormatPURI - Pending URI object.
- *
- * @next: Double-linked list header.
- * @prev: Double-linked list header.
- * @free: May be set by allocator and will be called when no longer needed.
- * @format:
- * @uri: Calculated URI of the part, if the part has one in its
- * Content-Location field.
- * @cid: The RFC2046 Content-Id of the part. If none is present, a unique value
- * is calculated from @part_id.
- * @part_id: A unique identifier for each part.
- * @func: Callback for when the URI is requested. The callback writes
- * its data to the supplied stream.
- * @part:
- * @use_count:
- *
- * This is used for multipart/related, and other formatters which may
- * need to include a reference to out-of-band data in the content
- * stream.
- *
- * This object may be subclassed as a struct.
- **/
-struct _EMFormatPURI {
- struct _EMFormatPURI *next;
- struct _EMFormatPURI *prev;
-
- void (*free)(struct _EMFormatPURI *p); /* optional callback for freeing user-fields */
- struct _EMFormat *format;
-
- gchar *uri; /* will be the location of the part, may be empty */
- gchar *cid; /* will always be set, a fake one created if needed */
- gchar *part_id; /* will always be set, emf->part_id->str for this part */
-
- EMFormatPURIFunc func;
- CamelMimePart *part;
-
- guint use_count; /* used by multipart/related to see if it was accessed */
-};
-
-/**
- * struct _EMFormatPURITree - Pending URI visibility tree.
- *
- * @next: Double-linked list header.
- * @prev: Double-linked list header.
- * @parent: Parent in tree.
- * @uri_list: List of EMFormatPURI objects at this level.
- * @children: Child nodes of EMFormatPURITree.
- *
- * This structure is used internally to form a visibility tree of
- * parts in the current formatting stream. This is to implement the
- * part resolution rules for RFC2387 to implement multipart/related.
- **/
-struct _EMFormatPURITree {
- struct _EMFormatPURITree *next;
- struct _EMFormatPURITree *prev;
- struct _EMFormatPURITree *parent;
-
- EDList uri_list;
- EDList children;
-};
-
-struct _EMFormatHeader {
- struct _EMFormatHeader *next, *prev;
-
- guint32 flags; /* E_FORMAT_HEADER_* */
- gchar name[1];
-};
-
-#define EM_FORMAT_HEADER_BOLD (1<<0)
-#define EM_FORMAT_HEADER_LAST (1<<4) /* reserve 4 slots */
-
-/**
- * struct _EMFormat - Mail formatter object.
- *
- * @parent:
- * @priv:
- * @message:
- * @folder:
- * @uid:
- * @part_id:
- * @header_list:
- * @session:
- * @base url:
- * @snoop_mime_type:
- * @valid:
- * @valid_parent:
- * @inline_table:
- * @pending_uri_table:
- * @pending_uri_tree:
- * @pending_uri_level:
- * @mode:
- * @charset:
- * @default_charset:
- *
- * Most fields are private or read-only.
- *
- * This is the base MIME formatter class. It provides no formatting
- * itself, but drives most of the basic types, including multipart / * types.
- **/
-struct _EMFormat {
- GObject parent;
-
- EMFormatPrivate *priv;
-
- CamelMimeMessage *message; /* the current message */
-
- CamelFolder *folder;
- gchar *uid;
-
- GString *part_id; /* current part id prefix, for identifying parts directly */
-
- EDList header_list; /* if empty, then all */
-
- CamelSession *session; /* session, used for authentication when required */
- CamelURL *base; /* content-base header or absolute content-location, for any part */
-
- const gchar *snoop_mime_type; /* if we snooped an application/octet-stream type, what we snooped */
-
- /* for validity enveloping */
- CamelCipherValidity *valid;
- CamelCipherValidity *valid_parent;
-
- /* for forcing inlining */
- GHashTable *inline_table;
-
- /* global lookup table for message */
- GHashTable *pending_uri_table;
-
- /* visibility tree, also stores every puri permanently */
- struct _EMFormatPURITree *pending_uri_tree;
- /* current level to search from */
- struct _EMFormatPURITree *pending_uri_level;
-
- em_format_mode_t mode; /* source/headers/etc */
- gchar *charset; /* charset override */
- gchar *default_charset; /* charset fallback */
- gboolean composer; /* Formatting from composer ?*/
- gboolean print;
- gboolean show_photo; /* Want to show the photo of the sender ?*/
- gboolean photo_local; /* Photos only from local addressbooks */
-};
-
-struct _EMFormatClass {
- GObjectClass parent_class;
-
- GHashTable *type_handlers;
-
- /* lookup handler, default falls back to hashtable above */
- const EMFormatHandler *(*find_handler)(EMFormat *, const gchar *mime_type);
-
- /* start formatting a message */
- void (*format_clone)(EMFormat *, CamelFolder *, const gchar *uid, CamelMimeMessage *, EMFormat *);
-
- /* some internel error/inconsistency */
- void (*format_error)(EMFormat *, CamelStream *, const gchar *msg);
-
- /* use for external structured parts */
- void (*format_attachment)(EMFormat *, CamelStream *, CamelMimePart *, const gchar *mime_type, const struct _EMFormatHandler *info);
-
- /* use for unparsable content */
- void (*format_source)(EMFormat *, CamelStream *, CamelMimePart *);
- /* for outputing secure(d) content */
- void (*format_secure)(EMFormat *, CamelStream *, CamelMimePart *, CamelCipherValidity *);
-
- /* returns true if the formatter is still busy with pending stuff */
- gboolean (*busy)(EMFormat *);
-
- /* Shows optional way to open messages */
- void (*format_optional)(EMFormat *, CamelStream *, CamelMimePart *, CamelStream* );
-
- /* signals */
- /* complete, alternative to polling busy, for asynchronous work */
- void (*complete)(EMFormat *);
-};
-
-/* helper entry point */
-void em_format_set_session(EMFormat *emf, CamelSession *s);
-
-void em_format_set_mode(EMFormat *emf, em_format_mode_t type);
-void em_format_set_charset(EMFormat *emf, const gchar *charset);
-void em_format_set_default_charset(EMFormat *emf, const gchar *charset);
-
-void em_format_clear_headers(EMFormat *emf); /* also indicates to show all headers */
-void em_format_default_headers(EMFormat *emf);
-void em_format_add_header(EMFormat *emf, const gchar *name, guint32 flags);
-
-/* FIXME: Need a 'clone' api to copy details about the current view (inlines etc)
- Or maybe it should live with sub-classes? */
-
-gint em_format_is_attachment(EMFormat *emf, CamelMimePart *part);
-
-gint em_format_is_inline(EMFormat *emf, const gchar *partid, CamelMimePart *part, const EMFormatHandler *handle);
-void em_format_set_inline(EMFormat *emf, const gchar *partid, gint state);
-
-gchar *em_format_describe_part(CamelMimePart *part, const gchar *mimetype);
-
-/* for implementers */
-GType em_format_get_type(void);
-
-void em_format_class_add_handler(EMFormatClass *emfc, EMFormatHandler *info);
-void em_format_class_remove_handler(EMFormatClass *emfc, EMFormatHandler *info);
-#define em_format_find_handler(emf, type) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->find_handler((emf), (type))
-const EMFormatHandler *em_format_fallback_handler(EMFormat *emf, const gchar *mime_type);
-
-/* puri is short for pending uri ... really */
-EMFormatPURI *em_format_add_puri(EMFormat *emf, gsize size, const gchar *uri, CamelMimePart *part, EMFormatPURIFunc func);
-EMFormatPURI *em_format_find_visible_puri(EMFormat *emf, const gchar *uri);
-EMFormatPURI *em_format_find_puri(EMFormat *emf, const gchar *uri);
-void em_format_clear_puri_tree(EMFormat *emf);
-void em_format_push_level(EMFormat *emf);
-void em_format_pull_level(EMFormat *emf);
-
-/* clones inline state/view and format, or use to redraw */
-void em_format_format_clone (EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *message, EMFormat *source);
-/* formats a new message */
-void em_format_format(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *message);
-void em_format_redraw(EMFormat *emf);
-void em_format_format_error(EMFormat *emf, CamelStream *stream, const gchar *fmt, ...);
-#define em_format_format_attachment(emf, stream, msg, type, info) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_attachment((emf), (stream), (msg), (type), (info))
-#define em_format_format_source(emf, stream, msg) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_source((emf), (stream), (msg))
-void em_format_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid);
-
-#define em_format_busy(emf) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->busy((emf))
-
-/* raw content only */
-void em_format_format_content(EMFormat *emf, CamelStream *stream, CamelMimePart *part);
-/* raw content text parts - should this just be checked/done by above? */
-void em_format_format_text(EMFormat *emf, CamelStream *stream, CamelDataWrapper *part);
-
-void em_format_part_as(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const gchar *mime_type);
-void em_format_part(EMFormat *emf, CamelStream *stream, CamelMimePart *part);
-void em_format_merge_handler(EMFormat *new, EMFormat *old);
-
-G_END_DECLS
-
-#endif /* EM_FORMAT_H */
diff --git a/mail/em-html-stream.c b/mail/em-html-stream.c
index 3f0177e7a4..cc3c795d32 100644
--- a/mail/em-html-stream.c
+++ b/mail/em-html-stream.c
@@ -27,84 +27,39 @@
#endif
#include <stdio.h>
-#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-stream.h>
#include <gtk/gtk.h>
#include "em-html-stream.h"
#define d(x)
-static void em_html_stream_class_init (EMHTMLStreamClass *klass);
-static void em_html_stream_init (CamelObject *object);
-static void em_html_stream_finalize (CamelObject *object);
-
-static gssize emhs_sync_write(CamelStream *stream, const gchar *buffer, gsize n);
-static gint emhs_sync_close(CamelStream *stream);
-static gint emhs_sync_flush(CamelStream *stream);
-
static EMSyncStreamClass *parent_class = NULL;
-CamelType
-em_html_stream_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- parent_class = (EMSyncStreamClass *)em_sync_stream_get_type();
- type = camel_type_register (em_sync_stream_get_type(),
- "EMHTMLStream",
- sizeof (EMHTMLStream),
- sizeof (EMHTMLStreamClass),
- (CamelObjectClassInitFunc) em_html_stream_class_init,
- NULL,
- (CamelObjectInitFunc) em_html_stream_init,
- (CamelObjectFinalizeFunc) em_html_stream_finalize);
- }
-
- return type;
-}
-
-static void
-em_html_stream_class_init (EMHTMLStreamClass *klass)
-{
- ((EMSyncStreamClass *)klass)->sync_write = emhs_sync_write;
- ((EMSyncStreamClass *)klass)->sync_flush = emhs_sync_flush;
- ((EMSyncStreamClass *)klass)->sync_close = emhs_sync_close;
-}
-
-static void
-em_html_stream_init (CamelObject *object)
-{
- /*EMHTMLStream *emhs = (EMHTMLStream *)object;*/
-}
-
static void
-emhs_cleanup(EMHTMLStream *emhs)
+emhs_cleanup (EMHTMLStream *emhs)
{
if (emhs->sync.cancel && emhs->html_stream)
- gtk_html_stream_close (emhs->html_stream, GTK_HTML_STREAM_ERROR);
+ gtk_html_stream_close (
+ emhs->html_stream, GTK_HTML_STREAM_ERROR);
+
emhs->html_stream = NULL;
emhs->sync.cancel = TRUE;
- g_signal_handler_disconnect(emhs->html, emhs->destroy_id);
- g_object_unref(emhs->html);
+ g_signal_handler_disconnect (emhs->html, emhs->destroy_id);
+ g_object_unref (emhs->html);
emhs->html = NULL;
}
static void
-em_html_stream_finalize (CamelObject *object)
+emhs_gtkhtml_destroy (GtkHTML *html,
+ EMHTMLStream *emhs)
{
- EMHTMLStream *emhs = (EMHTMLStream *)object;
-
- d(printf("%p: finalising stream\n", object));
- if (emhs->html_stream) {
- d(printf("%p: html stream still open - error\n", object));
- /* set 'in finalise' flag */
- camel_stream_close((CamelStream *)emhs);
- }
+ emhs->sync.cancel = TRUE;
+ emhs_cleanup (emhs);
}
static gssize
-emhs_sync_write(CamelStream *stream, const gchar *buffer, gsize n)
+emhs_sync_write (CamelStream *stream,
+ const gchar *buffer,
+ gsize n)
{
EMHTMLStream *emhs = EM_HTML_STREAM (stream);
@@ -112,9 +67,10 @@ emhs_sync_write(CamelStream *stream, const gchar *buffer, gsize n)
return -1;
if (emhs->html_stream == NULL)
- emhs->html_stream = gtk_html_begin_full (emhs->html, NULL, NULL, emhs->flags);
+ emhs->html_stream = gtk_html_begin_full (
+ emhs->html, NULL, NULL, emhs->flags);
- gtk_html_stream_write(emhs->html_stream, buffer, n);
+ gtk_html_stream_write (emhs->html_stream, buffer, n);
return (gssize) n;
}
@@ -133,48 +89,93 @@ emhs_sync_flush(CamelStream *stream)
}
static gint
-emhs_sync_close(CamelStream *stream)
+emhs_sync_close (CamelStream *stream)
{
EMHTMLStream *emhs = (EMHTMLStream *)stream;
if (emhs->html_stream == NULL)
return -1;
- gtk_html_stream_close(emhs->html_stream, GTK_HTML_STREAM_OK);
- emhs_cleanup(emhs);
+ gtk_html_stream_close (emhs->html_stream, GTK_HTML_STREAM_OK);
+ emhs_cleanup (emhs);
return 0;
}
static void
-emhs_gtkhtml_destroy(GtkHTML *html, EMHTMLStream *emhs)
+em_html_stream_class_init (EMHTMLStreamClass *class)
{
- d(printf("%p: emhs gtkhtml destroy\n", emhs));
- emhs->sync.cancel = TRUE;
- emhs_cleanup(emhs);
+ EMSyncStreamClass *sync_stream_class;
+
+ parent_class = (EMSyncStreamClass *)em_sync_stream_get_type();
+
+ sync_stream_class = EM_SYNC_STREAM_CLASS (class);
+ sync_stream_class->sync_write = emhs_sync_write;
+ sync_stream_class->sync_flush = emhs_sync_flush;
+ sync_stream_class->sync_close = emhs_sync_close;
+}
+
+static void
+em_html_stream_init (EMHTMLStream *emhs)
+{
+}
+
+static void
+em_html_stream_finalize (EMHTMLStream *emhs)
+{
+ if (emhs->html_stream) {
+ /* set 'in finalise' flag */
+ camel_stream_close (CAMEL_STREAM (emhs));
+ }
+}
+
+CamelType
+em_html_stream_get_type (void)
+{
+ static CamelType type = CAMEL_INVALID_TYPE;
+
+ if (G_UNLIKELY (type == CAMEL_INVALID_TYPE)) {
+ type = camel_type_register (
+ em_sync_stream_get_type(),
+ "EMHTMLStream",
+ sizeof (EMHTMLStream),
+ sizeof (EMHTMLStreamClass),
+ (CamelObjectClassInitFunc) em_html_stream_class_init,
+ NULL,
+ (CamelObjectInitFunc) em_html_stream_init,
+ (CamelObjectFinalizeFunc) em_html_stream_finalize);
+ }
+
+ return type;
}
/* TODO: Could pass NULL for html_stream, and do a gtk_html_begin
on first data -> less flashing */
CamelStream *
-em_html_stream_new(GtkHTML *html, GtkHTMLStream *html_stream)
+em_html_stream_new (GtkHTML *html,
+ GtkHTMLStream *html_stream)
{
EMHTMLStream *new;
+ g_return_val_if_fail (GTK_IS_HTML (html), NULL);
+
new = EM_HTML_STREAM (camel_object_new (EM_HTML_STREAM_TYPE));
new->html_stream = html_stream;
- new->html = html;
+ new->html = g_object_ref (html);
new->flags = 0;
- g_object_ref(html);
- new->destroy_id = g_signal_connect(html, "destroy", G_CALLBACK(emhs_gtkhtml_destroy), new);
+ new->destroy_id = g_signal_connect (
+ html, "destroy",
+ G_CALLBACK (emhs_gtkhtml_destroy), new);
- em_sync_stream_set_buffer_size(&new->sync, 8192);
+ em_sync_stream_set_buffer_size (&new->sync, 8192);
- return (CamelStream *)new;
+ return CAMEL_STREAM (new);
}
void
em_html_stream_set_flags (EMHTMLStream *emhs, GtkHTMLBeginFlags flags)
{
+ g_return_if_fail (EM_IS_HTML_STREAM (emhs));
+
emhs->flags = flags;
}
diff --git a/mail/em-html-stream.h b/mail/em-html-stream.h
index abd12e154f..7bf79470dd 100644
--- a/mail/em-html-stream.h
+++ b/mail/em-html-stream.h
@@ -24,34 +24,46 @@
#ifndef EM_HTML_STREAM_H
#define EM_HTML_STREAM_H
-G_BEGIN_DECLS
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-stream.h>
+#include <mail/em-sync-stream.h>
+
+#define EM_HTML_STREAM_TYPE \
+ (em_html_stream_get_type ())
+#define EM_HTML_STREAM(obj) \
+ (CAMEL_CHECK_CAST \
+ ((obj), EM_HTML_STREAM_TYPE, EMHTMLStream))
+#define EM_HTML_STREAM_CLASS(cls) \
+ (CAMEL_CHECK_CLASS_CAST \
+ ((cls), EM_HTML_STREAM_TYPE, EMHTMLStreamClass))
+#define EM_IS_HTML_STREAM(obj) \
+ (CAMEL_CHECK_TYPE \
+ ((obj), EM_HTML_STREAM_TYPE))
-#define EM_HTML_STREAM_TYPE (em_html_stream_get_type ())
-#define EM_HTML_STREAM(obj) (CAMEL_CHECK_CAST((obj), EM_HTML_STREAM_TYPE, EMHTMLStream))
-#define EM_HTML_STREAM_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), EM_HTML_STREAM_TYPE, EMHTMLStreamClass))
-#define EM_IS_HTML_STREAM(o) (CAMEL_CHECK_TYPE((o), EM_HTML_STREAM_TYPE))
+G_BEGIN_DECLS
-#include "mail/em-sync-stream.h"
+typedef struct _EMHTMLStream EMHTMLStream;
+typedef struct _EMHTMLStreamClass EMHTMLStreamClass;
-typedef struct _EMHTMLStream {
+struct _EMHTMLStream {
EMSyncStream sync;
guint destroy_id;
GtkHTML *html;
GtkHTMLStream *html_stream;
GtkHTMLBeginFlags flags;
-} EMHTMLStream;
+};
-typedef struct {
+struct _EMHTMLStreamClass {
EMSyncStreamClass parent_class;
-} EMHTMLStreamClass;
-
-CamelType em_html_stream_get_type (void);
+};
-/* the html_stream is closed when we are finalised (with an error), or closed (ok) */
-CamelStream *em_html_stream_new(GtkHTML *html, GtkHTMLStream *html_stream);
-void em_html_stream_set_flags (EMHTMLStream *emhs, GtkHTMLBeginFlags flags);
+CamelType em_html_stream_get_type (void);
+CamelStream * em_html_stream_new (GtkHTML *html,
+ GtkHTMLStream *html_stream);
+void em_html_stream_set_flags (EMHTMLStream *emhs,
+ GtkHTMLBeginFlags flags);
G_END_DECLS
diff --git a/mail/em-inline-filter.c b/mail/em-inline-filter.c
index 7ff92fae5e..2b68ed65b9 100644
--- a/mail/em-inline-filter.c
+++ b/mail/em-inline-filter.c
@@ -32,6 +32,7 @@
#include <camel/camel-stream-mem.h>
#include "em-utils.h"
+#include "em-format/em-format.h"
#define d(x)
@@ -175,7 +176,7 @@ emif_add_part(EMInlineFilter *emif, const gchar *data, gint len)
/* pre-snoop the mime type of unknown objects, and poke and hack it into place */
if (camel_content_type_is(dw->mime_type, "application", "octet-stream")
- && (mimetype = em_utils_snoop_type(part))
+ && (mimetype = em_format_snoop_type(part))
&& strcmp(mimetype, "application/octet-stream") != 0) {
camel_data_wrapper_set_mime_type(dw, mimetype);
camel_mime_part_set_content_type(part, mimetype);
diff --git a/mail/em-mailer-prefs.c b/mail/em-mailer-prefs.c
deleted file mode 100644
index 057b2d9210..0000000000
--- a/mail/em-mailer-prefs.c
+++ /dev/null
@@ -1,1618 +0,0 @@
-/*
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "em-mailer-prefs.h"
-#include "em-format.h"
-
-#include <camel/camel-iconv.h>
-#include <gtkhtml/gtkhtml-properties.h>
-#include <libxml/tree.h>
-#include "misc/e-charset-picker.h"
-#include <bonobo/bonobo-generic-factory.h>
-
-#include <glade/glade.h>
-
-#include <gconf/gconf-client.h>
-
-#include "libedataserverui/e-cell-renderer-color.h"
-
-#include "e-util/e-util-private.h"
-#include "e-util/e-util-labels.h"
-
-#include "mail-config.h"
-#include "em-junk-hook.h"
-#include "em-config.h"
-#include "mail-session.h"
-
-static void em_mailer_prefs_class_init (EMMailerPrefsClass *class);
-static void em_mailer_prefs_init (EMMailerPrefs *dialog);
-static void em_mailer_prefs_dispose (GObject *obj);
-
-static GtkVBoxClass *parent_class = NULL;
-
-enum {
- HEADER_LIST_NAME_COLUMN, /* displayable name of the header (may be a translation) */
- HEADER_LIST_ENABLED_COLUMN, /* is the header enabled? */
- HEADER_LIST_IS_DEFAULT_COLUMN, /* is this header a default header, eg From: */
- HEADER_LIST_HEADER_COLUMN, /* the real name of this header */
- HEADER_LIST_N_COLUMNS
-};
-
-static GType col_types[] = {
- G_TYPE_STRING,
- G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN,
- G_TYPE_STRING
-};
-
-/* temporarily copied from em-format.c */
-static const gchar *default_headers[] = {
- N_("From"),
- N_("Reply-To"),
- N_("To"),
- N_("Cc"),
- N_("Bcc"),
- N_("Subject"),
- N_("Date"),
- N_("Newsgroups"),
- N_("Face"),
- "x-evolution-mailer", /* DO NOT translate */
-};
-
-#define EM_FORMAT_HEADER_XMAILER "x-evolution-mailer"
-
-/* for empty trash on exit frequency */
-static const struct {
- const gchar *label;
- gint days;
-} empty_trash_frequency[] = {
- { N_("Every time"), 0 },
- { N_("Once per day"), 1 },
- { N_("Once per week"), 7 },
- { N_("Once per month"), 30 },
-};
-
-GType
-em_mailer_prefs_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- GTypeInfo type_info = {
- sizeof (EMMailerPrefsClass),
- NULL, NULL,
- (GClassInitFunc) em_mailer_prefs_class_init,
- NULL, NULL,
- sizeof (EMMailerPrefs),
- 0,
- (GInstanceInitFunc) em_mailer_prefs_init,
- };
-
- type = g_type_register_static (gtk_vbox_get_type (), "EMMailerPrefs", &type_info, 0);
- }
-
- return type;
-}
-
-static void
-em_mailer_prefs_class_init (EMMailerPrefsClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = (GObjectClass *) klass;
- parent_class = g_type_class_ref (gtk_vbox_get_type ());
-
- object_class->dispose = em_mailer_prefs_dispose;
-}
-
-static void
-em_mailer_prefs_init (EMMailerPrefs *preferences)
-{
- preferences->gconf = mail_config_get_gconf_client ();
-}
-
-static void
-em_mailer_prefs_dispose (GObject *obj)
-{
- EMMailerPrefs *prefs = (EMMailerPrefs *) obj;
-
- if (prefs->header_list_store) {
- g_object_unref (prefs->header_list_store);
- prefs->header_list_store = NULL;
- }
-
- g_object_unref (prefs->gui);
-
- if (prefs->labels_change_notify_id) {
- gconf_client_notify_remove (prefs->gconf, prefs->labels_change_notify_id);
-
- prefs->labels_change_notify_id = 0;
- }
-
- ((GObjectClass *)(parent_class))->dispose (obj);
-}
-
-static void
-color_button_set_color (GtkColorButton *color_button, const gchar *spec)
-{
- GdkColor color;
-
- if (gdk_color_parse (spec, &color))
- gtk_color_button_set_color (color_button, &color);
-}
-
-static void
-citation_color_set (GtkColorButton *color_button, EMMailerPrefs *prefs)
-{
- GdkColor color;
- gchar spec[16];
-
- gtk_color_button_get_color (color_button, &color);
- g_snprintf (spec, sizeof (spec), "#%04x%04x%04x",
- color.red, color.green, color.blue);
-
- gconf_client_set_string (prefs->gconf,
- "/apps/evolution/mail/display/citation_colour",
- spec, NULL);
-}
-
-enum {
- LABEL_LIST_COLUMN_COLOR,
- LABEL_LIST_COLUMN_TAG,
- LABEL_LIST_COLUMN_NAME
-};
-
-enum {
- JH_LIST_COLUMN_NAME,
- JH_LIST_COLUMN_VALUE
-};
-static void
-label_sensitive_buttons (EMMailerPrefs *prefs)
-{
- gboolean can_remove = FALSE, have_selected = FALSE, locked;
-
- g_return_if_fail (prefs);
-
- /* it's not sensitive if it's locked for updates */
- locked = !GTK_WIDGET_IS_SENSITIVE (prefs->label_tree);
-
- if (!locked) {
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->label_tree));
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- gchar *tag = NULL;
-
- gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1);
-
- can_remove = tag && !e_util_labels_is_system (tag);
- have_selected = TRUE;
-
- g_free (tag);
- }
- }
-
- gtk_widget_set_sensitive (prefs->label_remove, !locked && can_remove);
- gtk_widget_set_sensitive (prefs->label_edit, !locked && have_selected);
-}
-
-static void
-label_tree_cursor_changed (GtkWidget *widget, gpointer user_data)
-{
- label_sensitive_buttons (user_data);
-}
-
-static void
-label_tree_refill (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data)
-{
- EMMailerPrefs *prefs = (EMMailerPrefs *)user_data;
- GSList *labels, *l;
- GtkTreeSelection *selection;
- GtkListStore *store;
- GtkTreeModel *model;
- GtkTreeIter last_iter;
- gchar *last_path = NULL;
-
- g_return_if_fail (prefs != NULL);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->label_tree));
- if (gtk_tree_selection_get_selected (selection, &model, &last_iter))
- last_path = gtk_tree_model_get_string_from_iter (model, &last_iter);
-
- store = GTK_LIST_STORE (model);
- gtk_list_store_clear (store);
-
- /* cannot use mail-config cache here, because it's (or can be) updated later than this function call */
- labels = e_util_labels_parse (client);
-
- for (l = labels; l; l = l->next) {
- GdkColor color;
- GtkTreeIter iter;
- EUtilLabel *label = l->data;
-
- if (label->colour)
- gdk_color_parse (label->colour, &color);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (
- store, &iter,
- LABEL_LIST_COLUMN_COLOR, label->colour ? &color : NULL,
- LABEL_LIST_COLUMN_NAME, label->name,
- LABEL_LIST_COLUMN_TAG, label->tag,
- -1);
- }
-
- if (last_path) {
- gint children;
-
- children = gtk_tree_model_iter_n_children (model, NULL);
- if (children > 0) {
- GtkTreePath *path;
-
- if (!gtk_tree_model_get_iter_from_string (model, &last_iter, last_path))
- gtk_tree_model_iter_nth_child (model, &last_iter, NULL, children - 1);
-
- path = gtk_tree_model_get_path (model, &last_iter);
- if (path) {
- GtkTreeViewColumn *focus_col = gtk_tree_view_get_column (GTK_TREE_VIEW (prefs->label_tree), LABEL_LIST_COLUMN_NAME);
-
- gtk_tree_view_set_cursor (GTK_TREE_VIEW (prefs->label_tree), path, focus_col, FALSE);
- gtk_tree_view_row_activated (GTK_TREE_VIEW (prefs->label_tree), path, focus_col);
- gtk_tree_path_free (path);
- }
- }
-
- g_free (last_path);
- }
-
- label_sensitive_buttons (prefs);
- e_util_labels_free (labels);
-}
-
-static void
-jh_tree_refill (EMMailerPrefs *prefs)
-{
- GtkListStore *store;
- GSList *l, *cjh = gconf_client_get_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, NULL);
-
- store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (prefs->junk_header_tree)));
- gtk_list_store_clear (store);
-
- for (l = cjh; l; l = l->next) {
- GtkTreeIter iter;
- gchar **tokens = g_strsplit (l->data, "=", 2);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (
- store, &iter,
- JH_LIST_COLUMN_NAME , tokens[0] ? tokens[0] : "",
- JH_LIST_COLUMN_VALUE, tokens[1] ? tokens[1] : "" ,
- -1);
- g_strfreev (tokens);
- }
-
- g_slist_foreach (cjh, (GFunc) g_free, NULL);
- g_slist_free (cjh);
-}
-
-static void
-jh_add_cb (GtkWidget *widget, gpointer user_data)
-{
- EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
- GtkWidget *dialog, *l1, *l2, *entry1, *entry2, *vbox, *hbox;
- gint response;
- dialog = gtk_dialog_new_with_buttons (_("Add Custom Junk Header"), (GtkWindow *)gtk_widget_get_toplevel (widget), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
-
- vbox = gtk_vbox_new (FALSE, 6);
- hbox = gtk_hbox_new (FALSE, 0);
- l1 = gtk_label_new_with_mnemonic (_("Header Name:"));
- l2 = gtk_label_new_with_mnemonic (_("Header Value Contains:"));
- entry1 = gtk_entry_new ();
- entry2 = gtk_entry_new ();
- gtk_box_pack_start ((GtkBox *) hbox, l1, FALSE, FALSE, 6);
- gtk_box_pack_start ((GtkBox *)hbox, entry1, FALSE, FALSE, 6);
- gtk_box_pack_start ((GtkBox *)vbox, hbox, FALSE, FALSE, 6);
-
- hbox = gtk_hbox_new (FALSE, 0);
- gtk_box_pack_start ((GtkBox *)hbox, l2, FALSE, FALSE, 6);
- gtk_box_pack_start ((GtkBox *)hbox, entry2, FALSE, FALSE, 6);
- gtk_box_pack_start ((GtkBox *)vbox, hbox, FALSE, FALSE, 6);
-
- gtk_widget_show_all (vbox);
- gtk_container_add ((GtkContainer *)((GtkDialog *)dialog)->vbox, vbox);
- response = gtk_dialog_run ((GtkDialog *)dialog);
- if (response == GTK_RESPONSE_ACCEPT) {
- const gchar *name = gtk_entry_get_text ((GtkEntry *)entry1);
- const gchar *value = gtk_entry_get_text ((GtkEntry *)entry2);
- gchar *tok;
- GSList *list = gconf_client_get_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, NULL);
-
- /* FIXME: Validate the values */
-
- tok = g_strdup_printf ("%s=%s", name, value);
- list = g_slist_append (list, tok);
- gconf_client_set_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, list, NULL);
- g_slist_foreach (list, (GFunc)g_free, NULL);
-
- g_slist_free (list);
- }
- gtk_widget_destroy (dialog);
- jh_tree_refill (prefs);
-}
-
-static void
-jh_remove_cb (GtkWidget *widget, gpointer user_data)
-{
- EMMailerPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- g_return_if_fail (prefs != NULL);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->junk_header_tree));
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- gchar *name=NULL, *value=NULL;
- GSList *prev = NULL, *node, *list = gconf_client_get_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, NULL);
- gtk_tree_model_get (model, &iter, JH_LIST_COLUMN_NAME, &name, JH_LIST_COLUMN_VALUE, &value, -1);
- node = list;
- while (node) {
- gchar *test;
- gint len = strlen (name);
- test = strncmp (node->data, name, len) == 0 ? (gchar *) node->data+len:NULL;
-
- if (test) {
- test++;
- if (strcmp (test, value) == 0)
- break;
- }
-
- prev = node;
- node = node->next;
- }
-
- if (prev && !node) {
- /* Not found. So what? */
- } else if (prev && node) {
- prev->next = node->next;
- g_free (node->data);
- } else if (!prev && node) {
- list = list->next;
- g_free (node->data);
- }
-
- gconf_client_set_list (prefs->gconf, "/apps/evolution/mail/junk/custom_header", GCONF_VALUE_STRING, list, NULL);
-
- g_slist_foreach (list, (GFunc)g_free, NULL);
- g_slist_free (list);
- g_free (name);
- g_free (value);
-
- jh_tree_refill (prefs);
- }
-}
-
-static gboolean
-init_junk_tree (GtkTreeView *jh_tree, EMMailerPrefs *prefs)
-{
- GtkListStore *store;
- GtkCellRenderer *renderer;
- gint col;
-
- g_return_val_if_fail (jh_tree != NULL, FALSE);
- g_return_val_if_fail (prefs != NULL, FALSE);
-
- store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
- gtk_tree_view_set_model (GTK_TREE_VIEW (jh_tree), GTK_TREE_MODEL (store));
- g_object_unref (store);
-
- renderer = gtk_cell_renderer_text_new ();
- col = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (jh_tree), -1, _("Header"), renderer, "text", JH_LIST_COLUMN_NAME, NULL);
- g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
-
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (jh_tree), -1, _("Contains Value"), renderer, "text", JH_LIST_COLUMN_VALUE, NULL);
- g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
-
- jh_tree_refill (prefs);
-
- return TRUE;
-}
-
-static gboolean
-init_label_tree (GtkWidget *label_tree, EMMailerPrefs *prefs, gboolean locked)
-{
- GtkListStore *store;
- GtkCellRenderer *renderer;
- gint col;
-
- g_return_val_if_fail (label_tree != NULL, FALSE);
- g_return_val_if_fail (prefs != NULL, FALSE);
-
- store = gtk_list_store_new (3, GDK_TYPE_COLOR, G_TYPE_STRING, G_TYPE_STRING);
- gtk_tree_view_set_model (GTK_TREE_VIEW (label_tree), GTK_TREE_MODEL (store));
- g_object_unref (store);
-
- renderer = e_cell_renderer_color_new ();
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Color"), renderer, "color", LABEL_LIST_COLUMN_COLOR, NULL);
-
- renderer = gtk_cell_renderer_text_new ();
- col = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Tag"), renderer, "text", LABEL_LIST_COLUMN_TAG, NULL);
- g_object_set (G_OBJECT (renderer), "editable", FALSE, NULL);
- gtk_tree_view_column_set_visible (gtk_tree_view_get_column (GTK_TREE_VIEW (label_tree), col - 1), FALSE);
-
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (label_tree), -1, _("Name"), renderer, "text", LABEL_LIST_COLUMN_NAME, NULL);
- g_object_set (G_OBJECT (renderer), "editable", FALSE, NULL);
-
- if (!locked)
- g_signal_connect (label_tree, "cursor-changed", G_CALLBACK (label_tree_cursor_changed), prefs);
-
- label_tree_refill (NULL, 0, NULL, prefs);
-
- prefs->labels_change_notify_id = gconf_client_notify_add (prefs->gconf, E_UTIL_LABELS_GCONF_KEY, label_tree_refill, prefs, NULL, NULL);
-
- return TRUE;
-}
-
-static void
-label_add_cb (GtkWidget *widget, gpointer user_data)
-{
- gchar *tag;
-
- tag = e_util_labels_add_with_dlg (GTK_WINDOW (gtk_widget_get_toplevel (widget)), NULL);
-
- g_free (tag);
-}
-
-static void
-label_remove_cb (GtkWidget *widget, gpointer user_data)
-{
- EMMailerPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- g_return_if_fail (prefs != NULL);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->label_tree));
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- gchar *tag = NULL;
-
- gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1);
-
- if (tag && !e_util_labels_is_system (tag))
- e_util_labels_remove (tag);
-
- g_free (tag);
- }
-}
-
-static void
-label_edit_cb (GtkWidget *widget, gpointer user_data)
-{
- EMMailerPrefs *prefs = user_data;
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
-
- g_return_if_fail (prefs != NULL);
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (prefs->label_tree));
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- gchar *tag = NULL;
-
- gtk_tree_model_get (model, &iter, LABEL_LIST_COLUMN_TAG, &tag, -1);
-
- if (tag) {
- gchar *str = e_util_labels_add_with_dlg (GTK_WINDOW (gtk_widget_get_toplevel (widget)), tag);
-
- g_free (str);
- }
-
- g_free (tag);
- }
-}
-
-static void
-emmp_header_remove_sensitivity (EMMailerPrefs *prefs)
-{
- GtkTreeIter iter;
- GtkTreeSelection *selection = gtk_tree_view_get_selection (prefs->header_list);
- gboolean is_default;
-
- /* remove button should be sensitive if the currenlty selected entry in the list view
- is not a default header. if there are no entries, or none is selected, it should be
- disabled
- */
- if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
- gtk_tree_model_get (GTK_TREE_MODEL (prefs->header_list_store), &iter,
- HEADER_LIST_IS_DEFAULT_COLUMN, &is_default,
- -1);
- if (is_default)
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->remove_header), FALSE);
- else
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->remove_header), TRUE);
- } else {
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->remove_header), FALSE);
- }
-}
-
-static gboolean
-emmp_header_is_valid (const gchar *header)
-{
- gint len = g_utf8_strlen (header, -1);
-
- if (header[0] == 0
- || g_utf8_strchr (header, len, ':') != NULL
- || g_utf8_strchr (header, len, ' ') != NULL)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-emmp_header_add_sensitivity (EMMailerPrefs *prefs)
-{
- const gchar *entry_contents;
- GtkTreeIter iter;
- gboolean valid;
-
- /* the add header button should be sensitive if the text box contains
- a valid header string, that is not a duplicate with something already
- in the list view
- */
- entry_contents = gtk_entry_get_text (GTK_ENTRY (prefs->entry_header));
- if (!emmp_header_is_valid (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_HEADER_COLUMN, &header_name,
- -1);
- if (g_ascii_strcasecmp (header_name, entry_contents) == 0) {
- 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);
- }
-
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->add_header), TRUE);
-}
-
-static void
-emmp_save_headers (EMMailerPrefs *prefs)
-{
- GSList *header_list;
- GtkTreeIter iter;
- gboolean valid;
-
- /* Headers */
- header_list = NULL;
- valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (prefs->header_list_store), &iter);
- while (valid) {
- struct _EMMailerPrefsHeader h;
- gboolean enabled;
- gchar *xml;
-
- gtk_tree_model_get (GTK_TREE_MODEL (prefs->header_list_store), &iter,
- HEADER_LIST_HEADER_COLUMN, &h.name,
- HEADER_LIST_ENABLED_COLUMN, &enabled,
- -1);
- h.enabled = enabled;
-
- if ((xml = em_mailer_prefs_header_to_xml (&h)))
- 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_foreach (header_list, (GFunc) g_free, NULL);
- g_slist_free (header_list);
-}
-
-static void
-emmp_header_list_enabled_toggled (GtkCellRendererToggle *cell, const gchar *path_string, EMMailerPrefs *prefs)
-{
- 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);
-
- emmp_save_headers (prefs);
-}
-
-static void
-emmp_header_add_header (GtkWidget *widget, EMMailerPrefs *prefs)
-{
- GtkTreeModel *model = GTK_TREE_MODEL (prefs->header_list_store);
- GtkTreeIter iter;
- const gchar *text = gtk_entry_get_text (prefs->entry_header);
-
- g_strstrip ((gchar *)text);
-
- if (text && (strlen (text)>0)) {
- gtk_list_store_append (GTK_LIST_STORE (model), &iter);
- gtk_list_store_set (GTK_LIST_STORE (model), &iter,
- HEADER_LIST_NAME_COLUMN, text,
- HEADER_LIST_ENABLED_COLUMN, TRUE,
- HEADER_LIST_HEADER_COLUMN, text,
- HEADER_LIST_IS_DEFAULT_COLUMN, FALSE,
- -1);
- gtk_entry_set_text (prefs->entry_header, "");
- emmp_header_remove_sensitivity (prefs);
- emmp_header_add_sensitivity (prefs);
-
- emmp_save_headers (prefs);
- }
-}
-
-static void
-emmp_header_remove_header (GtkWidget *button, gpointer user_data)
-{
- EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
- GtkTreeModel *model = GTK_TREE_MODEL (prefs->header_list_store);
- GtkTreeSelection *selection = gtk_tree_view_get_selection (prefs->header_list);
- GtkTreeIter iter;
-
- if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
- return;
-
- gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
- emmp_header_remove_sensitivity (prefs);
-
- emmp_save_headers (prefs);
-}
-
-static void
-emmp_header_list_row_selected (GtkTreeSelection *selection, gpointer user_data)
-{
- EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
-
- emmp_header_remove_sensitivity (prefs);
-}
-
-static void
-emmp_header_entry_changed (GtkWidget *entry, gpointer user_data)
-{
- EMMailerPrefs *prefs = (EMMailerPrefs *) user_data;
-
- emmp_header_add_sensitivity (prefs);
-}
-
-static void
-mark_seen_timeout_changed (GtkSpinButton *spin, EMMailerPrefs *prefs)
-{
- gint timeout;
-
- timeout = (gint) (gtk_spin_button_get_value (prefs->timeout) * 1000.0);
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/display/mark_seen_timeout", timeout, NULL);
-}
-
-static void
-address_compress_count_changed (GtkSpinButton *spin, EMMailerPrefs *prefs)
-{
- gint count;
-
- count = (gint) gtk_spin_button_get_value (prefs->address_count);
-
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/display/address_count", count, NULL);
-}
-
-static void
-mlimit_count_changed (GtkSpinButton *spin, EMMailerPrefs *prefs)
-{
- gint count;
-
- count = (gint) gtk_spin_button_get_value (prefs->mlimit_count);
-
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/display/message_text_part_limit", count, NULL);
-}
-
-static void
-spin_button_init (EMMailerPrefs *prefs, GtkSpinButton *spin, const gchar *key, gfloat div, GCallback value_changed)
-{
- GError *err = NULL;
- double min, max;
- gchar *mkey, *p;
- gint val;
-
- gtk_spin_button_get_range (spin, &min, &max);
-
- mkey = g_alloca (strlen (key) + 5);
- p = g_stpcpy (mkey, key);
- *p++ = '_';
-
- /* see if the admin locked down the min value */
- strcpy (p, "min");
- val = gconf_client_get_int (prefs->gconf, mkey, &err);
- if (err == NULL)
- g_clear_error (&err);
- else
- min = (1.0 * val) / div;
-
- /* see if the admin locked down the max value */
- strcpy (p, "max");
- val = gconf_client_get_int (prefs->gconf, mkey, &err);
- if (err == NULL)
- g_clear_error (&err);
- else
- max = (1.0 * val) / div;
-
- gtk_spin_button_set_range (spin, min, max);
-
- /* get the value */
- val = gconf_client_get_int (prefs->gconf, key, NULL);
- gtk_spin_button_set_value (spin, (1.0 * val) / div);
-
- if (value_changed) {
- g_object_set_data ((GObject *) spin, "key", (gpointer) key);
- g_signal_connect (spin, "value-changed", value_changed, prefs);
- }
-
- if (!gconf_client_key_is_writable (prefs->gconf, key, NULL))
- gtk_widget_set_sensitive ((GtkWidget *) spin, FALSE);
-}
-
-static void
-toggle_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs)
-{
- const gchar *key;
-
- key = g_object_get_data ((GObject *) toggle, "key");
- gconf_client_set_bool (prefs->gconf, key, gtk_toggle_button_get_active (toggle), NULL);
-}
-
-static void
-photo_toggle_changed (GtkToggleButton *toggle, EMMailerPrefs *prefs)
-{
- toggle_button_toggled (toggle, prefs);
- if (gtk_toggle_button_get_active (toggle))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->photo_local, TRUE);
- else
- gtk_widget_set_sensitive ((GtkWidget *) prefs->photo_local, FALSE);
-}
-
-static void
-junk_book_lookup_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs)
-{
- toggle_button_toggled (toggle, prefs);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->junk_lookup_local_only), gtk_toggle_button_get_active (toggle));
-}
-
-static void
-custom_junk_button_toggled (GtkToggleButton *toggle, EMMailerPrefs *prefs)
-{
- toggle_button_toggled (toggle, prefs);
- if (gtk_toggle_button_get_active (toggle)) {
- gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_remove, TRUE);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_add, TRUE);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_tree, TRUE);
- } else {
- gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_tree, FALSE);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_add, FALSE);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->junk_header_remove, FALSE);
- }
-
-}
-
-static void
-custom_font_changed (GtkToggleButton *toggle, EMMailerPrefs *prefs)
-{
- gboolean use_custom;
-
- use_custom = !gtk_toggle_button_get_active (toggle);
-
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->font_fixed), use_custom);
- gtk_widget_set_sensitive (GTK_WIDGET (prefs->font_variable), use_custom);
-
- gconf_client_set_bool (prefs->gconf, "/apps/evolution/mail/display/fonts/use_custom", use_custom, NULL);
-}
-
-static void
-font_changed (GtkFontButton *font_button, EMMailerPrefs *prefs)
-{
- const gchar *key;
- const gchar *font_name;
-
- key = g_object_get_data (G_OBJECT (font_button), "key");
- font_name = gtk_font_button_get_font_name (font_button);
- gconf_client_set_string (prefs->gconf, key, font_name, NULL);
-}
-
-static void
-toggle_button_init (EMMailerPrefs *prefs, GtkToggleButton *toggle, gint not, const gchar *key, GCallback toggled)
-{
- gboolean bool;
-
- bool = gconf_client_get_bool (prefs->gconf, key, NULL);
- gtk_toggle_button_set_active (toggle, not ? !bool : bool);
-
- if (toggled) {
- g_object_set_data ((GObject *) toggle, "key", (gpointer) key);
- g_signal_connect (toggle, "toggled", toggled, prefs);
- }
-
- if (!gconf_client_key_is_writable (prefs->gconf, key, NULL))
- gtk_widget_set_sensitive ((GtkWidget *) toggle, FALSE);
-}
-
-static void
-charset_activate (GtkWidget *item, EMMailerPrefs *prefs)
-{
- GtkWidget *menu;
- gchar *string;
-
- menu = gtk_option_menu_get_menu (prefs->charset);
- if (!(string = e_charset_picker_get_charset (menu)))
- string = g_strdup (camel_iconv_locale_charset ());
-
- gconf_client_set_string (prefs->gconf, "/apps/evolution/mail/display/charset", string, NULL);
- g_free (string);
-}
-
-static void
-charset_menu_init (EMMailerPrefs *prefs)
-{
- GtkWidget *menu, *item;
- GList *items;
- gchar *buf;
-
- buf = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/charset", NULL);
- menu = e_charset_picker_new (buf && *buf ? buf : camel_iconv_locale_charset ());
- gtk_option_menu_set_menu (prefs->charset, GTK_WIDGET (menu));
- g_free (buf);
-
- items = GTK_MENU_SHELL (menu)->children;
- while (items) {
- item = items->data;
- g_signal_connect (item, "activate", G_CALLBACK (charset_activate), prefs);
- items = items->next;
- }
-
- if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/charset", NULL))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->charset, FALSE);
-}
-
-static void
-trash_days_changed (GtkComboBox *combobox, EMMailerPrefs *prefs)
-{
- gint idx;
-
- idx = gtk_combo_box_get_active (combobox);
- g_return_if_fail (idx >= 0 && idx < G_N_ELEMENTS (empty_trash_frequency));
-
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/trash/empty_on_exit_days", empty_trash_frequency [idx].days, NULL);
-}
-
-static void
-emmp_empty_trash_init (EMMailerPrefs *prefs)
-{
- gint locked, days, hist = 0, i;
-
- toggle_button_init (prefs, prefs->empty_trash, FALSE,
- "/apps/evolution/mail/trash/empty_on_exit",
- G_CALLBACK (toggle_button_toggled));
-
- days = gconf_client_get_int(prefs->gconf, "/apps/evolution/mail/trash/empty_on_exit_days", NULL);
-
- gtk_list_store_clear (GTK_LIST_STORE (gtk_combo_box_get_model (prefs->empty_trash_days)));
- for (i = 0; i < G_N_ELEMENTS (empty_trash_frequency); i++) {
- if (days >= empty_trash_frequency[i].days)
- hist = i;
-
- gtk_combo_box_append_text (prefs->empty_trash_days, _(empty_trash_frequency[i].label));
- }
-
- g_signal_connect (prefs->empty_trash_days, "changed", G_CALLBACK (trash_days_changed), prefs);
- gtk_combo_box_set_active (prefs->empty_trash_days, hist);
-
- locked = !gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/trash/empty_on_exit_days", NULL);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->empty_trash_days, !locked);
-}
-
-static void
-junk_days_changed (GtkComboBox *combobox, EMMailerPrefs *prefs)
-{
- gint idx;
-
- idx = gtk_combo_box_get_active (combobox);
- g_return_if_fail (idx >= 0 && idx < G_N_ELEMENTS (empty_trash_frequency));
-
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/junk/empty_on_exit_days", empty_trash_frequency[idx].days, NULL);
-}
-
-static void
-emmp_empty_junk_init (EMMailerPrefs *prefs)
-{
- gint locked, days, hist = 0, i;
-
- toggle_button_init (prefs, prefs->empty_junk, FALSE,
- "/apps/evolution/mail/junk/empty_on_exit",
- G_CALLBACK (toggle_button_toggled));
-
- days = gconf_client_get_int(prefs->gconf, "/apps/evolution/mail/junk/empty_on_exit_days", NULL);
-
- gtk_list_store_clear (GTK_LIST_STORE (gtk_combo_box_get_model (prefs->empty_junk_days)));
- for (i = 0; i < G_N_ELEMENTS (empty_trash_frequency); i++) {
- if (days >= empty_trash_frequency[i].days)
- hist = i;
-
- gtk_combo_box_append_text (prefs->empty_junk_days, _(empty_trash_frequency[i].label));
- }
-
- g_signal_connect (prefs->empty_junk_days, "changed", G_CALLBACK (junk_days_changed), prefs);
- gtk_combo_box_set_active (prefs->empty_junk_days, hist);
-
- locked = !gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/junk/empty_on_exit_days", NULL);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->empty_junk_days, !locked);
-}
-
-static void
-http_images_changed (GtkWidget *widget, EMMailerPrefs *prefs)
-{
- gint when;
-
- if (gtk_toggle_button_get_active (prefs->images_always))
- when = MAIL_CONFIG_HTTP_ALWAYS;
- else if (gtk_toggle_button_get_active (prefs->images_sometimes))
- when = MAIL_CONFIG_HTTP_SOMETIMES;
- else
- when = MAIL_CONFIG_HTTP_NEVER;
-
- gconf_client_set_int (prefs->gconf, "/apps/evolution/mail/display/load_http_images", when, NULL);
-}
-
-static GtkWidget *
-emmp_widget_glade(EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget *old, gpointer data)
-{
- EMMailerPrefs *prefs = data;
-
- return glade_xml_get_widget(prefs->gui, item->label);
-}
-
-/* plugin meta-data */
-static EMConfigItem emmp_items[] = {
- { E_CONFIG_BOOK, (gchar *) "", (gchar *) "preferences_toplevel", emmp_widget_glade },
- { E_CONFIG_PAGE, (gchar *) "00.general", (gchar *) "vboxGeneral", emmp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "00.general/00.fonts", (gchar *) "vboxMessageFonts", emmp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "00.general/10.display", (gchar *) "vboxMessageDisplay", emmp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "00.general/20.delete", (gchar *) "vboxDeletingMail", emmp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "00.general/30.newmail", (gchar *) "vboxNewMailNotify", emmp_widget_glade },
- { E_CONFIG_PAGE, (gchar *) "10.html", (gchar *) "vboxHtmlMail", emmp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "10.html/00.general", (gchar *) "vbox173", emmp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "10.html/10.images", (gchar *) "vbox190", emmp_widget_glade },
- { E_CONFIG_PAGE, (gchar *) "20.labels", (gchar *) "frameColours", emmp_widget_glade },
- /* this is a table, so we can't use it { E_CONFIG_SECTION, "20.labels/00.labels", "tableColours", emmp_widget_glade }, */
- { E_CONFIG_PAGE, (gchar *) "30.headers", (gchar *) "vboxHeaderTab", emmp_widget_glade },
- /* no subvbox for section { E_CONFIG_PAGE, "30.headers/00.headers", "vbox199", emmp_widget_glade }, */
- { E_CONFIG_PAGE, (gchar *) "40.junk", (gchar *) "vbox161", emmp_widget_glade },
- /* no subvbox for section { E_CONFIG_SECTION, "40.junk/00.general", xxx, emmp_widget_glade } */
- { E_CONFIG_SECTION, (gchar *) "40.junk/10.options", (gchar *) "vbox204", emmp_widget_glade },
-};
-
-static void
-emmp_free(EConfig *ec, GSList *items, gpointer data)
-{
- /* the prefs data is freed automagically */
-
- g_slist_free(items);
-}
-
-static void
-junk_plugin_changed (GtkWidget *combo, EMMailerPrefs *prefs)
-{
- gchar *def_plugin = gtk_combo_box_get_active_text(GTK_COMBO_BOX (combo));
- const GList *plugins = mail_session_get_junk_plugins();
-
- gconf_client_set_string (prefs->gconf, "/apps/evolution/mail/junk/default_plugin", def_plugin, NULL);
- while (plugins) {
- struct _EMJunkHookItem *item = plugins->data;;
-
- if (item->plugin_name && def_plugin && !strcmp (item->plugin_name, def_plugin)) {
- gboolean status;
-
- session->junk_plugin = CAMEL_JUNK_PLUGIN (&(item->csp));
- status = e_plugin_invoke (item->hook->hook.plugin, item->validate_binary, NULL) != NULL;
- if ((gboolean)status == TRUE) {
- gchar *text, *html;
- gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-info", GTK_ICON_SIZE_MENU);
- text = g_strdup_printf (_("%s plugin is available and the binary is installed."), item->plugin_name);
- html = g_strdup_printf ("<i>%s</i>", text);
- gtk_label_set_markup (prefs->plugin_status, html);
- g_free (html);
- g_free (text);
- } else {
- gchar *text, *html;
- gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-warning", GTK_ICON_SIZE_MENU);
- text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), item->plugin_name);
- html = g_strdup_printf ("<i>%s</i>", text);
- gtk_label_set_markup (prefs->plugin_status, html);
- g_free (html);
- g_free (text);
- }
- break;
- }
- plugins = plugins->next;
- }
-}
-
-static void
-junk_plugin_setup (GtkWidget *combo, EMMailerPrefs *prefs)
-{
- gint index = 0;
- gboolean def_set = FALSE;
- const GList *plugins = mail_session_get_junk_plugins();
- gchar *pdefault = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/junk/default_plugin", NULL);
-
- if (!plugins || !g_list_length ((GList *)plugins)) {
- gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("No Junk plugin available"));
- gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
- gtk_widget_set_sensitive (GTK_WIDGET (combo), FALSE);
- gtk_widget_hide (GTK_WIDGET (prefs->plugin_image));
- gtk_widget_hide (GTK_WIDGET (prefs->plugin_status));
- gtk_image_set_from_stock (prefs->plugin_image, NULL, 0);
- g_free (pdefault);
-
- return;
- }
-
- while (plugins) {
- struct _EMJunkHookItem *item = plugins->data;;
-
- gtk_combo_box_append_text (GTK_COMBO_BOX (combo), item->plugin_name);
- if (!def_set && pdefault && item->plugin_name && !strcmp(pdefault, item->plugin_name)) {
- gboolean status;
-
- def_set = TRUE;
- gtk_combo_box_set_active (GTK_COMBO_BOX (combo), index);
- status = e_plugin_invoke (item->hook->hook.plugin, item->validate_binary, NULL) != NULL;
- if (status) {
- gchar *text, *html;
- gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-info", GTK_ICON_SIZE_MENU);
- /* May be a better text */
- text = g_strdup_printf (_("%s plugin is available and the binary is installed."), item->plugin_name);
- html = g_strdup_printf ("<i>%s</i>", text);
- gtk_label_set_markup (prefs->plugin_status, html);
- g_free (html);
- g_free (text);
- } else {
- gchar *text, *html;
- gtk_image_set_from_stock (prefs->plugin_image, "gtk-dialog-warning", GTK_ICON_SIZE_MENU);
- /* May be a better text */
- text = g_strdup_printf (_("%s plugin is not available. Please check whether the package is installed."), item->plugin_name);
- html = g_strdup_printf ("<i>%s</i>", text);
- gtk_label_set_markup (prefs->plugin_status, html);
- g_free (html);
- g_free (text);
- }
- }
- plugins = plugins->next;
- index++;
- }
-
- g_signal_connect (combo, "changed", G_CALLBACK(junk_plugin_changed), prefs);
- g_free (pdefault);
-}
-
-GtkWidget *
-create_combo_text_widget (void) {
- return gtk_combo_box_new_text ();
-}
-
-static void
-em_mailer_prefs_construct (EMMailerPrefs *prefs)
-{
- GSList *header_config_list, *header_add_list, *p;
- GHashTable *default_header_hash;
- GtkWidget *toplevel;
- GtkTreeSelection *selection;
- GtkCellRenderer *renderer;
- GtkTreeIter iter;
- gchar *font, *buf;
- GladeXML *gui;
- gboolean locked;
- gint val, i;
- EMConfig *ec;
- EMConfigTargetPrefs *target;
- GSList *l;
- gchar *gladefile;
-
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-config.glade",
- NULL);
- gui = glade_xml_new (gladefile, "preferences_toplevel", NULL);
- g_free (gladefile);
-
- prefs->gui = gui;
-
- /** @HookPoint-EMConfig: Mail Preferences Page
- * @Id: org.gnome.evolution.mail.prefs
- * @Type: E_CONFIG_BOOK
- * @Class: org.gnome.evolution.mail.config:1.0
- * @Target: EMConfigTargetPrefs
- *
- * The main mail preferences page.
- */
- ec = em_config_new(E_CONFIG_BOOK, "org.gnome.evolution.mail.prefs");
- l = NULL;
- for (i=0;i<sizeof(emmp_items)/sizeof(emmp_items[0]);i++)
- l = g_slist_prepend(l, &emmp_items[i]);
- e_config_add_items((EConfig *)ec, l, NULL, NULL, emmp_free, prefs);
-
- /* General tab */
-
- /* Message Display */
- prefs->timeout_toggle = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkMarkTimeout"));
- toggle_button_init (prefs, prefs->timeout_toggle, FALSE,
- "/apps/evolution/mail/display/mark_seen",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->timeout = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "spinMarkTimeout"));
- spin_button_init (prefs, prefs->timeout,
- "/apps/evolution/mail/display/mark_seen_timeout",
- 1000.0, G_CALLBACK (mark_seen_timeout_changed));
-
- prefs->mlimit_toggle = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "mlimit_checkbutton"));
- toggle_button_init (prefs, prefs->mlimit_toggle, FALSE,
- "/apps/evolution/mail/display/force_message_limit",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->magic_spacebar = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "magic_spacebar_checkbox"));
- toggle_button_init (prefs, prefs->magic_spacebar, FALSE,
- "/apps/evolution/mail/display/magic_spacebar",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->mlimit_count = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "mlimit_spin"));
- spin_button_init (prefs, prefs->mlimit_count,
- "/apps/evolution/mail/display/message_text_part_limit",
- 1, G_CALLBACK (mlimit_count_changed));
-
- prefs->address_toggle = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "address_checkbox"));
- toggle_button_init (prefs, prefs->address_toggle, FALSE,
- "/apps/evolution/mail/display/address_compress",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->address_count = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "address_spin"));
- spin_button_init (prefs, prefs->address_count,
- "/apps/evolution/mail/display/address_count",
- 1, G_CALLBACK (address_compress_count_changed));
-
- prefs->charset = GTK_OPTION_MENU (glade_xml_get_widget (gui, "omenuCharset"));
- charset_menu_init (prefs);
-
- prefs->citation_highlight = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkHighlightCitations"));
- toggle_button_init (prefs, prefs->citation_highlight, FALSE,
- "/apps/evolution/mail/display/mark_citations",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->citation_color = GTK_COLOR_BUTTON (glade_xml_get_widget (gui, "colorButtonHighlightCitations"));
- buf = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/citation_colour", NULL);
- color_button_set_color (prefs->citation_color, buf ? buf : "#737373");
- g_signal_connect (prefs->citation_color, "color-set", G_CALLBACK (citation_color_set), prefs);
- if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/citation_colour", NULL))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->citation_color, FALSE);
- g_free (buf);
-
- prefs->enable_search_folders = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkEnableSearchFolders"));
- toggle_button_init (prefs, prefs->enable_search_folders, FALSE,
- "/apps/evolution/mail/display/enable_vfolders",
- G_CALLBACK (toggle_button_toggled));
-
- /* Deleting Mail */
- prefs->empty_trash = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkEmptyTrashOnExit"));
- prefs->empty_trash_days = GTK_COMBO_BOX (glade_xml_get_widget (gui, "comboboxEmptyTrashDays"));
- emmp_empty_trash_init (prefs);
-
- prefs->confirm_expunge = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkConfirmExpunge"));
- toggle_button_init (prefs, prefs->confirm_expunge, FALSE,
- "/apps/evolution/mail/prompts/expunge",
- G_CALLBACK (toggle_button_toggled));
-
- /* Mail Fonts */
- font = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/fonts/monospace", NULL);
- prefs->font_fixed = GTK_FONT_BUTTON (glade_xml_get_widget (gui, "FontFixed"));
- gtk_font_button_set_font_name (prefs->font_fixed, font);
- g_free (font);
- g_object_set_data ((GObject *) prefs->font_fixed, "key", (gpointer) "/apps/evolution/mail/display/fonts/monospace");
- g_signal_connect (prefs->font_fixed, "font-set", G_CALLBACK (font_changed), prefs);
- if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/fonts/monospace", NULL))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->font_fixed, FALSE);
-
- font = gconf_client_get_string (prefs->gconf, "/apps/evolution/mail/display/fonts/variable", NULL);
- prefs->font_variable = GTK_FONT_BUTTON (glade_xml_get_widget (gui, "FontVariable"));
- gtk_font_button_set_font_name (prefs->font_variable, font);
- g_free (font);
- g_object_set_data ((GObject *) prefs->font_variable, "key", (gpointer) "/apps/evolution/mail/display/fonts/variable");
- g_signal_connect (prefs->font_variable, "font-set", G_CALLBACK (font_changed), prefs);
- if (!gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/fonts/variable", NULL))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->font_variable, FALSE);
-
- prefs->font_share = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "radFontUseSame"));
- toggle_button_init (prefs, prefs->font_share, TRUE,
- "/apps/evolution/mail/display/fonts/use_custom",
- G_CALLBACK (custom_font_changed));
- custom_font_changed (prefs->font_share, prefs);
-
- /* HTML Mail tab */
-
- /* Loading Images */
- locked = !gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/load_http_images", NULL);
-
- val = gconf_client_get_int (prefs->gconf, "/apps/evolution/mail/display/load_http_images", NULL);
- prefs->images_never = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "radImagesNever"));
- gtk_toggle_button_set_active (prefs->images_never, val == MAIL_CONFIG_HTTP_NEVER);
- if (locked)
- gtk_widget_set_sensitive ((GtkWidget *) prefs->images_never, FALSE);
-
- prefs->images_sometimes = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "radImagesSometimes"));
- gtk_toggle_button_set_active (prefs->images_sometimes, val == MAIL_CONFIG_HTTP_SOMETIMES);
- if (locked)
- gtk_widget_set_sensitive ((GtkWidget *) prefs->images_sometimes, FALSE);
-
- prefs->images_always = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "radImagesAlways"));
- gtk_toggle_button_set_active (prefs->images_always, val == MAIL_CONFIG_HTTP_ALWAYS);
- if (locked)
- gtk_widget_set_sensitive ((GtkWidget *) prefs->images_always, FALSE);
-
- g_signal_connect (prefs->images_never, "toggled", G_CALLBACK (http_images_changed), prefs);
- g_signal_connect (prefs->images_sometimes, "toggled", G_CALLBACK (http_images_changed), prefs);
- g_signal_connect (prefs->images_always, "toggled", G_CALLBACK (http_images_changed), prefs);
-
- prefs->show_animated = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkShowAnimatedImages"));
- toggle_button_init (prefs, prefs->show_animated, FALSE,
- "/apps/evolution/mail/display/animate_images",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->prompt_unwanted_html = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkPromptWantHTML"));
- toggle_button_init (prefs, prefs->prompt_unwanted_html, FALSE,
- "/apps/evolution/mail/prompts/unwanted_html",
- G_CALLBACK (toggle_button_toggled));
-
- /* Labels... */
- locked = !gconf_client_key_is_writable (prefs->gconf, E_UTIL_LABELS_GCONF_KEY, NULL);
- prefs->label_add = glade_xml_get_widget (gui, "labelAdd");
- prefs->label_edit = glade_xml_get_widget (gui, "labelEdit");
- prefs->label_remove = glade_xml_get_widget (gui, "labelRemove");
- prefs->label_tree = glade_xml_get_widget (gui, "labelTree");
-
- gtk_widget_set_sensitive (prefs->label_add, !locked);
- gtk_widget_set_sensitive (prefs->label_remove, !locked);
- gtk_widget_set_sensitive (prefs->label_edit, !locked);
- gtk_widget_set_sensitive (prefs->label_tree, !locked);
-
- init_label_tree (prefs->label_tree, prefs, locked);
-
- if (!locked) {
- g_signal_connect (G_OBJECT (prefs->label_add), "clicked", G_CALLBACK (label_add_cb), prefs);
- g_signal_connect (G_OBJECT (prefs->label_remove), "clicked", G_CALLBACK (label_remove_cb), prefs);
- g_signal_connect (G_OBJECT (prefs->label_edit), "clicked", G_CALLBACK (label_edit_cb), prefs);
- }
-
- /* headers */
- locked = !gconf_client_key_is_writable (prefs->gconf, "/apps/evolution/mail/display/headers", NULL);
-
- prefs->photo_show= GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "photo_show"));
- toggle_button_init (prefs, prefs->photo_show, FALSE,
- "/apps/evolution/mail/display/sender_photo",
- G_CALLBACK (photo_toggle_changed));
- prefs->photo_local = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "photo_local"));
- toggle_button_init (prefs, prefs->photo_local, FALSE,
- "/apps/evolution/mail/display/photo_local",
- G_CALLBACK (toggle_button_toggled));
- if (!gtk_toggle_button_get_active (prefs->photo_show))
- gtk_widget_set_sensitive ((GtkWidget *) prefs->photo_local, FALSE);
-
- /* always de-sensitised until the user types something in the entry */
- prefs->add_header = GTK_BUTTON (glade_xml_get_widget (gui, "cmdHeadersAdd"));
- gtk_widget_set_sensitive ((GtkWidget *) prefs->add_header, FALSE);
-
- /* always de-sensitised until the user selects a header in the list */
- prefs->remove_header = GTK_BUTTON (glade_xml_get_widget (gui, "cmdHeadersRemove"));
- gtk_widget_set_sensitive ((GtkWidget *) prefs->remove_header, FALSE);
-
- prefs->entry_header = GTK_ENTRY (glade_xml_get_widget (gui, "txtHeaders"));
- gtk_widget_set_sensitive ((GtkWidget *) prefs->entry_header, !locked);
-
- prefs->header_list = GTK_TREE_VIEW (glade_xml_get_widget (gui, "treeHeaders"));
- gtk_widget_set_sensitive ((GtkWidget *) prefs->header_list, !locked);
-
- selection = gtk_tree_view_get_selection (prefs->header_list);
- g_signal_connect (selection, "changed", G_CALLBACK (emmp_header_list_row_selected), prefs);
- g_signal_connect (prefs->entry_header, "changed", G_CALLBACK (emmp_header_entry_changed), prefs);
- g_signal_connect (prefs->entry_header, "activate", G_CALLBACK (emmp_header_add_header), prefs);
- /* initialise the tree with appropriate headings */
- prefs->header_list_store = gtk_list_store_newv (HEADER_LIST_N_COLUMNS, col_types);
- g_signal_connect (prefs->add_header, "clicked", G_CALLBACK (emmp_header_add_header), prefs);
- g_signal_connect (prefs->remove_header, "clicked", G_CALLBACK (emmp_header_remove_header), prefs);
- gtk_tree_view_set_model (prefs->header_list, GTK_TREE_MODEL (prefs->header_list_store));
-
- renderer = gtk_cell_renderer_toggle_new ();
- g_object_set (renderer, "activatable", TRUE, NULL);
- g_signal_connect (renderer, "toggled", G_CALLBACK (emmp_header_list_enabled_toggled), prefs);
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (prefs->header_list), -1,
- "Enabled", renderer,
- "active", HEADER_LIST_ENABLED_COLUMN,
- NULL);
- renderer = gtk_cell_renderer_text_new ();
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (prefs->header_list), -1,
- "Name", renderer,
- "text", HEADER_LIST_NAME_COLUMN,
- NULL);
-
- /* populated the listview with entries; firstly we add all the default headers, and then
- we add read header configuration out of gconf. If a header in gconf is a default header,
- we update the enabled flag accordingly
- */
- header_add_list = NULL;
- default_header_hash = g_hash_table_new (g_str_hash, g_str_equal);
- for (i = 0; i < G_N_ELEMENTS (default_headers); i++) {
- struct _EMMailerPrefsHeader *h;
-
- h = g_malloc (sizeof (struct _EMMailerPrefsHeader));
- h->is_default = TRUE;
- h->name = g_strdup (default_headers[i]);
- h->enabled = strcmp ((gchar *)default_headers[i], "x-evolution-mailer") != 0;
- g_hash_table_insert (default_header_hash, (gpointer) default_headers[i], h);
- header_add_list = g_slist_append (header_add_list, h);
- }
-
- /* read stored headers 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) {
- struct _EMMailerPrefsHeader *h, *def;
- gchar *xml = (gchar *) p->data;
-
- h = em_mailer_prefs_header_from_xml (xml);
- if (h) {
- def = g_hash_table_lookup (default_header_hash, h->name);
- if (def) {
- def->enabled = h->enabled;
- em_mailer_prefs_header_free (h);
- } else {
- h->is_default = FALSE;
- header_add_list = g_slist_append (header_add_list, h);
- }
- }
-
- p = p->next;
- }
-
- g_hash_table_destroy (default_header_hash);
- g_slist_foreach (header_config_list, (GFunc) g_free, NULL);
- g_slist_free (header_config_list);
-
- p = header_add_list;
- while (p) {
- struct _EMMailerPrefsHeader *h = (struct _EMMailerPrefsHeader *) p->data;
- const gchar *name;
-
- if (g_ascii_strcasecmp (h->name, EM_FORMAT_HEADER_XMAILER) == 0)
- name = _("Mailer");
- else
- name = _(h->name);
-
- 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_ENABLED_COLUMN, h->enabled,
- HEADER_LIST_IS_DEFAULT_COLUMN, h->is_default,
- HEADER_LIST_HEADER_COLUMN, h->name,
- -1);
-
- em_mailer_prefs_header_free (h);
- p = p->next;
- }
-
- g_slist_free (header_add_list);
-
- /* Junk prefs */
- prefs->check_incoming = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkCheckIncomingMail"));
- toggle_button_init (prefs, prefs->check_incoming, FALSE,
- "/apps/evolution/mail/junk/check_incoming",
- G_CALLBACK (toggle_button_toggled));
-
- prefs->empty_junk = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "junk_empty_check"));
- prefs->empty_junk_days = GTK_COMBO_BOX (glade_xml_get_widget (gui, "junk_empty_combobox"));
- emmp_empty_junk_init (prefs);
-
- prefs->default_junk_plugin = GTK_COMBO_BOX (glade_xml_get_widget (gui, "default_junk_plugin"));
- prefs->plugin_status = GTK_LABEL (glade_xml_get_widget (gui, "plugin_status"));
- prefs->plugin_image = GTK_IMAGE (glade_xml_get_widget (gui, "plugin_image"));
- junk_plugin_setup (GTK_WIDGET (prefs->default_junk_plugin), prefs);
-
- prefs->junk_header_check = (GtkToggleButton *)glade_xml_get_widget (gui, "junk_header_check");
- prefs->junk_header_tree = (GtkTreeView *)glade_xml_get_widget (gui, "junk_header_tree");
- prefs->junk_header_add = (GtkButton *)glade_xml_get_widget (gui, "junk_header_add");
- prefs->junk_header_remove = (GtkButton *)glade_xml_get_widget (gui, "junk_header_remove");
- prefs->junk_book_lookup = (GtkToggleButton *)glade_xml_get_widget (gui, "lookup_book");
- prefs->junk_lookup_local_only = (GtkToggleButton *)glade_xml_get_widget (gui, "junk_lookup_local_only");
- toggle_button_init (prefs, prefs->junk_book_lookup, FALSE,
- "/apps/evolution/mail/junk/lookup_addressbook",
- G_CALLBACK (junk_book_lookup_button_toggled));
-
- toggle_button_init (prefs, prefs->junk_lookup_local_only, FALSE,
- "/apps/evolution/mail/junk/lookup_addressbook_local_only",
- G_CALLBACK (toggle_button_toggled));
-
- junk_book_lookup_button_toggled (prefs->junk_book_lookup, prefs);
-
- init_junk_tree ((GtkTreeView *)prefs->junk_header_tree, prefs);
- toggle_button_init (prefs, prefs->junk_header_check, FALSE,
- "/apps/evolution/mail/junk/check_custom_header",
- G_CALLBACK (custom_junk_button_toggled));
-
- custom_junk_button_toggled (prefs->junk_header_check, prefs);
- jh_tree_refill (prefs);
- g_signal_connect (G_OBJECT (prefs->junk_header_add), "clicked", G_CALLBACK (jh_add_cb), prefs);
- g_signal_connect (G_OBJECT (prefs->junk_header_remove), "clicked", G_CALLBACK (jh_remove_cb), prefs);
-
- /* get our toplevel widget */
- target = em_config_target_new_prefs(ec, prefs->gconf);
- e_config_set_target((EConfig *)ec, (EConfigTarget *)target);
- toplevel = e_config_create_widget((EConfig *)ec);
- gtk_container_add (GTK_CONTAINER (prefs), toplevel);
-}
-
-GtkWidget *
-em_mailer_prefs_new (void)
-{
- EMMailerPrefs *new;
-
- new = (EMMailerPrefs *) g_object_new (em_mailer_prefs_get_type (), NULL);
- em_mailer_prefs_construct (new);
-
- return (GtkWidget *) new;
-}
-
-static struct _EMMailerPrefsHeader *
-emmp_header_from_xmldoc (xmlDocPtr doc)
-{
- struct _EMMailerPrefsHeader *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 (struct _EMMailerPrefsHeader));
- h->name = g_strdup ((gchar *)name);
- xmlFree (name);
-
- if (xmlHasProp (root, (const guchar *)"enabled"))
- h->enabled = 1;
- else
- h->enabled = 0;
-
- return h;
-}
-
-/**
- * em_mailer_prefs_header_from_xml
- * @xml: XML configuration data
- *
- * Parses passed XML data, which should be of
- * the format <header name="foo" enabled />, and
- * returns a EMMailerPrefs structure, or NULL if there
- * is an error.
- **/
-struct _EMMailerPrefsHeader *
-em_mailer_prefs_header_from_xml (const gchar *xml)
-{
- struct _EMMailerPrefsHeader *header;
- xmlDocPtr doc;
-
- if (!(doc = xmlParseDoc ((guchar *) xml)))
- return NULL;
-
- header = emmp_header_from_xmldoc (doc);
- xmlFreeDoc (doc);
-
- return header;
-}
-
-/**
- * em_mailer_prefs_header_free
- * @header: header to free
- *
- * Frees the memory associated with the passed header
- * structure.
- */
-void
-em_mailer_prefs_header_free (struct _EMMailerPrefsHeader *header)
-{
- if (header == NULL)
- return;
-
- g_free (header->name);
- g_free (header);
-}
-
-/**
- * em_mailer_prefs_header_to_xml
- * @header: header from which to generate XML
- *
- * Returns the passed header as a XML structure,
- * or NULL on error
- */
-gchar *
-em_mailer_prefs_header_to_xml (struct _EMMailerPrefsHeader *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;
-}
diff --git a/mail/em-mailer-prefs.h b/mail/em-mailer-prefs.h
deleted file mode 100644
index f9f36662ff..0000000000
--- a/mail/em-mailer-prefs.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EM_MAILER_PREFS_H__
-#define __EM_MAILER_PREFS_H__
-
-#include <gtk/gtk.h>
-#include <shell/Evolution.h>
-#include <gconf/gconf-client.h>
-#include <e-util/e-signature.h>
-
-#define EM_MAILER_PREFS_TYPE (em_mailer_prefs_get_type ())
-#define EM_MAILER_PREFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EM_MAILER_PREFS_TYPE, EMMailerPrefs))
-#define EM_MAILER_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EM_MAILER_PREFS_TYPE, EMMailerPrefsClass))
-#define EM_IS_MAILER_PREFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EM_MAILER_PREFS_TYPE))
-#define EM_IS_MAILER_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EM_MAILER_PREFS_TYPE))
-
-G_BEGIN_DECLS
-
-typedef struct _EMMailerPrefs EMMailerPrefs;
-typedef struct _EMMailerPrefsClass EMMailerPrefsClass;
-typedef struct _EMMailerPrefsHeader EMMailerPrefsHeader;
-
-struct _EMMailerPrefsHeader {
- gchar *name;
- guint enabled:1;
- guint is_default:1;
-};
-
-struct _EMMailerPrefs {
- GtkVBox parent_object;
-
- GNOME_Evolution_Shell shell;
-
- struct _GladeXML *gui;
- struct _GConfClient *gconf;
-
- /* General tab */
-
- /* Message Display */
- GtkToggleButton *timeout_toggle;
- GtkSpinButton *timeout;
- GtkToggleButton *address_toggle;
- GtkSpinButton *address_count;
- GtkToggleButton *mlimit_toggle;
- GtkSpinButton *mlimit_count;
- GtkOptionMenu *charset;
- GtkToggleButton *citation_highlight;
- GtkColorButton *citation_color;
- GtkToggleButton *enable_search_folders;
- GtkToggleButton *magic_spacebar;
-
- /* Deleting Mail */
- GtkToggleButton *empty_trash;
- GtkComboBox *empty_trash_days;
- GtkToggleButton *confirm_expunge;
-
- /* HTML Mail tab */
- GtkFontButton *font_variable;
- GtkFontButton *font_fixed;
- GtkToggleButton *font_share;
-
- /* Loading Images */
- GtkToggleButton *images_always;
- GtkToggleButton *images_sometimes;
- GtkToggleButton *images_never;
-
- GtkToggleButton *show_animated;
- GtkToggleButton *autodetect_links;
- GtkToggleButton *prompt_unwanted_html;
-
- /* Labels and Colours tab */
- GtkWidget *label_add;
- GtkWidget *label_edit;
- GtkWidget *label_remove;
- GtkWidget *label_tree;
- guint labels_change_notify_id; /* mail_config's notify id */
-
- /* Headers tab */
- GtkButton *add_header;
- GtkButton *remove_header;
- GtkEntry *entry_header;
- GtkTreeView *header_list;
- GtkListStore *header_list_store;
- GtkToggleButton *photo_show;
- GtkToggleButton *photo_local;
-
- /* Junk prefs */
- GtkToggleButton *check_incoming;
- GtkToggleButton *empty_junk;
- GtkComboBox *empty_junk_days;
-
- GtkToggleButton *sa_local_tests_only;
- GtkToggleButton *sa_use_daemon;
- GtkComboBox *default_junk_plugin;
- GtkLabel *plugin_status;
- GtkImage *plugin_image;
-
- GtkToggleButton *junk_header_check;
- GtkTreeView *junk_header_tree;
- GtkButton *junk_header_add;
- GtkButton *junk_header_remove;
- GtkToggleButton *junk_book_lookup;
- GtkToggleButton *junk_lookup_local_only;
-};
-
-struct _EMMailerPrefsClass {
- GtkVBoxClass parent_class;
-
- /* signals */
-
-};
-
-GType em_mailer_prefs_get_type (void);
-GtkWidget * create_combo_text_widget (void);
-
-GtkWidget *em_mailer_prefs_new (void);
-
-EMMailerPrefsHeader *em_mailer_prefs_header_from_xml(const gchar *xml);
-gchar *em_mailer_prefs_header_to_xml(EMMailerPrefsHeader *header);
-void em_mailer_prefs_header_free(EMMailerPrefsHeader *header);
-
-/* needed by global config */
-#define EM_MAILER_PREFS_CONTROL_ID "OAFIID:GNOME_Evolution_Mail_MailerPrefs_ConfigControl:" BASE_VERSION
-
-G_END_DECLS
-
-#endif /* __EM_MAILER_PREFS_H__ */
diff --git a/mail/em-message-browser.c b/mail/em-message-browser.c
deleted file mode 100644
index fec31575b7..0000000000
--- a/mail/em-message-browser.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * 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:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#ifdef G_OS_WIN32
-/* Work around 'DATADIR' and 'interface' lossage in <windows.h> */
-#define DATADIR crap_DATADIR
-#include <windows.h>
-#undef DATADIR
-#undef interface
-#endif
-
-#include <gdk/gdkkeysyms.h>
-
-#include <gconf/gconf-client.h>
-
-#include <camel/camel-folder.h>
-
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-window.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <bonobo/bonobo-ui-util.h>
-
-#include "e-util/e-util-private.h"
-
-#include "e-mail-search-bar.h"
-#include "em-format-html-display.h"
-#include "em-message-browser.h"
-#include "em-menu.h"
-
-#include "evolution-shell-component-utils.h" /* Pixmap stuff, sigh */
-
-#define EM_MESSAGE_BROWSER_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), EM_TYPE_MESSAGE_BROWSER, EMMessageBrowserPrivate))
-
-#define DEFAULT_WIDTH 600
-#define DEFAULT_HEIGHT 400
-
-struct _EMMessageBrowserPrivate {
- GtkWidget *preview; /* container for message display */
- GtkWidget *search_bar;
-};
-
-static gpointer parent_class;
-static GtkAllocation window_size = { 0, 0, 0, 0 };
-
-static void
-emmb_close (BonoboUIComponent *uid,
- gpointer data,
- const gchar *path)
-{
- EMMessageBrowser *emmb = data;
- GtkWidget *toplevel;
-
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (emmb));
- gtk_widget_destroy (toplevel);
-}
-
-static BonoboUIVerb emmb_verbs[] = {
- BONOBO_UI_UNSAFE_VERB ("MessageBrowserClose", emmb_close),
- BONOBO_UI_VERB_END
-};
-
-static void
-emmb_set_message (EMFolderView *emfv,
- const gchar *uid,
- gint nomarkseen)
-{
- EMMessageBrowser *emmb = EM_MESSAGE_BROWSER (emfv);
- EMFolderViewClass *folder_view_class;
- CamelMessageInfo *info;
-
- /* Chain up to parent's set_message() method. */
- folder_view_class = EM_FOLDER_VIEW_CLASS (parent_class);
- folder_view_class->set_message (emfv, uid, nomarkseen);
-
- if (uid == NULL) {
- gtk_widget_destroy (GTK_WIDGET (emfv));
- return;
- }
-
- info = camel_folder_get_message_info (emfv->folder, uid);
-
- if (info != NULL) {
- gtk_window_set_title (
- GTK_WINDOW (emmb->window),
- camel_message_info_subject (info));
- camel_folder_free_message_info (emfv->folder, info);
- }
-
- /* Well we don't know if it got displayed (yet) ... but whatever ... */
- if (!nomarkseen)
- camel_folder_set_message_flags (
- emfv->folder, uid,
- CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
-}
-
-static void
-emmb_activate (EMFolderView *emfv,
- BonoboUIComponent *uic,
- gint state)
-{
- EMFolderViewClass *folder_view_class;
-
- folder_view_class = EM_FOLDER_VIEW_CLASS (parent_class);
-
- if (state) {
- /* Chain up to parent's activate() method. */
- folder_view_class->activate (emfv, uic, state);
-
- bonobo_ui_component_add_verb_list_with_data (
- uic, emmb_verbs, emfv);
- bonobo_ui_component_set_prop(
- uic, "/commands/EditPaste", "sensitive", "0", NULL);
- } else {
- const BonoboUIVerb *verb;
-
- for (verb = &emmb_verbs[0]; verb->cname; verb++)
- bonobo_ui_component_remove_verb (uic, verb->cname);
-
- /* Chain up to parent's activate() method. */
- folder_view_class->activate (emfv, uic, state);
- }
-}
-
-static void
-emmb_list_message_selected_cb (struct _MessageList *ml,
- const gchar *uid,
- EMMessageBrowser *emmb)
-{
- EMFolderView *emfv = EM_FOLDER_VIEW (emmb);
- CamelMessageInfo *info;
-
- if (uid == NULL)
- return;
-
- info = camel_folder_get_message_info (emfv->folder, uid);
- if (info == NULL)
- return;
-
- gtk_window_set_title (
- GTK_WINDOW (emmb->window),
- camel_message_info_subject (info));
- gtk_widget_grab_focus (
- GTK_WIDGET (emfv->preview->formathtml.html));
-
- camel_folder_free_message_info (emfv->folder, info);
-}
-
-static void
-emmb_window_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- GConfClient *client;
-
- /* FIXME Have GConfBridge handle this. */
-
- /* save to in-memory variable for current session access */
- window_size = *allocation;
-
- /* save the setting across sessions */
- client = gconf_client_get_default ();
- gconf_client_set_int (
- client, "/apps/evolution/mail/message_window/width",
- window_size.width, NULL);
- gconf_client_set_int (
- client, "/apps/evolution/mail/message_window/height",
- window_size.height, NULL);
- g_object_unref (client);
-}
-
-static gint
-emmb_key_press_event_cb (EMMessageBrowser *emmb,
- GdkEventKey *event)
-{
- if (event->keyval == GDK_Escape) {
- GtkWidget *toplevel;
-
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (emmb));
- gtk_widget_destroy (toplevel);
- g_signal_stop_emission_by_name (emmb, "key-press-event");
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-emmb_destroy (GtkObject *gtk_object)
-{
- EMFolderView *emfv = EM_FOLDER_VIEW (gtk_object);
-
- if (emfv->list) {
- gtk_widget_destroy (GTK_WIDGET (emfv->list));
- emfv->list = NULL;
- }
-
- /* Chain up to parent's destroy() method. */
- GTK_OBJECT_CLASS (parent_class)->destroy (gtk_object);
-}
-
-static void
-emmb_show_search_bar (EMFolderView *folder_view)
-{
- EMMessageBrowser *browser = EM_MESSAGE_BROWSER (folder_view);
-
- gtk_widget_show (browser->priv->search_bar);
-}
-
-static void
-emmb_class_init (EMMessageBrowserClass *class)
-{
- GtkObjectClass *gtk_object_class;
- EMFolderViewClass *folder_view_class;
-
- parent_class = g_type_class_peek_parent (class);
- g_type_class_add_private (class, sizeof (EMMessageBrowserPrivate));
-
- gtk_object_class = GTK_OBJECT_CLASS (class);
- gtk_object_class->destroy = emmb_destroy;
-
- folder_view_class = EM_FOLDER_VIEW_CLASS (class);
- folder_view_class->update_message_style = FALSE;
- folder_view_class->set_message = emmb_set_message;
- folder_view_class->activate = emmb_activate;
- folder_view_class->show_search_bar = emmb_show_search_bar;
-}
-
-static void
-emmb_init (EMMessageBrowser *emmb)
-{
- EMFolderView *emfv = EM_FOLDER_VIEW (emmb);
- GtkWidget *container;
- GtkWidget *widget;
- gchar *filename;
-
- emmb->priv = EM_MESSAGE_BROWSER_GET_PRIVATE (emmb);
-
- emfv->preview_active = TRUE;
-
- g_slist_foreach (emfv->ui_files, (GFunc) g_free, NULL);
- g_slist_free (emfv->ui_files);
- emfv->ui_files = NULL;
-
- filename = g_build_filename (
- EVOLUTION_UIDIR, "evolution-mail-messagedisplay.xml", NULL);
- emfv->ui_files = g_slist_append (emfv->ui_files, filename);
-
- filename = g_build_filename (
- EVOLUTION_UIDIR, "evolution-mail-message.xml", NULL);
- emfv->ui_files = g_slist_append (emfv->ui_files, filename);
-
- gtk_box_set_spacing (GTK_BOX (emmb), 1);
-
- container = GTK_WIDGET (emmb);
-
- widget = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (
- GTK_SCROLLED_WINDOW (widget),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (
- GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
- gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
- emmb->priv->preview = widget;
- gtk_widget_show (widget);
-
- widget = e_mail_search_bar_new (emfv->preview->formathtml.html);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emmb->priv->search_bar = widget;
- gtk_widget_hide (widget);
-
- g_signal_connect_swapped (
- widget, "changed",
- G_CALLBACK (em_format_redraw), emfv->preview);
-
- container = emmb->priv->preview;
-
- widget = GTK_WIDGET (emfv->preview->formathtml.html);
- gtk_container_add (GTK_CONTAINER (container), widget);
- gtk_widget_show (widget);
-
- /** @HookPoint-EMMenu: Standalone Message View Menu
- * @Id: org.gnome.evolution.mail.messagebrowser
- * @Class: org.gnome.evolution.mail.bonobomenu:1.0
- * @Target: EMMenuTargetSelect
- *
- * The main menu of standalone message viewer.
- */
- EM_FOLDER_VIEW (emmb)->menu =
- em_menu_new ("org.gnome.evolution.mail.messagebrowser");
-}
-
-GType
-em_message_browser_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EMMessageBrowserClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) emmb_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EMMessageBrowser),
- 0, /* n_preallocs */
- (GInstanceInitFunc) emmb_init,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- EM_TYPE_FOLDER_VIEW, "EMMessageBrowser",
- &type_info, 0);
- }
-
- return type;
-}
-
-GtkWidget *
-em_message_browser_new (void)
-{
- return g_object_new (EM_TYPE_MESSAGE_BROWSER, NULL);
-}
-
-GtkWidget *
-em_message_browser_window_new (void)
-{
- EMMessageBrowser *emmb;
- BonoboUIContainer *uicont;
- BonoboUIComponent *uic;
-
- emmb = (EMMessageBrowser *) em_message_browser_new ();
- gtk_widget_show (GTK_WIDGET (emmb));
-
- /* FIXME: title set elsewhere? */
- emmb->window = g_object_new (
- BONOBO_TYPE_WINDOW, "title", "Evolution", NULL);
- bonobo_window_set_contents (
- BONOBO_WINDOW (emmb->window), GTK_WIDGET (emmb));
-
- uic = bonobo_ui_component_new_default ();
- uicont = bonobo_window_get_ui_container (BONOBO_WINDOW (emmb->window));
- bonobo_ui_component_set_container (uic, BONOBO_OBJREF (uicont), NULL);
-
- em_folder_view_activate (EM_FOLDER_VIEW (emmb), uic, TRUE);
-
- if (window_size.width == 0) {
- /* initialize @window_size with the previous session's size */
-
- /* FIXME Have GConfBridge handle this. */
-
- GConfClient *client;
- GError *error = NULL;
-
- client = gconf_client_get_default ();
-
- window_size.width = gconf_client_get_int (
- client, "/apps/evolution/mail/message_window/width",
- &error);
- if (error != NULL) {
- window_size.width = DEFAULT_WIDTH;
- g_clear_error (&error);
- }
-
- window_size.height = gconf_client_get_int (
- client, "/apps/evolution/mail/message_window/height",
- &error);
- if (error != NULL) {
- window_size.height = DEFAULT_HEIGHT;
- g_clear_error (&error);
- }
-
- g_object_unref (client);
- }
-
- gtk_window_set_default_size (
- GTK_WINDOW (emmb->window),
- window_size.width, window_size.height);
-
- g_signal_connect (
- emmb->window, "size-allocate",
- G_CALLBACK (emmb_window_size_allocate), NULL);
- g_signal_connect (
- EM_FOLDER_VIEW (emmb)->list, "message_selected",
- G_CALLBACK (emmb_list_message_selected_cb), emmb);
- g_signal_connect (
- emmb, "key-press-event",
- G_CALLBACK (emmb_key_press_event_cb), NULL);
-
- /* cleanup? */
-
- return GTK_WIDGET (emmb);
-}
diff --git a/mail/em-message-browser.h b/mail/em-message-browser.h
deleted file mode 100644
index d394adc9ba..0000000000
--- a/mail/em-message-browser.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * 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)
- *
- */
-
-#ifndef EM_MESSAGE_BROWSER_H
-#define EM_MESSAGE_BROWSER_H
-
-#include <gtk/gtk.h>
-#include "em-folder-view.h"
-
-/* Standard GObject macros */
-#define EM_TYPE_MESSAGE_BROWSER \
- (em_message_browser_get_type ())
-#define EM_MESSAGE_BROWSER(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), EM_TYPE_MESSAGE_BROWSER, EMMessageBrowser))
-#define EM_MESSAGE_BROWSER_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), EM_TYPE_MESSAGE_BROWSER, EMMessageBrowserClass))
-#define EM_IS_MESSAGE_BROWSER(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), EM_TYPE_MESSAGE_BROWSER))
-#define EM_IS_MESSAGE_BROWSER_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), EM_TYPE_MESSAGE_BROWSER))
-#define EM_MESSAGE_BROWSER_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), EM_TYPE_MESSAGE_BROWSER, EMMessageBrowserClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EMMessageBrowser EMMessageBrowser;
-typedef struct _EMMessageBrowserClass EMMessageBrowserClass;
-typedef struct _EMMessageBrowserPrivate EMMessageBrowserPrivate;
-
-struct _EMMessageBrowser {
- EMFolderView parent;
-
- /* container, if setup */
- GtkWidget *window;
-
- EMMessageBrowserPrivate *priv;
-};
-
-struct _EMMessageBrowserClass {
- EMFolderViewClass parent_class;
-};
-
-GType em_message_browser_get_type (void);
-
-GtkWidget * em_message_browser_new (void);
-
-/* Also sets up a bonobo container window w/ docks and so on. */
-GtkWidget * em_message_browser_window_new (void);
-
-G_END_DECLS
-
-#endif /* EM_MESSAGE_BROWSER_H */
diff --git a/mail/em-migrate.c b/mail/em-migrate.c
deleted file mode 100644
index fd59bafea9..0000000000
--- a/mail/em-migrate.c
+++ /dev/null
@@ -1,3046 +0,0 @@
-/*
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <utime.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <regex.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#include <gtk/gtk.h>
-
-#include <gconf/gconf-client.h>
-
-#include <camel/camel.h>
-#include <camel/camel-store.h>
-#include <camel/camel-session.h>
-#include <camel/camel-file-utils.h>
-#include <camel/camel-disco-folder.h>
-
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-
-#include <glib/gi18n.h>
-
-#include <e-util/e-util.h>
-#include <libedataserver/e-xml-utils.h>
-#include <libedataserver/e-data-server-util.h>
-#include <e-util/e-xml-utils.h>
-
-#include "e-util/e-bconf-map.h"
-#include "libedataserver/e-account-list.h"
-#include "e-util/e-signature-list.h"
-#include "e-util/e-error.h"
-#include "e-util/e-util-private.h"
-#include "e-util/e-plugin.h"
-
-#include "mail-component.h"
-#include "mail-config.h"
-#include "mail-session.h"
-#include "em-utils.h"
-#include "em-migrate.h"
-
-#define d(x)
-
-#ifndef G_OS_WIN32
-/* No versions previous to 2.8 or thereabouts have been available on
- * Windows, so don't bother with upgrade support from earlier versions
- * on Win32. Do try to support upgrades from 2.12 and later to the
- * current version.
- */
-
-/* upgrade helper functions */
-static xmlDocPtr
-emm_load_xml (const gchar *dirname, const gchar *filename)
-{
- xmlDocPtr doc;
- struct stat st;
- gchar *path;
-
- path = g_strdup_printf ("%s/%s", dirname, filename);
- if (stat (path, &st) == -1 || !(doc = xmlParseFile (path))) {
- g_free (path);
- return NULL;
- }
-
- g_free (path);
-
- return doc;
-}
-
-static gint
-emm_save_xml (xmlDocPtr doc, const gchar *dirname, const gchar *filename)
-{
- gchar *path;
- gint retval;
-
- path = g_strdup_printf ("%s/%s", dirname, filename);
- retval = e_xml_save_file (path, doc);
- g_free (path);
-
- return retval;
-}
-
-static xmlNodePtr
-xml_find_node (xmlNodePtr parent, const gchar *name)
-{
- xmlNodePtr node;
-
- node = parent->children;
- while (node != NULL) {
- if (node->name && !strcmp ((gchar *)node->name, name))
- return node;
-
- node = node->next;
- }
-
- return NULL;
-}
-
-static void
-upgrade_xml_uris (xmlDocPtr doc, gchar * (* upgrade_uri) (const gchar *uri))
-{
- xmlNodePtr root, node;
- gchar *uri, *new;
-
- if (!doc || !(root = xmlDocGetRootElement (doc)))
- return;
-
- if (!root->name || strcmp ((gchar *)root->name, "filteroptions") != 0) {
- /* root node is not <filteroptions>, nothing to upgrade */
- return;
- }
-
- if (!(node = xml_find_node (root, "ruleset"))) {
- /* no ruleset node, nothing to upgrade */
- return;
- }
-
- node = node->children;
- while (node != NULL) {
- if (node->name && !strcmp ((gchar *)node->name, "rule")) {
- xmlNodePtr actionset, part, val, n;
-
- if ((actionset = xml_find_node (node, "actionset"))) {
- /* filters.xml */
- part = actionset->children;
- while (part != NULL) {
- if (part->name && !strcmp ((gchar *)part->name, "part")) {
- val = part->children;
- while (val != NULL) {
- if (val->name && !strcmp ((gchar *)val->name, "value")) {
- gchar *type;
-
- type = (gchar *)xmlGetProp (val, (const guchar *)"type");
- if (type && !strcmp ((gchar *)type, "folder")) {
- if ((n = xml_find_node (val, "folder"))) {
- uri = (gchar *)xmlGetProp (n, (const guchar *)"uri");
- new = upgrade_uri (uri);
- xmlFree (uri);
-
- xmlSetProp (n, (const guchar *)"uri", (guchar *)new);
- g_free (new);
- }
- }
-
- xmlFree (type);
- }
-
- val = val->next;
- }
- }
-
- part = part->next;
- }
- } else if ((actionset = xml_find_node (node, "sources"))) {
- /* vfolders.xml */
- n = actionset->children;
- while (n != NULL) {
- if (n->name && !strcmp ((gchar *)n->name, "folder")) {
- uri = (gchar *)xmlGetProp (n, (const guchar *)"uri");
- new = upgrade_uri (uri);
- xmlFree (uri);
-
- xmlSetProp (n, (const guchar *)"uri", (guchar *)new);
- g_free (new);
- }
-
- n = n->next;
- }
- }
- }
-
- node = node->next;
- }
-}
-
-/* 1.0 upgrade functions & data */
-
-/* as much info as we have on a given account */
-struct _account_info_1_0 {
- gchar *name;
- gchar *uri;
- gchar *base_uri;
- union {
- struct {
- /* for imap */
- gchar *namespace;
- gchar *namespace_full;
- guint32 capabilities;
- GHashTable *folders;
- gchar dir_sep;
- } imap;
- } u;
-};
-
-struct _imap_folder_info_1_0 {
- gchar *folder;
- /* encoded? decoded? canonicalised? */
- gchar dir_sep;
-};
-
-static GHashTable *accounts_1_0 = NULL;
-static GHashTable *accounts_name_1_0 = NULL;
-
-static void
-imap_folder_info_1_0_free (struct _imap_folder_info_1_0 *fi)
-{
- g_free(fi->folder);
- g_free(fi);
-}
-
-static void
-account_info_1_0_free (struct _account_info_1_0 *ai)
-{
- g_free(ai->name);
- g_free(ai->uri);
- g_free(ai->base_uri);
- g_free(ai->u.imap.namespace);
- g_free(ai->u.imap.namespace_full);
- g_hash_table_destroy(ai->u.imap.folders);
- g_free(ai);
-}
-
-static gchar *
-get_base_uri(const gchar *val)
-{
- const gchar *tmp;
-
- tmp = strchr(val, ':');
- if (tmp) {
- tmp++;
- if (strncmp(tmp, "//", 2) == 0)
- tmp += 2;
- tmp = strchr(tmp, '/');
- }
-
- if (tmp)
- return g_strndup(val, tmp-val);
- else
- return g_strdup(val);
-}
-
-static gchar *
-upgrade_xml_uris_1_0 (const gchar *uri)
-{
- gchar *out = NULL;
-
- /* upgrades camel uri's */
- if (strncmp (uri, "imap:", 5) == 0) {
- gchar *base_uri, dir_sep, *folder, *p;
- struct _account_info_1_0 *ai;
-
- /* add namespace, canonicalise dir_sep to / */
- base_uri = get_base_uri (uri);
- ai = g_hash_table_lookup (accounts_1_0, base_uri);
-
- if (ai == NULL) {
- g_free (base_uri);
- return NULL;
- }
-
- dir_sep = ai->u.imap.dir_sep;
- if (dir_sep == 0) {
- /* no dir_sep listed, try get it from the namespace, if set */
- if (ai->u.imap.namespace != NULL) {
- p = ai->u.imap.namespace;
- while ((dir_sep = *p++)) {
- if (dir_sep < '0'
- || (dir_sep > '9' && dir_sep < 'A')
- || (dir_sep > 'Z' && dir_sep < 'a')
- || (dir_sep > 'z')) {
- break;
- }
- p++;
- }
- }
-
- /* give up ... */
- if (dir_sep == 0) {
- g_free (base_uri);
- return NULL;
- }
- }
-
- folder = g_strdup (uri + strlen (base_uri) + 1);
-
- /* Add the namespace before the mailbox name, unless the mailbox is INBOX */
- if (ai->u.imap.namespace && strcmp ((gchar *)folder, "INBOX") != 0)
- out = g_strdup_printf ("%s/%s/%s", base_uri, ai->u.imap.namespace, folder);
- else
- out = g_strdup_printf ("%s/%s", base_uri, folder);
-
- p = out;
- while (*p) {
- if (*p == dir_sep)
- *p = '/';
- p++;
- }
-
- g_free (folder);
- g_free (base_uri);
- } else if (strncmp (uri, "exchange:", 9) == 0) {
- gchar *base_uri, *folder, *p;
-
- /* exchange://user@host/exchange/ * -> exchange://user@host/personal/ * */
- /* Any url encoding (%xx) in the folder name is also removed */
- base_uri = get_base_uri (uri);
- uri += strlen (base_uri) + 1;
- if (strncmp (uri, "exchange/", 9) == 0) {
- folder = e_bconf_url_decode (uri + 9);
- p = strchr (folder, '/');
- out = g_strdup_printf ("%s/personal%s", base_uri, p ? p : "/");
- g_free (folder);
- }
- } else if (strncmp (uri, "exchanget:", 10) == 0) {
- /* these should be converted in the accounts table when it is loaded */
- g_warning ("exchanget: uri not converted: '%s'", uri);
- }
-
- return out;
-}
-
-static gchar *
-parse_lsub (const gchar *lsub, gchar *dir_sep)
-{
- static gint comp;
- static regex_t pat;
- regmatch_t match[3];
- const gchar *m = "^\\* LSUB \\([^)]*\\) \"?([^\" ]+)\"? \"?(.*)\"?$";
-
- if (!comp) {
- if (regcomp (&pat, m, REG_EXTENDED|REG_ICASE) == -1) {
- g_warning ("reg comp '%s' failed: %s", m, g_strerror (errno));
- return NULL;
- }
- comp = 1;
- }
-
- if (regexec (&pat, lsub, 3, match, 0) == 0) {
- if (match[1].rm_so != -1 && match[2].rm_so != -1) {
- if (dir_sep)
- *dir_sep = (match[1].rm_eo - match[1].rm_so == 1) ? lsub[match[1].rm_so] : 0;
- return g_strndup (lsub + match[2].rm_so, match[2].rm_eo - match[2].rm_so);
- }
- }
-
- return NULL;
-}
-
-static gint
-read_imap_storeinfo (struct _account_info_1_0 *si)
-{
- FILE *storeinfo;
- guint32 tmp;
- gchar *buf, *folder, dir_sep, *path, *name, *p;
- struct _imap_folder_info_1_0 *fi;
-
- si->u.imap.folders = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) imap_folder_info_1_0_free);
-
- /* get details from uri first */
- name = strstr (si->uri, ";override_namespace");
- if (name) {
- name = strstr (si->uri, ";namespace=");
- if (name) {
- gchar *end;
-
- name += strlen (";namespace=");
- if (*name == '\"') {
- name++;
- end = strchr (name, '\"');
- } else {
- end = strchr (name, ';');
- }
-
- if (end) {
- /* try get the dir_sep from the namespace */
- si->u.imap.namespace = g_strndup (name, end-name);
-
- p = si->u.imap.namespace;
- while ((dir_sep = *p++)) {
- if (dir_sep < '0'
- || (dir_sep > '9' && dir_sep < 'A')
- || (dir_sep > 'Z' && dir_sep < 'a')
- || (dir_sep > 'z')) {
- si->u.imap.dir_sep = dir_sep;
- break;
- }
- p++;
- }
- }
- }
- }
-
- /* now load storeinfo if it exists */
- path = g_build_filename (g_get_home_dir (), "evolution", "mail", "imap", si->base_uri + 7, "storeinfo", NULL);
- storeinfo = fopen (path, "r");
- g_free (path);
- if (storeinfo == NULL) {
- g_warning ("could not find imap store info '%s'", path);
- return -1;
- }
-
- /* ignore version */
- camel_file_util_decode_uint32 (storeinfo, &tmp);
- camel_file_util_decode_uint32 (storeinfo, &si->u.imap.capabilities);
- g_free (si->u.imap.namespace);
- camel_file_util_decode_string (storeinfo, &si->u.imap.namespace);
- camel_file_util_decode_uint32 (storeinfo, &tmp);
- si->u.imap.dir_sep = tmp;
- /* strip trailing dir_sep or / */
- if (si->u.imap.namespace
- && (si->u.imap.namespace[strlen (si->u.imap.namespace) - 1] == si->u.imap.dir_sep
- || si->u.imap.namespace[strlen (si->u.imap.namespace) - 1] == '/')) {
- si->u.imap.namespace[strlen (si->u.imap.namespace) - 1] = 0;
- }
-
- d(printf ("namespace '%s' dir_sep '%c'\n", si->u.imap.namespace, si->u.imap.dir_sep ? si->u.imap.dir_sep : '?'));
-
- while (camel_file_util_decode_string (storeinfo, &buf) == 0) {
- folder = parse_lsub (buf, &dir_sep);
- if (folder) {
- fi = g_new0 (struct _imap_folder_info_1_0, 1);
- fi->folder = folder;
- fi->dir_sep = dir_sep;
-#if d(!)0
- printf (" add folder '%s' ", folder);
- if (dir_sep)
- printf ("'%c'\n", dir_sep);
- else
- printf ("NIL\n");
-#endif
- g_hash_table_insert (si->u.imap.folders, fi->folder, fi);
- } else {
- g_warning ("Could not parse LIST result '%s'\n", buf);
- }
- }
-
- fclose (storeinfo);
-
- return 0;
-}
-
-static gint
-load_accounts_1_0 (xmlDocPtr doc)
-{
- xmlNodePtr source;
- gchar *val, *tmp;
- gint count = 0, i;
- gchar key[32];
-
- if (!(source = e_bconf_get_path (doc, "/Mail/Accounts")))
- return 0;
-
- if ((val = e_bconf_get_value (source, "num"))) {
- count = atoi (val);
- xmlFree (val);
- }
-
- /* load account upgrade info for each account */
- for (i = 0; i < count; i++) {
- struct _account_info_1_0 *ai;
- gchar *rawuri;
-
- sprintf (key, "source_url_%d", i);
- if (!(rawuri = e_bconf_get_value (source, key)))
- continue;
-
- ai = g_malloc0 (sizeof (struct _account_info_1_0));
- ai->uri = e_bconf_hex_decode (rawuri);
- ai->base_uri = get_base_uri (ai->uri);
- sprintf (key, "account_name_%d", i);
- ai->name = e_bconf_get_string (source, key);
-
- d(printf("load account '%s'\n", ai->uri));
-
- if (!strncmp (ai->uri, "imap:", 5)) {
- read_imap_storeinfo (ai);
- } else if (!strncmp (ai->uri, "exchange:", 9)) {
- xmlNodePtr node;
-
- d(printf (" upgrade exchange account\n"));
- /* small hack, poke the source_url into the transport_url for exchanget: transports
- - this will be picked up later in the conversion */
- sprintf (key, "transport_url_%d", i);
- node = e_bconf_get_entry (source, key);
- if (node && (val = (gchar *)xmlGetProp (node, (const guchar *)"value"))) {
- tmp = e_bconf_hex_decode (val);
- xmlFree (val);
- if (strncmp (tmp, "exchanget:", 10) == 0)
- xmlSetProp (node, (const guchar *)"value", (guchar *)rawuri);
- g_free (tmp);
- } else {
- d(printf (" couldn't find transport uri?\n"));
- }
- }
- xmlFree (rawuri);
-
- g_hash_table_insert (accounts_1_0, ai->base_uri, ai);
- if (ai->name)
- g_hash_table_insert (accounts_name_1_0, ai->name, ai);
- }
-
- return 0;
-}
-
-static gint
-em_migrate_1_0 (const gchar *evolution_dir, xmlDocPtr config_xmldb, xmlDocPtr filters, xmlDocPtr vfolders, CamelException *ex)
-{
- accounts_1_0 = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) account_info_1_0_free);
- accounts_name_1_0 = g_hash_table_new (g_str_hash, g_str_equal);
- load_accounts_1_0 (config_xmldb);
-
- upgrade_xml_uris(filters, upgrade_xml_uris_1_0);
- upgrade_xml_uris(vfolders, upgrade_xml_uris_1_0);
-
- g_hash_table_destroy (accounts_1_0);
- g_hash_table_destroy (accounts_name_1_0);
-
- return 0;
-}
-
-/* 1.2 upgrade functions */
-static gint
-is_xml1encoded (const gchar *txt)
-{
- const guchar *p;
- gint isxml1 = FALSE;
- gint is8bit = FALSE;
-
- p = (const guchar *)txt;
- while (*p) {
- if (p[0] == '\\' && p[1] == 'U' && p[2] == '+'
- && isxdigit (p[3]) && isxdigit (p[4]) && isxdigit (p[5]) && isxdigit (p[6])
- && p[7] == '\\') {
- isxml1 = TRUE;
- p+=7;
- } else if (p[0] >= 0x80)
- is8bit = TRUE;
- p++;
- }
-
- /* check for invalid utf8 that needs cleaning */
- if (is8bit && !isxml1)
- isxml1 = !g_utf8_validate (txt, -1, NULL);
-
- return isxml1;
-}
-
-static gchar *
-decode_xml1 (const gchar *txt)
-{
- GString *out = g_string_new ("");
- const guchar *p;
- gchar *res;
-
- /* convert:
- \U+XXXX\ -> utf8
- 8 bit characters -> utf8 (iso-8859-1) */
-
- p = (const guchar *) txt;
- while (*p) {
- if (p[0] > 0x80
- || (p[0] == '\\' && p[1] == 'U' && p[2] == '+'
- && isxdigit (p[3]) && isxdigit (p[4]) && isxdigit (p[5]) && isxdigit (p[6])
- && p[7] == '\\')) {
- gchar utf8[8];
- gunichar u;
-
- if (p[0] == '\\') {
- memcpy (utf8, p + 3, 4);
- utf8[4] = 0;
- u = strtoul (utf8, NULL, 16);
- p+=7;
- } else
- u = p[0];
- utf8[g_unichar_to_utf8 (u, utf8)] = 0;
- g_string_append (out, utf8);
- } else {
- g_string_append_c (out, *p);
- }
- p++;
- }
-
- res = out->str;
- g_string_free (out, FALSE);
-
- return res;
-}
-
-static gchar *
-utf8_reencode (const gchar *txt)
-{
- GString *out = g_string_new ("");
- gchar *p;
- gchar *res;
-
- /* convert:
- libxml1 8 bit utf8 converted to xml entities byte-by-byte chars -> utf8 */
-
- p = (gchar *)txt;
-
- while (*p) {
- g_string_append_c (out, (gchar)g_utf8_get_char ((const gchar *)p));
- p = (gchar *)g_utf8_next_char (p);
- }
-
- res = out->str;
- if (g_utf8_validate (res, -1, NULL)) {
- g_string_free (out, FALSE);
- return res;
- } else {
- g_string_free (out, TRUE);
- return g_strdup (txt);
- }
-}
-
-static gint
-upgrade_xml_1_2_rec (xmlNodePtr node)
-{
- const gchar *value_tags[] = { "string", "address", "regex", "file", "command", NULL };
- const gchar *rule_tags[] = { "title", NULL };
- const gchar *item_props[] = { "name", NULL };
- struct {
- const gchar *name;
- const gchar **tags;
- const gchar **props;
- } tags[] = {
- { "value", value_tags, NULL },
- { "rule", rule_tags, NULL },
- { "item", NULL, item_props },
- { 0 },
- };
- xmlNodePtr work;
- gint i,j;
- gchar *txt, *tmp;
-
- /* upgrades the content of a node, if the node has a specific parent/node name */
-
- for (i = 0; tags[i].name; i++) {
- if (!strcmp ((gchar *)node->name, tags[i].name)) {
- if (tags[i].tags != NULL) {
- work = node->children;
- while (work) {
- for (j = 0; tags[i].tags[j]; j++) {
- if (!strcmp ((gchar *)work->name, tags[i].tags[j])) {
- txt = (gchar *)xmlNodeGetContent (work);
- if (is_xml1encoded (txt)) {
- tmp = decode_xml1 (txt);
- d(printf ("upgrading xml node %s/%s '%s' -> '%s'\n",
- tags[i].name, tags[i].tags[j], txt, tmp));
- xmlNodeSetContent (work, (guchar *)tmp);
- g_free (tmp);
- }
- xmlFree (txt);
- }
- }
- work = work->next;
- }
- break;
- }
-
- if (tags[i].props != NULL) {
- for (j = 0; tags[i].props[j]; j++) {
- txt = (gchar *)xmlGetProp (node, (guchar *)tags[i].props[j]);
- tmp = utf8_reencode (txt);
- d(printf ("upgrading xml property %s on node %s '%s' -> '%s'\n",
- tags[i].props[j], tags[i].name, txt, tmp));
- xmlSetProp (node, (const guchar *)tags[i].props[j], (guchar *)tmp);
- g_free (tmp);
- xmlFree (txt);
- }
- }
- }
- }
-
- node = node->children;
- while (node) {
- upgrade_xml_1_2_rec (node);
- node = node->next;
- }
-
- return 0;
-}
-
-static gint
-em_upgrade_xml_1_2 (xmlDocPtr doc)
-{
- xmlNodePtr root;
-
- if (!doc || !(root = xmlDocGetRootElement (doc)))
- return 0;
-
- return upgrade_xml_1_2_rec (root);
-}
-
-/* ********************************************************************** */
-/* Tables for converting flat bonobo conf -> gconf xml blob */
-/* ********************************************************************** */
-
-/* Mail/Accounts/ * */
-static e_bconf_map_t cc_map[] = {
- { "account_always_cc_%i", "always", E_BCONF_MAP_BOOL },
- { "account_always_cc_addrs_%i", "recipients", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { NULL },
-};
-
-static e_bconf_map_t bcc_map[] = {
- { "account_always_cc_%i", "always", E_BCONF_MAP_BOOL },
- { "account_always_bcc_addrs_%i", "recipients", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { NULL },
-};
-
-static e_bconf_map_t pgp_map[] = {
- { "account_pgp_encrypt_to_self_%i", "encrypt-to-self", E_BCONF_MAP_BOOL },
- { "account_pgp_always_trust_%i", "always-trust", E_BCONF_MAP_BOOL },
- { "account_pgp_always_sign_%i", "always-sign", E_BCONF_MAP_BOOL },
- { "account_pgp_no_imip_sign_%i", "no-imip-sign", E_BCONF_MAP_BOOL },
- { "account_pgp_key_%i", "key-id", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { NULL },
-};
-
-static e_bconf_map_t smime_map[] = {
- { "account_smime_encrypt_to_self_%i", "encrypt-to-self", E_BCONF_MAP_BOOL },
- { "account_smime_always_sign_%i", "always-sign", E_BCONF_MAP_BOOL },
- { "account_smime_key_%i", "key-id", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { NULL },
-};
-
-static e_bconf_map_t identity_sig_map[] = {
- { "identity_autogenerated_signature_%i", "auto", E_BCONF_MAP_BOOL },
- { "identity_def_signature_%i", "default", E_BCONF_MAP_LONG },
- { NULL },
-};
-
-static e_bconf_map_t identity_map[] = {
- { "identity_name_%i", "name", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { "identity_address_%i", "addr-spec", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { "identity_reply_to_%i", "reply-to", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { "identity_organization_%i", "organization", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { NULL, "signature", E_BCONF_MAP_CHILD, identity_sig_map },
- { NULL },
-};
-
-static e_bconf_map_t source_map[] = {
- { "source_save_passwd_%i", "save-passwd", E_BCONF_MAP_BOOL },
- { "source_keep_on_server_%i", "keep-on-server", E_BCONF_MAP_BOOL },
- { "source_auto_check_%i", "auto-check", E_BCONF_MAP_BOOL },
- { "source_auto_check_time_%i", "auto-check-timeout", E_BCONF_MAP_LONG },
- { "source_url_%i", "url", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { NULL },
-};
-
-static e_bconf_map_t transport_map[] = {
- { "transport_save_passwd_%i", "save-passwd", E_BCONF_MAP_BOOL },
- { "transport_url_%i", "url", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { NULL },
-};
-
-static e_bconf_map_t account_map[] = {
- { "account_name_%i", "name", E_BCONF_MAP_STRING },
- { "source_enabled_%i", "enabled", E_BCONF_MAP_BOOL },
- { NULL, "identity", E_BCONF_MAP_CHILD, identity_map },
- { NULL, "source", E_BCONF_MAP_CHILD, source_map },
- { NULL, "transport", E_BCONF_MAP_CHILD, transport_map },
- { "account_drafts_folder_uri_%i", "drafts-folder", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { "account_sent_folder_uri_%i", "sent-folder", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { NULL, "auto-cc", E_BCONF_MAP_CHILD, cc_map },
- { NULL, "auto-bcc", E_BCONF_MAP_CHILD, bcc_map },
- { NULL, "pgp", E_BCONF_MAP_CHILD, pgp_map },
- { NULL, "smime", E_BCONF_MAP_CHILD, smime_map },
- { NULL },
-};
-
-/* /Mail/Signatures/ * */
-static e_bconf_map_t signature_format_map[] = {
- { "text/plain", },
- { "text/html", },
- { NULL }
-};
-
-static e_bconf_map_t signature_map[] = {
- { "name_%i", "name", E_BCONF_MAP_STRING },
- { "html_%i", "format", E_BCONF_MAP_ENUM, signature_format_map },
- { "filename_%i", "filename", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { "script_%i", "script", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT },
- { NULL },
-};
-
-/* ********************************************************************** */
-/* Tables for bonobo conf -> gconf conversion */
-/* ********************************************************************** */
-
-static e_gconf_map_t mail_accounts_map[] = {
- /* /Mail/Accounts - most entries are processed via the xml blob routine */
- /* This also works because the initial uid mapping is 1:1 with the list order */
- { "default_account", "mail/default_account", E_GCONF_MAP_SIMPLESTRING },
- { 0 },
-};
-
-static e_gconf_map_t mail_display_map[] = {
- /* /Mail/Display */
- { "side_bar_search", "mail/display/side_bar_search", E_GCONF_MAP_BOOL },
- { "thread_list", "mail/display/thread_list", E_GCONF_MAP_BOOL },
- { "thread_subject", "mail/display/thread_subject", E_GCONF_MAP_BOOL },
- { "hide_deleted", "mail/display/show_deleted", E_GCONF_MAP_BOOLNOT },
- { "preview_pane", "mail/display/show_preview", E_GCONF_MAP_BOOL },
- { "paned_size", "mail/display/paned_size", E_GCONF_MAP_INT },
- { "seen_timeout", "mail/display/mark_seen_timeout", E_GCONF_MAP_INT },
- { "do_seen_timeout", "mail/display/mark_seen", E_GCONF_MAP_BOOL },
- { "http_images", "mail/display/load_http_images", E_GCONF_MAP_INT },
- { "citation_highlight", "mail/display/mark_citations", E_GCONF_MAP_BOOL },
- { "citation_color", "mail/display/citation_colour", E_GCONF_MAP_COLOUR },
- { 0 },
-};
-
-static e_gconf_map_t mail_format_map[] = {
- /* /Mail/Format */
- { "message_display_style", "mail/display/message_style", E_GCONF_MAP_INT },
- { "send_html", "mail/composer/send_html", E_GCONF_MAP_BOOL },
- { "default_reply_style", "mail/format/reply_style", E_GCONF_MAP_INT },
- { "default_forward_style", "mail/format/forward_style", E_GCONF_MAP_INT },
- { "default_charset", "mail/composer/charset", E_GCONF_MAP_STRING },
- { "confirm_unwanted_html", "mail/prompts/unwanted_html", E_GCONF_MAP_BOOL },
- { 0 },
-};
-
-static e_gconf_map_t mail_trash_map[] = {
- /* /Mail/Trash */
- { "empty_on_exit", "mail/trash/empty_on_exit", E_GCONF_MAP_BOOL },
- { 0 },
-};
-
-static e_gconf_map_t mail_prompts_map[] = {
- /* /Mail/Prompts */
- { "confirm_expunge", "mail/prompts/expunge", E_GCONF_MAP_BOOL },
- { "empty_subject", "mail/prompts/empty_subject", E_GCONF_MAP_BOOL },
- { "only_bcc", "mail/prompts/only_bcc", E_GCONF_MAP_BOOL },
- { 0 }
-};
-
-static e_gconf_map_t mail_filters_map[] = {
- /* /Mail/Filters */
- { "log", "mail/filters/log", E_GCONF_MAP_BOOL },
- { "log_path", "mail/filters/logfile", E_GCONF_MAP_STRING },
- { 0 }
-};
-
-static e_gconf_map_t mail_notify_map[] = {
- /* /Mail/Notify */
- { "new_mail_notification", "mail/notify/type", E_GCONF_MAP_INT },
- { "new_mail_notification_sound_file", "mail/notify/sound", E_GCONF_MAP_STRING },
- { 0 }
-};
-
-static e_gconf_map_t mail_filesel_map[] = {
- /* /Mail/Filesel */
- { "last_filesel_dir", "mail/save_dir", E_GCONF_MAP_STRING },
- { 0 }
-};
-
-static e_gconf_map_t mail_composer_map[] = {
- /* /Mail/Composer */
- { "ViewFrom", "mail/composer/view/From", E_GCONF_MAP_BOOL },
- { "ViewReplyTo", "mail/composer/view/ReplyTo", E_GCONF_MAP_BOOL },
- { "ViewCC", "mail/composer/view/Cc", E_GCONF_MAP_BOOL },
- { "ViewBCC", "mail/composer/view/Bcc", E_GCONF_MAP_BOOL },
- { "ViewSubject", "mail/composer/view/Subject", E_GCONF_MAP_BOOL },
- { 0 },
-};
-
-/* ********************************************************************** */
-
-static e_gconf_map_t importer_elm_map[] = {
- /* /Importer/Elm */
- { "mail", "importer/elm/mail", E_GCONF_MAP_BOOL },
- { "mail-imported", "importer/elm/mail-imported", E_GCONF_MAP_BOOL },
- { 0 },
-};
-
-static e_gconf_map_t importer_pine_map[] = {
- /* /Importer/Pine */
- { "mail", "importer/elm/mail", E_GCONF_MAP_BOOL },
- { "address", "importer/elm/address", E_GCONF_MAP_BOOL },
- { 0 },
-};
-
-static e_gconf_map_t importer_netscape_map[] = {
- /* /Importer/Netscape */
- { "mail", "importer/netscape/mail", E_GCONF_MAP_BOOL },
- { "settings", "importer/netscape/settings", E_GCONF_MAP_BOOL },
- { "filters", "importer/netscape/filters", E_GCONF_MAP_BOOL },
- { 0 },
-};
-
-/* ********************************************************************** */
-
-static e_gconf_map_list_t gconf_remap_list[] = {
- { "/Mail/Accounts", mail_accounts_map },
- { "/Mail/Display", mail_display_map },
- { "/Mail/Format", mail_format_map },
- { "/Mail/Trash", mail_trash_map },
- { "/Mail/Prompts", mail_prompts_map },
- { "/Mail/Filters", mail_filters_map },
- { "/Mail/Notify", mail_notify_map },
- { "/Mail/Filesel", mail_filesel_map },
- { "/Mail/Composer", mail_composer_map },
-
- { "/Importer/Elm", importer_elm_map },
- { "/Importer/Pine", importer_pine_map },
- { "/Importer/Netscape", importer_netscape_map },
-
- { 0 },
-};
-
-static struct {
- const gchar *label;
- const gchar *colour;
-} label_default[5] = {
- { N_("Important"), "#EF2929" }, /* red */
- { N_("Work"), "#F57900" }, /* orange */
- { N_("Personal"), "#4E9A06" }, /* green */
- { N_("To Do"), "#3465A4" }, /* blue */
- { N_("Later"), "#75507B" } /* purple */
-};
-
-/* remaps mail config from bconf to gconf */
-static gint
-bconf_import(GConfClient *gconf, xmlDocPtr config_xmldb)
-{
- xmlNodePtr source;
- gchar labx[16], colx[16];
- gchar *val, *lab, *col;
- GSList *list, *l;
- gint i;
-
- e_bconf_import(gconf, config_xmldb, gconf_remap_list);
-
- /* Labels:
- label string + label colour as integer
- -> label string:# colour as hex */
- source = e_bconf_get_path(config_xmldb, "/Mail/Labels");
- if (source) {
- list = NULL;
- for (i = 0; i < 5; i++) {
- sprintf(labx, "label_%d", i);
- sprintf(colx, "color_%d", i);
- lab = e_bconf_get_string(source, labx);
- if ((col = e_bconf_get_value(source, colx))) {
- sprintf(colx, "#%06x", atoi(col) & 0xffffff);
- g_free(col);
- } else
- strcpy(colx, label_default[i].colour);
-
- val = g_strdup_printf("%s:%s", lab ? lab : label_default[i].label, colx);
- list = g_slist_append(list, val);
- g_free(lab);
- }
-
- gconf_client_set_list(gconf, "/apps/evolution/mail/labels", GCONF_VALUE_STRING, list, NULL);
- while (list) {
- l = list->next;
- g_free(list->data);
- g_slist_free_1(list);
- list = l;
- }
- } else {
- g_warning("could not find /Mail/Labels in old config database, skipping");
- }
-
- /* Accounts: The flat bonobo-config structure is remapped to a list of xml blobs. Upgrades as necessary */
- e_bconf_import_xml_blob(gconf, config_xmldb, account_map, "/Mail/Accounts",
- "/apps/evolution/mail/accounts", "account", "uid");
-
- /* Same for signatures */
- e_bconf_import_xml_blob(gconf, config_xmldb, signature_map, "/Mail/Signatures",
- "/apps/evolution/mail/signatures", "signature", NULL);
-
- return 0;
-}
-
-static gint
-em_migrate_1_2(const gchar *evolution_dir, xmlDocPtr config_xmldb, xmlDocPtr filters, xmlDocPtr vfolders, CamelException *ex)
-{
- GConfClient *gconf;
-
- gconf = gconf_client_get_default();
- bconf_import(gconf, config_xmldb);
- g_object_unref(gconf);
-
- em_upgrade_xml_1_2(filters);
- em_upgrade_xml_1_2(vfolders);
-
- return 0;
-}
-
-/* 1.4 upgrade functions */
-
-#define EM_MIGRATE_SESSION_TYPE (em_migrate_session_get_type ())
-#define EM_MIGRATE_SESSION(obj) (CAMEL_CHECK_CAST((obj), EM_MIGRATE_SESSION_TYPE, EMMigrateSession))
-#define EM_MIGRATE_SESSION_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), EM_MIGRATE_SESSION_TYPE, EMMigrateSessionClass))
-#define EM_MIGRATE_IS_SESSION(o) (CAMEL_CHECK_TYPE((o), EM_MIGRATE_SESSION_TYPE))
-
-typedef struct _EMMigrateSession {
- CamelSession parent_object;
-
- CamelStore *store; /* new folder tree store */
- gchar *srcdir; /* old folder tree path */
-} EMMigrateSession;
-
-typedef struct _EMMigrateSessionClass {
- CamelSessionClass parent_class;
-
-} EMMigrateSessionClass;
-
-static CamelType em_migrate_session_get_type (void);
-static CamelSession *em_migrate_session_new (const gchar *path);
-
-static void
-class_init (EMMigrateSessionClass *klass)
-{
- ;
-}
-
-static CamelType
-em_migrate_session_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register (
- camel_session_get_type (),
- "EMMigrateSession",
- sizeof (EMMigrateSession),
- sizeof (EMMigrateSessionClass),
- (CamelObjectClassInitFunc) class_init,
- NULL,
- NULL,
- NULL);
- }
-
- return type;
-}
-
-static CamelSession *
-em_migrate_session_new (const gchar *path)
-{
- CamelSession *session;
-
- session = CAMEL_SESSION (camel_object_new (EM_MIGRATE_SESSION_TYPE));
-
- camel_session_construct (session, path);
-
- return session;
-}
-
-#endif /* !G_OS_WIN32 */
-
-static GtkWidget *window;
-static GtkLabel *label;
-static GtkProgressBar *progress;
-
-static void
-em_migrate_setup_progress_dialog (const gchar *title, const gchar *desc)
-{
- GtkWidget *vbox, *hbox, *w;
- gchar *markup;
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
- gtk_window_set_title (GTK_WINDOW (window), _("Migrating..."));
- gtk_window_set_modal (GTK_WINDOW (window), TRUE);
- gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (window), 6);
-
- hbox = gtk_hbox_new (FALSE, 24);
-
- /* Install the info image */
- w = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
- gtk_misc_set_alignment (GTK_MISC (w), 0.5, 0.0);
- gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);
-
- /* Prepare the message */
- vbox = gtk_vbox_new (FALSE, 12);
- gtk_widget_show (vbox);
- gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
-
- w = gtk_label_new (NULL);
- gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.0);
- markup = g_strconcat ("<big><b>", title ? title : _("Migration"), "</b></big>", NULL);
- gtk_label_set_markup (GTK_LABEL (w), markup);
- gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, TRUE, 0);
- g_free (markup);
-
- w = gtk_label_new (desc);
- gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.0);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, TRUE, 0);
-
- /* Progress bar */
- w = gtk_vbox_new (FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, TRUE, 0);
-
- label = GTK_LABEL (gtk_label_new (""));
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
- gtk_label_set_line_wrap (label, TRUE);
- gtk_widget_show (GTK_WIDGET (label));
- gtk_box_pack_start (GTK_BOX (w), GTK_WIDGET (label), TRUE, TRUE, 0);
-
- progress = GTK_PROGRESS_BAR (gtk_progress_bar_new ());
- gtk_widget_show (GTK_WIDGET (progress));
- gtk_box_pack_start (GTK_BOX (w), GTK_WIDGET (progress), TRUE, TRUE, 0);
-
- gtk_container_add (GTK_CONTAINER (window), hbox);
- gtk_widget_show_all (hbox);
- gtk_widget_show (window);
-}
-
-static void
-em_migrate_close_progress_dialog (void)
-{
- gtk_widget_destroy (GTK_WIDGET (window));
-}
-
-static void
-em_migrate_set_folder_name (const gchar *folder_name)
-{
- gchar *text;
-
- text = g_strdup_printf (_("Migrating '%s':"), folder_name);
- gtk_label_set_text (label, text);
- g_free (text);
-
- gtk_progress_bar_set_fraction (progress, 0.0);
- while (gtk_events_pending ())
- gtk_main_iteration ();
-}
-
-static void
-em_migrate_set_progress (double percent)
-{
- gchar text[5];
-
- snprintf (text, sizeof (text), "%d%%", (gint) (percent * 100.0f));
-
- gtk_progress_bar_set_fraction (progress, percent);
- gtk_progress_bar_set_text (progress, text);
-
- while (gtk_events_pending ())
- gtk_main_iteration ();
-}
-
-#ifndef G_OS_WIN32
-
-static gboolean
-is_mail_folder (const gchar *metadata)
-{
- xmlNodePtr node;
- xmlDocPtr doc;
- gchar *type;
-
- if (!(doc = xmlParseFile (metadata))) {
- g_warning ("Cannot parse `%s'", metadata);
- return FALSE;
- }
-
- if (!(node = xmlDocGetRootElement (doc))) {
- g_warning ("`%s' corrupt: document contains no root node", metadata);
- xmlFreeDoc (doc);
- return FALSE;
- }
-
- if (!node->name || strcmp ((gchar *)node->name, "efolder") != 0) {
- g_warning ("`%s' corrupt: root node is not 'efolder'", metadata);
- xmlFreeDoc (doc);
- return FALSE;
- }
-
- node = node->children;
- while (node != NULL) {
- if (node->name && !strcmp ((gchar *)node->name, "type")) {
- type = (gchar *)xmlNodeGetContent (node);
- if (!strcmp ((gchar *)type, "mail")) {
- xmlFreeDoc (doc);
- xmlFree (type);
-
- return TRUE;
- }
-
- xmlFree (type);
-
- break;
- }
-
- node = node->next;
- }
-
- xmlFreeDoc (doc);
-
- return FALSE;
-}
-
-static gint
-get_local_et_expanded (const gchar *dirname)
-{
- xmlNodePtr node;
- xmlDocPtr doc;
- struct stat st;
- gchar *buf, *p;
- gint thread_list;
-
- buf = g_strdup_printf ("%s/evolution/config/file:%s", g_get_home_dir (), dirname);
- p = buf + strlen (g_get_home_dir ()) + strlen ("/evolution/config/file:");
- e_filename_make_safe (p);
-
- if (stat (buf, &st) == -1) {
- g_free (buf);
- return -1;
- }
-
- if (!(doc = xmlParseFile (buf))) {
- g_free (buf);
- return -1;
- }
-
- g_free (buf);
-
- if (!(node = xmlDocGetRootElement (doc)) || strcmp ((gchar *)node->name, "expanded_state") != 0) {
- xmlFreeDoc (doc);
- return -1;
- }
-
- if (!(buf = (gchar *)xmlGetProp (node, (const guchar *)"default"))) {
- xmlFreeDoc (doc);
- return -1;
- }
-
- thread_list = strcmp (buf, "0") == 0 ? 0 : 1;
- xmlFree (buf);
-
- xmlFreeDoc (doc);
-
- return thread_list;
-}
-
-static gchar *
-get_local_store_uri (const gchar *dirname, gchar **namep, gint *indexp)
-{
- gchar *name, *protocol, *metadata, *tmp;
- gint index;
- struct stat st;
- xmlNodePtr node;
- xmlDocPtr doc;
-
- metadata = g_build_filename(dirname, "local-metadata.xml", NULL);
-
- /* in 1.4, any errors are treated as defaults, this function cannot fail */
-
- /* defaults */
- name = (gchar *) "mbox";
- protocol = (gchar *) "mbox";
- index = TRUE;
-
- if (stat (metadata, &st) == -1 || !S_ISREG (st.st_mode))
- goto nofile;
-
- doc = xmlParseFile(metadata);
- if (doc == NULL)
- goto nofile;
-
- node = doc->children;
- if (strcmp((gchar *)node->name, "folderinfo"))
- goto dodefault;
-
- for (node = node->children; node; node = node->next) {
- if (node->name && !strcmp ((gchar *)node->name, "folder")) {
- tmp = (gchar *)xmlGetProp (node, (const guchar *)"type");
- if (tmp) {
- protocol = alloca(strlen(tmp)+1);
- strcpy(protocol, tmp);
- xmlFree(tmp);
- }
- tmp = (gchar *)xmlGetProp (node, (const guchar *)"name");
- if (tmp) {
- name = alloca(strlen(tmp)+1);
- strcpy(name, tmp);
- xmlFree(tmp);
- }
- tmp = (gchar *)xmlGetProp (node, (const guchar *)"index");
- if (tmp) {
- index = atoi(tmp);
- xmlFree(tmp);
- }
- }
- }
-dodefault:
- xmlFreeDoc (doc);
-nofile:
- g_free(metadata);
-
- *namep = g_strdup(name);
- *indexp = index;
-
- return g_strdup_printf("%s:%s", protocol, dirname);
-}
-
-#endif /* !G_OS_WIN32 */
-
-enum {
- CP_UNIQUE = 0,
- CP_OVERWRITE,
- CP_APPEND
-};
-
-static gint open_flags[3] = {
- O_WRONLY | O_CREAT | O_TRUNC,
- O_WRONLY | O_CREAT | O_TRUNC,
- O_WRONLY | O_CREAT | O_APPEND,
-};
-
-static gint
-cp (const gchar *src, const gchar *dest, gboolean show_progress, gint mode)
-{
- guchar readbuf[65536];
- gssize nread, nwritten;
- gint errnosav, readfd, writefd;
- gsize total = 0;
- struct stat st;
- struct utimbuf ut;
-
- /* if the dest file exists and has content, abort - we don't
- * want to corrupt their existing data */
- if (g_stat (dest, &st) == 0 && st.st_size > 0 && mode == CP_UNIQUE) {
- errno = EEXIST;
- return -1;
- }
-
- if (g_stat (src, &st) == -1
- || (readfd = g_open (src, O_RDONLY | O_BINARY, 0)) == -1)
- return -1;
-
- if ((writefd = g_open (dest, open_flags[mode] | O_BINARY, 0666)) == -1) {
- errnosav = errno;
- close (readfd);
- errno = errnosav;
- return -1;
- }
-
- do {
- do {
- nread = read (readfd, readbuf, sizeof (readbuf));
- } while (nread == -1 && errno == EINTR);
-
- if (nread == 0)
- break;
- else if (nread < 0)
- goto exception;
-
- do {
- nwritten = write (writefd, readbuf, nread);
- } while (nwritten == -1 && errno == EINTR);
-
- if (nwritten < nread)
- goto exception;
-
- total += nwritten;
- if (show_progress)
- em_migrate_set_progress (((double) total) / ((double) st.st_size));
- } while (total < st.st_size);
-
- if (fsync (writefd) == -1)
- goto exception;
-
- close (readfd);
- if (close (writefd) == -1)
- goto failclose;
-
- ut.actime = st.st_atime;
- ut.modtime = st.st_mtime;
- utime (dest, &ut);
- chmod (dest, st.st_mode);
-
- return 0;
-
- exception:
-
- errnosav = errno;
- close (readfd);
- close (writefd);
- errno = errnosav;
-
- failclose:
-
- errnosav = errno;
- unlink (dest);
- errno = errnosav;
-
- return -1;
-}
-
-#ifndef G_OS_WIN32
-
-static gint
-cp_r (const gchar *src, const gchar *dest, const gchar *pattern, gint mode)
-{
- GString *srcpath, *destpath;
- struct dirent *dent;
- gsize slen, dlen;
- struct stat st;
- DIR *dir;
-
- if (g_mkdir_with_parents (dest, 0777) == -1)
- return -1;
-
- if (!(dir = opendir (src)))
- return -1;
-
- srcpath = g_string_new (src);
- g_string_append_c (srcpath, '/');
- slen = srcpath->len;
-
- destpath = g_string_new (dest);
- g_string_append_c (destpath, '/');
- dlen = destpath->len;
-
- while ((dent = readdir (dir))) {
- if (!strcmp (dent->d_name, ".") || !strcmp (dent->d_name, ".."))
- continue;
-
- g_string_truncate (srcpath, slen);
- g_string_truncate (destpath, dlen);
-
- g_string_append (srcpath, dent->d_name);
- g_string_append (destpath, dent->d_name);
-
- if (stat (srcpath->str, &st) == -1)
- continue;
-
- if (S_ISDIR (st.st_mode)) {
- cp_r (srcpath->str, destpath->str, pattern, mode);
- } else if (!pattern || !strcmp (dent->d_name, pattern)) {
- cp (srcpath->str, destpath->str, FALSE, mode);
- }
- }
-
- closedir (dir);
-
- g_string_free (destpath, TRUE);
- g_string_free (srcpath, TRUE);
-
- return 0;
-}
-
-static void
-mbox_build_filename (GString *path, const gchar *toplevel_dir, const gchar *full_name)
-{
- const gchar *start, *inptr = full_name;
- gint subdirs = 0;
-
- while (*inptr != '\0') {
- if (*inptr == '/')
- subdirs++;
- inptr++;
- }
-
- g_string_assign(path, toplevel_dir);
- g_string_append_c (path, '/');
-
- inptr = full_name;
- while (*inptr != '\0') {
- start = inptr;
- while (*inptr != '/' && *inptr != '\0')
- inptr++;
-
- g_string_append_len (path, start, inptr - start);
-
- if (*inptr == '/') {
- g_string_append (path, ".sbd/");
- inptr++;
-
- /* strip extranaeous '/'s */
- while (*inptr == '/')
- inptr++;
- }
- }
-}
-
-static gint
-em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *full_name, CamelException *ex)
-{
- CamelFolder *old_folder = NULL, *new_folder = NULL;
- CamelStore *local_store = NULL;
- gchar *name, *uri;
- GPtrArray *uids;
- struct stat st;
- gint thread_list;
- gint index, i;
- GString *src, *dest;
- gint res = -1;
-
- src = g_string_new("");
-
- g_string_printf(src, "%s/folder-metadata.xml", dirname);
- if (stat (src->str, &st) == -1
- || !S_ISREG (st.st_mode)
- || !is_mail_folder(src->str)) {
- /* Not an evolution mail folder */
- g_string_free(src, TRUE);
- return 0;
- }
-
- dest = g_string_new("");
- uri = get_local_store_uri(dirname, &name, &index);
- em_migrate_set_folder_name (full_name);
- thread_list = get_local_et_expanded (dirname);
-
- /* Manually copy local mbox files, its much faster */
- if (!strncmp (uri, "mbox:", 5)) {
- static const gchar *meta_ext[] = { ".summary", ".ibex.index", ".ibex.index.data" };
- gsize slen, dlen;
- FILE *fp;
- gchar *p;
- gint mode;
-
- g_string_printf (src, "%s/%s", uri + 5, name);
- mbox_build_filename (dest, ((CamelService *)session->store)->url->path, full_name);
- p = strrchr (dest->str, '/');
- *p = '\0';
-
- slen = src->len;
- dlen = dest->len;
-
- if (g_mkdir_with_parents (dest->str, 0777) == -1 && errno != EEXIST) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to create new folder `%s': %s"),
- dest->str, g_strerror(errno));
- goto fatal;
- }
-
- *p = '/';
- mode = CP_UNIQUE;
- retry_copy:
- if (cp (src->str, dest->str, TRUE, mode) == -1) {
- if (errno == EEXIST) {
- gint save = errno;
-
- switch (e_error_run(NULL, "mail:ask-migrate-existing", src->str, dest->str, NULL)) {
- case GTK_RESPONSE_ACCEPT:
- mode = CP_OVERWRITE;
- goto retry_copy;
- case GTK_RESPONSE_OK:
- mode = CP_APPEND;
- goto retry_copy;
- case GTK_RESPONSE_REJECT:
- goto ignore;
- }
-
- errno = save;
- }
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to copy folder `%s' to `%s': %s"),
- src->str, dest->str, g_strerror(errno));
- goto fatal;
- }
- ignore:
-
- /* create a .cmeta file specifying to index and/or thread the folder */
- g_string_truncate (dest, dlen);
- g_string_append (dest, ".cmeta");
- if ((fp = fopen (dest->str, "w")) != NULL) {
- gint fd = fileno (fp);
-
- /* write the magic string */
- if (fwrite ("CLMD", 4, 1, fp) != 1)
- goto cmeta_err;
-
- /* write the version (1) */
- if (camel_file_util_encode_uint32 (fp, 1) == -1)
- goto cmeta_err;
-
- /* write the meta count */
- if (camel_file_util_encode_uint32 (fp, thread_list != -1 ? 1 : 0) == -1)
- goto cmeta_err;
-
- if (thread_list != -1) {
- if (camel_file_util_encode_string (fp, "evolution:thread_list") == -1)
- goto cmeta_err;
-
- if (camel_file_util_encode_string (fp, thread_list ? "1" : "0") == -1)
- goto cmeta_err;
- }
-
- /* write the prop count (only prop is the index prop) */
- if (camel_file_util_encode_uint32 (fp, 1) == -1)
- goto cmeta_err;
-
- /* write the index prop tag (== CAMEL_FOLDER_ARG_LAST|CAMEL_ARG_BOO) */
- if (camel_file_util_encode_uint32 (fp, CAMEL_FOLDER_ARG_LAST|CAMEL_ARG_BOO) == -1)
- goto cmeta_err;
-
- /* write the index prop value */
- if (camel_file_util_encode_uint32 (fp, 1) == -1)
- goto cmeta_err;
-
- fflush (fp);
-
- if (fsync (fd) == -1) {
- cmeta_err:
- fclose (fp);
- unlink (dest->str);
- } else {
- fclose (fp);
- }
- }
-
- /* copy over the metadata files */
- for (i = 0; i < sizeof(meta_ext)/sizeof(meta_ext[0]); i++) {
- g_string_truncate (src, slen);
- g_string_truncate (dest, dlen);
-
- g_string_append (src, meta_ext[i]);
- g_string_append (dest, meta_ext[i]);
- cp (src->str, dest->str, FALSE, CP_OVERWRITE);
- }
- } else {
- guint32 flags = CAMEL_STORE_FOLDER_CREATE;
-
- if (!(local_store = camel_session_get_store ((CamelSession *) session, uri, ex))
- || !(old_folder = camel_store_get_folder (local_store, name, 0, ex)))
- goto fatal;
-
- flags |= (index ? CAMEL_STORE_FOLDER_BODY_INDEX : 0);
- if (!(new_folder = camel_store_get_folder (session->store, full_name, flags, ex)))
- goto fatal;
-
- if (thread_list != -1) {
- camel_object_meta_set (new_folder, "evolution:thread_list", thread_list ? "1" : "0");
- camel_object_state_write (new_folder);
- }
-
- uids = camel_folder_get_uids (old_folder);
- for (i = 0; i < uids->len; i++) {
- CamelMimeMessage *message;
- CamelMessageInfo *info;
-
- if (!(info = camel_folder_get_message_info (old_folder, uids->pdata[i])))
- continue;
-
- if (!(message = camel_folder_get_message (old_folder, uids->pdata[i], ex))) {
- camel_folder_free_message_info (old_folder, info);
- camel_folder_free_uids (old_folder, uids);
- goto fatal;
- }
-
- camel_folder_append_message (new_folder, message, info, NULL, ex);
- camel_folder_free_message_info (old_folder, info);
- camel_object_unref (message);
-
- if (camel_exception_is_set (ex))
- break;
-
- em_migrate_set_progress (((double) i + 1) / ((double) uids->len));
- }
-
- camel_folder_free_uids (old_folder, uids);
-
- if (camel_exception_is_set (ex))
- goto fatal;
- }
- res = 0;
-fatal:
- g_free (uri);
- g_free (name);
- g_string_free(src, TRUE);
- g_string_free(dest, TRUE);
- if (local_store)
- camel_object_unref(local_store);
- if (old_folder)
- camel_object_unref(old_folder);
- if (new_folder)
- camel_object_unref(new_folder);
-
- return res;
-}
-
-static gint
-em_migrate_dir (EMMigrateSession *session, const gchar *dirname, const gchar *full_name, CamelException *ex)
-{
- gchar *path;
- DIR *dir;
- struct stat st;
- struct dirent *dent;
- gint res = 0;
-
- if (em_migrate_folder(session, dirname, full_name, ex) == -1)
- return -1;
-
- /* no subfolders, not readable, don't care */
- path = g_strdup_printf ("%s/subfolders", dirname);
- if (stat (path, &st) == -1 || !S_ISDIR (st.st_mode)) {
- g_free (path);
- return 0;
- }
-
- if (!(dir = opendir (path))) {
- g_free (path);
- return 0;
- }
-
- while (res == 0 && (dent = readdir (dir))) {
- gchar *full_path;
- gchar *name;
-
- if (dent->d_name[0] == '.')
- continue;
-
- full_path = g_strdup_printf ("%s/%s", path, dent->d_name);
- if (stat (full_path, &st) == -1 || !S_ISDIR (st.st_mode)) {
- g_free (full_path);
- continue;
- }
-
- name = g_strdup_printf ("%s/%s", full_name, dent->d_name);
- res = em_migrate_dir (session, full_path, name, ex);
- g_free (full_path);
- g_free (name);
- }
-
- closedir (dir);
-
- g_free (path);
-
- return res;
-}
-
-static gint
-em_migrate_local_folders_1_4 (EMMigrateSession *session, CamelException *ex)
-{
- struct dirent *dent;
- struct stat st;
- DIR *dir;
- gint res = 0;
-
- if (!(dir = opendir (session->srcdir))) {
- camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to scan for existing mailboxes at `%s': %s"),
- session->srcdir, g_strerror(errno));
- return -1;
- }
-
- em_migrate_setup_progress_dialog (NULL, _("The location and hierarchy of the Evolution mailbox "
- "folders has changed since Evolution 1.x.\n\nPlease be "
- "patient while Evolution migrates your folders..."));
-
- while (res == 0 && (dent = readdir (dir))) {
- gchar *full_path;
-
- if (dent->d_name[0] == '.')
- continue;
-
- full_path = g_strdup_printf ("%s/%s", session->srcdir, dent->d_name);
- if (stat (full_path, &st) == -1 || !S_ISDIR (st.st_mode)) {
- g_free (full_path);
- continue;
- }
-
- res = em_migrate_dir (session, full_path, dent->d_name, ex);
- g_free (full_path);
- }
-
- closedir (dir);
-
- em_migrate_close_progress_dialog ();
-
- return res;
-}
-
-static gchar *
-upgrade_xml_uris_1_4 (const gchar *uri)
-{
- gchar *path, *prefix, *p;
- CamelURL *url;
-
- if (!strncmp (uri, "file:", 5)) {
- url = camel_url_new (uri, NULL);
- camel_url_set_protocol (url, "email");
- camel_url_set_user (url, "local");
- camel_url_set_host (url, "local");
-
- prefix = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
- if (strncmp (url->path, prefix, strlen (prefix)) != 0) {
- /* uri is busticated - user probably copied from another user's home directory */
- camel_url_free (url);
- g_free (prefix);
-
- return g_strdup (uri);
- }
- path = g_strdup (url->path + strlen (prefix));
- g_free (prefix);
-
- /* modify the path in-place */
- p = path + strlen (path) - 12;
- while (p > path) {
- if (!strncmp (p, "/subfolders/", 12))
- memmove (p, p + 11, strlen (p + 11) + 1);
-
- p--;
- }
-
- camel_url_set_path (url, path);
- g_free (path);
-
- path = camel_url_to_string (url, 0);
- camel_url_free (url);
-
- return path;
- } else {
- return em_uri_from_camel (uri);
- }
-}
-
-static void
-upgrade_vfolder_sources_1_4 (xmlDocPtr doc)
-{
- xmlNodePtr root, node;
-
- if (!doc || !(root = xmlDocGetRootElement (doc)))
- return;
-
- if (!root->name || strcmp ((gchar *)root->name, "filteroptions") != 0) {
- /* root node is not <filteroptions>, nothing to upgrade */
- return;
- }
-
- if (!(node = xml_find_node (root, "ruleset"))) {
- /* no ruleset node, nothing to upgrade */
- return;
- }
-
- node = node->children;
- while (node != NULL) {
- if (node->name && !strcmp ((gchar *)node->name, "rule")) {
- xmlNodePtr sources;
- gchar *src;
-
- if (!(src = (gchar *)xmlGetProp (node, (const guchar *)"source")))
- src = (gchar *)xmlStrdup ((const guchar *)"local"); /* default to all local folders? */
-
- xmlSetProp (node, (const guchar *)"source", (const guchar *)"incoming");
-
- if (!(sources = xml_find_node (node, "sources")))
- sources = xmlNewChild (node, NULL, (const guchar *)"sources", NULL);
-
- xmlSetProp (sources, (const guchar *)"with", (guchar *)src);
- xmlFree (src);
- }
-
- node = node->next;
- }
-}
-
-static gchar *
-get_nth_sig (gint id)
-{
- ESignatureList *list;
- ESignature *sig;
- EIterator *iter;
- gchar *uid = NULL;
- gint i = 0;
-
- list = mail_config_get_signatures ();
- iter = e_list_get_iterator ((EList *) list);
-
- while (e_iterator_is_valid (iter) && i < id) {
- e_iterator_next (iter);
- i++;
- }
-
- if (i == id && e_iterator_is_valid (iter)) {
- sig = (ESignature *) e_iterator_get (iter);
- uid = g_strdup (sig->uid);
- }
-
- g_object_unref (iter);
-
- return uid;
-}
-
-static void
-em_upgrade_accounts_1_4 (void)
-{
- EAccountList *accounts;
- EIterator *iter;
-
- if (!(accounts = mail_config_get_accounts ()))
- return;
-
- iter = e_list_get_iterator ((EList *) accounts);
- while (e_iterator_is_valid (iter)) {
- EAccount *account = (EAccount *) e_iterator_get (iter);
- gchar *url;
-
- if (account->drafts_folder_uri) {
- url = upgrade_xml_uris_1_4 (account->drafts_folder_uri);
- g_free (account->drafts_folder_uri);
- account->drafts_folder_uri = url;
- }
-
- if (account->sent_folder_uri) {
- url = upgrade_xml_uris_1_4 (account->sent_folder_uri);
- g_free (account->sent_folder_uri);
- account->sent_folder_uri = url;
- }
-
- if (account->id->sig_uid && !strncmp (account->id->sig_uid, "::", 2)) {
- gint sig_id;
-
- sig_id = strtol (account->id->sig_uid + 2, NULL, 10);
- g_free (account->id->sig_uid);
- account->id->sig_uid = get_nth_sig (sig_id);
- }
-
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
-
- mail_config_save_accounts ();
-}
-
-static gint
-em_migrate_pop_uid_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
-{
- GString *oldpath, *newpath;
- struct dirent *dent;
- gsize olen, nlen;
- gchar *cache_dir;
- DIR *dir;
- gint res = 0;
-
- /* Sigh, too many unique strings to translate, for cases which shouldn't ever happen */
-
- /* open the old cache dir */
- cache_dir = g_build_filename (g_get_home_dir (), "evolution", "mail", "pop3", NULL);
- if (!(dir = opendir (cache_dir))) {
- if (errno == ENOENT) {
- g_free(cache_dir);
- return 0;
- }
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to open old POP keep-on-server data `%s': %s"),
- cache_dir, g_strerror (errno));
- g_free (cache_dir);
- return -1;
- }
-
- oldpath = g_string_new (cache_dir);
- g_string_append_c (oldpath, '/');
- olen = oldpath->len;
- g_free (cache_dir);
-
- cache_dir = g_build_filename (evolution_dir, "mail", "pop", NULL);
- if (g_mkdir_with_parents (cache_dir, 0777) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to create POP3 keep-on-server data directory `%s': %s"),
- cache_dir, g_strerror(errno));
- g_string_free (oldpath, TRUE);
- g_free (cache_dir);
- closedir (dir);
- return -1;
- }
-
- newpath = g_string_new (cache_dir);
- g_string_append_c (newpath, '/');
- nlen = newpath->len;
- g_free (cache_dir);
-
- while (res == 0 && (dent = readdir (dir))) {
- if (strncmp (dent->d_name, "cache-pop:__", 12) != 0)
- continue;
-
- g_string_truncate (oldpath, olen);
- g_string_truncate (newpath, nlen);
-
- g_string_append (oldpath, dent->d_name);
- g_string_append (newpath, dent->d_name + 12);
-
- /* strip the trailing '_' */
- g_string_truncate (newpath, newpath->len - 1);
-
- if (g_mkdir_with_parents (newpath->str, 0777) == -1
- || cp(oldpath->str, (g_string_append(newpath, "/uid-cache"))->str, FALSE, CP_UNIQUE)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to copy POP3 keep-on-server data `%s': %s"),
- oldpath->str, g_strerror(errno));
- res = -1;
- }
-
- }
-
- g_string_free (oldpath, TRUE);
- g_string_free (newpath, TRUE);
-
- closedir (dir);
-
- return res;
-}
-
-static gint
-em_migrate_imap_caches_1_4 (const gchar *evolution_dir, CamelException *ex)
-{
- gchar *src, *dest;
- struct stat st;
-
- src = g_build_filename (g_get_home_dir (), "evolution", "mail", "imap", NULL);
- if (stat (src, &st) == -1 || !S_ISDIR (st.st_mode)) {
- g_free (src);
- return 0;
- }
-
- dest = g_build_filename (evolution_dir, "mail", "imap", NULL);
-
- /* we don't care if this fails, it's only a cache... */
- cp_r (src, dest, "summary", CP_OVERWRITE);
-
- g_free (dest);
- g_free (src);
-
- return 0;
-}
-
-static gint
-em_migrate_folder_expand_state_1_4 (const gchar *evolution_dir, CamelException *ex)
-{
- GString *srcpath, *destpath;
- gsize slen, dlen, rlen;
- gchar *evo14_mbox_root;
- struct dirent *dent;
- struct stat st;
- DIR *dir;
-
- srcpath = g_string_new (g_get_home_dir ());
- g_string_append (srcpath, "/evolution/config");
- if (stat (srcpath->str, &st) == -1 || !S_ISDIR (st.st_mode)) {
- g_string_free (srcpath, TRUE);
- return 0;
- }
-
- destpath = g_string_new (evolution_dir);
- g_string_append (destpath, "/mail/config");
- if (g_mkdir_with_parents (destpath->str, 0777) == -1 || !(dir = opendir (srcpath->str))) {
- g_string_free (destpath, TRUE);
- g_string_free (srcpath, TRUE);
- return 0;
- }
-
- g_string_append (srcpath, "/et-expanded-");
- slen = srcpath->len;
- g_string_append (destpath, "/et-expanded-");
- dlen = destpath->len;
-
- evo14_mbox_root = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
- e_filename_make_safe (evo14_mbox_root);
- rlen = strlen (evo14_mbox_root);
- evo14_mbox_root = g_realloc (evo14_mbox_root, rlen + 2);
- evo14_mbox_root[rlen++] = '_';
- evo14_mbox_root[rlen] = '\0';
-
- while ((dent = readdir (dir))) {
- gchar *full_name, *inptr, *buf = NULL;
- const gchar *filename;
- GString *new;
-
- if (strncmp (dent->d_name, "et-expanded-", 12) != 0)
- continue;
-
- if (!strncmp (dent->d_name + 12, "file:", 5)) {
- /* need to munge the filename */
- inptr = dent->d_name + 17;
-
- if (!strncmp (inptr, evo14_mbox_root, rlen)) {
- /* this should always be the case afaik... */
- inptr += rlen;
- new = g_string_new ("mbox:");
- g_string_append_printf (new, "%s/mail/local#", evolution_dir);
-
- full_name = g_strdup (inptr);
- inptr = full_name + strlen (full_name) - 12;
- while (inptr > full_name) {
- if (!strncmp (inptr, "_subfolders_", 12))
- memmove (inptr, inptr + 11, strlen (inptr + 11) + 1);
-
- inptr--;
- }
-
- g_string_append (new, full_name);
- g_free (full_name);
-
- filename = buf = new->str;
- g_string_free (new, FALSE);
- e_filename_make_safe (buf);
- } else {
- /* but just in case... */
- filename = dent->d_name + 12;
- }
- } else {
- /* no munging needed */
- filename = dent->d_name + 12;
- }
-
- g_string_append (srcpath, dent->d_name + 12);
- g_string_append (destpath, filename);
- g_free (buf);
-
- cp (srcpath->str, destpath->str, FALSE, CP_UNIQUE);
-
- g_string_truncate (srcpath, slen);
- g_string_truncate (destpath, dlen);
- }
-
- closedir (dir);
-
- g_free (evo14_mbox_root);
- g_string_free (destpath, TRUE);
- g_string_free (srcpath, TRUE);
-
- return 0;
-}
-
-static gint
-em_migrate_folder_view_settings_1_4 (const gchar *evolution_dir, CamelException *ex)
-{
- GString *srcpath, *destpath;
- gsize slen, dlen, rlen;
- gchar *evo14_mbox_root;
- struct dirent *dent;
- struct stat st;
- DIR *dir;
-
- srcpath = g_string_new (g_get_home_dir ());
- g_string_append (srcpath, "/evolution/views/mail");
- if (stat (srcpath->str, &st) == -1 || !S_ISDIR (st.st_mode)) {
- g_string_free (srcpath, TRUE);
- return 0;
- }
-
- destpath = g_string_new (evolution_dir);
- g_string_append (destpath, "/mail/views");
- if (g_mkdir_with_parents (destpath->str, 0777) == -1 || !(dir = opendir (srcpath->str))) {
- g_string_free (destpath, TRUE);
- g_string_free (srcpath, TRUE);
- return 0;
- }
-
- g_string_append_c (srcpath, '/');
- slen = srcpath->len;
- g_string_append_c (destpath, '/');
- dlen = destpath->len;
-
- evo14_mbox_root = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
- e_filename_make_safe (evo14_mbox_root);
- rlen = strlen (evo14_mbox_root);
- evo14_mbox_root = g_realloc (evo14_mbox_root, rlen + 2);
- evo14_mbox_root[rlen++] = '_';
- evo14_mbox_root[rlen] = '\0';
-
- while ((dent = readdir (dir))) {
- gchar *full_name, *inptr, *buf = NULL;
- const gchar *filename, *ext;
- gsize prelen = 0;
- GString *new;
-
- if (dent->d_name[0] == '.')
- continue;
-
- if (!(ext = strrchr (dent->d_name, '.')))
- continue;
-
- if (!strcmp (ext, ".galview") || !strcmp ((gchar *)dent->d_name, "galview.xml")) {
- /* just copy the file */
- filename = dent->d_name;
- goto copy;
- } else if (strcmp (ext, ".xml") != 0) {
- continue;
- }
-
- if (!strncmp ((const gchar *)dent->d_name, "current_view-", 13)) {
- prelen = 13;
- } else if (!strncmp ((const gchar *)dent->d_name, "custom_view-", 12)) {
- prelen = 12;
- } else {
- /* huh? wtf is this file? */
- continue;
- }
-
- if (!strncmp (dent->d_name + prelen, "file:", 5)) {
- /* need to munge the filename */
- inptr = dent->d_name + prelen + 5;
-
- if (!strncmp (inptr, evo14_mbox_root, rlen)) {
- /* this should always be the case afaik... */
- inptr += rlen;
- new = g_string_new ("mbox:");
- g_string_append_printf (new, "%s/mail/local#", evolution_dir);
-
- full_name = g_strdup (inptr);
- inptr = full_name + strlen (full_name) - 12;
- while (inptr > full_name) {
- if (!strncmp (inptr, "_subfolders_", 12))
- memmove (inptr, inptr + 11, strlen (inptr + 11) + 1);
-
- inptr--;
- }
-
- g_string_append (new, full_name);
- g_free (full_name);
-
- filename = buf = new->str;
- g_string_free (new, FALSE);
- e_filename_make_safe (buf);
- } else {
- /* but just in case... */
- filename = dent->d_name + prelen;
- }
- } else {
- /* no munging needed */
- filename = dent->d_name + prelen;
- }
-
- copy:
- g_string_append (srcpath, dent->d_name);
- if (prelen > 0)
- g_string_append_len (destpath, dent->d_name, prelen);
- g_string_append (destpath, filename);
- g_free (buf);
-
- cp (srcpath->str, destpath->str, FALSE, CP_UNIQUE);
-
- g_string_truncate (srcpath, slen);
- g_string_truncate (destpath, dlen);
- }
-
- closedir (dir);
-
- g_free (evo14_mbox_root);
- g_string_free (destpath, TRUE);
- g_string_free (srcpath, TRUE);
-
- return 0;
-}
-
-#define SUBFOLDER_DIR_NAME "subfolders"
-#define SUBFOLDER_DIR_NAME_LEN 10
-
-static gchar *
-e_path_to_physical (const gchar *prefix, const gchar *vpath)
-{
- const gchar *p, *newp;
- gchar *dp;
- gchar *ppath;
- gint ppath_len;
- gint prefix_len;
-
- while (*vpath == '/')
- vpath++;
- if (!prefix)
- prefix = "";
-
- /* Calculate the length of the real path. */
- ppath_len = strlen (vpath);
- ppath_len++; /* For the ending zero. */
-
- prefix_len = strlen (prefix);
- ppath_len += prefix_len;
- ppath_len++; /* For the separating slash. */
-
- /* Take account of the fact that we need to translate every
- * separator into `subfolders/'.
- */
- p = vpath;
- while (1) {
- newp = strchr (p, '/');
- if (newp == NULL)
- break;
-
- ppath_len += SUBFOLDER_DIR_NAME_LEN;
- ppath_len++; /* For the separating slash. */
-
- /* Skip consecutive slashes. */
- while (*newp == '/')
- newp++;
-
- p = newp;
- };
-
- ppath = g_malloc (ppath_len);
- dp = ppath;
-
- memcpy (dp, prefix, prefix_len);
- dp += prefix_len;
- *(dp++) = '/';
-
- /* Copy the mangled path. */
- p = vpath;
- while (1) {
- newp = strchr (p, '/');
- if (newp == NULL) {
- strcpy (dp, p);
- break;
- }
-
- memcpy (dp, p, newp - p + 1); /* `+ 1' to copy the slash too. */
- dp += newp - p + 1;
-
- memcpy (dp, SUBFOLDER_DIR_NAME, SUBFOLDER_DIR_NAME_LEN);
- dp += SUBFOLDER_DIR_NAME_LEN;
-
- *(dp++) = '/';
-
- /* Skip consecutive slashes. */
- while (*newp == '/')
- newp++;
-
- p = newp;
- }
-
- return ppath;
-}
-
-static gint
-em_migrate_imap_cmeta_1_4(const gchar *evolution_dir, CamelException *ex)
-{
- GConfClient *gconf;
- GSList *paths, *p;
- EAccountList *accounts;
- const EAccount *account;
-
- if (!(accounts = mail_config_get_accounts()))
- return 0;
-
- gconf = gconf_client_get_default();
- paths = gconf_client_get_list(gconf, "/apps/evolution/shell/offline/folder_paths", GCONF_VALUE_STRING, NULL);
- for (p = paths;p;p = g_slist_next(p)) {
- gchar *name, *path;
-
- name = p->data;
- if (*name)
- name++;
- path = strchr(name, '/');
- if (path) {
- *path++ = 0;
- account = e_account_list_find(accounts, E_ACCOUNT_FIND_NAME, name);
- if (account && !strncmp(account->source->url, "imap:", 5)) {
- CamelURL *url = camel_url_new(account->source->url, NULL);
-
- if (url) {
- gchar *dir, *base;
-
- base = g_strdup_printf("%s/mail/imap/%s@%s/folders",
- evolution_dir,
- url->user?url->user:"",
- url->host?url->host:"");
-
- dir = e_path_to_physical(base, path);
- if (g_mkdir_with_parents(dir, 0777) == 0) {
- gchar *cmeta;
- FILE *fp;
-
- cmeta = g_build_filename(dir, "cmeta", NULL);
- fp = fopen(cmeta, "w");
- if (fp) {
- /* header/version */
- fwrite("CLMD", 4, 1, fp);
- camel_file_util_encode_uint32(fp, 1);
- /* meta count, do we have any metadata? */
- camel_file_util_encode_uint32(fp, 0);
- /* prop count */
- camel_file_util_encode_uint32(fp, 1);
- /* sync offline property */
- camel_file_util_encode_uint32(fp, CAMEL_DISCO_FOLDER_OFFLINE_SYNC);
- camel_file_util_encode_uint32(fp, 1);
- fclose(fp);
- } else {
- g_warning("couldn't create imap folder cmeta file '%s'", cmeta);
- }
- g_free(cmeta);
- } else {
- g_warning("couldn't create imap folder directory '%s'", dir);
- }
- g_free(dir);
- g_free(base);
- camel_url_free(url);
- }
- } else
- g_warning("can't find offline folder '%s' '%s'", name, path);
- }
- g_free(p->data);
- }
- g_slist_free(paths);
- g_object_unref(gconf);
-
- /* we couldn't care less if this doesn't work */
-
- return 0;
-}
-
-static void
-remove_system_searches(xmlDocPtr searches)
-{
- xmlNodePtr node;
-
- /* in pre 2.0, system searches were stored in the user
- * searches.xml file with the source set to 'demand'. In 2.0+
- * the system searches are stored in the system
- * searchtypes.xml file instead */
-
- node = xmlDocGetRootElement(searches);
- if (!node->name || strcmp((gchar *)node->name, "filteroptions"))
- return;
-
- if (!(node = xml_find_node(node, "ruleset")))
- return;
-
- node = node->children;
- while (node != NULL) {
- xmlNodePtr nnode = node->next;
-
- if (node->name && !strcmp ((gchar *)node->name, "rule")) {
- gchar *src;
-
- src = (gchar *)xmlGetProp(node, (guchar *)"source");
- if (src && !strcmp((gchar *)src, "demand")) {
- xmlUnlinkNode(node);
- xmlFreeNodeList(node);
- }
- xmlFree (src);
- }
-
- node = nnode;
- }
-}
-
-static gint
-em_migrate_1_4 (const gchar *evolution_dir, xmlDocPtr filters, xmlDocPtr vfolders, CamelException *ex)
-{
- EMMigrateSession *session;
- CamelException lex;
- struct stat st;
- gchar *path;
- xmlDocPtr searches;
-
- path = g_build_filename (evolution_dir, "mail", NULL);
-
- camel_init (path, TRUE);
- camel_provider_init();
- session = (EMMigrateSession *) em_migrate_session_new (path);
- g_free (path);
-
- session->srcdir = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
-
- path = g_strdup_printf ("mbox:%s/.evolution/mail/local", g_get_home_dir ());
- if (stat (path + 5, &st) == -1) {
- if (errno != ENOENT || g_mkdir_with_parents (path + 5, 0777) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to create local mail storage `%s': %s"),
- path + 5, g_strerror (errno));
- g_free (session->srcdir);
- camel_object_unref (session);
- g_free (path);
- return -1;
- }
- }
-
- camel_exception_init (&lex);
- if (!(session->store = camel_session_get_store ((CamelSession *) session, path, &lex))) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Failed to create local mail storage `%s': %s"),
- path, lex.desc);
- g_free (session->srcdir);
- camel_object_unref (session);
- camel_exception_clear (&lex);
- g_free (path);
- return -1;
- }
- g_free (path);
-
- if (em_migrate_local_folders_1_4 (session, ex) == -1)
- return -1;
-
- camel_object_unref (session->store);
- g_free (session->srcdir);
-
- camel_object_unref (session);
-
- em_upgrade_accounts_1_4();
-
- upgrade_xml_uris(filters, upgrade_xml_uris_1_4);
- upgrade_vfolder_sources_1_4(vfolders);
- upgrade_xml_uris(vfolders, upgrade_xml_uris_1_4);
-
- path = g_build_filename(g_get_home_dir(), "evolution", NULL);
- searches = emm_load_xml(path, "searches.xml");
- g_free(path);
- if (searches) {
- remove_system_searches(searches);
- path = g_build_filename(evolution_dir, "mail", NULL);
- emm_save_xml(searches, path, "searches.xml");
- g_free(path);
- xmlFreeDoc(searches);
- }
-
- if (em_migrate_pop_uid_caches_1_4 (evolution_dir, ex) == -1)
- return -1;
-
- /* these are non-fatal */
- em_migrate_imap_caches_1_4 (evolution_dir, ex);
- camel_exception_clear(ex);
- em_migrate_folder_expand_state_1_4 (evolution_dir, ex);
- camel_exception_clear(ex);
- em_migrate_folder_view_settings_1_4 (evolution_dir, ex);
- camel_exception_clear(ex);
- em_migrate_imap_cmeta_1_4(evolution_dir, ex);
- camel_exception_clear(ex);
-
- return 0;
-}
-
-static void
-em_update_accounts_2_11 (void)
-{
- EAccountList *accounts;
- EIterator *iter;
- gboolean changed = FALSE;
-
- if (!(accounts = mail_config_get_accounts ()))
- return;
-
- iter = e_list_get_iterator ((EList *) accounts);
- while (e_iterator_is_valid (iter)) {
- EAccount *account = (EAccount *) e_iterator_get (iter);
-
- if (g_str_has_prefix (account->source->url, "spool://")) {
- if (g_file_test (account->source->url + 8, G_FILE_TEST_IS_DIR)) {
- gchar *str = g_strdup_printf ("spooldir://%s", account->source->url + 8);
-
- g_free (account->source->url);
- account->source->url = str;
- changed = TRUE;
- }
- }
-
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
-
- if (changed)
- mail_config_save_accounts ();
-}
-
-#endif /* !G_OS_WIN32 */
-
-static gint
-emm_setup_initial(const gchar *evolution_dir)
-{
- GDir *dir;
- const gchar *d;
- gchar *local = NULL, *base;
- const gchar * const *language_names;
-
- /* special-case - this means brand new install of evolution */
- /* FIXME: create default folders and stuff... */
-
- d(printf("Setting up initial mail tree\n"));
-
- base = g_build_filename(evolution_dir, "mail", "local", NULL);
- if (g_mkdir_with_parents(base, 0777) == -1 && errno != EEXIST) {
- g_free(base);
- return -1;
- }
-
- /* e.g. try en-AU then en, etc */
- language_names = g_get_language_names ();
- while (*language_names != NULL) {
- local = g_build_filename (
- EVOLUTION_PRIVDATADIR, "default",
- *language_names, "mail", "local", NULL);
- if (g_file_test (local, G_FILE_TEST_EXISTS))
- break;
- g_free (local);
- language_names++;
- }
-
- /* Make sure we found one. */
- g_return_val_if_fail (*language_names != NULL, 0);
-
- dir = g_dir_open(local, 0, NULL);
- if (dir) {
- while ((d = g_dir_read_name(dir))) {
- gchar *src, *dest;
-
- src = g_build_filename(local, d, NULL);
- dest = g_build_filename(base, d, NULL);
-
- cp(src, dest, FALSE, CP_UNIQUE);
- g_free(dest);
- g_free(src);
- }
- g_dir_close(dir);
- }
-
- g_free(local);
- g_free(base);
-
- return 0;
-}
-
-static gboolean
-is_in_plugs_list (GSList *list, const gchar *value)
-{
- GSList *l;
-
- for (l = list; l; l = l->next) {
- if (l->data && !strcmp (l->data, value))
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*
- * em_update_message_notify_settings_2_21
- * DBus plugin and sound email notification was merged to mail-notification plugin,
- * so move these options to new locations.
- */
-static void
-em_update_message_notify_settings_2_21 (void)
-{
- GConfClient *client;
- GConfValue *is_key;
- gboolean dbus, status;
- GSList *list;
- gchar *str;
- gint val;
-
- client = gconf_client_get_default ();
-
- is_key = gconf_client_get (client, "/apps/evolution/eplugin/mail-notification/dbus-enabled", NULL);
- if (is_key) {
- /* already migrated, so do not migrate again */
- gconf_value_free (is_key);
- g_object_unref (client);
-
- return;
- }
-
- gconf_client_set_bool (client, "/apps/evolution/eplugin/mail-notification/status-blink-icon",
- gconf_client_get_bool (client, "/apps/evolution/mail/notification/blink-status-icon", NULL), NULL);
- gconf_client_set_bool (client, "/apps/evolution/eplugin/mail-notification/status-notification",
- gconf_client_get_bool (client, "/apps/evolution/mail/notification/notification", NULL), NULL);
-
- list = gconf_client_get_list (client, "/apps/evolution/eplugin/disabled", GCONF_VALUE_STRING, NULL);
- dbus = !is_in_plugs_list (list, "org.gnome.evolution.new_mail_notify");
- status = !is_in_plugs_list (list, "org.gnome.evolution.mail_notification");
-
- gconf_client_set_bool (client, "/apps/evolution/eplugin/mail-notification/dbus-enabled", dbus, NULL);
- gconf_client_set_bool (client, "/apps/evolution/eplugin/mail-notification/status-enabled", status, NULL);
-
- if (!status) {
- /* enable this plugin, because it holds all those other things */
- GSList *plugins, *l;
-
- plugins = e_plugin_list_plugins ();
-
- for (l = plugins; l; l = l->next) {
- EPlugin *p = l->data;
-
- if (p && p->id && !strcmp (p->id, "org.gnome.evolution.mail_notification")) {
- e_plugin_enable (p, 1);
- break;
- }
- }
-
- g_slist_foreach (plugins, (GFunc)g_object_unref, NULL);
- g_slist_free (plugins);
- }
-
- g_slist_foreach (list, (GFunc) g_free, NULL);
- g_slist_free (list);
-
- val = gconf_client_get_int (client, "/apps/evolution/mail/notify/type", NULL);
- gconf_client_set_bool (client, "/apps/evolution/eplugin/mail-notification/sound-enabled", val == 1 || val == 2, NULL);
- gconf_client_set_bool (client, "/apps/evolution/eplugin/mail-notification/sound-beep", val == 0 || val == 1, NULL);
-
- str = gconf_client_get_string (client, "/apps/evolution/mail/notify/sound", NULL);
- gconf_client_set_string (client, "/apps/evolution/eplugin/mail-notification/sound-file", str ? str : "", NULL);
- g_free (str);
-
- g_object_unref (client);
-}
-
-/* fixing typo in SpamAssassin name */
-static void
-em_update_sa_junk_setting_2_23 (void)
-{
- GConfClient *client;
- GConfValue *key;
-
- client = gconf_client_get_default ();
-
- key = gconf_client_get (client, "/apps/evolution/mail/junk/default_plugin", NULL);
- if (key) {
- const gchar *str = gconf_value_get_string (key);
-
- if (str && strcmp (str, "Spamassasin") == 0)
- gconf_client_set_string (client, "/apps/evolution/mail/junk/default_plugin", "SpamAssassin", NULL);
-
- gconf_value_free (key);
- g_object_unref (client);
-
- return;
- }
-
- g_object_unref (client);
-}
-
-static gboolean
-update_progress_in_main_thread (double *progress)
-{
- em_migrate_set_progress (*progress);
- return FALSE;
-}
-
-static void
-migrate_folders(CamelStore *store, gboolean is_local, CamelFolderInfo *fi, const gchar *acc, CamelException *ex, gboolean *done, gint *nth_folder, gint total_folders)
-{
- CamelFolder *folder;
-
- while (fi) {
- double progress;
- gchar *tmp;
-
- *nth_folder = *nth_folder + 1;
-
- tmp = g_strdup_printf ("%s/%s", acc, fi->full_name);
- em_migrate_set_folder_name (tmp);
- g_free (tmp);
-
- progress = (double) (*nth_folder) / total_folders;
- g_idle_add ((GSourceFunc) update_progress_in_main_thread, &progress);
-
- if (is_local)
- folder = camel_store_get_folder (store, fi->full_name, CAMEL_STORE_IS_MIGRATING, ex);
- else
- folder = camel_store_get_folder (store, fi->full_name, 0, ex);
-
- if (folder != NULL)
- camel_folder_summary_migrate_infos (folder->summary);
-
- migrate_folders(store, is_local, fi->child, acc, ex, done, nth_folder, total_folders);
-
- fi = fi->next;
- }
-
- if ( (*nth_folder) == (total_folders - 1))
- *done = TRUE;
-}
-
-/* This could be in CamelStore.ch */
-static void
-count_folders (CamelFolderInfo *fi, gint *count)
-{
- while (fi) {
- *count = *count + 1;
- count_folders (fi->child , count);
- fi = fi->next;
- }
-}
-
-static CamelStore *
-setup_local_store (MailComponent *mc)
-{
- CamelURL *url;
- gchar *tmp;
- CamelStore *store;
-
- url = camel_url_new("mbox:", NULL);
- tmp = g_build_filename (mail_component_peek_base_directory(mc), "local", NULL);
- camel_url_set_path(url, tmp);
- g_free(tmp);
- tmp = camel_url_to_string(url, 0);
- store = (CamelStore *)camel_session_get_service(session, tmp, CAMEL_PROVIDER_STORE, NULL);
- g_free(tmp);
-
- return store;
-
-}
-
-struct migrate_folders_to_db_structure {
- gchar *account_name;
- CamelException ex;
- CamelStore *store;
- CamelFolderInfo *info;
- gboolean done;
- gboolean is_local_store;
-};
-
-static void migrate_folders_to_db_thread (struct migrate_folders_to_db_structure *migrate_dbs)
-{
- gint num_of_folders = 0, nth_folder = 0;
- count_folders (migrate_dbs->info, &num_of_folders);
- migrate_folders (migrate_dbs->store, migrate_dbs->is_local_store, migrate_dbs->info,
- migrate_dbs->account_name, &(migrate_dbs->ex), &(migrate_dbs->done),
- &nth_folder, num_of_folders);
-}
-
-static void
-migrate_to_db()
-{
- EAccountList *accounts;
- EIterator *iter;
- gint i=0, len;
- MailComponent *component = mail_component_peek ();
- CamelStore *store = NULL;
- CamelFolderInfo *info;
-
- if (!(accounts = mail_config_get_accounts ()))
- return;
-
- iter = e_list_get_iterator ((EList *) accounts);
- len = e_list_length ((EList *) accounts);
-
- camel_session_set_online ((CamelSession *) session, FALSE);
-
- em_migrate_setup_progress_dialog (_("Migrating Folders"), _("The summary format of the Evolution mailbox "
- "folders has been moved to SQLite since Evolution 2.24.\n\nPlease be "
- "patient while Evolution migrates your folders..."));
-
- store = setup_local_store (component);
- info = camel_store_get_folder_info (store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST|CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, NULL);
-
- if (info) {
- GThread *thread;
- struct migrate_folders_to_db_structure migrate_dbs;
-
- if (g_str_has_suffix (((CamelService *)store)->url->path, ".evolution/mail/local"))
- migrate_dbs.is_local_store = TRUE;
- else
- migrate_dbs.is_local_store = FALSE;
- camel_exception_init (&migrate_dbs.ex);
- migrate_dbs.account_name = _("On This Computer");
- migrate_dbs.info = info;
- migrate_dbs.store = store;
- migrate_dbs.done = FALSE;
-
- thread = g_thread_create ((GThreadFunc) migrate_folders_to_db_thread, &migrate_dbs, TRUE, NULL);
- while (!migrate_dbs.done)
- g_main_context_iteration (NULL, TRUE);
- }
- i++;
- while (e_iterator_is_valid (iter)) {
- EAccount *account = (EAccount *) e_iterator_get (iter);
- EAccountService *service;
- const gchar *name;
-
- service = account->source;
- name = account->name;
- if (account->enabled
- && service->url != NULL
- && service->url[0]
- && strncmp(service->url, "mbox:", 5) != 0) {
-
- CamelException ex;
-
- camel_exception_init (&ex);
- mail_component_load_store_by_uri (component, service->url, name);
-
- store = (CamelStore *) camel_session_get_service (session, service->url, CAMEL_PROVIDER_STORE, &ex);
- info = camel_store_get_folder_info (store, NULL, CAMEL_STORE_FOLDER_INFO_RECURSIVE|CAMEL_STORE_FOLDER_INFO_FAST|CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, &ex);
- if (info) {
- GThread *thread;
- struct migrate_folders_to_db_structure migrate_dbs;
-
- migrate_dbs.ex = ex;
- migrate_dbs.account_name = account->name;
- migrate_dbs.info = info;
- migrate_dbs.store = store;
- migrate_dbs.done = FALSE;
-
- thread = g_thread_create ((GThreadFunc) migrate_folders_to_db_thread, &migrate_dbs, TRUE, NULL);
- while (!migrate_dbs.done)
- g_main_context_iteration (NULL, TRUE);
- } else
- printf("%s:%s: failed to get folder infos \n", G_STRLOC, G_STRFUNC);
- camel_exception_clear(&ex);
- }
- i++;
- e_iterator_next (iter);
- }
- /* camel_session_set_online ((CamelSession *) session, TRUE); */
- g_object_unref (iter);
- em_migrate_close_progress_dialog ();
-}
-
-gint
-em_migrate (const gchar *evolution_dir, gint major, gint minor, gint revision, CamelException *ex)
-{
- struct stat st;
- gchar *path;
-
- /* make sure ~/.evolution/mail exists */
- path = g_build_filename (evolution_dir, "mail", NULL);
- if (g_stat (path, &st) == -1) {
- if (errno != ENOENT || g_mkdir_with_parents (path, 0777) == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to create local mail folders at `%s': %s"),
- path, g_strerror (errno));
- g_free (path);
- return -1;
- }
- }
-
- g_free (path);
-
- if (major == 0)
- return emm_setup_initial(evolution_dir);
-
- if (major == 1 && minor < 5) {
-#ifndef G_OS_WIN32
- xmlDocPtr config_xmldb = NULL, filters, vfolders;
-
- path = g_build_filename (g_get_home_dir (), "evolution", NULL);
- if (minor <= 2 && !(config_xmldb = emm_load_xml (path, "config.xmldb"))) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Unable to read settings from previous Evolution install, "
- "`evolution/config.xmldb' does not exist or is corrupt."));
- g_free (path);
- return -1;
- }
- filters = emm_load_xml (path, "filters.xml");
- vfolders = emm_load_xml (path, "vfolders.xml");
- g_free (path);
-
- if (minor == 0) {
- if (em_migrate_1_0 (evolution_dir, config_xmldb, filters, vfolders, ex) == -1) {
- xmlFreeDoc (config_xmldb);
- xmlFreeDoc (filters);
- xmlFreeDoc (vfolders);
- return -1;
- }
- }
-
- if (minor <= 2) {
- if (em_migrate_1_2 (evolution_dir, config_xmldb, filters, vfolders, ex) == -1) {
- xmlFreeDoc (config_xmldb);
- xmlFreeDoc (filters);
- xmlFreeDoc (vfolders);
- return -1;
- }
-
- xmlFreeDoc (config_xmldb);
- }
-
- if (minor <= 4) {
- if (em_migrate_1_4 (evolution_dir, filters, vfolders, ex) == -1) {
- xmlFreeDoc (filters);
- xmlFreeDoc (vfolders);
- return -1;
- }
- }
-
- path = g_build_filename (evolution_dir, "mail", NULL);
-
- if (filters) {
- emm_save_xml (filters, path, "filters.xml");
- xmlFreeDoc (filters);
- }
-
- if (vfolders) {
- emm_save_xml (vfolders, path, "vfolders.xml");
- xmlFreeDoc (vfolders);
- }
-
- g_free (path);
-#else
- g_error ("Upgrading from ancient versions not supported on Windows");
-#endif
- }
-
- if (major < 2 || (major == 2 && minor < 12)) {
-#ifndef G_OS_WIN32
- em_update_accounts_2_11 ();
-#else
- g_error ("Upgrading from ancient versions not supported on Windows");
-#endif
- }
-
- if (major < 2 || (major == 2 && minor < 22))
- em_update_message_notify_settings_2_21 ();
-
- if (major < 2 || (major == 2 && minor < 24)) {
- em_update_sa_junk_setting_2_23 ();
- migrate_to_db ();
- }
-
- return 0;
-}
diff --git a/mail/em-network-prefs.c b/mail/em-network-prefs.c
deleted file mode 100644
index d8b576f1f1..0000000000
--- a/mail/em-network-prefs.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * 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:
- * Veerapuram Varadhan <vvaradhan@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "em-network-prefs.h"
-
-#include <bonobo/bonobo-generic-factory.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gconf/gconf-client.h>
-#include <glade/glade.h>
-
-#include <glib/gstdio.h>
-
-#include "e-util/e-error.h"
-#include "e-util/e-util-private.h"
-
-#include "mail-config.h"
-#include "em-config.h"
-
-#define d(x)
-
-#define GCONF_E_SHELL_NETWORK_CONFIG_PATH "/apps/evolution/shell/network_config/"
-#define GCONF_E_HTTP_HOST_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "http_host"
-#define GCONF_E_HTTP_PORT_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "http_port"
-#define GCONF_E_HTTPS_HOST_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "secure_host"
-#define GCONF_E_HTTPS_PORT_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "secure_port"
-#define GCONF_E_SOCKS_HOST_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "socks_host"
-#define GCONF_E_SOCKS_PORT_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "socks_port"
-#define GCONF_E_IGNORE_HOSTS_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "ignore_hosts"
-#define GCONF_E_USE_AUTH_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "use_authentication"
-#define GCONF_E_PROXY_TYPE_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "proxy_type"
-#define GCONF_E_AUTH_USER_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "authentication_user"
-#define GCONF_E_AUTH_PWD_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "authentication_password"
-#define GCONF_E_USE_PROXY_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "use_http_proxy"
-#define GCONF_E_AUTOCONFIG_URL_KEY GCONF_E_SHELL_NETWORK_CONFIG_PATH "autoconfig_url"
-
-static void em_network_prefs_class_init (EMNetworkPrefsClass *class);
-static void em_network_prefs_init (EMNetworkPrefs *dialog);
-static void em_network_prefs_destroy (GtkObject *obj);
-static void em_network_prefs_finalise (GObject *obj);
-
-static GtkVBoxClass *parent_class = NULL;
-
-GType
-em_network_prefs_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EMNetworkPrefsClass),
- NULL, NULL,
- (GClassInitFunc) em_network_prefs_class_init,
- NULL, NULL,
- sizeof (EMNetworkPrefs),
- 0,
- (GInstanceInitFunc) em_network_prefs_init,
- };
-
- type = g_type_register_static (gtk_vbox_get_type (), "EMNetworkPrefs", &info, 0);
- }
-
- return type;
-}
-
-static void
-em_network_prefs_class_init (EMNetworkPrefsClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_ref (gtk_vbox_get_type ());
-
- object_class->destroy = em_network_prefs_destroy;
- gobject_class->finalize = em_network_prefs_finalise;
-}
-
-static void
-em_network_prefs_init (EMNetworkPrefs *prefs)
-{
- /* do something here */
-}
-
-static void
-em_network_prefs_finalise (GObject *obj)
-{
- d(g_print ("Network preferences finalize is called\n"));
-
- /* do something here */
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-static void
-em_network_prefs_destroy (GtkObject *obj)
-{
- d(g_print ("Network preferences destroy is called\n"));
-
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
-}
-
-static void
-toggle_button_toggled (GtkToggleButton *toggle, EMNetworkPrefs *prefs)
-{
- const gchar *key;
-
- key = g_object_get_data ((GObject *) toggle, "key");
- gconf_client_set_bool (prefs->gconf, key, gtk_toggle_button_get_active (toggle), NULL);
- if (toggle == prefs->use_auth) {
- gboolean sensitivity = gtk_toggle_button_get_active (prefs->use_auth);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_auth_user, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_auth_pwd, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->auth_user, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->auth_pwd, sensitivity);
- }
-}
-
-static void
-toggle_button_init (EMNetworkPrefs *prefs, GtkToggleButton *toggle, const gchar *key)
-{
- gboolean bool;
-
- bool = gconf_client_get_bool (prefs->gconf, key, NULL);
- gtk_toggle_button_set_active (toggle, bool);
-
- g_object_set_data ((GObject *) toggle, "key", (gpointer) key);
- g_signal_connect (toggle, "toggled", G_CALLBACK (toggle_button_toggled), prefs);
-
- if (!gconf_client_key_is_writable (prefs->gconf, key, NULL))
- gtk_widget_set_sensitive ((GtkWidget *) toggle, FALSE);
-}
-
-static GtkWidget *
-emnp_widget_glade(EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget *old, gpointer data)
-{
- EMNetworkPrefs *prefs = data;
-
- return glade_xml_get_widget(prefs->gui, item->label);
-}
-
-static void
-emnp_set_sensitiveness (EMNetworkPrefs *prefs, NetworkConfigProxyType type, gboolean sensitivity)
-{
-#if 0
- if (type == NETWORK_PROXY_AUTOCONFIG) {
- gtk_widget_set_sensitive ((GtkWidget *) prefs->auto_proxy_url, sensitivity);
- d(g_print ("Setting sensitivity of autoconfig to: %d\n", sensitivity));
- } else
-#endif
- if (type == NETWORK_PROXY_MANUAL) {
- gboolean state;
-
- gtk_widget_set_sensitive ((GtkWidget *) prefs->http_host, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->https_host, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->ignore_hosts, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->use_auth, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->http_port, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->https_port, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_ignore_hosts, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_http_host, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_http_port, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_https_host, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_https_port, sensitivity);
-#if 0
- gtk_widget_set_sensitive ((GtkWidget *) prefs->socks_host, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->socks_port, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_socks_host, sensitivity);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_socks_port, sensitivity);
-#endif
- state = sensitivity && gtk_toggle_button_get_active (prefs->use_auth);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_auth_user, state);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->lbl_auth_pwd, state);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->auth_user, state);
- gtk_widget_set_sensitive ((GtkWidget *) prefs->auth_pwd, state);
-
- d(g_print ("Setting sensitivity of manual proxy to: %d\n", sensitivity));
- }
-}
-
-static void
-notify_proxy_type_changed (GtkWidget *widget, EMNetworkPrefs *prefs)
-{
- gint type;
-
- if (gtk_toggle_button_get_active (prefs->sys_proxy))
- type = NETWORK_PROXY_SYS_SETTINGS;
- else if (gtk_toggle_button_get_active (prefs->no_proxy))
- type = NETWORK_PROXY_DIRECT_CONNECTION;
- else if (gtk_toggle_button_get_active (prefs->manual_proxy))
- type = NETWORK_PROXY_MANUAL;
- else
-#if 0
- type = NETWORK_PROXY_AUTOCONFIG;
-#else
- type = NETWORK_PROXY_SYS_SETTINGS;
-#endif
-
- gconf_client_set_int (prefs->gconf, "/apps/evolution/shell/network_config/proxy_type", type, NULL);
-
- if (type == NETWORK_PROXY_DIRECT_CONNECTION ||
- type == NETWORK_PROXY_SYS_SETTINGS) {
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_MANUAL, FALSE);
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_AUTOCONFIG, FALSE);
- } else if (type == NETWORK_PROXY_AUTOCONFIG) {
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_MANUAL, FALSE);
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_AUTOCONFIG, TRUE);
- } else if (type == NETWORK_PROXY_MANUAL) {
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_AUTOCONFIG, FALSE);
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_MANUAL, TRUE);
- }
-
- if (type != NETWORK_PROXY_DIRECT_CONNECTION)
- gconf_client_set_bool (prefs->gconf, GCONF_E_USE_PROXY_KEY, TRUE, NULL);
- else if (type != NETWORK_PROXY_SYS_SETTINGS)
- gconf_client_set_bool (prefs->gconf, GCONF_E_USE_PROXY_KEY, FALSE, NULL);
-
-}
-
-static void
-widget_entry_changed_cb (GtkWidget *widget, gpointer data)
-{
- const gchar *value;
- gint port = -1;
- GConfClient *gconf = mail_config_get_gconf_client ();
-
- /*
- Do not change the order of comparison -
- GtkSpinButton is an extended form of GtkEntry
- */
- if (GTK_IS_SPIN_BUTTON (widget)) {
- port = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
- gconf_client_set_int (gconf, (const gchar *)data, port, NULL);
- d(g_print ("%s:%s: %s is SpinButton: value = [%d]\n", G_STRLOC, G_STRFUNC, (const gchar *)data, port));
- } else if (GTK_IS_ENTRY (widget)) {
- value = gtk_entry_get_text (GTK_ENTRY (widget));
- gconf_client_set_string (gconf, (const gchar *)data, value, NULL);
- d(g_print ("%s:%s: %s is Entry: value = [%s]\n", G_STRLOC, G_STRFUNC, (const gchar *)data, value));
- }
-
-}
-
-/* plugin meta-data */
-static EMConfigItem emnp_items[] = {
- { E_CONFIG_BOOK, (gchar *) "", (gchar *) "network_preferences_toplevel", emnp_widget_glade },
- { E_CONFIG_PAGE, (gchar *) "00.general", (gchar *) "vboxGeneral", emnp_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "00.general/00.proxy", (gchar *) "frameProxy", emnp_widget_glade },
-};
-
-static void
-emnp_free(EConfig *ec, GSList *items, gpointer data)
-{
- /* the prefs data is freed automagically */
-
- g_slist_free(items);
-}
-
-static void
-emnp_set_markups (EMNetworkPrefs *prefs)
-{
- gtk_label_set_use_markup (GTK_LABEL (GTK_BIN(prefs->sys_proxy)->child), TRUE);
- gtk_label_set_use_markup (GTK_LABEL (GTK_BIN(prefs->no_proxy)->child), TRUE);
- gtk_label_set_use_markup (GTK_LABEL (GTK_BIN(prefs->manual_proxy)->child), TRUE);
-#if 0
- gtk_label_set_use_markup (GTK_LABEL (GTK_BIN(prefs->auto_proxy)->child), TRUE);
-#endif
-}
-
-static void
-em_network_prefs_construct (EMNetworkPrefs *prefs)
-{
- GtkWidget *toplevel;
- GladeXML *gui;
- GSList* l;
- gchar *buf;
- EMConfig *ec;
- EMConfigTargetPrefs *target;
- gboolean locked;
- gint i, val, port;
- gchar *gladefile;
-
- prefs->gconf = mail_config_get_gconf_client ();
-
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "mail-config.glade",
- NULL);
- gui = glade_xml_new (gladefile, "network_preferences_toplevel", NULL);
- prefs->gui = gui;
- g_free (gladefile);
-
- /** @HookPoint-EMConfig: Network Preferences
- * @Id: org.gnome.evolution.mail.networkPrefs
- * @Type: E_CONFIG_BOOK
- * @Class: org.gnome.evolution.mail.config:1.0
- * @Target: EMConfigTargetPrefs
- *
- * The network preferences settings page.
- */
- ec = em_config_new(E_CONFIG_BOOK, "org.gnome.evolution.mail.networkPrefs");
- l = NULL;
- for (i=0;i<sizeof(emnp_items)/sizeof(emnp_items[0]);i++)
- l = g_slist_prepend(l, &emnp_items[i]);
- e_config_add_items((EConfig *)ec, l, NULL, NULL, emnp_free, prefs);
-
- /* Proxy tab */
-
- /* Default Behavior */
- locked = !gconf_client_key_is_writable (prefs->gconf, GCONF_E_PROXY_TYPE_KEY, NULL);
-
- val = gconf_client_get_int (prefs->gconf, GCONF_E_PROXY_TYPE_KEY, NULL);
-
- /* no auto-proxy at the moment */
- if (val == NETWORK_PROXY_AUTOCONFIG)
- val = NETWORK_PROXY_SYS_SETTINGS;
-
- prefs->sys_proxy = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "rdoSysSettings"));
- gtk_toggle_button_set_active (prefs->sys_proxy, val == NETWORK_PROXY_SYS_SETTINGS);
- if (locked)
- gtk_widget_set_sensitive ((GtkWidget *) prefs->sys_proxy, FALSE);
-
- d(g_print ("Sys settings ----!!! \n"));
-
- prefs->no_proxy = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "rdoNoProxy"));
- gtk_toggle_button_set_active (prefs->no_proxy, val == NETWORK_PROXY_DIRECT_CONNECTION);
- if (locked)
- gtk_widget_set_sensitive ((GtkWidget *) prefs->no_proxy, FALSE);
-
- d(g_print ("No proxy settings ----!!! \n"));
-
- /* no auto-proxy at the moment */
-#if 0
- prefs->auto_proxy = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "rdoAutoConfig"));
- prefs->auto_proxy_url = GTK_ENTRY (glade_xml_get_widget (gui, "txtAutoConfigUrl"));
-
- gtk_toggle_button_set_active (prefs->auto_proxy, val == NETWORK_PROXY_AUTOCONFIG);
-
- g_signal_connect(prefs->auto_proxy_url, "changed", G_CALLBACK(widget_entry_changed_cb), GCONF_E_AUTOCONFIG_URL_KEY);
- if (locked)
- gtk_widget_set_sensitive ((GtkWidget *) prefs->auto_proxy, FALSE);
-#endif
-
- d(g_print ("Auto config settings ----!!! \n"));
-
- prefs->manual_proxy = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "rdoManualProxy"));
- prefs->http_host = GTK_ENTRY (glade_xml_get_widget (gui, "txtHttpHost"));
- prefs->https_host = GTK_ENTRY (glade_xml_get_widget (gui, "txtHttpsHost"));
- prefs->ignore_hosts = GTK_ENTRY (glade_xml_get_widget (gui, "txtIgnoreHosts"));
- prefs->http_port = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "spnHttpPort"));
- prefs->https_port = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "spnHttpsPort"));
- prefs->lbl_http_host = GTK_LABEL (glade_xml_get_widget (gui, "lblHttpHost"));
- prefs->lbl_http_port = GTK_LABEL (glade_xml_get_widget (gui, "lblHttpPort"));
- prefs->lbl_https_host = GTK_LABEL (glade_xml_get_widget (gui, "lblHttpsHost"));
- prefs->lbl_https_port = GTK_LABEL (glade_xml_get_widget (gui, "lblHttpsPort"));
- prefs->lbl_ignore_hosts = GTK_LABEL (glade_xml_get_widget (gui, "lblIgnoreHosts"));
- prefs->use_auth = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui, "chkUseAuth"));
- toggle_button_init (prefs, prefs->use_auth, GCONF_E_USE_AUTH_KEY);
- prefs->lbl_auth_user = GTK_LABEL (glade_xml_get_widget (gui, "lblAuthUser"));
- prefs->lbl_auth_pwd = GTK_LABEL (glade_xml_get_widget (gui, "lblAuthPwd"));
- prefs->auth_user = GTK_ENTRY (glade_xml_get_widget (gui, "txtAuthUser"));
- prefs->auth_pwd = GTK_ENTRY (glade_xml_get_widget (gui, "txtAuthPwd"));
-
-#if 0
- prefs->socks_host = GTK_ENTRY (glade_xml_get_widget (gui, "txtSocksHost"));
- prefs->socks_port = GTK_SPIN_BUTTON (glade_xml_get_widget (gui, "spnSocksPort"));
- prefs->lbl_socks_host = GTK_LABEL (glade_xml_get_widget (gui, "lblSocksHost"));
- prefs->lbl_socks_port = GTK_LABEL (glade_xml_get_widget (gui, "lblSocksPort"));
- g_signal_connect (prefs->socks_host, "changed",
- G_CALLBACK(widget_entry_changed_cb), GCONF_E_SOCKS_HOST_KEY);
- g_signal_connect (prefs->socks_port, "value_changed",
- G_CALLBACK(widget_entry_changed_cb), GCONF_E_SOCKS_PORT_KEY);
-#endif
-
- /* Manual proxy options */
- g_signal_connect (prefs->http_host, "changed",
- G_CALLBACK(widget_entry_changed_cb),
- (gpointer) GCONF_E_HTTP_HOST_KEY);
- g_signal_connect (prefs->https_host, "changed",
- G_CALLBACK(widget_entry_changed_cb),
- (gpointer) GCONF_E_HTTPS_HOST_KEY);
- g_signal_connect (prefs->ignore_hosts, "changed",
- G_CALLBACK(widget_entry_changed_cb),
- (gpointer) GCONF_E_IGNORE_HOSTS_KEY);
- g_signal_connect (prefs->http_port, "value_changed",
- G_CALLBACK(widget_entry_changed_cb),
- (gpointer) GCONF_E_HTTP_PORT_KEY);
- g_signal_connect (prefs->https_port, "value_changed",
- G_CALLBACK(widget_entry_changed_cb),
- (gpointer) GCONF_E_HTTPS_PORT_KEY);
- g_signal_connect (prefs->auth_user, "changed",
- G_CALLBACK(widget_entry_changed_cb),
- (gpointer) GCONF_E_AUTH_USER_KEY);
- g_signal_connect (prefs->auth_pwd, "changed",
- G_CALLBACK(widget_entry_changed_cb),
- (gpointer) GCONF_E_AUTH_PWD_KEY);
-
- gtk_toggle_button_set_active (prefs->manual_proxy, val == NETWORK_PROXY_MANUAL);
- g_signal_connect (prefs->sys_proxy, "toggled", G_CALLBACK (notify_proxy_type_changed), prefs);
- g_signal_connect (prefs->no_proxy, "toggled", G_CALLBACK (notify_proxy_type_changed), prefs);
-#if 0
- g_signal_connect (prefs->auto_proxy, "toggled", G_CALLBACK (notify_proxy_type_changed), prefs);
-#endif
- g_signal_connect (prefs->manual_proxy, "toggled", G_CALLBACK (notify_proxy_type_changed), prefs);
-
- if (locked)
- gtk_widget_set_sensitive ((GtkWidget *) prefs->manual_proxy, FALSE);
- d(g_print ("Manual settings ----!!! \n"));
-
- buf = gconf_client_get_string (prefs->gconf, GCONF_E_HTTP_HOST_KEY, NULL);
- gtk_entry_set_text (prefs->http_host, buf ? buf : "");
- g_free (buf);
-
- buf = gconf_client_get_string (prefs->gconf, GCONF_E_HTTPS_HOST_KEY, NULL);
- gtk_entry_set_text (prefs->https_host, buf ? buf : "");
- g_free (buf);
-
- buf = gconf_client_get_string (prefs->gconf, GCONF_E_IGNORE_HOSTS_KEY, NULL);
- gtk_entry_set_text (prefs->ignore_hosts, buf ? buf : "");
- g_free (buf);
-
- buf = gconf_client_get_string (prefs->gconf, GCONF_E_AUTH_USER_KEY, NULL);
- gtk_entry_set_text (prefs->auth_user, buf ? buf : "");
- g_free (buf);
-
- buf = gconf_client_get_string (prefs->gconf, GCONF_E_AUTH_PWD_KEY, NULL);
- gtk_entry_set_text (prefs->auth_pwd, buf ? buf : "");
- g_free (buf);
-
- port = gconf_client_get_int (prefs->gconf, GCONF_E_HTTP_PORT_KEY, NULL);
- gtk_spin_button_set_value (prefs->http_port, (gdouble)port);
-
- port = gconf_client_get_int (prefs->gconf, GCONF_E_HTTPS_PORT_KEY, NULL);
- gtk_spin_button_set_value (prefs->https_port, (gdouble)port);
-
-#if 0
- buf = gconf_client_get_string (prefs->gconf, GCONF_E_SOCKS_HOST_KEY, NULL);
- gtk_entry_set_text (prefs->socks_host, buf ? buf : "");
- g_free (buf);
-
- port = gconf_client_get_int (prefs->gconf, GCONF_E_SOCKS_PORT_KEY, NULL);
- gtk_spin_button_set_value (prefs->socks_port, (gdouble)port);
-#endif
- emnp_set_markups (prefs);
-
- if (val == NETWORK_PROXY_DIRECT_CONNECTION ||
- val == NETWORK_PROXY_SYS_SETTINGS) {
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_MANUAL, FALSE);
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_AUTOCONFIG, FALSE);
- } else if (val == NETWORK_PROXY_AUTOCONFIG) {
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_MANUAL, FALSE);
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_AUTOCONFIG, TRUE);
- } else if (val == NETWORK_PROXY_MANUAL) {
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_AUTOCONFIG, FALSE);
- emnp_set_sensitiveness (prefs, NETWORK_PROXY_MANUAL, TRUE);
- }
-
- /* get our toplevel widget */
- target = em_config_target_new_prefs(ec, prefs->gconf);
- e_config_set_target((EConfig *)ec, (EConfigTarget *)target);
- toplevel = e_config_create_widget((EConfig *)ec);
- gtk_container_add (GTK_CONTAINER (prefs), toplevel);
-}
-
-GtkWidget *
-em_network_prefs_new (void)
-{
- EMNetworkPrefs *new;
-
- new = (EMNetworkPrefs *) g_object_new (em_network_prefs_get_type (), NULL);
- em_network_prefs_construct (new);
-
- return (GtkWidget *) new;
-}
diff --git a/mail/em-network-prefs.h b/mail/em-network-prefs.h
deleted file mode 100644
index 0b6cd5ff63..0000000000
--- a/mail/em-network-prefs.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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:
- * Veerapuram Varadhan <vvaradhan@novell.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EM_NETWORK_PREFS_H__
-#define __EM_NETWORK_PREFS_H__
-
-#include <gtk/gtk.h>
-#include <glade/glade.h>
-#include <gconf/gconf-client.h>
-
-#define EM_NETWORK_PREFS_TYPE (em_network_prefs_get_type ())
-#define EM_NETWORK_PREFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EM_NETWORK_PREFS_TYPE, EMNetworkPrefs))
-#define EM_NETWORK_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EM_NETWORK_PREFS_TYPE, EMNetworkPrefsClass))
-#define EM_IS_NETWORK_PREFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EM_NETWORK_PREFS_TYPE))
-#define EM_IS_NETWORK_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EM_NETWORK_PREFS_TYPE))
-
-G_BEGIN_DECLS
-
-typedef struct _EMNetworkPrefs EMNetworkPrefs;
-typedef struct _EMNetworkPrefsClass EMNetworkPrefsClass;
-
-typedef enum {
- NETWORK_PROXY_SYS_SETTINGS,
- NETWORK_PROXY_DIRECT_CONNECTION,
- NETWORK_PROXY_MANUAL,
- NETWORK_PROXY_AUTOCONFIG
-} NetworkConfigProxyType;
-
-struct _EMNetworkPrefs {
- GtkVBox parent_object;
-
- GConfClient *gconf;
-
- GladeXML *gui;
-
- /* Default Behavior */
- GtkToggleButton *sys_proxy;
- GtkToggleButton *no_proxy;
- GtkToggleButton *manual_proxy;
-#if 0
- GtkToggleButton *auto_proxy;
-#endif
- GtkToggleButton *use_auth;
-
- GtkEntry *http_host;
- GtkEntry *https_host;
- GtkEntry *ignore_hosts;
-#if 0
- GtkEntry *auto_proxy_url;
-#endif
- GtkEntry *auth_user;
- GtkEntry *auth_pwd;
-
- GtkLabel *lbl_http_host;
- GtkLabel *lbl_http_port;
- GtkLabel *lbl_https_host;
- GtkLabel *lbl_https_port;
- GtkLabel *lbl_ignore_hosts;
- GtkLabel *lbl_auth_user;
- GtkLabel *lbl_auth_pwd;
-
- GtkSpinButton *http_port;
- GtkSpinButton *https_port;
-#if 0
- GtkLabel *lbl_socks_host;
- GtkEntry *socks_host;
- GtkLabel *lbl_socks_port;
- GtkSpinButton *socks_port;
-#endif
-};
-
-struct _EMNetworkPrefsClass {
- GtkVBoxClass parent_class;
-
- /* signals */
-
-};
-
-GType em_network_prefs_get_type (void);
-
-GtkWidget *em_network_prefs_new (void);
-
-/* needed by global config */
-#define EM_NETWORK_PREFS_CONTROL_ID "OAFIID:GNOME_Evolution_Mail_NetworkPrefs_ConfigControl:" BASE_VERSION
-
-G_END_DECLS
-
-#endif /* __EM_NETWORK_PREFS_H__ */
diff --git a/mail/em-popup.c b/mail/em-popup.c
index 4fc912ba07..f9caf9de0c 100644
--- a/mail/em-popup.c
+++ b/mail/em-popup.c
@@ -55,8 +55,6 @@
#include <e-util/e-util.h>
#include "e-attachment.h"
-static void emp_standard_menu_factory(EPopup *emp, gpointer data);
-
static GObjectClass *emp_parent;
static void
@@ -110,8 +108,6 @@ emp_class_init(GObjectClass *klass)
{
klass->finalize = emp_finalise;
((EPopupClass *)klass)->target_free = emp_target_free;
-
- e_popup_class_add_factory((EPopupClass *)klass, NULL, emp_standard_menu_factory, NULL);
}
GType
@@ -353,418 +349,6 @@ done:
/* ********************************************************************** */
-static void
-emp_part_popup_saveas(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- CamelMimePart *part = NULL;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- em_utils_save_part(ep->target->widget, _("Save As..."), part);
-}
-
-static void
-emp_part_popup_set_background(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- GConfClient *gconf;
- gchar *str, *filename, *path, *extension;
- guint i=1;
- CamelMimePart *part = NULL;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- if (!part)
- return;
-
- filename = g_strdup(camel_mime_part_get_filename(part));
-
- /* if filename is blank, create a default filename based on MIME type */
- if (!filename || !filename[0]) {
- CamelContentType *ct;
-
- ct = camel_mime_part_get_content_type(part);
- g_free (filename);
- filename = g_strdup_printf (_("untitled_image.%s"), ct->subtype);
- }
-
- e_filename_make_safe(filename);
-
- path = g_build_filename(g_get_home_dir(), ".gnome2", "wallpapers", filename, NULL);
-
- extension = strrchr(filename, '.');
- if (extension)
- *extension++ = 0;
-
- /* if file exists, stick a (number) on the end */
- while (g_file_test(path, G_FILE_TEST_EXISTS)) {
- gchar *name;
- name = g_strdup_printf(extension?"%s (%d).%s":"%s (%d)", filename, i++, extension);
- g_free(path);
- path = g_build_filename(g_get_home_dir(), ".gnome2", "wallpapers", name, NULL);
- g_free(name);
- }
-
- g_free(filename);
-
- if (em_utils_save_part_to_file(ep->target->widget, path, part)) {
- gconf = gconf_client_get_default();
-
- /* if the filename hasn't changed, blank the filename before
- * setting it so that gconf detects a change and updates it */
- if ((str = gconf_client_get_string(gconf, "/desktop/gnome/background/picture_filename", NULL)) != NULL
- && strcmp (str, path) == 0) {
- gconf_client_set_string(gconf, "/desktop/gnome/background/picture_filename", "", NULL);
- }
-
- g_free (str);
- gconf_client_set_string(gconf, "/desktop/gnome/background/picture_filename", path, NULL);
-
- /* if GNOME currently doesn't display a picture, set to "wallpaper"
- * display mode, otherwise leave it alone */
- if ((str = gconf_client_get_string(gconf, "/desktop/gnome/background/picture_options", NULL)) == NULL
- || strcmp(str, "none") == 0) {
- gconf_client_set_string(gconf, "/desktop/gnome/background/picture_options", "wallpaper", NULL);
- }
-
- gconf_client_suggest_sync(gconf, NULL);
-
- g_free(str);
- g_object_unref(gconf);
- }
-
- g_free(path);
-}
-
-static void
-emp_part_popup_reply_sender(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part);
- em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_SENDER, NULL);
-}
-
-static void
-emp_part_popup_reply_list (EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part);
- em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_LIST, NULL);
-}
-
-static void
-emp_part_popup_reply_all (EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part);
- em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_ALL, NULL);
-}
-
-static void
-emp_part_popup_forward (EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- part = ((EMPopupTargetPart *) t)->part;
-
- /* TODO: have a emfv specific override so we can get the parent folder uri */
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *) part);
- em_utils_forward_message(message, NULL);
-}
-
-static EMPopupItem emp_standard_object_popups[] = {
- { E_POPUP_ITEM, (gchar *) "00.part.00", (gchar *) N_("_Save As..."), emp_part_popup_saveas, NULL, (gchar *) "document-save-as", 0 },
- { E_POPUP_ITEM, (gchar *) "00.part.10", (gchar *) N_("Set as _Background"), emp_part_popup_set_background, NULL, NULL, EM_POPUP_PART_IMAGE },
- { E_POPUP_BAR, (gchar *) "10.part", NULL, NULL, NULL, NULL, EM_POPUP_PART_MESSAGE },
- { E_POPUP_ITEM, (gchar *) "10.part.00", (gchar *) N_("_Reply to sender"), emp_part_popup_reply_sender, NULL, (gchar *) "mail-reply-sender" , EM_POPUP_PART_MESSAGE },
- { E_POPUP_ITEM, (gchar *) "10.part.01", (gchar *) N_("Reply to _List"), emp_part_popup_reply_list, NULL, NULL, EM_POPUP_PART_MESSAGE},
- { E_POPUP_ITEM, (gchar *) "10.part.03", (gchar *) N_("Reply to _All"), emp_part_popup_reply_all, NULL, (gchar *) "mail-reply-all", EM_POPUP_PART_MESSAGE},
- { E_POPUP_BAR, (gchar *) "20.part", NULL, NULL, NULL, NULL, EM_POPUP_PART_MESSAGE },
- { E_POPUP_ITEM, (gchar *) "20.part.00", (gchar *) N_("_Forward"), emp_part_popup_forward, NULL, (gchar *) "mail-forward", EM_POPUP_PART_MESSAGE },
-};
-
-static const EPopupItem emp_standard_part_apps_bar = { E_POPUP_BAR, (gchar *) "99.object" };
-
-/* ********************************************************************** */
-
-static void
-emp_uri_popup_link_open(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
-
- /* FIXME Pass a parent window. */
- e_show_uri (NULL, t->uri);
-}
-
-static void
-emp_uri_popup_address_send(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
-
- /* TODO: have an emfv specific override to get the from uri */
- em_utils_compose_new_message_with_mailto(t->uri, NULL);
-}
-
-static void
-emp_uri_popup_address_add(EPopup *ep, EPopupItem *item, gpointer data)
-{
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
- CamelURL *url;
-
- url = camel_url_new(t->uri, NULL);
- if (url == NULL) {
- g_warning("cannot parse url '%s'", t->uri);
- return;
- }
-
- if (url->path && url->path[0])
- em_utils_add_address(ep->target->widget, url->path);
-
- camel_url_free(url);
-}
-
-static EPopupItem emp_standard_uri_popups[] = {
- { E_POPUP_ITEM, (gchar *) "00.uri.00", (gchar *) N_("_Open Link in Browser"), emp_uri_popup_link_open, NULL, NULL, EM_POPUP_URI_HTTP },
- { E_POPUP_ITEM, (gchar *) "00.uri.10", (gchar *) N_("_Send New Message To..."), emp_uri_popup_address_send, NULL, (gchar *) "mail-message-new", EM_POPUP_URI_MAILTO },
- { E_POPUP_ITEM, (gchar *) "00.uri.20", (gchar *) N_("_Add to Address Book"), emp_uri_popup_address_add, NULL, (gchar *) "contact-new", EM_POPUP_URI_MAILTO },
-};
-
-/* ********************************************************************** */
-
-#define LEN(x) (sizeof(x)/sizeof(x[0]))
-
-static void
-emp_apps_open_in(EPopup *ep, EPopupItem *item, gpointer data)
-{
- gchar *path;
- EPopupTarget *target = ep->target;
- CamelMimePart *part;
-
- part = ((EMPopupTargetPart *) target)->part;
-
- path = em_utils_temp_save_part(target->widget, part, TRUE);
- if (path) {
- GAppInfo *app = item->user_data;
- GList *uris = NULL;
- GError *error = NULL;
-
- if (g_app_info_supports_files (app)) {
- GFile *file = g_file_new_for_path (path);
-
- uris = g_list_append (uris, file);
- g_app_info_launch (app, uris, NULL, &error);
- g_object_unref (file);
- } else {
- gchar *uri;
-
- uri = e_util_filename_to_uri (path);
- uris = g_list_append (uris, uri);
-
- g_app_info_launch_uris (app, uris, NULL, &error);
- g_free (uri);
- }
-
- if (error) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- g_list_free (uris);
- g_free (path);
- }
-}
-
-static void
-emp_apps_popup_free(EPopup *ep, GSList *free_list, gpointer data)
-{
- while (free_list) {
- GSList *n = free_list->next;
- EPopupItem *item = free_list->data;
-
- if (item->user_data && item->activate == emp_apps_open_in)
- g_object_unref (item->user_data);
-
- g_free(item->path);
- g_free(item->label);
- g_free(item);
- g_slist_free_1(free_list);
-
- free_list = n;
- }
-}
-
-static void
-emp_standard_items_free(EPopup *ep, GSList *items, gpointer data)
-{
- g_slist_free(items);
-}
-
-static void
-emp_add_vcard (EPopup *ep, EPopupItem *item, gpointer data)
-{
- EPopupTarget *target = ep->target;
- CamelMimePart *part;
- CamelDataWrapper *content;
- CamelStreamMem *mem;
-
- part = ((EMPopupTargetPart *) target)->part;
-
- if (!part)
- return;
-
- content = camel_medium_get_content_object (CAMEL_MEDIUM (part));
- mem = CAMEL_STREAM_MEM (camel_stream_mem_new ());
-
- if (camel_data_wrapper_decode_to_stream (content, CAMEL_STREAM (mem)) == -1 ||
- !mem->buffer->data)
- g_warning ("Read part's content failed!");
- else {
- GString *vcard = g_string_new_len ((const gchar *) mem->buffer->data, mem->buffer->len);
-
- em_utils_add_vcard (target->widget, vcard->str);
-
- g_string_free (vcard, TRUE);
- }
-
- camel_object_unref (mem);
-}
-
-static void
-emp_standard_menu_factory(EPopup *emp, gpointer data)
-{
- gint i, len;
- EPopupItem *items;
- GSList *menus = NULL;
- GList *apps = NULL;
- gchar *mime_type = NULL;
- const gchar *filename = NULL;
-
- switch (emp->target->type) {
-#if 0
- case EM_POPUP_TARGET_SELECT:
- return;
- items = emp_standard_select_popups;
- len = LEN(emp_standard_select_popups);
- break;
-#endif
- case EM_POPUP_TARGET_URI: {
- /*EMPopupTargetURI *t = (EMPopupTargetURI *)target;*/
-
- items = emp_standard_uri_popups;
- len = LEN(emp_standard_uri_popups);
- break; }
- case EM_POPUP_TARGET_PART: {
- EMPopupTargetPart *t = (EMPopupTargetPart *)emp->target;
- mime_type = camel_data_wrapper_get_mime_type((CamelDataWrapper *)t->part);
- filename = camel_mime_part_get_filename(t->part);
-
- items = emp_standard_object_popups;
- len = LEN(emp_standard_object_popups);
- break; }
- default:
- items = NULL;
- len = 0;
- }
-
- if (mime_type) {
- gchar *cp;
-
- /* GIO expects lowercase MIME types. */
- for (cp = mime_type; *cp != '\0'; cp++)
- *cp = g_ascii_tolower (*cp);
-
- cp = g_content_type_from_mime_type (mime_type);
- apps = g_app_info_get_all_for_type (cp ? cp : mime_type);
- g_free (cp);
-
- if (apps == NULL || strcmp (mime_type, "application/octet-stream") == 0) {
- if (filename != NULL) {
- gchar *name_type;
-
- name_type = e_util_guess_mime_type (filename, FALSE);
- cp = g_content_type_from_mime_type (name_type);
- /* show alternative apps first */
- apps = g_list_concat (g_app_info_get_all_for_type (cp ? cp : name_type), apps);
- g_free (cp);
- g_free (name_type);
- }
- }
-
- if (apps) {
- GString *label = g_string_new("");
- GSList *open_menus = NULL;
- GList *l;
-
- menus = g_slist_prepend(menus, (gpointer)&emp_standard_part_apps_bar);
-
- for (l = apps, i = 0; l; l = l->next, i++) {
- GAppInfo *app = l->data;
- EPopupItem *item;
-
- item = g_malloc0(sizeof(*item));
- item->type = E_POPUP_ITEM;
- item->path = g_strdup_printf("99.object.%02d", i);
- item->label = g_strdup_printf(_("Open in %s..."), g_app_info_get_name (app));
- item->activate = emp_apps_open_in;
- item->user_data = app;
-
- open_menus = g_slist_prepend(open_menus, item);
- }
-
- if (open_menus)
- e_popup_add_items(emp, open_menus, NULL, emp_apps_popup_free, NULL);
-
- g_string_free(label, TRUE);
- g_list_free(apps);
- }
-
- if (g_ascii_strcasecmp (mime_type, "text/x-vcard") == 0||
- g_ascii_strcasecmp (mime_type, "text/vcard") == 0) {
- EPopupItem *item;
-
- item = g_malloc0 (sizeof (*item));
- item->type = E_POPUP_ITEM;
- item->path = (gchar *) "00.00.vcf.00"; /* make it first item */
- item->label = _("_Add to Address Book");
- item->activate = emp_add_vcard;
- item->user_data = NULL;
- item->image = (gchar *) "contact-new";
-
- e_popup_add_items (emp, g_slist_append (NULL, item), NULL, NULL, NULL);
- }
-
- g_free (mime_type);
- }
-
- for (i=0;i<len;i++) {
- if ((items[i].visible & emp->target->mask) == 0)
- menus = g_slist_prepend(menus, &items[i]);
- }
-
- if (menus)
- e_popup_add_items(emp, menus, NULL, emp_standard_items_free, NULL);
-}
-
-/* ********************************************************************** */
-
/* Popup menu plugin handler */
/*
diff --git a/mail/em-search-context.c b/mail/em-search-context.c
index 22369b4f60..7bc43a18be 100644
--- a/mail/em-search-context.c
+++ b/mail/em-search-context.c
@@ -33,35 +33,40 @@
#include "filter/filter-option.h"
#include "filter/filter-int.h"
-static FilterElement *em_search_new_element(RuleContext *rc, const gchar *type);
+static gpointer parent_class;
-static RuleContextClass *parent_class = NULL;
-
-static void
-em_search_context_finalise (GObject *obj)
+static FilterElement *
+search_context_new_element (RuleContext *context,
+ const gchar *type)
{
- G_OBJECT_CLASS (parent_class)->finalize (obj);
+ if (strcmp (type, "system-flag") == 0)
+ return (FilterElement *) filter_option_new ();
+
+ if (strcmp (type, "score") == 0)
+ return (FilterElement *) filter_int_new_type ("score", -3, 3);
+
+ /* Chain up to parent's new_element() method. */
+ return RULE_CONTEXT_CLASS (parent_class)->new_element (context, type);
}
static void
-em_search_context_class_init (EMSearchContextClass *klass)
+search_context_class_init (EMSearchContextClass *class)
{
- parent_class = g_type_class_ref (RULE_TYPE_CONTEXT);
+ RuleContextClass *rule_context_class;
- ((GObjectClass *)klass)->finalize = em_search_context_finalise;
- ((RuleContextClass *)klass)->new_element = em_search_new_element;
+ parent_class = g_type_class_peek_parent (class);
+
+ rule_context_class = RULE_CONTEXT_CLASS (class);
+ rule_context_class->new_element = search_context_new_element;
}
static void
-em_search_context_init (EMSearchContext *vc)
+search_context_init (EMSearchContext *vc)
{
- rule_context_add_part_set ((RuleContext *)vc, "partset", filter_part_get_type (),
- rule_context_add_part, rule_context_next_part);
-
- rule_context_add_rule_set ((RuleContext *)vc, "ruleset", filter_rule_get_type (),
- rule_context_add_rule, rule_context_next_rule);
+ RuleContext *rule_context;
- ((RuleContext *)vc)->flags = RULE_CONTEXT_THREADING | RULE_CONTEXT_GROUPING;
+ rule_context = RULE_CONTEXT (vc);
+ rule_context->flags = RULE_CONTEXT_THREADING | RULE_CONTEXT_GROUPING;
}
GType
@@ -69,46 +74,29 @@ em_search_context_get_type (void)
{
static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
sizeof (EMSearchContextClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) em_search_context_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) search_context_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
sizeof (EMSearchContext),
- 0, /* n_preallocs */
- (GInstanceInitFunc) em_search_context_init,
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) search_context_init,
+ NULL /* value_table */
};
- type = g_type_register_static (RULE_TYPE_CONTEXT, "EMSearchContext", &info, 0);
+ type = g_type_register_static (
+ RULE_TYPE_CONTEXT, "EMSearchContext", &type_info, 0);
}
return type;
}
-/**
- * em_search_context_new:
- *
- * Create a new EMSearchContext object.
- *
- * Return value: A new #EMSearchContext object.
- **/
-EMSearchContext *
+RuleContext *
em_search_context_new (void)
{
- return (EMSearchContext *) g_object_new (EM_SEARCH_TYPE_CONTEXT, NULL, NULL);
-}
-
-static FilterElement *
-em_search_new_element(RuleContext *rc, const gchar *type)
-{
- if (!strcmp (type, "system-flag")) {
- return (FilterElement *) filter_option_new ();
- } else if (!strcmp (type, "score")) {
- return (FilterElement *) filter_int_new_type("score", -3, 3);
- } else {
- return parent_class->new_element(rc, type);
- }
+ return g_object_new (EM_SEARCH_TYPE_CONTEXT, NULL);
}
diff --git a/mail/em-search-context.h b/mail/em-search-context.h
index 47dc6ea86a..d8b890270c 100644
--- a/mail/em-search-context.h
+++ b/mail/em-search-context.h
@@ -22,31 +22,46 @@
*
*/
-#ifndef _EM_SEARCH_CONTEXT_H
-#define _EM_SEARCH_CONTEXT_H
+#ifndef EM_SEARCH_CONTEXT_H
+#define EM_SEARCH_CONTEXT_H
-#include "filter/rule-context.h"
+#include <filter/rule-context.h>
-#define EM_SEARCH_TYPE_CONTEXT (em_search_context_get_type ())
-#define EM_SEARCH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_SEARCH_TYPE_CONTEXT, EMSearchContext))
-#define EM_SEARCH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EM_SEARCH_TYPE_CONTEXT, EMSearchContextClass))
-#define IS_EM_SEARCH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_SEARCH_TYPE_CONTEXT))
-#define IS_EM_SEARCH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EM_SEARCH_TYPE_CONTEXT))
-#define EM_SEARCH_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EM_SEARCH_TYPE_CONTEXT, EMSearchContextClass))
+/* Standard GObject macros */
+#define EM_SEARCH_TYPE_CONTEXT \
+ (em_search_context_get_type ())
+#define EM_SEARCH_CONTEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EM_SEARCH_TYPE_CONTEXT, EMSearchContext))
+#define EM_SEARCH_CONTEXT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EM_SEARCH_TYPE_CONTEXT, EMSearchContextClass))
+#define EM_IS_SEARCH_CONTEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EM_SEARCH_TYPE_CONTEXT))
+#define EM_IS_SEARCH_CONTEXT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EM_SEARCH_TYPE_CONTEXT))
+#define EM_SEARCH_CONTEXT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EM_SEARCH_TYPE_CONTEXT, EMSearchContextClass))
+
+G_BEGIN_DECLS
typedef struct _EMSearchContext EMSearchContext;
typedef struct _EMSearchContextClass EMSearchContextClass;
struct _EMSearchContext {
- RuleContext parent_object;
+ RuleContext parent;
};
struct _EMSearchContextClass {
RuleContextClass parent_class;
};
-GType em_search_context_get_type (void);
+GType em_search_context_get_type (void);
+RuleContext * em_search_context_new (void);
-EMSearchContext *em_search_context_new (void);
+G_END_DECLS
-#endif /* ! _EM_SEARCH_CONTEXT_H */
+#endif /* EM_SEARCH_CONTEXT_H */
diff --git a/mail/em-stripsig-filter.c b/mail/em-stripsig-filter.c
deleted file mode 100644
index 42d824778b..0000000000
--- a/mail/em-stripsig-filter.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- *
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-
-#include "em-stripsig-filter.h"
-
-static void em_stripsig_filter_class_init (EMStripSigFilterClass *klass);
-static void em_stripsig_filter_init (EMStripSigFilter *filter, EMStripSigFilterClass *klass);
-
-static void filter_filter (CamelMimeFilter *filter, const gchar *in, gsize len, gsize prespace,
- gchar **out, gsize *outlen, gsize *outprespace);
-static void filter_complete (CamelMimeFilter *filter, const gchar *in, gsize len, gsize prespace,
- gchar **out, gsize *outlen, gsize *outprespace);
-static void filter_reset (CamelMimeFilter *filter);
-
-static CamelMimeFilterClass *parent_class = NULL;
-
-CamelType
-em_stripsig_filter_get_type (void)
-{
- static CamelType type = CAMEL_INVALID_TYPE;
-
- if (type == CAMEL_INVALID_TYPE) {
- type = camel_type_register (camel_mime_filter_get_type (),
- "EMStripSigFilter",
- sizeof (EMStripSigFilter),
- sizeof (EMStripSigFilterClass),
- (CamelObjectClassInitFunc) em_stripsig_filter_class_init,
- NULL,
- (CamelObjectInitFunc) em_stripsig_filter_init,
- NULL);
- }
-
- return type;
-}
-
-static void
-em_stripsig_filter_class_init (EMStripSigFilterClass *klass)
-{
- CamelMimeFilterClass *filter_class = (CamelMimeFilterClass *) klass;
-
- parent_class = CAMEL_MIME_FILTER_CLASS (camel_type_get_global_classfuncs (camel_mime_filter_get_type ()));
-
- filter_class->reset = filter_reset;
- filter_class->filter = filter_filter;
- filter_class->complete = filter_complete;
-}
-
-static void
-em_stripsig_filter_init (EMStripSigFilter *filter, EMStripSigFilterClass *klass)
-{
- filter->midline = FALSE;
-}
-
-static void
-strip_signature (CamelMimeFilter *filter, const gchar *in, gsize len, gsize prespace,
- gchar **out, gsize *outlen, gsize *outprespace, gint flush)
-{
- EMStripSigFilter *stripsig = (EMStripSigFilter *) filter;
- register const gchar *inptr = in;
- const gchar *inend = in + len;
- const gchar *start = NULL;
-
- if (stripsig->midline) {
- while (inptr < inend && *inptr != '\n')
- inptr++;
-
- if (inptr < inend) {
- stripsig->midline = FALSE;
- inptr++;
- }
- }
-
- while (inptr < inend) {
- if ((inend - inptr) >= 4 && !strncmp (inptr, "-- \n", 4)) {
- start = inptr;
- inptr += 4;
- } else {
- while (inptr < inend && *inptr != '\n')
- inptr++;
-
- if (inptr == inend) {
- stripsig->midline = TRUE;
- break;
- }
-
- inptr++;
- }
- }
-
- if (start != NULL)
- inptr = start;
-
- if (!flush && inend > inptr)
- camel_mime_filter_backup (filter, inptr, inend - inptr);
- else if (!start)
- inptr = inend;
-
- *out = (gchar *)in;
- *outlen = inptr - in;
- *outprespace = prespace;
-}
-
-static void
-filter_filter (CamelMimeFilter *filter, const gchar *in, gsize len, gsize prespace,
- gchar **out, gsize *outlen, gsize *outprespace)
-{
- strip_signature (filter, in, len, prespace, out, outlen, outprespace, FALSE);
-}
-
-static void
-filter_complete (CamelMimeFilter *filter, const gchar *in, gsize len, gsize prespace,
- gchar **out, gsize *outlen, gsize *outprespace)
-{
- strip_signature (filter, in, len, prespace, out, outlen, outprespace, TRUE);
-}
-
-/* should this 'flush' outstanding state/data bytes? */
-static void
-filter_reset (CamelMimeFilter *filter)
-{
- EMStripSigFilter *stripsig = (EMStripSigFilter *) filter;
-
- stripsig->midline = FALSE;
-}
-
-/**
- * em_stripsig_filter_new:
- *
- * Creates a new stripsig filter.
- *
- * Returns a new stripsig filter.
- **/
-CamelMimeFilter *
-em_stripsig_filter_new (void)
-{
- return (CamelMimeFilter *) camel_object_new (EM_TYPE_STRIPSIG_FILTER);
-}
diff --git a/mail/em-stripsig-filter.h b/mail/em-stripsig-filter.h
deleted file mode 100644
index 39493e5e88..0000000000
--- a/mail/em-stripsig-filter.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef __EM_STRIPSIG_FILTER_H__
-#define __EM_STRIPSIG_FILTER_H__
-
-#include <camel/camel-mime-filter.h>
-
-G_BEGIN_DECLS
-
-#define EM_TYPE_STRIPSIG_FILTER (em_stripsig_filter_get_type ())
-#define EM_STRIPSIG_FILTER(obj) (CAMEL_CHECK_CAST ((obj), EM_TYPE_STRIPSIG_FILTER, EMStripSigFilter))
-#define EM_STRIPSIG_FILTER_CLASS(klass) (CAMEL_CHECK_CLASS_CAST ((klass), EM_TYPE_STRIPSIG_FILTER, EMStripSigFilterClass))
-#define EM_IS_STRIPSIG_FILTER(obj) (CAMEL_CHECK_TYPE ((obj), EM_TYPE_STRIPSIG_FILTER))
-#define EM_IS_STRIPSIG_FILTER_CLASS(klass) (CAMEL_CHECK_CLASS_TYPE ((klass), EM_TYPE_STRIPSIG_FILTER))
-#define EM_STRIPSIG_FILTER_GET_CLASS(obj) (CAMEL_CHECK_GET_CLASS ((obj), EM_TYPE_STRIPSIG_FILTER, EMStripSigFilterClass))
-
-typedef struct _EMStripSigFilter EMStripSigFilter;
-typedef struct _EMStripSigFilterClass EMStripSigFilterClass;
-
-struct _EMStripSigFilter {
- CamelMimeFilter parent_object;
-
- guint32 midline:1;
-};
-
-struct _EMStripSigFilterClass {
- CamelMimeFilterClass parent_class;
-
-};
-
-CamelType em_stripsig_filter_get_type (void);
-
-CamelMimeFilter *em_stripsig_filter_new (void);
-
-G_END_DECLS
-
-#endif /* __EM_STRIPSIG_FILTER_H__ */
diff --git a/mail/em-subscribe-editor.c b/mail/em-subscribe-editor.c
index 4d20b31baa..d572c89eaf 100644
--- a/mail/em-subscribe-editor.c
+++ b/mail/em-subscribe-editor.c
@@ -35,8 +35,9 @@
#include "camel/camel-exception.h"
#include "camel/camel-store.h"
#include "camel/camel-session.h"
-#include "libedataserver/e-account-list.h"
#include "libedataserver/e-msgport.h"
+
+#include "e-util/e-account-utils.h"
#include "e-util/e-util-private.h"
#include "em-subscribe-editor.h"
@@ -820,7 +821,8 @@ window_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
g_object_unref (gconf);
}
-GtkDialog *em_subscribe_editor_new(void)
+GtkWidget *
+em_subscribe_editor_new(void)
{
EMSubscribeEditor *se;
EAccountList *accounts;
@@ -895,7 +897,7 @@ GtkDialog *em_subscribe_editor_new(void)
1, TRUE,
-1);
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
for (iter = e_list_get_iterator ((EList *) accounts);
e_iterator_is_valid (iter);
e_iterator_next (iter)) {
@@ -945,5 +947,5 @@ GtkDialog *em_subscribe_editor_new(void)
gtk_window_set_default_size ((GtkWindow *) se->dialog, window_size.width, window_size.height);
g_signal_connect (se->dialog, "size-allocate", G_CALLBACK (window_size_allocate), NULL);
- return se->dialog;
+ return GTK_WIDGET (se->dialog);
}
diff --git a/mail/em-subscribe-editor.h b/mail/em-subscribe-editor.h
index 36710ec0c5..d10d68bbb8 100644
--- a/mail/em-subscribe-editor.h
+++ b/mail/em-subscribe-editor.h
@@ -23,6 +23,6 @@
#include <gtk/gtk.h>
-GtkDialog *em_subscribe_editor_new(void);
+GtkWidget *em_subscribe_editor_new(void);
#endif /* ! _EM_SUBSCRIBE_EDITOR_H */
diff --git a/mail/em-utils.c b/mail/em-utils.c
index b1cc782b4c..b47b934ee2 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -56,7 +56,6 @@
#include <gio/gio.h>
-#include "mail-component.h"
#include "mail-mt.h"
#include "mail-ops.h"
#include "mail-tools.h"
@@ -69,24 +68,52 @@
#include "e-util/e-util.h"
#include "e-util/e-util-private.h"
#include "e-util/e-mktemp.h"
-#include "libedataserver/e-account-list.h"
+#include "e-util/e-account-utils.h"
#include "e-util/e-dialog-utils.h"
#include "e-util/e-error.h"
+#include "shell/e-shell.h"
+#include "widgets/misc/e-alert-activity.h"
+#include "widgets/misc/e-attachment.h"
#include "em-utils.h"
#include "em-composer-utils.h"
-#include "em-folder-view.h"
#include "em-format-quote.h"
-#include "em-account-editor.h"
-#include "e-attachment.h"
-#include "e-activity-handler.h"
+#include "e-mail-local.h"
static void emu_save_part_done (CamelMimePart *part, gchar *name, gint done, gpointer data);
-extern CamelSession *session;
-
#define d(x)
+const gchar *
+em_utils_get_data_dir (void)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ /* XXX This is a temporary solution until I can figure out a
+ * better way. Ideally, nothing below the module layer
+ * should need to know about the user data directory. */
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ return e_shell_backend_get_data_dir (shell_backend);
+}
+
+const gchar *
+em_utils_get_config_dir (void)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ /* XXX This is a temporary solution until I can figure out a
+ * better way. Ideally, nothing below the module layer
+ * should need to know about the user config directory. */
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ return e_shell_backend_get_config_dir (shell_backend);
+}
+
/**
* em_utils_prompt_user:
* @parent: parent window
@@ -175,64 +202,24 @@ em_utils_uids_free (GPtrArray *uids)
g_ptr_array_free (uids, TRUE);
}
-static void
-druid_destroy_cb (gpointer user_data, GObject *deadbeef)
-{
- gtk_main_quit ();
-}
-
-/**
- * em_utils_configure_account:
- * @parent: parent window for the druid to be a child of.
- *
- * Displays a druid allowing the user to configure an account. If
- * @parent is non-NULL, then the druid will be created as a child
- * window of @parent's toplevel window.
- *
- * Returns %TRUE if an account has been configured or %FALSE
- * otherwise.
- **/
-gboolean
-em_utils_configure_account (GtkWidget *parent)
-{
- EMAccountEditor *emae;
-
- emae = em_account_editor_new(NULL, EMAE_DRUID, "org.gnome.evolution.mail.config.accountDruid");
- if (parent != NULL)
- e_dialog_set_transient_for((GtkWindow *)emae->editor, parent);
-
- g_object_weak_ref((GObject *)emae->editor, (GWeakNotify) druid_destroy_cb, NULL);
- gtk_widget_show(emae->editor);
- gtk_grab_add(emae->editor);
- gtk_main();
-
- return mail_config_is_configured();
-}
-
/**
* em_utils_check_user_can_send_mail:
- * @parent: parent window for the druid to be a child of.
- *
- * If no accounts have been configured, the user will be given a
- * chance to configure an account. In the case that no accounts are
- * configured, a druid will be created. If @parent is non-NULL, then
- * the druid will be created as a child window of @parent's toplevel
- * window.
*
* Returns %TRUE if the user has an account configured (to send mail)
* or %FALSE otherwise.
**/
gboolean
-em_utils_check_user_can_send_mail (GtkWidget *parent)
+em_utils_check_user_can_send_mail (void)
{
+ EAccountList *account_list;
EAccount *account;
- if (!mail_config_is_configured ()) {
- if (!em_utils_configure_account (parent))
- return FALSE;
- }
+ account_list = e_get_account_list ();
+
+ if (e_list_length ((EList *) account_list) == 0)
+ return FALSE;
- if (!(account = mail_config_get_default_account ()))
+ if (!(account = e_get_default_account ()))
return FALSE;
/* Check for a transport */
@@ -252,11 +239,12 @@ em_filter_editor_response (GtkWidget *dialog, gint button, gpointer user_data)
EMFilterContext *fc;
if (button == GTK_RESPONSE_OK) {
+ const gchar *data_dir;
gchar *user;
+ data_dir = em_utils_get_data_dir ();
fc = g_object_get_data ((GObject *) dialog, "context");
- user = g_strdup_printf ("%s/filters.xml",
- mail_component_peek_base_directory (mail_component_peek ()));
+ user = g_strdup_printf ("%s/filters.xml", data_dir);
rule_context_save ((RuleContext *) fc, user);
g_free (user);
}
@@ -283,7 +271,7 @@ static EMFilterSource em_filter_source_element_names[] = {
void
em_utils_edit_filters (GtkWidget *parent)
{
- const gchar *base_directory = mail_component_peek_base_directory (mail_component_peek ());
+ const gchar *data_dir;
gchar *user, *system;
EMFilterContext *fc;
@@ -292,8 +280,10 @@ em_utils_edit_filters (GtkWidget *parent)
return;
}
+ data_dir = em_utils_get_data_dir ();
+
fc = em_filter_context_new ();
- user = g_strdup_printf ("%s/filters.xml", base_directory);
+ user = g_build_filename (data_dir, "filters.xml", NULL);
system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
rule_context_load ((RuleContext *) fc, system, user);
g_free (user);
@@ -383,12 +373,14 @@ emu_save_get_filename_for_part (CamelMimePart *part)
* Saves a mime part to disk (prompting the user for filename).
**/
void
-em_utils_save_part (GtkWidget *parent, const gchar *prompt, CamelMimePart *part)
+em_utils_save_part (GtkWindow *parent, const gchar *prompt, CamelMimePart *part)
{
GtkWidget *file_chooser;
const gchar *utf8_filename;
gchar *uri = NULL, *filename;
+ g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
+
utf8_filename = emu_save_get_filename_for_part (part);
filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
em_filename_make_safe (filename);
@@ -498,12 +490,14 @@ get_unique_file_names (GSList *parts)
}
void
-em_utils_save_parts (GtkWidget *parent, const gchar *prompt, GSList *parts)
+em_utils_save_parts (GtkWindow *parent, const gchar *prompt, GSList *parts)
{
GtkWidget *file_chooser;
gchar *path_uri;
GSList *iter, *file_names, *iter_file;
+ g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
+
file_chooser = e_file_get_save_filesel (
parent, prompt, NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
@@ -553,7 +547,7 @@ exit:
* Returns %TRUE if saving succeeded, %FALSE otherwise
**/
gboolean
-em_utils_save_part_to_file(GtkWidget *parent, const gchar *filename, CamelMimePart *part)
+em_utils_save_part_to_file(GtkWindow *parent, const gchar *filename, CamelMimePart *part)
{
gint done;
gchar *dirname;
@@ -564,7 +558,7 @@ em_utils_save_part_to_file(GtkWidget *parent, const gchar *filename, CamelMimePa
dirname = g_path_get_dirname(filename);
if (g_mkdir_with_parents(dirname, 0777) == -1) {
- GtkWidget *w = e_error_new((GtkWindow *)parent, "mail:no-create-path", filename, g_strerror(errno), NULL);
+ GtkWidget *w = e_error_new(parent, "mail:no-create-path", filename, g_strerror(errno), NULL);
g_free(dirname);
em_utils_show_error_silent (w);
return FALSE;
@@ -573,13 +567,13 @@ em_utils_save_part_to_file(GtkWidget *parent, const gchar *filename, CamelMimePa
if (g_access(filename, F_OK) == 0) {
if (g_access(filename, W_OK) != 0) {
- e_error_run((GtkWindow *)parent, E_ERROR_ASK_FILE_EXISTS_OVERWRITE, filename, NULL);
+ e_error_run(parent, E_ERROR_ASK_FILE_EXISTS_OVERWRITE, filename, NULL);
return FALSE;
}
}
if (g_stat(filename, &st) != -1 && !S_ISREG(st.st_mode)) {
- GtkWidget *w = e_error_new((GtkWindow *)parent, "mail:no-write-path-notfile", filename, NULL);
+ GtkWidget *w = e_error_new(parent, "mail:no-write-path-notfile", filename, NULL);
em_utils_show_error_silent (w);
return FALSE;
}
@@ -632,13 +626,14 @@ emu_save_messages_response(GtkWidget *filesel, gint response, struct _save_messa
* user for filename).
**/
void
-em_utils_save_messages (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids)
+em_utils_save_messages (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids)
{
struct _save_messages_data *data;
GtkWidget *filesel;
gchar *filename = NULL;
CamelMessageInfo *info = NULL;
+ g_return_if_fail (GTK_IS_WINDOW (parent));
g_return_if_fail (CAMEL_IS_FOLDER (folder));
g_return_if_fail (uids != NULL);
@@ -678,7 +673,7 @@ emu_add_address_cb(BonoboListener *listener, const gchar *name, const CORBA_any
/* one of email or vcard should be always NULL, never both of them */
static void
-emu_add_address_or_vcard (GtkWidget *parent, const gchar *email, const gchar *vcard)
+emu_add_address_or_vcard (GtkWindow *parent, const gchar *email, const gchar *vcard)
{
GtkWidget *win;
GtkWidget *control;
@@ -701,14 +696,7 @@ emu_add_address_or_vcard (GtkWidget *parent, const gchar *email, const gchar *vc
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title((GtkWindow *)win, _("Add address"));
- if (parent && !GTK_IS_WINDOW (parent)) {
- parent = gtk_widget_get_toplevel (parent);
- if (!parent || !(GTK_WIDGET_TOPLEVEL (parent)))
- parent = NULL;
- }
-
- if (parent)
- gtk_window_set_transient_for((GtkWindow *)win, ((GtkWindow *)parent));
+ gtk_window_set_transient_for((GtkWindow *)win, parent);
gtk_window_set_position((GtkWindow *)win, GTK_WIN_POS_CENTER_ON_PARENT);
gtk_window_set_type_hint((GtkWindow *)win, GDK_WINDOW_TYPE_HINT_DIALOG);
@@ -739,8 +727,10 @@ emu_add_address_or_vcard (GtkWidget *parent, const gchar *email, const gchar *vc
* Add address @email to the addressbook.
**/
void
-em_utils_add_address (GtkWidget *parent, const gchar *email)
+em_utils_add_address (GtkWindow *parent, const gchar *email)
{
+ g_return_if_fail (GTK_IS_WINDOW (parent));
+
emu_add_address_or_vcard (parent, email, NULL);
}
@@ -749,67 +739,19 @@ em_utils_add_address (GtkWidget *parent, const gchar *email)
* Adds whole vCard to the addressbook.
**/
void
-em_utils_add_vcard (GtkWidget *parent, const gchar *vcard)
+em_utils_add_vcard (GtkWindow *parent, const gchar *vcard)
{
+ g_return_if_fail (GTK_IS_WINDOW (parent));
+
emu_add_address_or_vcard (parent, NULL, vcard);
}
/* ********************************************************************** */
/* Flag-for-Followup... */
-/* tag-editor callback data */
-struct ted_t {
- EMFolderView *emfv;
- MessageTagEditor *editor;
- CamelFolder *folder;
- GPtrArray *uids;
-};
-
-static void
-ted_free (struct ted_t *ted)
-{
- camel_object_unref (ted->folder);
- em_utils_uids_free (ted->uids);
- g_free (ted);
-}
-
-static void
-tag_editor_response (GtkWidget *dialog, gint button, struct ted_t *ted)
-{
- CamelFolder *folder;
- CamelTag *tags, *t;
- GPtrArray *uids;
- gint i;
-
- if (button == GTK_RESPONSE_OK && (tags = message_tag_editor_get_tag_list (ted->editor))) {
- folder = ted->folder;
- uids = ted->uids;
-
- camel_folder_freeze (folder);
- for (i = 0; i < uids->len; i++) {
- CamelMessageInfo *mi = camel_folder_get_message_info(folder, uids->pdata[i]);
-
- if (mi) {
- for (t = tags; t; t = t->next)
- camel_message_info_set_user_tag(mi, t->name, t->value);
-
- camel_message_info_free(mi);
- }
- }
-
- camel_folder_thaw (folder);
- camel_tag_list_free (&tags);
-
- if (ted->emfv->preview)
- em_format_redraw (EM_FORMAT (ted->emfv->preview));
- }
-
- gtk_widget_destroy (dialog);
-}
-
/**
* em_utils_flag_for_followup:
- * @parent: parent window
+ * @reader: an #EMailReader
* @folder: folder containing messages to flag
* @uids: uids of messages to flag
*
@@ -817,38 +759,38 @@ tag_editor_response (GtkWidget *dialog, gint button, struct ted_t *ted)
* @folder and @uids.
**/
void
-em_utils_flag_for_followup (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids)
+em_utils_flag_for_followup (EMailReader *reader,
+ CamelFolder *folder,
+ GPtrArray *uids)
{
- GtkWidget *editor;
- struct ted_t *ted;
+ EMFormatHTMLDisplay *html_display;
+ MessageTagEditor *editor;
+ GtkWindow *parent;
+ CamelTag *tags;
gint i;
+ g_return_if_fail (E_IS_MAIL_READER (reader));
g_return_if_fail (CAMEL_IS_FOLDER (folder));
g_return_if_fail (uids != NULL);
- editor = (GtkWidget *) message_tag_followup_new ();
-
- if (parent != NULL)
- e_dialog_set_transient_for ((GtkWindow *) editor, parent);
-
- camel_object_ref (folder);
-
- ted = g_new (struct ted_t, 1);
- ted->emfv = (EMFolderView *) parent;
- ted->editor = MESSAGE_TAG_EDITOR (editor);
- ted->folder = folder;
- ted->uids = uids;
+ editor = message_tag_followup_new ();
+ parent = e_mail_reader_get_window (reader);
+ gtk_window_set_transient_for (GTK_WINDOW (editor), parent);
for (i = 0; i < uids->len; i++) {
CamelMessageInfo *info;
info = camel_folder_get_message_info (folder, uids->pdata[i]);
- if (info) {
- message_tag_followup_append_message (MESSAGE_TAG_FOLLOWUP (editor),
- camel_message_info_from (info),
- camel_message_info_subject (info));
- camel_message_info_free(info);
- }
+
+ if (info == NULL)
+ continue;
+
+ message_tag_followup_append_message (
+ MESSAGE_TAG_FOLLOWUP (editor),
+ camel_message_info_from (info),
+ camel_message_info_subject (info));
+
+ camel_message_info_free(info);
}
/* special-case... */
@@ -857,18 +799,49 @@ em_utils_flag_for_followup (GtkWidget *parent, CamelFolder *folder, GPtrArray *u
info = camel_folder_get_message_info (folder, uids->pdata[0]);
if (info) {
- const CamelTag *tags = camel_message_info_user_tags(info);
+ tags = (CamelTag *) camel_message_info_user_tags (info);
if (tags)
- message_tag_editor_set_tag_list (MESSAGE_TAG_EDITOR (editor), (CamelTag *)tags);
- camel_message_info_free(info);
+ message_tag_editor_set_tag_list (editor, tags);
+ camel_message_info_free (info);
}
}
- g_signal_connect (editor, "response", G_CALLBACK (tag_editor_response), ted);
- g_object_weak_ref ((GObject *) editor, (GWeakNotify) ted_free, ted);
+ if (gtk_dialog_run (GTK_DIALOG (editor)) != GTK_RESPONSE_OK)
+ goto exit;
+
+ tags = message_tag_editor_get_tag_list (editor);
+ if (tags == NULL)
+ goto exit;
+
+ camel_folder_freeze (folder);
+ for (i = 0; i < uids->len; i++) {
+ CamelMessageInfo *info;
+ CamelTag *iter;
+
+ info = camel_folder_get_message_info(folder, uids->pdata[i]);
+
+ if (info == NULL)
+ continue;
+
+ for (iter = tags; iter != NULL; iter = iter->next)
+ camel_message_info_set_user_tag (
+ info, iter->name, iter->value);
+
+ camel_message_info_free (info);
+ }
- gtk_widget_show (editor);
+ camel_folder_thaw (folder);
+ camel_tag_list_free (&tags);
+
+ html_display = e_mail_reader_get_html_display (reader);
+ em_format_redraw (EM_FORMAT (html_display));
+
+exit:
+ /* XXX We shouldn't be freeing this. */
+ em_utils_uids_free (uids);
+
+ gtk_widget_destroy (GTK_WIDGET (editor));
}
/**
@@ -881,10 +854,11 @@ em_utils_flag_for_followup (GtkWidget *parent, CamelFolder *folder, GPtrArray *u
* @folder and @uids.
**/
void
-em_utils_flag_for_followup_clear (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids)
+em_utils_flag_for_followup_clear (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids)
{
gint i;
+ g_return_if_fail (GTK_IS_WINDOW (parent));
g_return_if_fail (CAMEL_IS_FOLDER (folder));
g_return_if_fail (uids != NULL);
@@ -915,11 +889,12 @@ em_utils_flag_for_followup_clear (GtkWidget *parent, CamelFolder *folder, GPtrAr
* Flag-for-Followup.
**/
void
-em_utils_flag_for_followup_completed (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids)
+em_utils_flag_for_followup_completed (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids)
{
gchar *now;
gint i;
+ g_return_if_fail (GTK_IS_WINDOW (parent));
g_return_if_fail (CAMEL_IS_FOLDER (folder));
g_return_if_fail (uids != NULL);
@@ -1375,19 +1350,23 @@ em_utils_temp_save_part(GtkWidget *parent, CamelMimePart *part, gboolean mode)
gboolean
em_utils_folder_is_templates (CamelFolder *folder, const gchar *uri)
{
+ CamelFolder *local_templates_folder;
EAccountList *accounts;
EAccount *account;
EIterator *iter;
gint is = FALSE;
gchar *templates_uri;
- if (folder == mail_component_get_folder (NULL, MAIL_COMPONENT_FOLDER_TEMPLATES))
+ local_templates_folder =
+ e_mail_local_get_folder (E_MAIL_FOLDER_TEMPLATES);
+
+ if (folder == local_templates_folder)
return TRUE;
- if (uri == NULL)
+ if (folder == NULL || uri == NULL)
return FALSE;
- accounts = mail_config_get_accounts();
+ accounts = e_get_account_list ();
iter = e_list_get_iterator ((EList *)accounts);
while (e_iterator_is_valid (iter)) {
account = (EAccount *)e_iterator_get (iter);
@@ -1422,19 +1401,23 @@ em_utils_folder_is_templates (CamelFolder *folder, const gchar *uri)
gboolean
em_utils_folder_is_drafts(CamelFolder *folder, const gchar *uri)
{
+ CamelFolder *local_drafts_folder;
EAccountList *accounts;
EAccount *account;
EIterator *iter;
gint is = FALSE;
gchar *drafts_uri;
- if (folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS))
+ local_drafts_folder =
+ e_mail_local_get_folder (E_MAIL_FOLDER_DRAFTS);
+
+ if (folder == local_drafts_folder)
return TRUE;
- if (uri == NULL)
+ if (folder == NULL || uri == NULL)
return FALSE;
- accounts = mail_config_get_accounts();
+ accounts = e_get_account_list ();
iter = e_list_get_iterator((EList *)accounts);
while (e_iterator_is_valid(iter)) {
account = (EAccount *)e_iterator_get(iter);
@@ -1469,19 +1452,22 @@ em_utils_folder_is_drafts(CamelFolder *folder, const gchar *uri)
gboolean
em_utils_folder_is_sent(CamelFolder *folder, const gchar *uri)
{
+ CamelFolder *local_sent_folder;
EAccountList *accounts;
EAccount *account;
EIterator *iter;
gint is = FALSE;
gchar *sent_uri;
- if (folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT))
+ local_sent_folder = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
+
+ if (folder == local_sent_folder)
return TRUE;
- if (uri == NULL)
+ if (folder == NULL || uri == NULL)
return FALSE;
- accounts = mail_config_get_accounts();
+ accounts = e_get_account_list ();
iter = e_list_get_iterator((EList *)accounts);
while (e_iterator_is_valid(iter)) {
account = (EAccount *)e_iterator_get(iter);
@@ -1516,8 +1502,13 @@ em_utils_folder_is_sent(CamelFolder *folder, const gchar *uri)
gboolean
em_utils_folder_is_outbox(CamelFolder *folder, const gchar *uri)
{
+ CamelFolder *local_outbox_folder;
+
+ local_outbox_folder =
+ e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+
/* <Highlander>There can be only one.</Highlander> */
- return folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
+ return folder == local_outbox_folder;
}
/**
@@ -1592,53 +1583,6 @@ em_utils_get_proxy_uri (const gchar *pUri)
}
/**
- * em_utils_part_to_html:
- * @part:
- *
- * Converts a mime part's contents into html text. If @credits is given,
- * then it will be used as an attribution string, and the
- * content will be cited. Otherwise no citation or attribution
- * will be performed.
- *
- * Return Value: The part in displayable html format.
- **/
-gchar *
-em_utils_part_to_html(CamelMimePart *part, gssize *len, EMFormat *source)
-{
- EMFormatQuote *emfq;
- CamelStreamMem *mem;
- GByteArray *buf;
- gchar *text;
-
- buf = g_byte_array_new ();
- mem = (CamelStreamMem *) camel_stream_mem_new ();
- camel_stream_mem_set_byte_array (mem, buf);
-
- emfq = em_format_quote_new(NULL, (CamelStream *)mem, 0);
- ((EMFormat *) emfq)->composer = TRUE;
- em_format_set_session((EMFormat *)emfq, session);
- if (source) {
- /* copy over things we can, other things are internal, perhaps need different api than 'clone' */
- if (source->default_charset)
- em_format_set_default_charset((EMFormat *)emfq, source->default_charset);
- if (source->charset)
- em_format_set_default_charset((EMFormat *)emfq, source->charset);
- }
- em_format_part((EMFormat *) emfq, (CamelStream *)mem, part);
- g_object_unref(emfq);
-
- camel_stream_write((CamelStream *) mem, "", 1);
- camel_object_unref(mem);
-
- text = (gchar *)buf->data;
- if (len)
- *len = buf->len-1;
- g_byte_array_free (buf, FALSE);
-
- return text;
-}
-
-/**
* em_utils_message_to_html:
* @message:
* @credits:
@@ -1666,7 +1610,6 @@ em_utils_message_to_html(CamelMimeMessage *message, const gchar *credits, guint3
emfq = em_format_quote_new(credits, (CamelStream *)mem, flags);
((EMFormat *) emfq)->composer = TRUE;
- em_format_set_session((EMFormat *)emfq, session);
if (!source) {
GConfClient *gconf;
@@ -1740,7 +1683,7 @@ em_utils_empty_trash (GtkWidget *parent)
camel_exception_init (&ex);
/* expunge all remote stores */
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
iter = e_list_get_iterator ((EList *) accounts);
while (e_iterator_is_valid (iter)) {
account = (EAccount *) e_iterator_get (iter);
@@ -1909,7 +1852,7 @@ gchar *em_uri_to_camel(const gchar *euri)
uid = g_strdup(eurl->host);
}
- accounts = mail_config_get_accounts();
+ accounts = e_get_account_list ();
account = e_account_list_find(accounts, E_ACCOUNT_FIND_UID, uid);
g_free(uid);
@@ -2294,93 +2237,12 @@ em_utils_contact_photo (CamelInternetAddress *cia, gboolean local)
return part;
}
-/**
- * em_utils_snoop_type:
- * @part:
- *
- * Tries to snoop the mime type of a part.
- *
- * Return value: NULL if unknown (more likely application/octet-stream).
- **/
-const gchar *
-em_utils_snoop_type(CamelMimePart *part)
-{
- /* cache is here only to be able still return const gchar * */
- static GHashTable *types_cache = NULL;
-
- const gchar *filename;
- gchar *name_type = NULL, *magic_type = NULL, *res, *tmp;
- CamelDataWrapper *dw;
-
- filename = camel_mime_part_get_filename (part);
- if (filename != NULL)
- name_type = e_util_guess_mime_type (filename, FALSE);
-
- dw = camel_medium_get_content_object((CamelMedium *)part);
- if (!camel_data_wrapper_is_offline(dw)) {
- CamelStreamMem *mem = (CamelStreamMem *)camel_stream_mem_new();
-
- if (camel_data_wrapper_decode_to_stream(dw, (CamelStream *)mem) > 0) {
- gchar *ct = g_content_type_guess (filename, mem->buffer->data, mem->buffer->len, NULL);
-
- if (ct)
- magic_type = g_content_type_get_mime_type (ct);
-
- g_free (ct);
- }
- camel_object_unref(mem);
- }
-
- d(printf("snooped part, magic_type '%s' name_type '%s'\n", magic_type, name_type));
-
- /* If gvfs doesn't recognize the data by magic, but it
- * contains English words, it will call it text/plain. If the
- * filename-based check came up with something different, use
- * that instead and if it returns "application/octet-stream"
- * try to do better with the filename check.
- */
-
- if (magic_type) {
- if (name_type
- && (!strcmp(magic_type, "text/plain")
- || !strcmp(magic_type, "application/octet-stream")))
- res = name_type;
- else
- res = magic_type;
- } else
- res = name_type;
-
- if (res != name_type)
- g_free (name_type);
-
- if (res != magic_type)
- g_free (magic_type);
-
- if (!types_cache)
- types_cache = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) NULL);
-
- if (res) {
- tmp = g_hash_table_lookup (types_cache, res);
- if (tmp) {
- g_free (res);
- res = tmp;
- } else {
- g_hash_table_insert (types_cache, res, res);
- }
- }
-
- return res;
-
- /* We used to load parts to check their type, we dont anymore,
- see bug #11778 for some discussion */
-}
-
void
em_utils_clear_get_password_canceled_accounts_flag (void)
{
EAccountList *accounts;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
if (accounts) {
EIterator *iter;
@@ -2400,25 +2262,73 @@ em_utils_clear_get_password_canceled_accounts_flag (void)
}
}
-static void error_response(GtkObject *o, gint button, gpointer data)
-{
- gtk_widget_destroy((GtkWidget *)o);
-}
-
void
em_utils_show_error_silent (GtkWidget *widget)
{
- EActivityHandler *handler = mail_component_peek_activity_handler (mail_component_peek ());
- if(!g_object_get_data ((GObject *) widget, "response-handled"))
- g_signal_connect(widget, "response", G_CALLBACK(error_response), NULL);
- e_activity_handler_make_error (handler, "mail", E_LOG_ERROR, widget);
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EActivity *activity;
+
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ activity = e_alert_activity_new_warning (widget);
+ e_shell_backend_add_activity (shell_backend, activity);
+ g_object_unref (activity);
+
+ if (g_object_get_data (G_OBJECT (widget), "response-handled") == NULL)
+ g_signal_connect (
+ widget, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
}
void
em_utils_show_info_silent (GtkWidget *widget)
{
- EActivityHandler *handler = mail_component_peek_activity_handler (mail_component_peek ());
- if(!g_object_get_data ((GObject *) widget, "response-handled"))
- g_signal_connect(widget, "response", G_CALLBACK(error_response), NULL);
- e_activity_handler_make_error (handler, "mail", E_LOG_WARNINGS, widget);
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EActivity *activity;
+
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ activity = e_alert_activity_new_info (widget);
+ e_shell_backend_add_activity (shell_backend, activity);
+ g_object_unref (activity);
+
+ if (g_object_get_data (G_OBJECT (widget), "response-handled") == NULL)
+ g_signal_connect (
+ widget, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+}
+
+gchar *
+em_utils_url_unescape_amp (const gchar *url)
+{
+ gchar *buff;
+ gint i, j, amps;
+
+ if (!url)
+ return NULL;
+
+ amps = 0;
+ for (i = 0; url [i]; i++) {
+ if (url [i] == '&' && strncmp (url + i, "&amp;", 5) == 0)
+ amps++;
+ }
+
+ buff = g_strdup (url);
+
+ if (!amps)
+ return buff;
+
+ for (i = 0, j = 0; url [i]; i++, j++) {
+ buff [j] = url [i];
+
+ if (url [i] == '&' && strncmp (url + i, "&amp;", 5) == 0)
+ i += 4;
+ }
+ buff [j] = 0;
+
+ return buff;
}
diff --git a/mail/em-utils.h b/mail/em-utils.h
index 22b47b5be2..14dc8cef23 100644
--- a/mail/em-utils.h
+++ b/mail/em-utils.h
@@ -25,33 +25,43 @@
#include <gtk/gtk.h>
#include <sys/types.h>
+#include <camel/camel-exception.h>
+#include <camel/camel-folder.h>
+#include <camel/camel-internet-address.h>
+#include <camel/camel-mime-message.h>
+#include <camel/camel-mime-part.h>
+#include <camel/camel-stream.h>
-#include <mail/em-format.h>
+#include <mail/e-mail-reader.h>
G_BEGIN_DECLS
+struct _EMFormat;
+
+const gchar * em_utils_get_data_dir (void);
+const gchar * em_utils_get_config_dir (void);
+
gboolean em_utils_prompt_user(GtkWindow *parent, const gchar *promptkey, const gchar *tag, const gchar *arg0, ...);
GPtrArray *em_utils_uids_copy (GPtrArray *uids);
void em_utils_uids_free (GPtrArray *uids);
-gboolean em_utils_configure_account (GtkWidget *parent);
-gboolean em_utils_check_user_can_send_mail (GtkWidget *parent);
+gboolean em_utils_check_user_can_send_mail (void);
void em_utils_edit_filters (GtkWidget *parent);
void em_filename_make_safe (gchar *string);
void em_utils_edit_vfolders (GtkWidget *parent);
-void em_utils_save_part(GtkWidget *parent, const gchar *prompt, CamelMimePart *part);
-gboolean em_utils_save_part_to_file(GtkWidget *parent, const gchar *filename, CamelMimePart *part);
-void em_utils_save_messages (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids);
+void em_utils_save_part(GtkWindow *parent, const gchar *prompt, CamelMimePart *part);
+gboolean em_utils_save_part_to_file(GtkWindow *parent, const gchar *filename, CamelMimePart *part);
+void em_utils_save_messages (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids);
-void em_utils_add_address(GtkWidget *parent, const gchar *email);
-void em_utils_add_vcard(GtkWidget *parent, const gchar *vcard);
+void em_utils_add_address(GtkWindow *parent, const gchar *email);
+void em_utils_add_vcard(GtkWindow *parent, const gchar *vcard);
-void em_utils_flag_for_followup (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids);
-void em_utils_flag_for_followup_clear (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids);
-void em_utils_flag_for_followup_completed (GtkWidget *parent, CamelFolder *folder, GPtrArray *uids);
+void em_utils_flag_for_followup (EMailReader *reader, CamelFolder *folder, GPtrArray *uids);
+void em_utils_flag_for_followup_clear (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids);
+void em_utils_flag_for_followup_completed (GtkWindow *parent, CamelFolder *folder, GPtrArray *uids);
/* This stuff that follows probably doesn't belong here, then again, the stuff above probably belongs elsewhere */
@@ -65,7 +75,7 @@ void em_utils_selection_set_urilist(GtkSelectionData *data, CamelFolder *folder,
void em_utils_selection_get_urilist(GtkSelectionData *data, CamelFolder *folder);
gchar *em_utils_temp_save_part(GtkWidget *parent, CamelMimePart *part, gboolean mode);
-void em_utils_save_parts (GtkWidget *parent, const gchar *prompt, GSList * parts);
+void em_utils_save_parts (GtkWindow *parent, const gchar *prompt, GSList * parts);
gboolean em_utils_folder_is_drafts(CamelFolder *folder, const gchar *uri);
gboolean em_utils_folder_is_templates(CamelFolder *folder, const gchar *uri);
@@ -77,8 +87,7 @@ void em_utils_adjustment_page(GtkAdjustment *adj, gboolean down);
gchar *em_utils_get_proxy_uri (const gchar *uri);
/* FIXME: should this have an override charset? */
-gchar *em_utils_part_to_html(CamelMimePart *part, gssize *len, EMFormat *source);
-gchar *em_utils_message_to_html(CamelMimeMessage *msg, const gchar *credits, guint32 flags, gssize *len, EMFormat *source, const gchar *append);
+gchar *em_utils_message_to_html(CamelMimeMessage *msg, const gchar *credits, guint32 flags, gssize *len, struct _EMFormat *source, const gchar *append);
void em_utils_expunge_folder (GtkWidget *parent, CamelFolder *folder);
void em_utils_empty_trash (GtkWidget *parent);
@@ -98,11 +107,12 @@ void em_utils_show_info_silent (GtkWidget *widget);
gboolean em_utils_in_addressbook (CamelInternetAddress *addr, gboolean local_only);
CamelMimePart *em_utils_contact_photo (CamelInternetAddress *addr, gboolean local);
-const gchar *em_utils_snoop_type(CamelMimePart *part);
-
/* clears flag 'get_password_canceled' at every known accounts, so if needed, get_password will show dialog */
void em_utils_clear_get_password_canceled_accounts_flag (void);
+/* Unescapes &amp; back to a real & in URIs */
+gchar *em_utils_url_unescape_amp (const gchar *url);
+
G_END_DECLS
#endif /* __EM_UTILS_H__ */
diff --git a/mail/em-vfolder-editor.c b/mail/em-vfolder-editor.c
index 13a41c1888..84acd5f293 100644
--- a/mail/em-vfolder-editor.c
+++ b/mail/em-vfolder-editor.c
@@ -98,7 +98,7 @@ em_vfolder_editor_get_type (void)
*
* Return value: A new #EMVFolderEditor object.
**/
-EMVFolderEditor *
+GtkWidget *
em_vfolder_editor_new (EMVFolderContext *vc)
{
EMVFolderEditor *ve = (EMVFolderEditor *) g_object_new (em_vfolder_editor_get_type(), NULL);
@@ -116,7 +116,7 @@ em_vfolder_editor_new (EMVFolderContext *vc)
gtk_widget_hide (glade_xml_get_widget (gui, "filter_source_combobox"));
g_object_unref (gui);
- return ve;
+ return GTK_WIDGET (ve);
}
static FilterRule *
diff --git a/mail/em-vfolder-editor.h b/mail/em-vfolder-editor.h
index 58bcd566a1..550f7cd2d3 100644
--- a/mail/em-vfolder-editor.h
+++ b/mail/em-vfolder-editor.h
@@ -47,6 +47,6 @@ struct _EMVFolderEditorClass {
GType em_vfolder_editor_get_type (void);
-EMVFolderEditor *em_vfolder_editor_new (EMVFolderContext *vc);
+GtkWidget *em_vfolder_editor_new (EMVFolderContext *vc);
#endif /* ! _EM_VFOLDER_EDITOR_H */
diff --git a/mail/em-vfolder-rule.c b/mail/em-vfolder-rule.c
index f2cc7cb57f..4d690115ac 100644
--- a/mail/em-vfolder-rule.c
+++ b/mail/em-vfolder-rule.c
@@ -34,10 +34,10 @@
#include "camel/camel-url.h"
#include "em-vfolder-context.h"
#include "em-vfolder-rule.h"
+#include "mail/e-mail-store.h"
#include "mail/em-utils.h"
#include "mail/em-folder-tree.h"
#include "mail/em-folder-selector.h"
-#include "mail/mail-component.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
@@ -507,8 +507,8 @@ source_add(GtkWidget *widget, struct _source_data *data)
EMFolderTree *emft;
GtkWidget *dialog;
- emft =(EMFolderTree *)em_folder_tree_new_with_model(mail_component_peek_tree_model(mail_component_peek()));
- em_folder_tree_set_excluded(emft, EMFT_EXCLUDE_NOSELECT);
+ emft =(EMFolderTree *) em_folder_tree_new ();
+ em_folder_tree_set_excluded (emft, EMFT_EXCLUDE_NOSELECT);
dialog = em_folder_selector_new(emft, EM_FOLDER_SELECTOR_CAN_CREATE, _("Select Folder"), NULL, _("_Add"));
gtk_window_set_transient_for((GtkWindow *)dialog, (GtkWindow *)gtk_widget_get_toplevel(widget));
diff --git a/mail/evolution-mail.schemas.in b/mail/evolution-mail.schemas.in
index fbc23eb746..e0895c330c 100644
--- a/mail/evolution-mail.schemas.in
+++ b/mail/evolution-mail.schemas.in
@@ -374,6 +374,20 @@
</schema>
<schema>
+ <key>/schema/apps/evolution/mail/display/show_all_headers</key>
+ <applyto>/apps/evolution/mail/display/show_all_headers</applyto>
+ <owner>evolution-mail</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>Show all message headers</short>
+ <long>
+ Show all the headers when viewing a messages.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
<key>/schemas/apps/evolution/mail/display/headers</key>
<applyto>/apps/evolution/mail/display/headers</applyto>
<owner>evolution-mail</owner>
@@ -576,16 +590,19 @@
</schema>
<schema>
- <key>/schemas/apps/evolution/mail/display/show_wide</key>
- <applyto>/apps/evolution/mail/display/show_wide</applyto>
+ <key>/schemas/apps/evolution/mail/display/layout</key>
+ <applyto>/apps/evolution/mail/display/layout</applyto>
<owner>evolution-mail</owner>
- <type>bool</type>
- <default>false</default>
+ <type>int</type>
+ <default>0</default>
<locale name="C">
- <short>Use side-by-side or wide layout</short>
- <long>
- If the &quot;Preview&quot; pane is on, then show it side-by-side rather than vertically.
- </long>
+ <short>Layout style</short>
+ <long>
+ The layout style determines where to place the preview pane
+ in relation to the message list. "0" (Classic View) places
+ the preview pane below the message list. "1" (Vertical View)
+ places the preview pane next to the message list.
+ </long>
</locale>
</schema>
@@ -750,29 +767,41 @@
</locale>
</schema>
- <!-- Message Window -->
+ <!-- Mail Browser -->
<schema>
- <key>/schemas/apps/evolution/mail/message_window/width</key>
- <applyto>/apps/evolution/mail/message_window/width</applyto>
+ <key>/schemas/apps/evolution/mail/mail_browser_width</key>
+ <applyto>/apps/evolution/mail/mail_browser_width</applyto>
<owner>evolution-mail</owner>
<type>int</type>
<default>600</default>
<locale name="C">
- <short>Message Window default width</short>
- <long>Default width of the message window.</long>
+ <short>Mail browser width</short>
+ <long>Default width of the mail browser window.</long>
</locale>
</schema>
<schema>
- <key>/schemas/apps/evolution/mail/message_window/height</key>
- <applyto>/apps/evolution/mail/message_window/height</applyto>
+ <key>/schemas/apps/evolution/mail/mail_browser_height</key>
+ <applyto>/apps/evolution/mail/mail_browser_height</applyto>
<owner>evolution-mail</owner>
<type>int</type>
<default>400</default>
<locale name="C">
- <short>Message Window default height</short>
- <long>Default height of the message window.</long>
+ <short>Mail browser height</short>
+ <long>Default height of the mail browser window.</long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/evolution/mail/mail_browser_maximized</key>
+ <applyto>/apps/evolution/mail/mail_browser_maximized</applyto>
+ <owner>evolution-mail</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>Mail browser maximized</short>
+ <long>Default maximized state of the mail browser window.</long>
</locale>
</schema>
diff --git a/mail/filtertypes.xml b/mail/filtertypes.xml
index f2f69c4c06..a93b887271 100644
--- a/mail/filtertypes.xml
+++ b/mail/filtertypes.xml
@@ -636,7 +636,7 @@
</option>
</input>
<input type="optionlist" name="versus">
- <dynamic func="e_util_labels_get_filter_options"/>
+ <dynamic func="e_mail_labels_get_filter_options"/>
</input>
</part>
@@ -923,7 +923,7 @@
<title>Set Label</title>
<code>(set-label ${label})</code>
<input type="optionlist" name="label">
- <dynamic func="e_util_labels_get_filter_options"/>
+ <dynamic func="e_mail_labels_get_filter_options"/>
</input>
</part>
<part name="colour">
diff --git a/mail/importers/Makefile.am b/mail/importers/Makefile.am
index 5e46a54c4d..bd38762ea2 100644
--- a/mail/importers/Makefile.am
+++ b/mail/importers/Makefile.am
@@ -1,6 +1,5 @@
if OS_WIN32
WIN32_BOOTSTRAP_LIBS = \
- $(top_builddir)/win32/libevolution-mail-shared.la \
$(top_builddir)/win32/libevolution-mail.la
endif
@@ -10,6 +9,7 @@ AM_CPPFLAGS = -I.. \
-I$(srcdir)/.. \
-I$(top_srcdir) \
-I$(top_srcdir)/widgets \
+ $(EVOLUTION_MAIL_CFLAGS) \
-DG_LOG_DOMAIN=\"evolution-mail-importer\" \
-DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \
$(IMPORTERS_CFLAGS)
@@ -27,6 +27,7 @@ libevolution_mail_importers_la_LIBADD = \
$(WIN32_BOOTSTRAP_LIBS) \
$(top_builddir)/e-util/libeutil.la \
$(top_builddir)/filter/libfilter.la \
+ $(top_builddir)/mail/libevolution-mail.la \
$(IMPORTERS_LIBS)
-include $(top_srcdir)/git.mk
diff --git a/mail/importers/evolution-mbox-importer.c b/mail/importers/evolution-mbox-importer.c
index 7cd2b34b22..ade34526fc 100644
--- a/mail/importers/evolution-mbox-importer.c
+++ b/mail/importers/evolution-mbox-importer.c
@@ -40,9 +40,10 @@
#include <camel/camel-exception.h>
+#include "mail/e-mail-local.h"
+#include "mail/e-mail-store.h"
#include "mail/em-folder-selection-button.h"
-
-#include "mail/mail-component.h"
+#include "mail/em-folder-tree-model.h"
#include "mail/mail-mt.h"
#include "mail-importer.h"
@@ -73,15 +74,18 @@ static GtkWidget *
mbox_getwidget(EImport *ei, EImportTarget *target, EImportImporter *im)
{
GtkWidget *hbox, *w;
+ const gchar *local_inbox_uri;
+
+ local_inbox_uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_INBOX);
hbox = gtk_hbox_new(FALSE, 0);
w = gtk_label_new(_("Destination folder:"));
gtk_box_pack_start((GtkBox *)hbox, w, FALSE, TRUE, 6);
- w = em_folder_selection_button_new(_("Select folder"), _("Select folder to import into"));
- em_folder_selection_button_set_selection((EMFolderSelectionButton *)w,
- mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_INBOX));
+ w = em_folder_selection_button_new(
+ _("Select folder"), _("Select folder to import into"));
+ em_folder_selection_button_set_selection((EMFolderSelectionButton *)w, local_inbox_uri);
g_signal_connect(w, "selected", G_CALLBACK(folder_selected), target);
gtk_box_pack_start((GtkBox *)hbox, w, FALSE, TRUE, 6);
diff --git a/mail/importers/mail-importer.c b/mail/importers/mail-importer.c
index daecfaee53..dd4de6370b 100644
--- a/mail/importers/mail-importer.c
+++ b/mail/importers/mail-importer.c
@@ -36,7 +36,6 @@
#include <glib.h>
#include <glib/gstdio.h>
-#include <gmodule.h>
#include <glib/gi18n.h>
#include <camel/camel-folder.h>
#include <camel/camel-store.h>
@@ -46,10 +45,12 @@
#include <camel/camel-stream-mem.h>
#include "e-util/e-util-private.h"
+#include "shell/e-shell-backend.h"
-#include "mail/mail-mt.h"
-#include "mail/mail-component.h"
-#include "mail/mail-tools.h"
+#include "mail-mt.h"
+#include "mail-tools.h"
+#include "e-mail-local.h"
+#include "em-utils.h"
#include "mail-importer.h"
@@ -203,7 +204,7 @@ import_mbox_exec (struct _import_mbox_msg *m)
}
if (m->uri == NULL || m->uri[0] == 0)
- folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_INBOX);
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_INBOX);
else
folder = mail_tool_uri_to_folder(m->uri, CAMEL_STORE_FOLDER_CREATE, &m->base.ex);
@@ -360,6 +361,7 @@ import_folders_rec(struct _import_folders_data *m, const gchar *filepath, const
GDir *dir;
const gchar *d;
struct stat st;
+ const gchar *data_dir;
gchar *filefull, *foldersub, *uri, *utf8_filename;
const gchar *folder;
@@ -367,6 +369,8 @@ import_folders_rec(struct _import_folders_data *m, const gchar *filepath, const
if (dir == NULL)
return;
+ data_dir = em_utils_get_data_dir ();
+
utf8_filename = g_filename_to_utf8 (filepath, -1, NULL, NULL, NULL);
camel_operation_start(NULL, _("Scanning %s"), utf8_filename);
g_free (utf8_filename);
@@ -395,9 +399,9 @@ import_folders_rec(struct _import_folders_data *m, const gchar *filepath, const
break;
}
/* FIXME: need a better way to get default store location */
- uri = g_strdup_printf("mbox:%s/local#%s", mail_component_peek_base_directory(NULL), folder);
+ uri = g_strdup_printf("mbox:%s/local#%s", data_dir, folder);
} else {
- uri = g_strdup_printf("mbox:%s/local#%s/%s", mail_component_peek_base_directory(NULL), folderparent, folder);
+ uri = g_strdup_printf("mbox:%s/local#%s/%s", data_dir, folderparent, folder);
}
printf("importing to uri %s\n", uri);
diff --git a/mail/mail-autofilter.c b/mail/mail-autofilter.c
index 2efa02e972..ece7e75ca5 100644
--- a/mail/mail-autofilter.c
+++ b/mail/mail-autofilter.c
@@ -32,7 +32,6 @@
#include "mail-vfolder.h"
#include "mail-autofilter.h"
-#include "mail-component.h"
#include "em-utils.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
@@ -345,14 +344,15 @@ void
filter_gui_add_from_message (CamelMimeMessage *msg, const gchar *source, gint flags)
{
EMFilterContext *fc;
+ const gchar *data_dir;
gchar *user, *system;
FilterRule *rule;
g_return_if_fail (msg != NULL);
fc = em_filter_context_new ();
- user = g_strdup_printf ("%s/filters.xml",
- mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "filters.xml", NULL);
system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
rule_context_load ((RuleContext *)fc, system, user);
g_free (system);
@@ -370,6 +370,7 @@ void
mail_filter_rename_uri(CamelStore *store, const gchar *olduri, const gchar *newuri)
{
EMFilterContext *fc;
+ const gchar *data_dir;
gchar *user, *system;
GList *changed;
gchar *eolduri, *enewuri;
@@ -378,7 +379,8 @@ mail_filter_rename_uri(CamelStore *store, const gchar *olduri, const gchar *newu
enewuri = em_uri_from_camel(newuri);
fc = em_filter_context_new ();
- user = g_strdup_printf ("%s/filters.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "filters.xml", NULL);
system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
rule_context_load ((RuleContext *)fc, system, user);
g_free (system);
@@ -402,6 +404,7 @@ void
mail_filter_delete_uri(CamelStore *store, const gchar *uri)
{
EMFilterContext *fc;
+ const gchar *data_dir;
gchar *user, *system;
GList *deleted;
gchar *euri;
@@ -409,7 +412,8 @@ mail_filter_delete_uri(CamelStore *store, const gchar *uri)
euri = em_uri_from_camel(uri);
fc = em_filter_context_new ();
- user = g_strdup_printf ("%s/filters.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "filters.xml", NULL);
system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
rule_context_load ((RuleContext *)fc, system, user);
g_free (system);
diff --git a/mail/mail-component-factory.c b/mail/mail-component-factory.c
deleted file mode 100644
index 9a95823bd4..0000000000
--- a/mail/mail-component-factory.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "mail-component.h"
-#include "em-account-prefs.h"
-#include "em-mailer-prefs.h"
-#include "em-composer-prefs.h"
-#include "em-network-prefs.h"
-
-#include "mail-config-factory.h"
-#include "mail-config.h"
-#include "mail-mt.h"
-
-#include "em-popup.h"
-#include "em-menu.h"
-#include "em-event.h"
-#include "em-config.h"
-#include "em-format-hook.h"
-#include "em-junk-hook.h"
-#include "em-format-html-display.h"
-
-#include "importers/mail-importer.h"
-#include "e-util/e-import.h"
-
-#include <bonobo-activation/bonobo-activation.h>
-#include <bonobo/bonobo-shlib-factory.h>
-
-#include <string.h>
-
-/* TODO: clean up these definitions */
-
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Mail_Factory:" BASE_VERSION
-#define COMPONENT_ID "OAFIID:GNOME_Evolution_Mail_Component:" BASE_VERSION
-#define FOLDER_INFO_ID "OAFIID:GNOME_Evolution_FolderInfo:" BASE_VERSION
-
-static BonoboObject *
-factory(BonoboGenericFactory *factory, const gchar *component_id, gpointer closure)
-{
- BonoboObject *o;
-
- if (strcmp (component_id, COMPONENT_ID) == 0) {
- MailComponent *component = mail_component_peek ();
-
- bonobo_object_ref (BONOBO_OBJECT (component));
- return BONOBO_OBJECT (component);
- } else if (strcmp (component_id, EM_ACCOUNT_PREFS_CONTROL_ID) == 0
- || strcmp (component_id, EM_MAILER_PREFS_CONTROL_ID) == 0
- || strcmp (component_id, EM_COMPOSER_PREFS_CONTROL_ID) == 0
- || strcmp (component_id, EM_NETWORK_PREFS_CONTROL_ID) == 0) {
- return mail_config_control_factory_cb (factory, component_id, CORBA_OBJECT_NIL);
- }
-
- o = mail_importer_factory_cb(factory, component_id, NULL);
- if (o == NULL)
- g_warning (FACTORY_ID ": Don't know what to do with %s", component_id);
-
- return o;
-}
-
-static Bonobo_Unknown
-make_factory (PortableServer_POA poa, const gchar *iid, gpointer impl_ptr, CORBA_Environment *ev)
-{
- static gint init = 0;
-
- if (!init) {
- EImportClass *klass;
-
- init = 1;
-
- mail_config_init();
- mail_msg_init();
-
- e_plugin_hook_register_type(em_popup_hook_get_type());
- e_plugin_hook_register_type(em_menu_hook_get_type());
- e_plugin_hook_register_type(em_config_hook_get_type());
-
- em_format_hook_register_type(em_format_get_type());
- em_format_hook_register_type(em_format_html_get_type());
- em_format_hook_register_type(em_format_html_display_get_type());
- em_junk_hook_register_type(emj_get_type());
-
- e_plugin_hook_register_type(em_format_hook_get_type());
- e_plugin_hook_register_type(em_event_hook_get_type());
- e_plugin_hook_register_type(em_junk_hook_get_type());
-
- klass = g_type_class_ref(e_import_get_type());
- e_import_class_add_importer(klass, mbox_importer_peek(), NULL, NULL);
- e_import_class_add_importer(klass, elm_importer_peek(), NULL, NULL);
- e_import_class_add_importer(klass, pine_importer_peek(), NULL, NULL);
- }
-
- return bonobo_shlib_factory_std (FACTORY_ID, poa, impl_ptr, factory, NULL, ev);
-}
-
-static BonoboActivationPluginObject plugin_list[] = {
- { FACTORY_ID, make_factory},
- { NULL }
-};
-
-const BonoboActivationPlugin Bonobo_Plugin_info = {
- plugin_list, "Evolution Mail component factory"
-};
diff --git a/mail/mail-component.c b/mail/mail-component.c
index 70da7b796a..0963a81726 100644
--- a/mail/mail-component.c
+++ b/mail/mail-component.c
@@ -37,7 +37,7 @@
#include <libedataserver/e-data-server-util.h>
#include "em-utils.h"
#include "em-composer-utils.h"
-#include "em-format.h"
+#include "em-format/em-format.h"
#include "em-folder-tree.h"
#include "em-folder-browser.h"
#include "em-message-browser.h"
@@ -99,35 +99,6 @@
#define d(x)
-static void create_local_item_cb(EUserCreatableItemsHandler *handler, const gchar *item_type_name, gpointer data);
-static void view_changed_timeout_remove (EComponentView *component_view);
-
-#define MAIL_COMPONENT_DEFAULT(mc) if (mc == NULL) mc = mail_component_peek();
-
-extern gint camel_application_is_exiting;
-
-#define PARENT_TYPE evolution_component_get_type ()
-static BonoboObjectClass *parent_class = NULL;
-const gchar *x_mailer = "Evolution " VERSION SUB_VERSION " " VERSION_COMMENT;
-#define OFFLINE 0
-#define ONLINE 1
-
-struct _store_info {
- CamelStore *store;
- gchar *name;
-
- /* we keep a reference to these so they remain around for the session */
- CamelFolder *vtrash;
- CamelFolder *vjunk;
-
- /* for setup only */
- void (*done)(CamelStore *store, CamelFolderInfo *info, gpointer data);
- gpointer done_data;
-
- gint ref_count:31;
- guint removed:1;
-};
-
struct _MailComponentPrivate {
GMutex *lock;
@@ -158,324 +129,6 @@ struct _MailComponentPrivate {
guint mail_sync_in_progress; /* is greater than 0 if still waiting to finish sync on some store */
};
-/* indexed by _mail_component_folder_t */
-static struct {
- const gchar *name;
- gchar *uri;
- CamelFolder *folder;
-} mc_default_folders[] = {
- /* translators: standard local mailbox names */
- { N_("Inbox"), },
- { N_("Drafts"), },
- { N_("Outbox"), },
- { N_("Sent"), },
- { N_("Templates"), },
- { "Inbox", }, /* 'always local' inbox */
-};
-
-static struct _store_info *
-store_info_new(CamelStore *store, const gchar *name)
-{
- struct _store_info *si;
-
- si = g_malloc0(sizeof(*si));
- si->ref_count = 1;
- if (name == NULL)
- si->name = camel_service_get_name((CamelService *)store, TRUE);
- else
- si->name = g_strdup(name);
- si->store = store;
- camel_object_ref(store);
- /* If these are vfolders then they need to be opened now,
- * otherwise they wont keep track of all folders */
- if ((store->flags & CAMEL_STORE_VTRASH) != 0)
- si->vtrash = camel_store_get_trash(store, NULL);
- if ((store->flags & CAMEL_STORE_VJUNK) != 0)
- si->vjunk = camel_store_get_junk(store, NULL);
-
- return si;
-}
-
-static void
-store_info_ref(struct _store_info *si)
-{
- si->ref_count++;
-}
-
-static void
-store_info_unref(struct _store_info *si)
-{
- if (si->ref_count > 1) {
- si->ref_count--;
- return;
- }
-
- if (si->vtrash)
- camel_object_unref(si->vtrash);
- if (si->vjunk)
- camel_object_unref(si->vjunk);
- camel_object_unref(si->store);
- g_free(si->name);
- g_free(si);
-}
-
-static gboolean
-mc_add_store_done(CamelStore *store, CamelFolderInfo *info, gpointer data)
-{
- struct _store_info *si = data;
-
- if (si->done)
- si->done(store, info, si);
-
- if (!si->removed) {
- /* let the counters know about the already opened junk/trash folders */
- if (si->vtrash)
- mail_note_folder(si->vtrash);
- if (si->vjunk)
- mail_note_folder(si->vjunk);
- }
-
- store_info_unref(si);
-
- return TRUE;
-}
-
-/* Utility functions. */
-static void
-mc_add_store(MailComponent *component, CamelStore *store, const gchar *name, void (*done)(CamelStore *store, CamelFolderInfo *info, gpointer data))
-{
- struct _store_info *si;
-
- MAIL_COMPONENT_DEFAULT(component);
-
- si = store_info_new(store, name);
- si->done = done;
- g_hash_table_insert(component->priv->store_hash, store, si);
- em_folder_tree_model_add_store(component->priv->model, store, si->name);
- store_info_ref(si);
- mail_note_store(store, NULL, mc_add_store_done, si);
-}
-
-static void
-mc_add_local_store_done(CamelStore *store, CamelFolderInfo *info, gpointer data)
-{
- /*MailComponent *mc = data;*/
- gint i;
-
- for (i=0;i<sizeof(mc_default_folders)/sizeof(mc_default_folders[0]);i++) {
- if (mc_default_folders[i].folder)
- mail_note_folder(mc_default_folders[i].folder);
- }
-}
-
-static void
-mc_add_local_store(CamelStore *store, const gchar *name, MailComponent *mc)
-{
- mc_add_store(mc, store, name, mc_add_local_store_done);
- camel_object_unref(store);
- g_object_unref(mc);
-}
-
-static void
-mc_setup_local_store(MailComponent *mc)
-{
- MailComponentPrivate *p = mc->priv;
- CamelURL *url;
- gchar *tmp;
- CamelException ex;
- gint i;
-
- g_mutex_lock(p->lock);
- if (p->local_store != NULL) {
- g_mutex_unlock(p->lock);
- return;
- }
-
- camel_exception_init(&ex);
-
- url = camel_url_new("mbox:", NULL);
- tmp = g_build_filename (p->base_directory, "local", NULL);
- camel_url_set_path(url, tmp);
- g_free(tmp);
- tmp = camel_url_to_string(url, 0);
- p->local_store = (CamelStore *)camel_session_get_service(session, tmp, CAMEL_PROVIDER_STORE, &ex);
- g_free(tmp);
- if (p->local_store == NULL)
- goto fail;
-
- for (i=0;i<sizeof(mc_default_folders)/sizeof(mc_default_folders[0]);i++) {
- /* FIXME: should this uri be account relative? */
- camel_url_set_fragment(url, mc_default_folders[i].name);
- mc_default_folders[i].uri = camel_url_to_string(url, 0);
- mc_default_folders[i].folder = camel_store_get_folder(p->local_store, mc_default_folders[i].name,
- CAMEL_STORE_FOLDER_CREATE, &ex);
- camel_exception_clear(&ex);
- }
-
- camel_url_free(url);
- g_mutex_unlock(p->lock);
-
- g_object_ref(mc);
- camel_object_ref(p->local_store);
- mail_async_event_emit(p->async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)mc_add_local_store, p->local_store, _("On This Computer"), mc);
-
- return;
-fail:
- g_mutex_unlock(p->lock);
-
- g_warning("Could not setup local store/folder: %s", ex.desc);
-
- camel_url_free(url);
- camel_exception_clear(&ex);
-}
-
-static void
-load_accounts (MailComponent *component, EAccountList *accounts)
-{
- EIterator *iter;
-
- /* Load each service (don't connect!). Check its provider and
- * see if this belongs in the shell's folder list. If so, add
- * it.
- */
-
- iter = e_list_get_iterator ((EList *) accounts);
- while (e_iterator_is_valid (iter)) {
- EAccountService *service;
- EAccount *account;
- const gchar *name;
-
- account = (EAccount *) e_iterator_get (iter);
- service = account->source;
- name = account->name;
-
- /* HACK: mbox url's are handled by the local store setup above,
- any that come through as account sources are really movemail sources! */
- if (account->enabled
- && service->url != NULL
- && service->url[0]
- && strncmp(service->url, "mbox:", 5) != 0)
- mail_component_load_store_by_uri (component, service->url, name);
-
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
-}
-
-static void
-setup_search_context (MailComponent *component)
-{
- MailComponentPrivate *priv = component->priv;
-
- if (priv->search_context == NULL) {
- gchar *user = g_build_filename(component->priv->base_directory, "searches.xml", NULL);
- gchar *system = g_build_filename (EVOLUTION_PRIVDATADIR, "searchtypes.xml", NULL);
-
- priv->search_context = (RuleContext *)em_search_context_new ();
- g_object_set_data_full (G_OBJECT (priv->search_context), "user", user, g_free);
- g_object_set_data_full (G_OBJECT (priv->search_context), "system", system, g_free);
- rule_context_load (priv->search_context, system, user);
- }
-}
-
-static void
-mc_startup(MailComponent *mc)
-{
- static gint started = 0;
- GConfClient *gconf;
-
- if (started)
- return;
- started = 1;
-
- mc_setup_local_store(mc);
- load_accounts(mc, mail_config_get_accounts());
-
- gconf = mail_config_get_gconf_client();
-
- if (gconf_client_get_bool (gconf, "/apps/evolution/mail/display/enable_vfolders", NULL))
- vfolder_load_storage();
-}
-
-static void
-folder_selected_cb (EMFolderTree *emft, const gchar *path, const gchar *uri, guint32 flags, EMFolderView *view)
-{
- EMFolderTreeModel *model;
-
- if ((flags & CAMEL_FOLDER_NOSELECT) || !path) {
- em_folder_view_set_folder (view, NULL, NULL);
- } else {
- model = em_folder_tree_get_model (emft);
- em_folder_tree_model_set_selected (model, uri);
- em_folder_tree_model_save_state (model);
-
- em_folder_view_set_folder_uri (view, uri);
- }
-}
-
-static void
-tree_hidden_key_event_cb (EMFolderTree *emft, GdkEvent *event, EMFolderView *view)
-{
- if (event && event->type == GDK_KEY_PRESS && view && view->list) {
- switch (event->key.keyval) {
- case '[':
- case ',':
- gtk_widget_grab_focus ((GtkWidget *) view->list);
- message_list_select (view->list, MESSAGE_LIST_SELECT_PREVIOUS|MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
- break;
- case ']':
- case '.':
- gtk_widget_grab_focus ((GtkWidget *) view->list);
- message_list_select (view->list, MESSAGE_LIST_SELECT_NEXT|MESSAGE_LIST_SELECT_WRAP, 0, CAMEL_MESSAGE_SEEN);
- break;
- }
- }
-}
-
-static gint
-check_autosave(gpointer data)
-{
- e_msg_composer_check_autosave(NULL);
-
- return FALSE;
-}
-
-static void
-view_control_activate_cb (BonoboControl *control, gboolean activate, EMFolderView *view)
-{
- BonoboUIComponent *uic;
- static gint recover = 0;
-
- uic = bonobo_control_get_ui_component (control);
- g_return_if_fail (uic != NULL);
-
- if (activate) {
- Bonobo_UIContainer container;
-
- container = bonobo_control_get_remote_ui_container (control, NULL);
- bonobo_ui_component_set_container (uic, container, NULL);
- bonobo_object_release_unref (container, NULL);
-
- g_return_if_fail (container == bonobo_ui_component_get_container(uic));
- g_return_if_fail (container != CORBA_OBJECT_NIL);
-
- em_folder_view_activate (view, uic, activate);
- e_user_creatable_items_handler_activate(g_object_get_data((GObject *)view, "e-creatable-items-handler"), uic);
- } else {
- em_folder_view_activate (view, uic, activate);
- bonobo_ui_component_unset_container (uic, NULL);
- }
-
- /* This is a weird place to put it, but createControls does it too early.
- I also think we should wait to do it until we actually visit the mailer.
- The delay is arbitrary - without it it shows up before the main window */
- if (!recover) {
- recover = 1;
- g_timeout_add(1000, check_autosave, NULL);
- }
-}
-
/* GObject methods. */
static void
@@ -488,8 +141,6 @@ impl_dispose (GObject *object)
priv->mail_sync_id = 0;
}
- view_changed_timeout_remove ((EComponentView *)object);
-
if (priv->activity_handler != NULL) {
g_object_unref (priv->activity_handler);
priv->activity_handler = NULL;
@@ -542,157 +193,6 @@ view_on_url (GObject *emitter, const gchar *url, const gchar *nice_url, MailComp
}
static void
-view_changed(EMFolderView *emfv, EComponentView *component_view)
-{
- EInfoLabel *el = g_object_get_data((GObject *)component_view, "info-label");
- CORBA_Environment ev;
-
- CORBA_exception_init(&ev);
-
- if (emfv->folder) {
- gchar *name, *title;
- const gchar *use_name; /* will contain localized name, if necessary */
- guint32 visible, unread, deleted, junked, junked_not_deleted;
- GPtrArray *selected;
- GString *tmp = g_string_new("");
-
- camel_object_get(emfv->folder, NULL,
- CAMEL_FOLDER_NAME, &name,
- CAMEL_FOLDER_DELETED, &deleted,
- CAMEL_FOLDER_VISIBLE, &visible,
- CAMEL_FOLDER_JUNKED, &junked,
- CAMEL_FOLDER_JUNKED_NOT_DELETED, &junked_not_deleted,
- CAMEL_FOLDER_UNREAD, &unread, NULL);
-
- selected = message_list_get_selected(emfv->list);
-
- /* This is so that if any of these are
- * shared/reused, we fallback to the standard
- * display behaviour */
- if (selected->len > 1)
- g_string_append_printf(tmp, ngettext ("%d selected, ", "%d selected, ", selected->len), selected->len);
-
- if (CAMEL_IS_VTRASH_FOLDER(emfv->folder)) {
- if (((CamelVTrashFolder *)emfv->folder)->type == CAMEL_VTRASH_FOLDER_TRASH) {
- g_string_append_printf(tmp, ngettext ("%d deleted", "%d deleted", deleted), deleted);
- } else {
- guint32 num = junked_not_deleted;
-
- if (!emfv->hide_deleted)
- num = junked;
-
- g_string_append_printf (tmp, ngettext ("%d junk", "%d junk", num), num);
- }
- } else if (em_utils_folder_is_drafts(emfv->folder, emfv->folder_uri)) {
- g_string_append_printf(tmp, ngettext ("%d draft", "%d drafts", visible), visible);
- } else if (em_utils_folder_is_sent(emfv->folder, emfv->folder_uri)) {
- g_string_append_printf(tmp, ngettext ("%d sent", "%d sent", visible), visible);
- } else if (em_utils_folder_is_outbox(emfv->folder, emfv->folder_uri)) {
- g_string_append_printf(tmp, ngettext ("%d unsent", "%d unsent", visible), visible);
- /* HACK: hardcoded inbox or maildir '.' folder */
- } else {
- if (!emfv->hide_deleted)
- visible += deleted - junked + junked_not_deleted;
- if (unread && selected->len <= 1)
- g_string_append_printf(tmp, ngettext ("%d unread, ", "%d unread, ", unread), unread);
- g_string_append_printf(tmp, ngettext ("%d total", "%d total", visible), visible);
- }
-
- message_list_free_uids(emfv->list, selected);
-
- if (emfv->folder->parent_store == mail_component_peek_local_store(NULL)
- && (!strcmp (name, "Drafts") || !strcmp (name, "Inbox")
- || !strcmp (name, "Outbox") || !strcmp (name, "Sent") || !strcmp (name, "Templates")))
- use_name = _(name);
- else if (!strcmp (name, "INBOX"))
- use_name = _("Inbox");
- else
- use_name = name;
-
- e_info_label_set_info (el, use_name, tmp->str);
- title = g_strdup_printf ("%s (%s)", use_name, tmp->str);
- e_component_view_set_title(component_view, title);
- g_free(title);
-
- g_string_free(tmp, TRUE);
- camel_object_free(emfv->folder, CAMEL_FOLDER_NAME, name);
- } else {
- e_info_label_set_info(el, _("Mail"), "");
- e_component_view_set_title(component_view, _("Mail"));
- }
-}
-
-static void
-view_changed_timeout_remove (EComponentView *component_view)
-{
- gpointer v;
- EInfoLabel *el;
- EMFolderView *emfv;
-
- v = g_object_get_data((GObject *)component_view, "view-changed-timeout");
- if (v) {
- g_source_remove(GPOINTER_TO_INT(v));
- g_object_set_data((GObject *)component_view, "view-changed-timeout", NULL);
-
- el = g_object_get_data((GObject *)component_view, "info-label");
- emfv = g_object_get_data((GObject *)el, "folderview");
- g_object_unref(el);
- g_object_unref(emfv);
- }
-}
-
-static gint
-view_changed_timeout(gpointer d)
-{
- EComponentView *component_view = d;
- EInfoLabel *el = g_object_get_data((GObject *)component_view, "info-label");
- EMFolderView *emfv = g_object_get_data((GObject *)el, "folderview");
-
- view_changed(emfv, component_view);
-
- g_object_set_data((GObject *)component_view, "view-changed-timeout", NULL);
-
- g_object_unref(el);
- g_object_unref(emfv);
-
- return 0;
-}
-
-static void
-view_changed_cb(EMFolderView *emfv, EComponentView *component_view)
-{
- MailComponent *mc = mail_component_peek ();
- gpointer v;
- EInfoLabel *el = g_object_get_data((GObject *)component_view, "info-label");
-
- v = g_object_get_data((GObject *)component_view, "view-changed-timeout");
-
- if (mc->priv->quit_state != -1) {
- if (v) {
- g_source_remove(GPOINTER_TO_INT(v));
- g_object_set_data((GObject *)component_view, "view-changed-timeout", NULL);
- g_object_unref (emfv);
- g_object_unref (el);
- }
-
- return;
-
- }
- /* This can get called 3 times every cursor move, so
- we don't need to/want to run it immediately */
-
- /* NB: we should have a 'view' struct/object to manage this crap, but this'll do for now */
- if (v) {
- g_source_remove(GPOINTER_TO_INT(v));
- } else {
- g_object_ref(emfv);
- g_object_ref(el);
- }
-
- g_object_set_data((GObject *)component_view, "view-changed-timeout", GINT_TO_POINTER(g_timeout_add(250, view_changed_timeout, component_view)));
-}
-
-static void
disable_folder_tree (gpointer *emfb, GtkWidget *widget)
{
gtk_widget_set_sensitive (widget, FALSE);
@@ -756,60 +256,59 @@ impl_createView (PortableServer_Servant servant,
em_folder_browser_suppress_message_selection (
(EMFolderBrowser *) view_widget);
- tree_widget = (GtkWidget *) em_folder_tree_new_with_model (priv->model);
- em_folder_tree_set_excluded ((EMFolderTree *) tree_widget, 0);
- em_folder_tree_enable_drag_and_drop ((EMFolderTree *) tree_widget);
-
- if ((uri = em_folder_tree_model_get_selected (priv->model))) {
- gboolean expanded;
-
- expanded = em_folder_tree_model_get_expanded_uri (priv->model, uri);
- em_folder_tree_set_selected ((EMFolderTree *) tree_widget, uri, FALSE);
- em_folder_view_set_folder_uri ((EMFolderView *) view_widget, uri);
-
- if (!expanded)
- em_folder_tree_model_set_expanded_uri (priv->model, uri, expanded);
-
- g_free (uri);
- }
+// tree_widget = (GtkWidget *) em_folder_tree_new_with_model (priv->model);
+// em_folder_tree_set_excluded ((EMFolderTree *) tree_widget, 0);
+// em_folder_tree_enable_drag_and_drop ((EMFolderTree *) tree_widget);
+
+// if ((uri = em_folder_tree_model_get_selected (priv->model))) {
+// gboolean expanded;
+//
+// expanded = em_folder_tree_model_get_expanded_uri (priv->model, uri);
+// em_folder_tree_set_selected ((EMFolderTree *) tree_widget, uri, FALSE);
+// em_folder_view_set_folder_uri ((EMFolderView *) view_widget, uri);
+//
+// if (!expanded)
+// em_folder_tree_model_set_expanded_uri (priv->model, uri, expanded);
+//
+// g_free (uri);
+// }
em_format_set_session ((EMFormat *) ((EMFolderView *) view_widget)->preview, session);
g_signal_connect (view_widget, "on-url", G_CALLBACK (view_on_url), mail_component);
em_folder_view_set_statusbar ((EMFolderView*)view_widget, FALSE);
- statusbar_widget = e_task_bar_new ();
- e_activity_handler_attach_task_bar (priv->activity_handler, E_TASK_BAR (statusbar_widget));
+// statusbar_widget = e_task_bar_new ();
+// e_activity_handler_attach_task_bar (priv->activity_handler, E_TASK_BAR (statusbar_widget));
gtk_widget_show (tree_widget);
gtk_widget_show (view_widget);
gtk_widget_show (statusbar_widget);
- vbox = gtk_vbox_new(FALSE, 0);
- info = e_info_label_new("evolution-mail");
- e_info_label_set_info((EInfoLabel *)info, _("Mail"), "");
- gtk_box_pack_start((GtkBox *)vbox, info, FALSE, TRUE, 0);
- gtk_box_pack_start((GtkBox *)vbox, tree_widget, TRUE, TRUE, 0);
+// vbox = gtk_vbox_new(FALSE, 0);
+// info = e_info_label_new("evolution-mail");
+// e_info_label_set_info((EInfoLabel *)info, _("Mail"), "");
+// gtk_box_pack_start((GtkBox *)vbox, info, FALSE, TRUE, 0);
+// gtk_box_pack_start((GtkBox *)vbox, tree_widget, TRUE, TRUE, 0);
gtk_widget_show(info);
gtk_widget_show(vbox);
- component_view = e_component_view_new(parent, "mail", vbox, view_widget, statusbar_widget);
-
- g_object_set_data((GObject *)component_view, "info-label", info);
-
- g_object_set_data_full((GObject *)view_widget, "e-creatable-items-handler",
- e_user_creatable_items_handler_new("mail", create_local_item_cb, tree_widget),
- (GDestroyNotify)g_object_unref);
+// component_view = e_component_view_new(parent, "mail", vbox, view_widget, statusbar_widget);
+//
+// g_object_set_data((GObject *)component_view, "info-label", info);
+//
+// g_object_set_data_full((GObject *)view_widget, "e-creatable-items-handler",
+// e_user_creatable_items_handler_new("mail", create_local_item_cb, tree_widget),
+// (GDestroyNotify)g_object_unref);
g_signal_connect (component_view->view_control, "activate", G_CALLBACK (view_control_activate_cb), view_widget);
- g_signal_connect (tree_widget, "folder-selected", G_CALLBACK (folder_selected_cb), view_widget);
- g_signal_connect (tree_widget, "hidden-key-event", G_CALLBACK (tree_hidden_key_event_cb), view_widget);
+// g_signal_connect (tree_widget, "folder-selected", G_CALLBACK (folder_selected_cb), view_widget);
g_signal_connect((EMFolderBrowser *)view_widget, "account_search_cleared", G_CALLBACK (enable_folder_tree), tree_widget);
g_signal_connect(((EMFolderBrowser *)view_widget), "account_search_activated", G_CALLBACK (disable_folder_tree), tree_widget);
- g_signal_connect(view_widget, "changed", G_CALLBACK(view_changed_cb), component_view);
- g_signal_connect(view_widget, "loaded", G_CALLBACK(view_changed_cb), component_view);
+// g_signal_connect(view_widget, "changed", G_CALLBACK(view_changed_cb), component_view);
+// g_signal_connect(view_widget, "loaded", G_CALLBACK(view_changed_cb), component_view);
g_object_set_data((GObject*)info, "folderview", view_widget);
g_object_set_data((GObject*)view_widget, "foldertree", tree_widget);
@@ -877,11 +376,14 @@ static CORBA_boolean
impl_quit(PortableServer_Servant servant, CORBA_Environment *ev)
{
MailComponent *mc = MAIL_COMPONENT(bonobo_object_from_servant(servant));
+ EAccountList *account_list;
if (mc->priv->quit_state == -1)
mc->priv->quit_state = MC_QUIT_START;
- mail_config_prune_proxies ();
+ account_list = e_get_account_list ();
+ e_account_list_prune_proxies (account_list);
+
switch (mc->priv->quit_state) {
case MC_QUIT_START: {
gint now = time(NULL)/60/60/24, days;
@@ -934,323 +436,6 @@ impl_quit(PortableServer_Servant servant, CORBA_Environment *ev)
return TRUE;
}
-static GNOME_Evolution_CreatableItemTypeList *
-impl__get_userCreatableItems (PortableServer_Servant servant, CORBA_Environment *ev)
-{
- GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc ();
-
- list->_length = 2;
- list->_maximum = list->_length;
- list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length);
-
- CORBA_sequence_set_release (list, FALSE);
-
- list->_buffer[0].id = (gchar *) "message";
- list->_buffer[0].description = _("New Mail Message");
- list->_buffer[0].menuDescription = (gchar *) C_("New", "_Mail Message");
- list->_buffer[0].tooltip = _("Compose a new mail message");
- list->_buffer[0].menuShortcut = 'm';
- list->_buffer[0].iconName = (gchar *) "mail-message-new";
- list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT;
-
- list->_buffer[1].id = (gchar *) "folder";
- list->_buffer[1].description = _("New Mail Folder");
- list->_buffer[1].menuDescription = (gchar *) C_("New", "Mail _Folder");
- list->_buffer[1].tooltip = _("Create a new mail folder");
- list->_buffer[1].menuShortcut = '\0';
- list->_buffer[1].iconName = (gchar *) "folder-new";
- list->_buffer[1].type = GNOME_Evolution_CREATABLE_FOLDER;
-
- return list;
-}
-
-static gint
-create_item(const gchar *type, EMFolderTreeModel *model, const gchar *uri, gpointer tree)
-{
- if (strcmp(type, "message") == 0) {
- if (!em_utils_check_user_can_send_mail(NULL))
- return 0;
-
- em_utils_compose_new_message(uri);
- } else if (strcmp(type, "folder") == 0) {
- em_folder_utils_create_folder (NULL, tree, NULL);
- } else
- return -1;
-
- return 0;
-}
-
-static void
-create_local_item_cb(EUserCreatableItemsHandler *handler, const gchar *item_type_name, gpointer data)
-{
- EMFolderTree *tree = data;
- gchar *uri = em_folder_tree_get_selected_uri(tree);
-
- create_item(item_type_name, em_folder_tree_get_model(tree), uri, (gpointer) tree);
- g_free(uri);
-}
-
-static void
-impl_requestCreateItem (PortableServer_Servant servant,
- const CORBA_char *item_type_name,
- CORBA_Environment *ev)
-{
- MailComponent *mc = MAIL_COMPONENT(bonobo_object_from_servant(servant));
-
- if (create_item(item_type_name, mc->priv->model, NULL, NULL) == -1) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Component_UnknownType, NULL);
- }
-}
-
-static void
-handleuri_got_folder(gchar *uri, CamelFolder *folder, gpointer data)
-{
- CamelURL *url = data;
- EMMessageBrowser *emmb;
-
- if (folder != NULL) {
- const gchar *reply = camel_url_get_param(url, "reply");
- const gchar *forward = camel_url_get_param(url, "forward");
- gint mode;
-
- if (reply) {
-
- if (!strcmp(reply, "all"))
- mode = REPLY_MODE_ALL;
- else if (!strcmp(reply, "list"))
- mode = REPLY_MODE_LIST;
- else /* if "sender" or anything else */
- mode = REPLY_MODE_SENDER;
-
- em_utils_reply_to_message(folder, camel_url_get_param(url, "uid"), NULL, mode, NULL);
- } else if (forward) {
- GPtrArray *uids;
- const gchar * uid;
-
- uid = camel_url_get_param(url, "uid");
- if (uid == NULL)
- g_warning("Could not forward the message. UID is NULL.");
- else {
- uids = g_ptr_array_new();
- g_ptr_array_add(uids, g_strdup(uid));
-
- if (!strcmp(forward, "attached"))
- em_utils_forward_attached(folder, uids, uri);
- else if (!strcmp(forward, "inline"))
- em_utils_forward_inline(folder, uids, uri);
- else if (!strcmp(forward, "quoted"))
- em_utils_forward_quoted(folder, uids, uri);
- else { /* Just the default forward */
- em_utils_forward_messages(folder, uids, uri);
- }
- }
- } else {
- emmb = (EMMessageBrowser *)em_message_browser_window_new();
- /*message_list_set_threaded(((EMFolderView *)emmb)->list, emfv->list->threaded);*/
- /* FIXME: session needs to be passed easier than this */
- em_format_set_session((EMFormat *)((EMFolderView *)emmb)->preview, session);
- em_folder_view_set_folder((EMFolderView *)emmb, folder, uri);
- em_folder_view_set_message((EMFolderView *)emmb, camel_url_get_param(url, "uid"), FALSE);
- gtk_widget_show(emmb->window);
- }
- } else {
- g_warning("Couldn't open folder '%s'", uri);
- }
- camel_url_free(url);
-}
-
-static void
-impl_handleURI (PortableServer_Servant servant, const gchar *uri, CORBA_Environment *ev)
-{
- if (!strncmp (uri, "mailto:", 7)) {
- if (!em_utils_check_user_can_send_mail(NULL))
- return;
-
- em_utils_compose_new_message_with_mailto (uri, NULL);
- } else if (!strncmp(uri, "email:", 6)) {
- CamelURL *url = camel_url_new(uri, NULL);
-
- if (camel_url_get_param(url, "uid") != NULL) {
- gchar *curi = em_uri_to_camel(uri);
-
- mail_get_folder(curi, 0, handleuri_got_folder, url, mail_msg_unordered_push);
- g_free(curi);
- } else {
- g_warning("email uri's must include a uid parameter");
- camel_url_free(url);
- }
- }
-}
-
-static void
-impl_sendAndReceive (PortableServer_Servant servant, CORBA_Environment *ev)
-{
- em_utils_clear_get_password_canceled_accounts_flag ();
- mail_send_receive ();
-}
-
-static void
-impl_upgradeFromVersion (PortableServer_Servant servant, const short major, const short minor, const short revision, CORBA_Environment *ev)
-{
- MailComponent *component;
- CamelException ex;
-
- component = mail_component_peek ();
-
- camel_exception_init (&ex);
- if (em_migrate (e_get_user_data_dir (), major, minor, revision, &ex) == -1) {
- GNOME_Evolution_Component_UpgradeFailed *failedex;
-
- failedex = GNOME_Evolution_Component_UpgradeFailed__alloc();
- failedex->what = CORBA_string_dup(_("Failed upgrading Mail settings or folders."));
- failedex->why = CORBA_string_dup(ex.desc);
- CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex);
- }
-
- camel_exception_clear (&ex);
-}
-
-static void
-mc_sync_store_done (CamelStore *store, gpointer data)
-{
- MailComponent *mc = (MailComponent *) data;
-
- mc->priv->mail_sync_in_progress--;
-}
-
-static void
-mc_sync_store (gpointer key, gpointer value, gpointer user_data)
-{
- MailComponent *mc = (MailComponent *) user_data;
-
- mc->priv->mail_sync_in_progress++;
-
- if (!camel_application_is_exiting)
- mail_sync_store (CAMEL_STORE (key), FALSE, mc_sync_store_done, mc);
- else
- mc_sync_store_done (CAMEL_STORE (key), mc);
-}
-
-static gboolean
-call_mail_sync (gpointer user_data)
-{
- MailComponent *mc = (MailComponent *)user_data;
-
- if (camel_application_is_exiting)
- return FALSE;
-
- if (!mc->priv->mail_sync_in_progress && session && camel_session_is_online (session))
- mail_component_stores_foreach (mc, mc_sync_store, mc);
-
- return !camel_application_is_exiting;
-}
-
-struct _setline_data {
- GNOME_Evolution_Listener listener;
- CORBA_boolean status;
- gint pending;
-};
-
-static void
-setline_done(CamelStore *store, gpointer data)
-{
- struct _setline_data *sd = data;
-
- g_return_if_fail (sd->pending > 0);
-
- sd->pending--;
- if (sd->pending == 0) {
- CORBA_Environment ev = { NULL };
-
- GNOME_Evolution_Listener_complete(sd->listener, &ev);
- CORBA_exception_free(&ev);
- CORBA_Object_release(sd->listener, &ev);
- CORBA_exception_free(&ev);
- if (!sd->status)
- camel_session_set_online(session, sd->status);
- g_free(sd);
- }
-}
-
-static void
-setline_check(gpointer key, gpointer value, gpointer data)
-{
- CamelService *service = key;
- struct _setline_data *sd = data;
-
- if (CAMEL_IS_DISCO_STORE(service)
- || CAMEL_IS_OFFLINE_STORE(service)) {
- sd->pending++;
- mail_store_set_offline((CamelStore *)service, !sd->status, setline_done, sd);
- }
-}
-
-gint
-status_check (GNOME_Evolution_ShellState shell_state)
-{
- gint status = 0;
-
- switch (shell_state)
- {
- case GNOME_Evolution_USER_OFFLINE:
- status = OFFLINE;
- if (em_utils_prompt_user (NULL, "/apps/evolution/mail/prompts/quick_offline", "mail:ask-quick-offline", NULL))
- break;
- case GNOME_Evolution_FORCED_OFFLINE:
- /*Network is down so change network state on the camel session*/
- status = OFFLINE;
- /* Cancel all operations as they wont happen anyway cos Network is down*/
- mail_cancel_all ();
- camel_session_set_network_state (session, FALSE);
- break;
- case GNOME_Evolution_USER_ONLINE:
- camel_session_set_network_state (session, TRUE);
- status = ONLINE;
- }
-
- return status;
-}
-
-static void
-impl_setLineStatus(PortableServer_Servant servant, GNOME_Evolution_ShellState shell_state, GNOME_Evolution_Listener listener, CORBA_Environment *ev)
-{
- struct _setline_data *sd;
- gint status = status_check(shell_state);
-
- /* This will dis/enable further auto-mail-check action. */
- /* FIXME: If send/receive active, wait for it to finish? */
- if (status)
- camel_session_set_online(session, status);
-
- sd = g_malloc0(sizeof(*sd));
- sd->status = status;
- sd->listener = CORBA_Object_duplicate(listener, ev);
- if (ev->_major == CORBA_NO_EXCEPTION)
- mail_component_stores_foreach(mail_component_peek(), setline_check, sd);
- else
- CORBA_exception_free(ev);
-
- if (sd->pending == 0) {
- if (sd->listener) {
- CORBA_Object_release(sd->listener, ev);
- CORBA_exception_free(ev);
- }
-
- g_free(sd);
-
- if (!status)
- camel_session_set_online(session, status);
- GNOME_Evolution_Listener_complete(listener, ev);
- }
-}
-
-static void
-impl_mail_test(PortableServer_Servant servant, CORBA_Environment *ev)
-{
- printf("*** Testing mail interface!! ***\n");
-}
-
/* Initialization. */
static void
@@ -1271,25 +456,22 @@ mail_component_class_init (MailComponentClass *class)
epv->createView = impl_createView;
epv->requestQuit = impl_requestQuit;
epv->quit = impl_quit;
- epv->_get_userCreatableItems = impl__get_userCreatableItems;
- epv->requestCreateItem = impl_requestCreateItem;
- epv->handleURI = impl_handleURI;
- epv->sendAndReceive = impl_sendAndReceive;
- epv->upgradeFromVersion = impl_upgradeFromVersion;
- epv->setLineStatus = impl_setLineStatus;
-
- mepv->test = impl_mail_test;
+// epv->_get_userCreatableItems = impl__get_userCreatableItems;
+// epv->requestCreateItem = impl_requestCreateItem;
+// epv->handleURI = impl_handleURI;
+// epv->sendAndReceive = impl_sendAndReceive;
+// epv->upgradeFromVersion = impl_upgradeFromVersion;
+// epv->setLineStatus = impl_setLineStatus;
- /* Register attachment handler types. */
- e_attachment_handler_mail_get_type ();
+// mepv->test = impl_mail_test;
}
-static void
-store_hash_free (struct _store_info *si)
-{
- si->removed = 1;
- store_info_unref(si);
-}
+//static void
+//store_hash_free (struct _store_info *si)
+//{
+// si->removed = 1;
+// store_info_unref(si);
+//}
static void
mail_component_init (MailComponent *component)
@@ -1302,318 +484,42 @@ mail_component_init (MailComponent *component)
priv->lock = g_mutex_new();
priv->quit_state = -1;
- /* FIXME This is used as both a filename and URI path throughout
- * the mail code. Need to clean this up; maybe provide a
- * mail_component_get_base_uri() function. */
- priv->base_directory = g_build_filename (e_get_user_data_dir (), "mail", NULL);
-#ifdef G_OS_WIN32
- {
- gchar *p = priv->base_directory;
- while ((p = strchr(p, '\\')))
- *p++ = '/';
- }
-#endif
-
- if (g_mkdir_with_parents (e_get_user_data_dir (), 0777) == -1 && errno != EEXIST)
- abort ();
-
- priv->model = em_folder_tree_model_new (e_get_user_data_dir ());
+// /* FIXME This is used as both a filename and URI path throughout
+// * the mail code. Need to clean this up; maybe provide a
+// * mail_component_get_base_uri() function. */
+// priv->base_directory = g_build_filename (e_get_user_data_dir (), "mail", NULL);
+//#ifdef G_OS_WIN32
+// {
+// gchar *p = priv->base_directory;
+// while ((p = strchr(p, '\\')))
+// *p++ = '/';
+// }
+//#endif
+
+// if (g_mkdir_with_parents (e_get_user_data_dir (), 0777) == -1 && errno != EEXIST)
+// abort ();
+
+// priv->model = em_folder_tree_model_new (e_get_user_data_dir ());
priv->logger = e_logger_create ("mail");
priv->activity_handler = e_activity_handler_new ();
e_activity_handler_set_logger (priv->activity_handler, priv->logger);
e_activity_handler_set_error_flush_time (priv->activity_handler, mail_config_get_error_timeout ()*1000);
- mail_session_init (e_get_user_data_dir ());
-
- priv->async_event = mail_async_event_new();
- priv->store_hash = g_hash_table_new_full (
- NULL, NULL,
- (GDestroyNotify) NULL,
- (GDestroyNotify) store_hash_free);
-
- mail_autoreceive_init (session);
-
- priv->mail_sync_in_progress = 0;
- if (g_getenv("CAMEL_FLUSH_CHANGES"))
- priv->mail_sync_id = g_timeout_add_seconds (mail_config_get_sync_timeout (), call_mail_sync, component);
- else
- priv->mail_sync_id = 0;
-}
-
-/* Public API. */
-MailComponent *
-mail_component_peek (void)
-{
- static MailComponent *component = NULL;
-
- if (component == NULL)
- component = g_object_new(mail_component_get_type(), NULL);
+// mail_session_init (e_get_user_data_dir ());
- return component;
-}
+// priv->async_event = mail_async_event_new();
+// priv->store_hash = g_hash_table_new_full (
+// NULL, NULL,
+// (GDestroyNotify) NULL,
+// (GDestroyNotify) store_hash_free);
-const gchar *
-mail_component_peek_base_directory (MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
+// mail_autoreceive_init (session);
- return component->priv->base_directory;
-}
-
-RuleContext *
-mail_component_peek_search_context (MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- setup_search_context(component);
-
- return component->priv->search_context;
-}
-
-EActivityHandler *
-mail_component_peek_activity_handler (MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- return component->priv->activity_handler;
-}
-
-CamelSession *mail_component_peek_session(MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- return session;
-}
-
-void
-mail_component_add_store (MailComponent *component, CamelStore *store, const gchar *name)
-{
- mc_add_store(component, store, name, NULL);
-}
-
-/**
- * mail_component_load_store_by_uri:
- * @component: mail component
- * @uri: uri of store
- * @name: name of store (used for display purposes)
- *
- * Return value: Pointer to the newly added CamelStore. The caller is supposed
- * to ref the object if it wants to store it.
- **/
-CamelStore *
-mail_component_load_store_by_uri (MailComponent *component, const gchar *uri, const gchar *name)
-{
- CamelException ex;
- CamelStore *store;
- CamelProvider *prov;
-
- MAIL_COMPONENT_DEFAULT(component);
-
- camel_exception_init (&ex);
-
- /* Load the service (don't connect!). Check its provider and
- * see if this belongs in the shell's folder list. If so, add
- * it.
- */
-
- prov = camel_provider_get(uri, &ex);
- if (prov == NULL) {
- /* EPFIXME: real error dialog */
- g_warning ("couldn't get service %s: %s\n", uri,
- camel_exception_get_description (&ex));
- camel_exception_clear (&ex);
- return NULL;
- }
-
- if (!(prov->flags & CAMEL_PROVIDER_IS_STORAGE))
- return NULL;
-
- store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex);
- if (store == NULL) {
- /* EPFIXME: real error dialog */
- g_warning ("couldn't get service %s: %s\n", uri,
- camel_exception_get_description (&ex));
- camel_exception_clear (&ex);
- return NULL;
- }
-
- mail_component_add_store(component, store, name);
- camel_object_unref (store);
-
- return store;
-}
-
-static void
-store_disconnect (CamelStore *store, gpointer event_data, gpointer user_data)
-{
- camel_service_disconnect (CAMEL_SERVICE (store), TRUE, NULL);
- camel_object_unref (store);
-}
-
-void
-mail_component_remove_store (MailComponent *component, CamelStore *store)
-{
- MailComponentPrivate *priv;
-
- MAIL_COMPONENT_DEFAULT(component);
-
- priv = component->priv;
-
- /* Because the store_hash holds a reference to each store
- * used as a key in it, none of them will ever be gc'ed, meaning
- * any call to camel_session_get_{service,store} with the same
- * URL will always return the same object. So this works.
- */
-
- if (g_hash_table_lookup (priv->store_hash, store) == NULL)
- return;
-
- camel_object_ref (store);
- g_hash_table_remove (priv->store_hash, store);
-
- /* so i guess potentially we could have a race, add a store while one
- being removed. ?? */
- mail_note_store_remove (store);
-
- em_folder_tree_model_remove_store (priv->model, store);
-
- mail_async_event_emit (priv->async_event, MAIL_ASYNC_THREAD, (MailAsyncFunc) store_disconnect, store, NULL, NULL);
-}
-
-void
-mail_component_remove_store_by_uri (MailComponent *component, const gchar *uri)
-{
- CamelProvider *prov;
- CamelStore *store;
-
- MAIL_COMPONENT_DEFAULT(component);
-
- if (!(prov = camel_provider_get(uri, NULL)))
- return;
-
- if (!(prov->flags & CAMEL_PROVIDER_IS_STORAGE))
- return;
-
- store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, NULL);
- if (store != NULL) {
- mail_component_remove_store (component, store);
- camel_object_unref (store);
- }
-}
-
-gint
-mail_component_get_store_count (MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- return g_hash_table_size (component->priv->store_hash);
-}
-
-/* need to map from internal struct to external api */
-struct _store_foreach_data {
- GHFunc func;
- gpointer data;
-};
-
-static void
-mc_stores_foreach(CamelStore *store, struct _store_info *si, struct _store_foreach_data *data)
-{
- data->func((gpointer)store, (gpointer)si->name, data->data);
-}
-
-void
-mail_component_stores_foreach (MailComponent *component, GHFunc func, gpointer user_data)
-{
- struct _store_foreach_data data = { func, user_data };
-
- MAIL_COMPONENT_DEFAULT(component);
-
- g_hash_table_foreach (component->priv->store_hash, (GHFunc)mc_stores_foreach, &data);
-}
-
-void
-mail_component_remove_folder (MailComponent *component, CamelStore *store, const gchar *path)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- /* FIXME: implement me. but first, am I really even needed? */
-}
-
-EMFolderTreeModel *
-mail_component_peek_tree_model (MailComponent *component)
-{
- MAIL_COMPONENT_DEFAULT(component);
-
- return component->priv->model;
-}
-
-CamelStore *
-mail_component_peek_local_store (MailComponent *mc)
-{
- MAIL_COMPONENT_DEFAULT (mc);
- mc_setup_local_store (mc);
-
- return mc->priv->local_store;
-}
-
-/**
- * mail_component_get_folder:
- * @mc:
- * @id:
- *
- * Get a standard/default folder by id. This call is thread-safe.
- *
- * Return value:
- **/
-CamelFolder *
-mail_component_get_folder(MailComponent *mc, enum _mail_component_folder_t id)
-{
- g_return_val_if_fail (id <= MAIL_COMPONENT_FOLDER_LOCAL_INBOX, NULL);
-
- MAIL_COMPONENT_DEFAULT(mc);
- mc_setup_local_store(mc);
-
- return mc_default_folders[id].folder;
-}
-
-/**
- * mail_component_get_folder_uri:
- * @mc:
- * @id:
- *
- * Get a standard/default folder's uri. This call is thread-safe.
- *
- * Return value:
- **/
-const gchar *
-mail_component_get_folder_uri(MailComponent *mc, enum _mail_component_folder_t id)
-{
- g_return_val_if_fail (id <= MAIL_COMPONENT_FOLDER_LOCAL_INBOX, NULL);
-
- MAIL_COMPONENT_DEFAULT(mc);
- mc_setup_local_store(mc);
-
- return mc_default_folders[id].uri;
-}
-
-/**
- * mail_indicate_new_mail
- * Indicates new mail in a shell window.
- * @param have_new_mail TRUE when have new mail, false otherwise.
- **/
-void
-mail_indicate_new_mail (gboolean have_new_mail)
-{
- const gchar *icon = NULL;
- MailComponent *mc = mail_component_peek ();
-
- g_return_if_fail (mc != NULL);
-
- if (have_new_mail)
- icon = "mail-unread";
-
- if (mc->priv->component_view)
- e_component_view_set_button_icon (mc->priv->component_view, icon);
+// priv->mail_sync_in_progress = 0;
+// if (g_getenv("CAMEL_FLUSH_CHANGES"))
+// priv->mail_sync_id = g_timeout_add_seconds (mail_config_get_sync_timeout (), call_mail_sync, component);
+// else
+// priv->mail_sync_id = 0;
}
void
@@ -1624,5 +530,3 @@ mail_component_show_logger (gpointer top)
eni_show_logger(logger, top, MAILER_ERROR_TIME_OUT_KEY, MAILER_ERROR_LEVEL_KEY);
}
-
-BONOBO_TYPE_FUNC_FULL (MailComponent, GNOME_Evolution_MailComponent, PARENT_TYPE, mail_component)
diff --git a/mail/mail-component.h b/mail/mail-component.h
index 18ec0a7dd9..f5e2ad0f6d 100644
--- a/mail/mail-component.h
+++ b/mail/mail-component.h
@@ -72,8 +72,6 @@ const gchar *mail_component_peek_base_directory (MailComponent *compone
RuleContext *mail_component_peek_search_context (MailComponent *component);
EActivityHandler *mail_component_peek_activity_handler (MailComponent *component);
-CamelSession *mail_component_peek_session(MailComponent *);
-
void mail_component_add_store (MailComponent *component,
CamelStore *store,
const gchar *name);
diff --git a/mail/mail-config-factory.c b/mail/mail-config-factory.c
deleted file mode 100644
index 75442b27fb..0000000000
--- a/mail/mail-config-factory.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-
-#include "em-account-prefs.h"
-#include "em-composer-prefs.h"
-#include "em-mailer-prefs.h"
-#include "em-network-prefs.h"
-
-#include "mail-config-factory.h"
-
-#define CONFIG_CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Mail_ConfigControlFactory:" BASE_VERSION
-
-BonoboObject *
-mail_config_control_factory_cb (BonoboGenericFactory *factory, const gchar *component_id, gpointer user_data)
-{
- GNOME_Evolution_Shell shell = (GNOME_Evolution_Shell) user_data;
- EvolutionConfigControl *control;
- GtkWidget *prefs = NULL;
-
- if (!strcmp (component_id, EM_ACCOUNT_PREFS_CONTROL_ID)) {
- prefs = em_account_prefs_new (shell);
- } else if (!strcmp (component_id, EM_MAILER_PREFS_CONTROL_ID)) {
- prefs = em_mailer_prefs_new ();
- } else if (!strcmp (component_id, EM_COMPOSER_PREFS_CONTROL_ID)) {
- prefs = em_composer_prefs_new ();
- } else if (!strcmp (component_id, EM_NETWORK_PREFS_CONTROL_ID)) {
- prefs = em_network_prefs_new ();
- } else {
- g_return_val_if_reached(NULL);
- }
-
- gtk_widget_show_all (prefs);
-
- control = evolution_config_control_new (prefs);
-
- return BONOBO_OBJECT (control);
-}
diff --git a/mail/mail-config.c b/mail/mail-config.c
index 316957bf38..1ac6892b74 100644
--- a/mail/mail-config.c
+++ b/mail/mail-config.c
@@ -37,10 +37,7 @@
#include <gtk/gtk.h>
#include <glib/gstdio.h>
-
-#ifndef G_OS_WIN32
-#include <sys/wait.h>
-#endif
+#include <glib/gi18n-lib.h>
#include <gtkhtml/gtkhtml.h>
#include <glade/glade.h>
@@ -48,19 +45,11 @@
#include <libxml/tree.h>
#include <libxml/parser.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-context.h>
-#include <bonobo/bonobo-moniker-util.h>
-#include <bonobo/bonobo-exception.h>
-
#include <libedataserver/e-data-server-util.h>
#include <e-util/e-util.h>
#include <misc/e-gui-utils.h>
-#include "e-util/e-util-labels.h"
-
-#include <libedataserver/e-account-list.h>
-#include <e-util/e-signature-list.h>
+#include "e-util/e-account-utils.h"
+#include "e-util/e-signature-utils.h"
#include <camel/camel-service.h>
#include <camel/camel-stream-mem.h>
@@ -70,22 +59,18 @@
#include <libedataserverui/e-passwords.h>
-#include "mail-component.h"
#include "mail-session.h"
#include "mail-config.h"
#include "mail-mt.h"
#include "mail-tools.h"
+#include "em-utils.h"
+#include "e-mail-local.h"
typedef struct {
GConfClient *gconf;
- gboolean corrupt;
-
gchar *gtkrc;
- EAccountList *accounts;
- ESignatureList *signatures;
-
GSList *labels;
gboolean address_compress;
@@ -110,18 +95,6 @@ extern gint camel_header_param_encode_filenames_in_rfc_2047;
static MailConfig *config = NULL;
static guint config_write_timeout = 0;
-void
-mail_config_save_accounts (void)
-{
- e_account_list_save (config->accounts);
-}
-
-void
-mail_config_save_signatures (void)
-{
- e_signature_list_save (config->signatures);
-}
-
static void
config_clear_mime_types (void)
{
@@ -215,33 +188,6 @@ config_write_style (void)
}
static void
-config_clear_labels (void)
-{
- if (!config)
- return;
-
- e_util_labels_free (config->labels);
- config->labels = NULL;
-}
-
-static void
-config_cache_labels (GConfClient *client)
-{
- if (!config)
- return;
-
- config->labels = e_util_labels_parse (client);
-}
-
-static void
-gconf_labels_changed (GConfClient *client, guint cnxn_id,
- GConfEntry *entry, gpointer user_data)
-{
- config_clear_labels ();
- config_cache_labels (client);
-}
-
-static void
gconf_style_changed (GConfClient *client, guint cnxn_id,
GConfEntry *entry, gpointer user_data)
{
@@ -368,9 +314,6 @@ mail_config_init (void)
mail_config_clear ();
- config->accounts = e_account_list_new (config->gconf);
- config->signatures = e_signature_list_new (config->gconf);
-
gtk_rc_parse (config->gtkrc);
/* Composer Configuration */
@@ -473,18 +416,6 @@ mail_config_init (void)
gconf_client_notify_add (
config->gconf, key, func, NULL, NULL, NULL);
- /* Label Configuration */
-
- gconf_client_add_dir (
- config->gconf, E_UTIL_LABELS_GCONF_KEY,
- GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
-
- gconf_client_notify_add (
- config->gconf, E_UTIL_LABELS_GCONF_KEY,
- gconf_labels_changed, NULL, NULL, NULL);
-
- config_cache_labels (config->gconf);
-
/* MIME Type Configuration */
gconf_client_add_dir (
@@ -549,28 +480,23 @@ mail_config_clear (void)
if (!config)
return;
- if (config->accounts) {
- g_object_unref (config->accounts);
- config->accounts = NULL;
- }
-
- if (config->signatures) {
- g_object_unref (config->signatures);
- config->signatures = NULL;
- }
-
- config_clear_labels ();
config_clear_mime_types ();
}
void
mail_config_write (void)
{
+ EAccountList *account_list;
+ ESignatureList *signature_list;
+
if (!config)
return;
- e_account_list_save (config->accounts);
- e_signature_list_save (config->signatures);
+ account_list = e_get_account_list ();
+ signature_list = e_get_signature_list ();
+
+ e_account_list_save (account_list);
+ e_signature_list_save (signature_list);
gconf_client_suggest_sync (config->gconf, NULL);
}
@@ -578,6 +504,7 @@ mail_config_write (void)
void
mail_config_write_on_exit (void)
{
+ EAccountList *account_list;
EAccount *account;
EIterator *iter;
@@ -591,7 +518,8 @@ mail_config_write_on_exit (void)
/* then we make sure the ones we want to remember are in the
session cache */
- iter = e_list_get_iterator ((EList *) config->accounts);
+ account_list = e_get_account_list ();
+ iter = e_list_get_iterator ((EList *) account_list);
while (e_iterator_is_valid (iter)) {
gchar *passwd;
@@ -620,7 +548,7 @@ mail_config_write_on_exit (void)
e_passwords_clear_passwords ("Mail");
/* then we remember them */
- iter = e_list_get_iterator ((EList *) config->accounts);
+ iter = e_list_get_iterator ((EList *) account_list);
while (e_iterator_is_valid (iter)) {
account = (EAccount *) e_iterator_get (iter);
@@ -654,18 +582,6 @@ mail_config_get_gconf_client (void)
return config->gconf;
}
-gboolean
-mail_config_is_configured (void)
-{
- return e_list_length ((EList *) config->accounts) > 0;
-}
-
-gboolean
-mail_config_is_corrupt (void)
-{
- return config->corrupt;
-}
-
gint
mail_config_get_address_count (void)
{
@@ -733,74 +649,16 @@ mail_config_get_enable_magic_spacebar ()
return config->magic_spacebar;
}
-/**
- * mail_config_get_labels
- *
- * @return list of known labels, each member data is EUtilLabel structure.
- * Returned list should not be freed, neither data inside it.
- **/
-GSList *
-mail_config_get_labels (void)
-{
- return config->labels;
-}
-
const gchar **
mail_config_get_allowable_mime_types (void)
{
return (const gchar **) config->mime_types->pdata;
}
-gboolean
-mail_config_find_account (EAccount *account)
-{
- EAccount *acnt;
- EIterator *iter;
-
- iter = e_list_get_iterator ((EList *) config->accounts);
- while (e_iterator_is_valid (iter)) {
- acnt = (EAccount *) e_iterator_get (iter);
- if (acnt == account) {
- g_object_unref (iter);
- return TRUE;
- }
-
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
-
- return FALSE;
-}
-
-EAccount *
-mail_config_get_default_account (void)
-{
- if (config == NULL)
- mail_config_init ();
-
- if (!config->accounts)
- return NULL;
-
- /* should probably return const */
- return (EAccount *)e_account_list_get_default(config->accounts);
-}
-
-EAccount *
-mail_config_get_account_by_name (const gchar *account_name)
-{
- return (EAccount *)e_account_list_find(config->accounts, E_ACCOUNT_FIND_NAME, account_name);
-}
-
-EAccount *
-mail_config_get_account_by_uid (const gchar *uid)
-{
- return (EAccount *) e_account_list_find (config->accounts, E_ACCOUNT_FIND_UID, uid);
-}
-
static EAccount *
mc_get_account_by (const gchar *given_url, const gchar * (get_url_string)(EAccount *account))
{
+ EAccountList *account_list;
EAccount *account = NULL;
EIterator *iter;
CamelURL *url;
@@ -815,7 +673,8 @@ mc_get_account_by (const gchar *given_url, const gchar * (get_url_string)(EAccou
provider = camel_provider_get (given_url, NULL);
g_return_val_if_fail (provider != NULL && provider->url_equal != NULL, NULL);
- iter = e_list_get_iterator ((EList *) config->accounts);
+ account_list = e_get_account_list ();
+ iter = e_list_get_iterator ((EList *) account_list);
while (account == NULL && e_iterator_is_valid (iter)) {
CamelURL *account_url;
const gchar *account_url_string;
@@ -877,77 +736,21 @@ mail_config_get_account_by_transport_url (const gchar *transport_url)
return mc_get_account_by (transport_url, get_transport_url_string);
}
-gint
-mail_config_has_proxies (EAccount *account)
-{
- return e_account_list_account_has_proxies (config->accounts, account);
-}
-
-void
-mail_config_remove_account_proxies (EAccount *account)
-{
- e_account_list_remove_account_proxies (config->accounts, account);
-}
-
-void
-mail_config_prune_proxies (void)
-{
- e_account_list_prune_proxies (config->accounts);
-}
-
-EAccountList *
-mail_config_get_accounts (void)
-{
- if (config == NULL)
- mail_config_init ();
-
- return config->accounts;
-}
-
-void
-mail_config_add_account (EAccount *account)
-{
- e_account_list_add(config->accounts, account);
- mail_config_save_accounts ();
-}
-
-void
-mail_config_remove_account (EAccount *account)
-{
- e_account_list_remove(config->accounts, account);
- mail_config_save_accounts ();
-}
-
-void
-mail_config_set_default_account (EAccount *account)
-{
- e_account_list_set_default(config->accounts, account);
-}
-
-EAccountIdentity *
-mail_config_get_default_identity (void)
-{
- EAccount *account;
-
- account = mail_config_get_default_account ();
- if (account)
- return account->id;
- else
- return NULL;
-}
-
EAccountService *
mail_config_get_default_transport (void)
{
+ EAccountList *account_list;
EAccount *account;
EIterator *iter;
- account = mail_config_get_default_account ();
+ account_list = e_get_account_list ();
+ account = e_get_default_account ();
+
if (account && account->enabled && account->transport && account->transport->url && account->transport->url[0])
return account->transport;
/* return the first account with a transport? */
- iter = e_list_get_iterator ((EList *) config->accounts);
+ iter = e_list_get_iterator ((EList *) account_list);
while (e_iterator_is_valid (iter)) {
account = (EAccount *) e_iterator_get (iter);
@@ -968,17 +771,19 @@ mail_config_get_default_transport (void)
static gchar *
uri_to_evname (const gchar *uri, const gchar *prefix)
{
- const gchar *base_directory = mail_component_peek_base_directory (mail_component_peek ());
+ const gchar *data_dir;
gchar *safe;
gchar *tmp;
+ data_dir = em_utils_get_data_dir ();
+
safe = g_strdup (uri);
e_filename_make_safe (safe);
/* blah, easiest thing to do */
if (prefix[0] == '*')
- tmp = g_strdup_printf ("%s/%s%s.xml", base_directory, prefix + 1, safe);
+ tmp = g_strdup_printf ("%s/%s%s.xml", data_dir, prefix + 1, safe);
else
- tmp = g_strdup_printf ("%s/%s%s", base_directory, prefix, safe);
+ tmp = g_strdup_printf ("%s/%s%s", data_dir, prefix, safe);
g_free (safe);
return tmp;
}
@@ -986,6 +791,7 @@ uri_to_evname (const gchar *uri, const gchar *prefix)
void
mail_config_uri_renamed (GCompareFunc uri_cmp, const gchar *old, const gchar *new)
{
+ EAccountList *account_list;
EAccount *account;
EIterator *iter;
gint i, work = 0;
@@ -998,7 +804,8 @@ mail_config_uri_renamed (GCompareFunc uri_cmp, const gchar *old, const gchar *ne
"*views/custom_view-",
NULL };
- iter = e_list_get_iterator ((EList *) config->accounts);
+ account_list = e_get_account_list ();
+ iter = e_list_get_iterator ((EList *) account_list);
while (e_iterator_is_valid (iter)) {
account = (EAccount *) e_iterator_get (iter);
@@ -1039,26 +846,33 @@ mail_config_uri_renamed (GCompareFunc uri_cmp, const gchar *old, const gchar *ne
void
mail_config_uri_deleted (GCompareFunc uri_cmp, const gchar *uri)
{
+ EAccountList *account_list;
EAccount *account;
EIterator *iter;
gint work = 0;
+ const gchar *local_drafts_folder_uri;
+ const gchar *local_sent_folder_uri;
+
/* assumes these can't be removed ... */
- const gchar *default_sent_folder_uri = mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_SENT);
- const gchar *default_drafts_folder_uri = mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS);
+ local_drafts_folder_uri =
+ e_mail_local_get_folder_uri (E_MAIL_FOLDER_DRAFTS);
+ local_sent_folder_uri =
+ e_mail_local_get_folder_uri (E_MAIL_FOLDER_SENT);
- iter = e_list_get_iterator ((EList *) config->accounts);
+ account_list = e_get_account_list ();
+ iter = e_list_get_iterator ((EList *) account_list);
while (e_iterator_is_valid (iter)) {
account = (EAccount *) e_iterator_get (iter);
if (account->sent_folder_uri && uri_cmp (account->sent_folder_uri, uri)) {
g_free (account->sent_folder_uri);
- account->sent_folder_uri = g_strdup (default_sent_folder_uri);
+ account->sent_folder_uri = g_strdup (local_sent_folder_uri);
work = 1;
}
if (account->drafts_folder_uri && uri_cmp (account->drafts_folder_uri, uri)) {
g_free (account->drafts_folder_uri);
- account->drafts_folder_uri = g_strdup (default_drafts_folder_uri);
+ account->drafts_folder_uri = g_strdup (local_drafts_folder_uri);
work = 1;
}
@@ -1091,113 +905,18 @@ gchar *
mail_config_folder_to_cachename (CamelFolder *folder, const gchar *prefix)
{
gchar *url, *basename, *filename;
- const gchar *evolution_dir;
-
- evolution_dir = mail_component_peek_base_directory (mail_component_peek ());
+ const gchar *config_dir;
+ config_dir = em_utils_get_config_dir ();
url = mail_config_folder_to_safe_url (folder);
basename = g_strdup_printf ("%s%s", prefix, url);
- filename = g_build_filename (evolution_dir, "config", basename, NULL);
+ filename = g_build_filename (config_dir, basename, NULL);
g_free (basename);
g_free (url);
return filename;
}
-ESignatureList *
-mail_config_get_signatures (void)
-{
- return config->signatures;
-}
-
-static gchar *
-get_new_signature_filename (void)
-{
- const gchar *base_directory;
- gchar *filename, *id;
- struct stat st;
- gint i;
-
- base_directory = e_get_user_data_dir ();
- filename = g_build_filename (base_directory, "signatures", NULL);
- if (g_lstat (filename, &st)) {
- if (errno == ENOENT) {
- if (g_mkdir (filename, 0700))
- g_warning ("Fatal problem creating %s directory.", filename);
- } else
- g_warning ("Fatal problem with %s directory.", filename);
- }
- g_free (filename);
-
- filename = g_malloc (strlen (base_directory) + sizeof ("/signatures/signature-") + 12);
- id = g_stpcpy (filename, base_directory);
- id = g_stpcpy (id, "/signatures/signature-");
-
- for (i = 0; i < (INT_MAX - 1); i++) {
- sprintf (id, "%d", i);
- if (g_lstat (filename, &st) == -1 && errno == ENOENT) {
- gint fd;
-
- fd = g_creat (filename, 0600);
- if (fd >= 0) {
- close (fd);
- return filename;
- }
- }
- }
-
- g_free (filename);
-
- return NULL;
-}
-
-ESignature *
-mail_config_signature_new (const gchar *filename, gboolean script, gboolean html)
-{
- ESignature *sig;
-
- sig = e_signature_new ();
- sig->name = g_strdup (_("Unnamed"));
- sig->script = script;
- sig->html = html;
-
- if (filename == NULL)
- sig->filename = get_new_signature_filename ();
- else
- sig->filename = g_strdup (filename);
-
- return sig;
-}
-
-ESignature *
-mail_config_get_signature_by_uid (const gchar *uid)
-{
- return (ESignature *) e_signature_list_find (config->signatures, E_SIGNATURE_FIND_UID, uid);
-}
-
-ESignature *
-mail_config_get_signature_by_name (const gchar *name)
-{
- return (ESignature *) e_signature_list_find (config->signatures, E_SIGNATURE_FIND_NAME, name);
-}
-
-void
-mail_config_add_signature (ESignature *signature)
-{
- e_signature_list_add (config->signatures, signature);
- mail_config_save_signatures ();
-}
-
-void
-mail_config_remove_signature (ESignature *signature)
-{
- if (signature->filename && !signature->script)
- g_unlink (signature->filename);
-
- e_signature_list_remove (config->signatures, signature);
- mail_config_save_signatures ();
-}
-
void
mail_config_reload_junk_headers (void)
{
@@ -1228,131 +947,3 @@ mail_config_get_lookup_book_local_only (void)
return config->book_lookup_local_only;
}
-
-gboolean
-mail_config_scripts_disabled (void)
-{
- if (config == NULL)
- mail_config_init ();
-
- return config->scripts_disabled;
-}
-
-gchar *
-mail_config_signature_run_script (const gchar *script)
-{
-#ifndef G_OS_WIN32
- gint result, status;
- gint in_fds[2];
- pid_t pid;
-
- if (mail_config_scripts_disabled ())
- return NULL;
-
- if (pipe (in_fds) == -1) {
- g_warning ("Failed to create pipe to '%s': %s", script, g_strerror (errno));
- return NULL;
- }
-
- if (!(pid = fork ())) {
- /* child process */
- gint maxfd, i;
-
- close (in_fds [0]);
- if (dup2 (in_fds[1], STDOUT_FILENO) < 0)
- _exit (255);
- close (in_fds [1]);
-
- setsid ();
-
- maxfd = sysconf (_SC_OPEN_MAX);
- for (i = 3; i < maxfd; i++) {
- if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO)
- fcntl (i, F_SETFD, FD_CLOEXEC);
- }
-
- execlp("/bin/sh", "/bin/sh", "-c", script, NULL);
- g_warning ("Could not execute %s: %s\n", script, g_strerror (errno));
- _exit (255);
- } else if (pid < 0) {
- g_warning ("Failed to create create child process '%s': %s", script, g_strerror (errno));
- close (in_fds [0]);
- close (in_fds [1]);
- return NULL;
- } else {
- CamelStreamFilter *filtered_stream;
- CamelStreamMem *memstream;
- CamelMimeFilter *charenc;
- CamelStream *stream;
- GByteArray *buffer;
- gchar *charset;
- gchar *content;
-
- /* parent process */
- close (in_fds[1]);
-
- stream = camel_stream_fs_new_with_fd (in_fds[0]);
-
- memstream = (CamelStreamMem *) camel_stream_mem_new ();
- buffer = g_byte_array_new ();
- camel_stream_mem_set_byte_array (memstream, buffer);
-
- camel_stream_write_to_stream (stream, (CamelStream *) memstream);
- camel_object_unref (stream);
-
- /* signature scripts are supposed to generate UTF-8 content, but because users
- are known to not ever read the manual... we try to do our best if the
- content isn't valid UTF-8 by assuming that the content is in the user's
- preferred charset. */
- if (!g_utf8_validate ((gchar *)buffer->data, buffer->len, NULL)) {
- stream = (CamelStream *) memstream;
- memstream = (CamelStreamMem *) camel_stream_mem_new ();
- camel_stream_mem_set_byte_array (memstream, g_byte_array_new ());
-
- filtered_stream = camel_stream_filter_new_with_stream (stream);
- camel_object_unref (stream);
-
- charset = gconf_client_get_string (config->gconf, "/apps/evolution/mail/composer/charset", NULL);
- if (charset && *charset) {
- if ((charenc = (CamelMimeFilter *) camel_mime_filter_charset_new_convert (charset, "utf-8"))) {
- camel_stream_filter_add (filtered_stream, charenc);
- camel_object_unref (charenc);
- }
- }
- g_free (charset);
-
- camel_stream_write_to_stream ((CamelStream *) filtered_stream, (CamelStream *) memstream);
- camel_object_unref (filtered_stream);
- g_byte_array_free (buffer, TRUE);
-
- buffer = memstream->buffer;
- }
-
- camel_object_unref (memstream);
-
- g_byte_array_append (buffer, (const guchar *)"", 1);
- content = (gchar *)buffer->data;
- g_byte_array_free (buffer, FALSE);
-
- /* wait for the script process to terminate */
- result = waitpid (pid, &status, 0);
-
- if (result == -1 && errno == EINTR) {
- /* child process is hanging... */
- kill (pid, SIGTERM);
- sleep (1);
- result = waitpid (pid, &status, WNOHANG);
- if (result == 0) {
- /* ...still hanging, set phasers to KILL */
- kill (pid, SIGKILL);
- sleep (1);
- result = waitpid (pid, &status, WNOHANG);
- }
- }
-
- return content;
- }
-#else
- return NULL;
-#endif
-}
diff --git a/mail/mail-config.glade b/mail/mail-config.glade
index 586dc854b1..b54025297d 100644
--- a/mail/mail-config.glade
+++ b/mail/mail-config.glade
@@ -1,3 +1,146 @@
+<<<<<<< HEAD:mail/mail-config.glade
+<?xml version="1.0"?>
+<glade-interface>
+ <requires lib="gnome"/>
+ <!-- interface-requires gnome 2298.56488 -->
+ <!-- interface-requires gtk+ 2.16 -->
+ <!-- interface-naming-policy toplevel-contextual -->
+ <widget class="GtkWindow" id="account_druid">
+ <property name="title" translatable="yes">Evolution Account Assistant</property>
+ <child>
+ <widget class="GnomeDruid" id="druid">
+ <property name="visible">True</property>
+ <property name="border_width">4</property>
+ <child>
+ <widget class="GnomeDruidPageEdge" id="start_page">
+ <property name="visible">True</property>
+ <property name="position">Edge Start</property>
+ <property name="title" translatable="yes">Mail Configuration</property>
+ <property name="text" translatable="yes">Welcome to the Evolution Mail Configuration Assistant.
+
+Click "Forward" to begin. </property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GnomeDruidPageStandard" id="identity_page">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Identity</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="druid_identity_vbox">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="identity_help">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Please enter your name and email address below. The "optional" fields below do not need to be filled in, unless you wish to include this information in email you send.</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GnomeDruidPageStandard" id="source_page">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Receiving Email</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="druid_source_vbox">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="extra_help">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Please select among the following options</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GnomeDruidPageStandard" id="transport_page">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Sending Email</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="druid_transport_vbox">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="transport_help">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Please enter information about the way you will send mail. If you are not sure, ask your system administrator or Internet Service Provider.</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GnomeDruidPageStandard" id="management_page">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Account Management</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="druid_management_vbox">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="management_help">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Please enter a descriptive name for this account in the space below.
+This name will be used for display purposes only.</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GnomeDruidPageEdge" id="finish_page">
+ <property name="visible">True</property>
+ <property name="position">Edge Finish</property>
+ <property name="title" translatable="yes">Done</property>
+ <property name="text" translatable="yes">Congratulations, your mail configuration is complete.
+=======
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
@@ -5612,1810 +5755,5468 @@ For example: &quot;Work&quot; or &quot;Personal&quot;</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">4</property>
+>>>>>>> master:mail/mail-config.glade
- <child>
- <widget class="GtkCheckButton" id="chkEmptyTrashOnExit">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Empty trash folders on e_xit</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
+You are now ready to send and receive email
+using Evolution.
- <child>
- <widget class="GtkComboBox" id="comboboxEmptyTrashDays">
- <property name="visible">True</property>
- <property name="items" translatable="yes">a
+Click "Apply" to save your settings.</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="account_editor">
+ <property name="title" translatable="yes">Account Editor</property>
+ <child>
+ <widget class="GtkNotebook" id="account_editor_notebook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="border_width">12</property>
+ <child>
+ <widget class="GtkVBox" id="vboxIdentityBorder">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="management_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label470">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Account Information&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox172">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label568">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table12">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="account_vbox">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="management_description_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Type the name by which you would like to refer to this account.
+For example: "Work" or "Personal"</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxIdentityName">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="management_name_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Name:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">management_name</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="management_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="identity_required_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label464">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Required Information&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox170">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label569">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table10">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkTable" id="identity_required_table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkEntry" id="identity_address">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <atkrelation type="labelled-by" target="label464"/>
+ <atkrelation type="labelled-by" target="identity_address_label"/>
+ </accessibility>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="identity_address_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Email _Address:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">identity_address</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="identity_full_name_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Full Nam_e:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">identity_full_name</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="identity_full_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <atkrelation type="labelled-by" target="identity_full_name_label"/>
+ <atkrelation type="labelled-by" target="label464"/>
+ </accessibility>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="identity_optional_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label466">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Optional Information&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox171">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label570">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="identity_optional_table">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="sigLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Signat_ure:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">signature_dropdown</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox169">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="Custom" id="signature_dropdown">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_dropdown_new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="sigAddNew">
+ <property name="label" translatable="yes">Add Ne_w Signature...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="sigAddNewClicked"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="identity_organization">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <atkrelation type="labelled-by" target="label466"/>
+ <atkrelation type="labelled-by" target="identity_organization_label"/>
+ </accessibility>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="identity_organization_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Or_ganization:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">identity_organization</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="identity_reply_to">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <atkrelation type="labelled-by" target="reply_to_label"/>
+ <atkrelation type="labelled-by" target="label466"/>
+ </accessibility>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="reply_to_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Re_ply-To:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">identity_reply_to</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="management_default">
+ <property name="label" translatable="yes">_Make this my default account</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label31">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Identity</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxSourceBorder">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="source_vbox">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkTable" id="source_type_table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="source_type_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Server _Type: </property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">source_type_dropdown</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label442">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Description:</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="source_description">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">description</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="source_type_dropdown">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_dropdown_new</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHSeparator" id="hseparator2">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="source_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label472">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Configuration&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox173">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label565">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table13">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkTable" id="table4">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="source_host_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Server:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">source_host</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="source_user_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">User_name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">source_user</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="source_host">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="source_user">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="source_path_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Path:</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFileChooserButton" id="source_path_entry">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Mailbox location</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="source_security_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label515">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Security&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="mnemonic_widget">source_auth_dropdown</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox201">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label567">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox181">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="source_ssl_hbox">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="lblSourceUseSSL">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Use Secure Connection:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">source_use_ssl</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="source_use_ssl">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_ssl_selector_new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="source_ssl_disabled">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-warning</property>
+ <property name="icon-size">4</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label514">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;b&gt;SSL is not supported in this build of Evolution&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="source_auth_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label474">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;_Authentication Type&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">source_auth_dropdown</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox174">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label566">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox179">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hbox199">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="Custom" id="source_auth_dropdown">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_dropdown_new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="source_check_supported">
+ <property name="label" translatable="yes"> Ch_eck for Supported Types </property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="source_remember_password">
+ <property name="label" translatable="yes">Re_member password</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Note: you will not be prompted for a password until you connect for the first time</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label33">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Receiving Email</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxTransportBorder">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="transport_vbox">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkTable" id="transport_type_table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="transport_type_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Server _Type: </property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">transport_type_dropdown</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label50">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Description:</property>
+ <property name="justify">right</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="transport_type_dropdown">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_dropdown_new</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="transport_description">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">description</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHSeparator" id="hseparator3">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="transport_frame">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="transport_server_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label476">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Server Configuration&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox175">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label562">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table15">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox12">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkTable" id="table6">
+ <property name="visible">True</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="transport_host_label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Server:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">transport_host</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="transport_host">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="transport_needs_auth">
+ <property name="label" translatable="yes">Ser_ver requires authentication</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="transport_security_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label517">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Security&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox203">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label564">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox183">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="transport_ssl_hbox">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="lblTransportUseSSL">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Use Secure Connection:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">transport_use_ssl</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="transport_use_ssl">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_ssl_selector_new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="transport_ssl_disabled">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-dialog-warning</property>
+ <property name="icon-size">4</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="transport_ssl_disabled_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;b&gt;SSL is not supported in this build of Evolution&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="transport_auth_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label478">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Authentication&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox176">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label563">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table16">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox61">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkTable" id="table31">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="transport_auth_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">T_ype: </property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">transport_auth_dropdown</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="transport_user_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">User_name:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">transport_user</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="transport_user">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox195">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="Custom" id="transport_auth_dropdown">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_dropdown_new</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="transport_check_supported">
+ <property name="label" translatable="yes">Ch_eck for Supported Types </property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFixed" id="fixed5">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="transport_remember_password">
+ <property name="label" translatable="yes">Remember _password</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label34">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Sending Mail</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxFoldersBorder">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="folders_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label482">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Sent and Draft Messages&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox177">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label560">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table17">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox184">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkTable" id="folders_table">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="drafts_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Drafts _Folder:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">drafts_button</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="sent_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Sent _Messages Folder:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">sent_button</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="sent_button">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_folder_selector_button_new</property>
+ <property name="string1">Select Sent Folder</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="drafts_button">
+ <property name="visible">True</property>
+ <property name="creation_function">em_account_editor_folder_selector_button_new</property>
+ <property name="string1">Select Drafts Folder</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFixed" id="fixed9">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFixed" id="fixed8">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox216">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkButton" id="default_folders_button">
+ <property name="label">gtk-revert-to-saved</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFixed" id="fixed12">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="frame2">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label484">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Composing Messages&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox178">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label561">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table18">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkTable" id="table8">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkVBox" id="vbox186">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="always_cc">
+ <property name="label" translatable="yes">Alway_s carbon-copy (cc) to:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox210">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label522">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table32">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox187">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkEntry" id="cc_addrs">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox188">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="always_bcc">
+ <property name="label" translatable="yes">Always _blind carbon-copy (bcc) to:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox211">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label523">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table33">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox189">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkEntry" id="bcc_addrs">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox205">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label578">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Message Receipts&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox231">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label581">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox232">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label583">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">S_end message receipts:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">receipt_policy_dropdown</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="receipt_policy_dropdown">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes"></property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label35">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Defaults</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxSecurityBorder">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="pgp_frame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label486">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Pretty Good Privacy (PGP/GPG)&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox179">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label558">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table19">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxPGP">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hbox63">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="pgp_key_id_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">PGP/GPG _Key ID:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">pgp_key</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="pgp_key">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="pgp_always_sign">
+ <property name="label" translatable="yes">Al_ways sign outgoing messages when using this account</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="pgp_no_imip_sign">
+ <property name="label" translatable="yes">_Do not sign meeting requests (for Outlook compatibility)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="pgp_encrypt_to_self">
+ <property name="label" translatable="yes">Always encrypt to _myself when sending encrypted messages</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="pgp_always_trust">
+ <property name="label" translatable="yes">Always _trust keys in my keyring when encrypting</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="smime_vbox">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label519">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Secure MIME (S/MIME)&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox206">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label559">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="smime_table">
+ <property name="visible">True</property>
+ <property name="n_rows">6</property>
+ <property name="n_columns">3</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkEntry" id="smime_sign_key">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="smime_encrypt_key">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="smime_encrypt_to_self">
+ <property name="label" translatable="yes">Also encrypt to sel_f when sending encrypted messages</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">3</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="smime_encrypt_default">
+ <property name="label" translatable="yes">Encrypt out_going messages (by default)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">3</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="smime_sign_default">
+ <property name="label" translatable="yes">Digitally sign o_utgoing messages (by default)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHSeparator" id="hseparator1">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ <property name="y_padding">6</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Encry_ption certificate:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">smime_encrypt_key</property>
+ </widget>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label469">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Sig_ning certificate:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">smime_sign_key</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox208">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkButton" id="smime_encrypt_key_select">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment28">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkImage" id="image3">
+ <property name="visible">True</property>
+ <property name="stock">gtk-open</property>
+ <property name="icon-size">4</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="button98">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">S_elect...</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="smime_encrypt_key_clear">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment35">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox230">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkImage" id="image10">
+ <property name="visible">True</property>
+ <property name="stock">gtk-clear</property>
+ <property name="icon-size">4</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label577">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Clea_r</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox209">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkButton" id="smime_sign_key_select">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment29">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkImage" id="image4">
+ <property name="visible">True</property>
+ <property name="stock">gtk-open</property>
+ <property name="icon-size">4</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Select...</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="smime_sign_key_clear">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment34">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox229">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkImage" id="image9">
+ <property name="visible">True</property>
+ <property name="stock">gtk-clear</property>
+ <property name="icon-size">4</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label576">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Cle_ar</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblSecurity">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Security</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="preferences_tab">
+ <property name="title" translatable="yes">Mail Preferences</property>
+ <child>
+ <widget class="GtkNotebook" id="preferences_toplevel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="scrollable">True</property>
+ <child>
+ <widget class="GtkVBox" id="vboxGeneral">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="FontsFrame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label492">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Message Fonts&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox182">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label540">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table22">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxMessageFonts">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="radFontUseSame">
+ <property name="label" translatable="yes">_Use the same fonts as other applications</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="tblScreen">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblScreenVariable">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">S_tandard Font:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">FontVariable</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFontButton" id="FontFixed">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Select HTML fixed width font</property>
+ <signal name="font_set" handler="changed"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFontButton" id="FontVariable">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Select HTML variable width font</property>
+ <signal name="font_set" handler="changed"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label444">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Fix_ed width Font:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">right</property>
+ <property name="mnemonic_widget">FontFixed</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="MessageDisplayFrame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label494">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Message Display&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox183">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label541">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table23">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxMessageDisplay">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hboxReadTimeout">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkMarkTimeout">
+ <property name="label" translatable="yes">_Mark messages as read after</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="spinMarkTimeout">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">1.5 0 10 1 1 0</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">1</property>
+ <property name="numeric">True</property>
+ <property name="update_policy">if-valid</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblSeconds">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">seconds</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox234">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <widget class="GtkCheckButton" id="mlimit_checkbutton">
+ <property name="label" translatable="yes">Do not format messages when text si_ze exceeds</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="mlimit_spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">0 0 30000 1 10 0</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label585">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">KB</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox233">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="address_checkbox">
+ <property name="label" translatable="yes">_Shrink To / Cc / Bcc headers to </property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="address_spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">5 1 100 1 10 0</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">2</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label584">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">addresses</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">2</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="magic_spacebar_checkbox">
+ <property name="label" translatable="yes">Enable Magic S_pacebar</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxHighlightColor">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkHighlightCitations">
+ <property name="label" translatable="yes">Highlight _quotations with</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkColorButton" id="colorButtonHighlightCitations">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Pick a color</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblColor">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">color</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxDefaultCharset">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblDefaultCharset">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Default character e_ncoding:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxEnableSearchFolders">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkEnableSearchFolders">
+ <property name="label" translatable="yes">Enable Sea_rch Folders</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblEnableSFRestart">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">(Note: Requires restart of the application)</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="DeleteMailFrame">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label496">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Delete Mail&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox184">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label542">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table24">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxDeletingMail">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hbox220">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkEmptyTrashOnExit">
+ <property name="label" translatable="yes">Empty trash folders on e_xit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="comboboxEmptyTrashDays">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">a
b</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</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">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkConfirmExpunge">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Confirm _when expunging a folder</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</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="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">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblGeneral">
- <property name="visible">True</property>
- <property name="label" translatable="yes">General</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxHtmlMail">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label530">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;General&lt;/span&gt;</property>
- <property name="use_underline">False</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="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</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="hbox215">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label538">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox173">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkCheckButton" id="chkShowAnimatedImages">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes" comments="If enabled, show animation; if disabled, only display a static image without any animation">_Show image animations</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkPromptWantHTML">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Prompt on sending HTML mail to contacts that do not want them</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</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">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxLoadingImages">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label500">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Loading Images&lt;/span&gt;</property>
- <property name="use_underline">False</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="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</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="hbox186">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label539">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox190">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkRadioButton" id="radImagesNever">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Never load images from the Internet</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkRadioButton" id="radImagesSometimes">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Load images in messages from contacts</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">radImagesNever</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkRadioButton" id="radImagesAlways">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Always load images from the Internet</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">radImagesNever</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">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="lblHtmlMail">
- <property name="visible">True</property>
- <property name="label" translatable="yes">HTML Messages</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="frameColours">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label502">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Labels&lt;/span&gt;</property>
- <property name="use_underline">False</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="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</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="hbox187">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label537">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</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="hbox242">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkVBox" id="vbox209">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow50">
- <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_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="labelTree">
- <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>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</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="GtkLabel" id="label589">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Note: Underscore in the label name is used as mnemonic identifier in menu.</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">True</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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">10</property>
- <property name="expand">False</property>
- <property name="fill">False</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="vbox208">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">2</property>
-
- <child>
- <widget class="GtkButton" id="labelAdd">
- <property name="visible">True</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>
- <property name="focus_on_click">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="labelEdit">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-edit</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="labelRemove">
- <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>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="padding">6</property>
- <property name="expand">False</property>
- <property name="fill">False</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="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="lblColours">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Labels</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vboxHeaderTab">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox206">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkHBox" id="hbox238">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label587">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Sender Photograph&lt;/b&gt;</property>
- <property name="use_underline">False</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.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</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">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox206">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox239">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkCheckButton" id="photo_show">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Show the photograph of sender in the message preview</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">10</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox240">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkCheckButton" id="photo_local">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">S_earch for sender photograph only in local address books</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">10</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label524">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Displayed Message _Headers&lt;/span&gt;</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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</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="hbox212">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="label536">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox199">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">12</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">*</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_IN</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>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</property>
- <accessibility>
- <atkproperty name="AtkObject::accessible_name" translatable="yes">Mail Headers Table</atkproperty>
- </accessibility>
- </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="vbox200">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</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>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</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>
- <property name="focus_on_click">True</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">0</property>
- <property name="expand">False</property>
- <property name="fill">False</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">Headers</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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox161">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox192">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label526">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;General&lt;/span&gt;</property>
- <property name="use_underline">False</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="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table34">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="n_rows">9</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">3</property>
- <property name="column_spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox235">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label586">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Default junk plugin:</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>
- <property name="mnemonic_widget">default_junk_plugin</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">6</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="default_junk_plugin">
- <property name="visible">True</property>
- <property name="creation_function">create_combo_text_widget</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Fri, 23 Mar 2007 09:28:55 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">7</property>
- <property name="bottom_attach">8</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkCheckIncomingMail">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Checks incoming mail messages to be Junk</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Check incoming _messages for junk</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_padding">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox236">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkImage" id="plugin_image">
- <property name="visible">True</property>
- <property name="icon_size">4</property>
- <property name="icon_name">gtk-info</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="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="plugin_status">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</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.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">8</property>
- <property name="bottom_attach">9</property>
- <property name="x_padding">15</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox237">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">4</property>
-
- <child>
- <widget class="GtkCheckButton" id="junk_empty_check">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Delete junk messages on e_xit</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkComboBox" id="junk_empty_combobox">
- <property name="visible">True</property>
- <property name="items" translatable="yes">a
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkConfirmExpunge">
+ <property name="label" translatable="yes">Confirm _when expunging a folder</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblGeneral">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">General</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxHtmlMail">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label530">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;General&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox215">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label538">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox173">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkShowAnimatedImages">
+ <property name="label" translatable="yes" comments="If enabled, show animation; if disabled, only display a static image without any animation">_Show image animations</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkPromptWantHTML">
+ <property name="label" translatable="yes">_Prompt on sending HTML mail to contacts that do not want them</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxLoadingImages">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label500">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Loading Images&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox186">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label539">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox190">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkRadioButton" id="radImagesNever">
+ <property name="label" translatable="yes">_Never load images from the Internet</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="radImagesSometimes">
+ <property name="label" translatable="yes">_Load images in messages from contacts</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radImagesNever</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="radImagesAlways">
+ <property name="label" translatable="yes">_Always load images from the Internet</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radImagesNever</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblHtmlMail">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">HTML Messages</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="frameColours">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label502">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Labels&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="labels-alignment">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblColours">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Labels</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxHeaderTab">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkVBox" id="vbox206">
+ <property name="visible">True</property>
+ <property name="spacing">3</property>
+ <child>
+ <widget class="GtkHBox" id="hbox238">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label587">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Sender Photograph&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hbox239">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="photo_show">
+ <property name="label" translatable="yes">_Show the photograph of sender in the message preview</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">10</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox240">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="photo_local">
+ <property name="label" translatable="yes">S_earch for sender photograph only in local address books</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">10</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label524">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Displayed Message _Headers&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtHeaders</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox212">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label536">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox199">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkEntry" id="txtHeaders">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow49">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <widget class="GtkTreeView" id="treeHeaders">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <accessibility>
+ <atkproperty name="AtkObject::accessible-name" translatable="yes">Mail Headers Table</atkproperty>
+ </accessibility>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox200">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkButton" id="cmdHeadersAdd">
+ <property name="label">gtk-add</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="cmdHeadersRemove">
+ <property name="label">gtk-remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblHeaders">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Headers</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox161">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkVBox" id="vbox192">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label526">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;General&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table34">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="n_rows">9</property>
+ <property name="row_spacing">3</property>
+ <child>
+ <widget class="GtkHBox" id="hbox235">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label586">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Default junk plugin:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">default_junk_plugin</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">6</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="default_junk_plugin">
+ <property name="visible">True</property>
+ <property name="creation_function">create_combo_text_widget</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">7</property>
+ <property name="bottom_attach">8</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkCheckIncomingMail">
+ <property name="label" translatable="yes">Check incoming _messages for junk</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip" translatable="yes">Checks incoming mail messages to be Junk</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="x_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox236">
+ <property name="visible">True</property>
+ <property name="spacing">3</property>
+ <child>
+ <widget class="GtkImage" id="plugin_image">
+ <property name="visible">True</property>
+ <property name="icon_name">gtk-info</property>
+ <property name="icon-size">4</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="plugin_status">
+ <property name="visible">True</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">8</property>
+ <property name="bottom_attach">9</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="x_padding">15</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox237">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <widget class="GtkCheckButton" id="junk_empty_check">
+ <property name="label" translatable="yes">Delete junk messages on e_xit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="junk_empty_combobox">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">a
b</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_padding">4</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="junk_header_check">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Check cu_stom headers for junk</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_padding">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox243">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkScrolledWindow" id="scrolledwindow51">
- <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_IN</property>
- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
- <child>
- <widget class="GtkTreeView" id="junk_header_tree">
- <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>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</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="GtkVButtonBox" id="vbuttonbox26">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="junk_header_add">
- <property name="visible">True</property>
- <property name="can_default">True</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>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="junk_header_remove">
- <property name="visible">True</property>
- <property name="can_default">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>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_padding">22</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="lookup_book">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Do not mar_k messages as junk if sender is in my address book</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_padding">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="junk_lookup_local_only">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Lookup in local address book only</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_padding">25</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox244">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkImage" id="image11">
- <property name="visible">True</property>
- <property name="stock">gtk-info</property>
- <property name="icon_size">4</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="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label590">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Option is ignored if a match for custom junk headers is found.</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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
- <property name="x_options">fill</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="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox195">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="tab_expand">False</property>
- <property name="tab_fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label473">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Junk</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>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">tab</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-<widget class="GtkWindow" id="composer_tab">
- <property name="title" translatable="yes">Message Composer</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GtkNotebook" id="composer_toplevel">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="show_tabs">True</property>
- <property name="show_border">True</property>
- <property name="tab_pos">GTK_POS_TOP</property>
- <property name="scrollable">False</property>
- <property name="enable_popup">False</property>
-
- <child>
- <widget class="GtkVBox" id="vboxGeneral">
- <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">18</property>
-
- <child>
- <widget class="GtkVBox" id="frameBehavior">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label504">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;span weight=&quot;bold&quot;&gt;Default Behavior&lt;/span&gt;</property>
- <property name="use_underline">False</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="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</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="hbox189">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label505">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></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">12</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="table28">
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">1</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">2</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vboxBehavior">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">8</property>
-
- <child>
- <widget class="GtkCheckButton" id="chkSendHTML">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Format messages in _HTML</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkAutoSmileys">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Automatically insert _emoticon images</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkRequestReceipt">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Always request rea_d receipt</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkReplyStartBottom">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Start _typing at the bottom on replying</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="chkOutlookFilenames">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Encode file names in an Outlook/GMail way</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkTable" id="tableForwardsReplies">
- <property name="visible">True</property>
- <property name="n_rows">3</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">12</property>
-
- <child>
- <widget class="GtkLabel" id="lblReplyStyle">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Reply style:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</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="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkAlignment" id="alignment25">
- <property name="visible">True</property>
- <property name="xalign">7.45058015283e-09</property>
- <property name="yalign">0.5</property>
- <property name="xscale">0</property>
- <property name="yscale">1</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkHBox" id="hboxReplyStyle">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkComboBox" id="comboboxReplyStyle">
- <property name="visible">True</property>
- <property name="items" translatable="yes">Attachment
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="x_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="junk_header_check">
+ <property name="label" translatable="yes">Check cu_stom headers for junk</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="x_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox243">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow51">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <widget class="GtkTreeView" id="junk_header_tree">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox26">
+ <property name="visible">True</property>
+ <property name="layout_style">spread</property>
+ <child>
+ <widget class="GtkButton" id="junk_header_add">
+ <property name="label">gtk-add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="junk_header_remove">
+ <property name="label">gtk-remove</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_padding">22</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="lookup_book">
+ <property name="label" translatable="yes">Do not mar_k messages as junk if sender is in my address book</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="x_padding">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="junk_lookup_local_only">
+ <property name="label" translatable="yes">_Lookup in local address book only</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="x_padding">25</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox244">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkImage" id="image11">
+ <property name="visible">True</property>
+ <property name="stock">gtk-info</property>
+ <property name="icon-size">4</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label590">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Option is ignored if a match for custom junk headers is found.</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox195">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label473">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Junk</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="composer_tab">
+ <property name="title" translatable="yes">Message Composer</property>
+ <child>
+ <widget class="GtkNotebook" id="composer_toplevel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <widget class="GtkVBox" id="vboxGeneral">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">18</property>
+ <child>
+ <widget class="GtkVBox" id="frameBehavior">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label504">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Default Behavior&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox189">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label505">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table28">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxBehavior">
+ <property name="visible">True</property>
+ <property name="spacing">8</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkSendHTML">
+ <property name="label" translatable="yes">Format messages in _HTML</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkAutoSmileys">
+ <property name="label" translatable="yes">Automatically insert _emoticon images</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkRequestReceipt">
+ <property name="label" translatable="yes">Always request rea_d receipt</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkReplyStartBottom">
+ <property name="label" translatable="yes">Start _typing at the bottom on replying</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkOutlookFilenames">
+ <property name="label" translatable="yes">Encode file names in an Outlook/GMail way</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="tableForwardsReplies">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblReplyStyle">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Reply style:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment25">
+ <property name="visible">True</property>
+ <property name="xalign">7.4505801528346183e-09</property>
+ <property name="xscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hboxReplyStyle">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkComboBox" id="comboboxReplyStyle">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">Attachment
Inline (Outlook style)
Quoted
Do not quote</property>
- <property name="add_tearoffs">False</property>
- <property name="focus_on_click">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hboxForwardStyle">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkComboBox" id="comboboxForwardStyle">
- <property name="visible">True</property>
- <property name="items" translatable="yes">Attachment
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxForwardStyle">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkComboBox" id="comboboxForwardStyle">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes">Attachment
Inline
Quoted</property>
+<<<<<<< HEAD:mail/mail-config.glade
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblForwardStyle">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Forward style:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblCharset">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">C_haracter set:</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxComposerCharset">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox241">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox207">
+ <property name="visible">True</property>
+ <property name="spacing">8</property>
+ <child>
+ <widget class="GtkLabel" id="label588">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.47999998927116394</property>
+ <property name="label" translatable="yes">&lt;b&gt;Top Posting Option&lt;/b&gt; (Not Recommended)</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkTopSignature">
+ <property name="label" translatable="yes">_Keep Signature above the original message on replying</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label506">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Alerts&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox190">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label507">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table29">
+ <property name="visible">True</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vboxAlerts">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkPromptEmptySubject">
+ <property name="label" translatable="yes">_Prompt when sending messages with an empty subject line</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkPromptBccOnly">
+ <property name="label" translatable="yes">Pr_ompt when sending messages with only Bcc recipients defined</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblGeneral">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">General</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxSignatures">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="vbox201">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label548">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;b&gt;Sig_natures&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignSignatures">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox202">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label551">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;b&gt;Preview&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox162">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label552">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolled-sig">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblSignatures">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Signatures</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxSpellChecking">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="vbox196">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label534">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;b&gt;_Languages&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">listSpellCheckLanguage</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox218">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label555">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox197">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkVBox" id="vbox178">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hbox192">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="hboxLanguages">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow48">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <widget class="GtkTreeView" id="listSpellCheckLanguage">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <accessibility>
+ <atkproperty name="AtkObject::accessible-name" translatable="yes">Languages Table</atkproperty>
+ </accessibility>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxImageAndHelp">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkImage" id="pixmapSpellInfo">
+ <property name="visible">True</property>
+ <property name="yalign">0</property>
+ <property name="stock">gtk-dialog-info</property>
+ <property name="icon-size">4</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblSpellChecking">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">The list of languages here reflects only the languages for which you have a dictionary installed.</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="frameSpellChecking">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label508">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Options&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox191">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkLabel" id="label556">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxOptions">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="chkEnableSpellChecking">
+ <property name="label" translatable="yes">Check spelling while I _type</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hboxSpellCheckColor">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblSpellCheckColor">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Color for _misspelled words:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">colorButtonSpellCheckColor</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkColorButton" id="colorButtonSpellCheckColor">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Pick a color</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label450">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Spell Checking</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="font_tab">
+ <property name="title" translatable="yes">Font Properties</property>
+ <child>
+ <widget class="GtkVBox" id="toplevel">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="frame4">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label512">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Printed Fonts&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox194">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="label513">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="tblPrint">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblPrintVariable">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">V_ariable-width:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">print_variable</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblPrintFixed">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Fi_xed-width:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">print_fixed</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFontButton" id="print_fixed">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Select HTML fixed width font for printing</property>
+ <signal name="font_set" handler="changed"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFontButton" id="print_variable">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="title" translatable="yes">Select HTML variable width font for printing</property>
+ <signal name="font_set" handler="changed"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkDialog" id="add_script_signature">
+ <property name="type_hint">normal</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkVBox" id="vbox160">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox_add_script_signature">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hboxImageAndHelp">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkImage" id="pixmap1">
+ <property name="visible">True</property>
+ <property name="yalign">0</property>
+ <property name="stock">gtk-dialog-info</property>
+ <property name="icon-size">6</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label456">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">The output of this script will be used as your
+signature. The name you specify will be used
+for display purposes only. </property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="tblNameScript">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label459">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Name:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">entry_add_script_name</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label460">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Script:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">center</property>
+ <property name="mnemonic_widget">filechooserbutton_add_script</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_add_script_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFileChooserButton" id="filechooserbutton_add_script">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes"></property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <widget class="GtkButton" id="button_add_script_add">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment30">
+ <property name="visible">True</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <widget class="GtkHBox" id="hbox221">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkImage" id="image5">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ <property name="icon-size">4</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label547">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Add Signature</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_add_script_cancel">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="network_prefs_tab">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">window1</property>
+ <child>
+ <widget class="GtkNotebook" id="network_preferences_toplevel">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <widget class="GtkVBox" id="vboxGeneral">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">18</property>
+ <child>
+ <widget class="GtkVBox" id="frameProxy">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label76">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;span weight="bold"&gt;Proxy Settings&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vboxProxy">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="spacing">8</property>
+ <child>
+ <widget class="GtkRadioButton" id="rdoSysSettings">
+ <property name="label" translatable="yes">_Use system defaults</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="rdoNoProxy">
+ <property name="label" translatable="yes">_Direct connection to the Internet</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">rdoSysSettings</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="rdoManualProxy">
+ <property name="label" translatable="yes">_Manual proxy configuration:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">rdoSysSettings</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment27">
+ <property name="visible">True</property>
+ <property name="left_padding">24</property>
+ <child>
+ <widget class="GtkVBox" id="vbox18">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkTable" id="table8">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="lblHttpHost">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">H_TTP Proxy:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtHttpHost</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblHttpsHost">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Secure HTTP Proxy:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtHttpsHost</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblIgnoreHosts">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">No _Proxy for:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtIgnoreHosts</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="txtHttpHost">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="txtHttpsHost">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblHttpPort">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Port:</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblHttpsPort">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Port:</property>
+ </widget>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="spnHttpPort">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">0 0 65535 1 10 0</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="spnHttpsPort">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">0 0 65535 1 10 0</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="txtIgnoreHosts">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="chkUseAuth">
+ <property name="label" translatable="yes">Use Authe_ntication</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment26">
+ <property name="visible">True</property>
+ <property name="left_padding">24</property>
+ <child>
+ <widget class="GtkTable" id="table11">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">3</property>
+ <child>
+ <widget class="GtkLabel" id="lblAuthUser">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Us_ername:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtAuthUser</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblAuthPwd">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Pass_word:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">txtAuthPwd</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="txtAuthUser">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="txtAuthPwd">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="visibility">False</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="lblGeneral">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">General</property>
+ </widget>
+ <packing>
+ <property name="tab_fill">False</property>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+=======
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
</widget>
@@ -9842,4 +13643,5 @@ signature. The name you specify will be used for display purposes only.</propert
</child>
</widget>
+>>>>>>> master:mail/mail-config.glade
</glade-interface>
diff --git a/mail/mail-config.h b/mail/mail-config.h
index 80a82a2f83..cc5878456c 100644
--- a/mail/mail-config.h
+++ b/mail/mail-config.h
@@ -33,14 +33,6 @@
G_BEGIN_DECLS
-typedef struct _MailConfigSignature {
- gint id;
- gchar *name;
- gchar *filename;
- gchar *script;
- gboolean html;
-} MailConfigSignature;
-
typedef enum {
MAIL_CONFIG_HTTP_NEVER,
MAIL_CONFIG_HTTP_SOMETIMES,
@@ -83,53 +75,20 @@ void mail_config_write_on_exit (void);
GConfClient *mail_config_get_gconf_client (void);
/* General Accessor functions */
-gboolean mail_config_is_configured (void);
-gboolean mail_config_is_corrupt (void);
-
-GSList *mail_config_get_labels (void);
-
const gchar **mail_config_get_allowable_mime_types (void);
void mail_config_service_set_save_passwd (EAccountService *service, gboolean save_passwd);
/* accounts */
-gboolean mail_config_find_account (EAccount *account);
-EAccount *mail_config_get_default_account (void);
-EAccount *mail_config_get_account_by_name (const gchar *account_name);
-EAccount *mail_config_get_account_by_uid (const gchar *uid);
EAccount *mail_config_get_account_by_source_url (const gchar *url);
EAccount *mail_config_get_account_by_transport_url (const gchar *url);
-EAccountList *mail_config_get_accounts (void);
-void mail_config_add_account (EAccount *account);
-void mail_config_remove_account (EAccount *account);
-void mail_config_set_default_account (EAccount *account);
gint mail_config_get_address_count (void);
gint mail_config_get_message_limit (void);
gboolean mail_config_get_enable_magic_spacebar (void);
-void mail_config_remove_account_proxies (EAccount *account);
-void mail_config_prune_proxies (void);
-gint mail_config_has_proxies (EAccount *account);
-
-EAccountIdentity *mail_config_get_default_identity (void);
EAccountService *mail_config_get_default_transport (void);
-void mail_config_save_accounts (void);
-
-/* signatures */
-ESignature *mail_config_signature_new (const gchar *filename, gboolean script, gboolean html);
-ESignature *mail_config_get_signature_by_uid (const gchar *uid);
-ESignature *mail_config_get_signature_by_name (const gchar *name);
-
-ESignatureList *mail_config_get_signatures (void);
-void mail_config_add_signature (ESignature *signature);
-void mail_config_remove_signature (ESignature *signature);
-
-void mail_config_save_signatures (void);
-
-gchar *mail_config_signature_run_script (const gchar *script);
-
/* uri's got changed by the store, etc */
void mail_config_uri_renamed (GCompareFunc uri_cmp, const gchar *old, const gchar *new);
void mail_config_uri_deleted (GCompareFunc uri_cmp, const gchar *uri);
@@ -146,12 +105,8 @@ void mail_config_reload_junk_headers (void);
gboolean mail_config_get_lookup_book (void);
gboolean mail_config_get_lookup_book_local_only (void);
-gboolean mail_config_scripts_disabled (void);
-
GType evolution_mail_config_get_type (void);
-gboolean evolution_mail_config_factory_init (void);
-
G_END_DECLS
#endif /* MAIL_CONFIG_H */
diff --git a/mail/mail-crypto.c b/mail/mail-crypto.c
deleted file mode 100644
index f484e0a5d8..0000000000
--- a/mail/mail-crypto.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <camel/camel-gpg-context.h>
-#include <libedataserver/e-account.h>
-
-#include "mail-crypto.h"
-#include "mail-session.h"
-
-/**
- * mail_crypto_get_pgp_cipher_context:
- * @account: Account that will be using this context
- *
- * Constructs a new GnuPG cipher context with the appropriate
- * options set based on the account provided.
- **/
-CamelCipherContext *
-mail_crypto_get_pgp_cipher_context (EAccount *account)
-{
- CamelCipherContext *cipher;
-
- cipher = camel_gpg_context_new (session);
- if (account)
- camel_gpg_context_set_always_trust ((CamelGpgContext *) cipher, account->pgp_always_trust);
-
- return cipher;
-}
diff --git a/mail/mail-crypto.h b/mail/mail-crypto.h
deleted file mode 100644
index d4d5b7f504..0000000000
--- a/mail/mail-crypto.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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:
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef MAIL_CRYPTO_H
-#define MAIL_CRYPTO_H
-
-G_BEGIN_DECLS
-
-/* PGP/MIME convenience wrappers */
-CamelCipherContext *mail_crypto_get_pgp_cipher_context(EAccount *account);
-
-G_END_DECLS
-
-#endif /* ! MAIL_CRYPTO_H */
diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c
index 50167b7f0a..bf728aa963 100644
--- a/mail/mail-folder-cache.c
+++ b/mail/mail-folder-cache.c
@@ -39,7 +39,6 @@
#include <libgnome/gnome-sound.h>
#include <glib/gi18n.h>
-#include <bonobo/bonobo-exception.h>
#include <camel/camel-store.h>
#include <camel/camel-folder.h>
#include <camel/camel-vtrash-folder.h>
@@ -50,12 +49,12 @@
#include <libedataserver/e-data-server-util.h>
#include <libedataserver/e-msgport.h>
#include "e-util/e-util.h"
+#include "shell/e-shell.h"
#include "mail-mt.h"
#include "mail-folder-cache.h"
#include "mail-ops.h"
#include "mail-session.h"
-#include "mail-component.h"
#include "mail-tools.h"
/* For notifications of changes */
@@ -65,6 +64,10 @@
#include "em-folder-tree-model.h"
#include "em-event.h"
+#include "em-utils.h"
+
+#include "e-mail-local.h"
+#include "e-mail-store.h"
#define w(x)
#define d(x)
@@ -150,14 +153,14 @@ free_update(struct _folder_update *up)
}
static void
-real_flush_updates(gpointer o, gpointer event_data, gpointer data)
+real_flush_updates (void)
{
- struct _MailComponent *component;
- struct _EMFolderTreeModel *model;
+ EShell *shell;
+ EMFolderTreeModel *default_model;
struct _folder_update *up;
- component = mail_component_peek ();
- model = mail_component_peek_tree_model (component);
+ shell = e_shell_get_default ();
+ default_model = em_folder_tree_model_get_default ();
LOCK(info_lock);
while ((up = (struct _folder_update *)e_dlist_remhead(&updates))) {
@@ -186,17 +189,22 @@ real_flush_updates(gpointer o, gpointer event_data, gpointer data)
}
/* update unread counts */
- em_folder_tree_model_set_unread_count (model, up->store, up->full_name, up->unread);
+ em_folder_tree_model_set_unread_count (
+ default_model, up->store, up->full_name, up->unread);
if (up->uri) {
EMEvent *e = em_event_peek();
EMEventTargetFolder *t = em_event_target_new_folder(e, up->uri, up->new);
- t->is_inbox = em_folder_tree_model_is_type_inbox (model, up->store, up->full_name);
- t->name = em_folder_tree_model_get_folder_name (model, up->store, up->full_name);
+ t->is_inbox = em_folder_tree_model_is_type_inbox (
+ default_model, up->store, up->full_name);
+ t->name = em_folder_tree_model_get_folder_name (
+ default_model, up->store, up->full_name);
if (t->new > 0)
- mail_indicate_new_mail (TRUE);
+ e_shell_event (
+ shell, "mail-icon",
+ (gpointer) "mail-unread");
/** @Event: folder.changed
* @Title: Folder changed
@@ -208,6 +216,19 @@ real_flush_updates(gpointer o, gpointer event_data, gpointer data)
e_event_emit((EEvent *)e, "folder.changed", (EEventTarget *)t);
}
+ if (CAMEL_IS_VEE_STORE (up->store) && !up->remove) {
+ /* Normally the vfolder store takes care of the folder_opened event itself,
+ but we add folder to the noting system later, thus we do not know about
+ search folders to update them in a tree, thus ensure their changes will
+ be tracked correctly. */
+ CamelFolder *folder = camel_store_get_folder (up->store, up->full_name, 0, NULL);
+
+ if (folder) {
+ mail_note_folder (folder);
+ camel_object_unref (folder);
+ }
+ }
+
free_update(up);
LOCK(info_lock);
@@ -217,10 +238,13 @@ real_flush_updates(gpointer o, gpointer event_data, gpointer data)
}
static void
-flush_updates(void)
+flush_updates (void)
{
if (update_id == -1 && !e_dlist_empty(&updates))
- update_id = mail_async_event_emit(mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc)real_flush_updates, NULL, NULL, NULL);
+ update_id = mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI,
+ (MailAsyncFunc) real_flush_updates,
+ NULL, NULL, NULL);
}
static void
@@ -289,20 +313,26 @@ update_1folder(struct _folder_info *mfi, gint new, CamelFolderInfo *info)
{
struct _folder_update *up;
CamelFolder *folder;
+ CamelFolder *local_drafts;
+ CamelFolder *local_outbox;
+ CamelFolder *local_sent;
gint unread = -1;
gint deleted;
+ local_drafts = e_mail_local_get_folder (E_MAIL_FOLDER_DRAFTS);
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ local_sent = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
+
folder = mfi->folder;
if (folder) {
d(printf("update 1 folder '%s'\n", folder->full_name));
if ((count_trash && (CAMEL_IS_VTRASH_FOLDER (folder)))
- || folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX)
- || folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)
- || (count_sent && folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT))) {
+ || folder == local_drafts
+ || folder == local_outbox
+ || (count_sent && folder == local_sent)) {
d(printf(" total count\n"));
unread = camel_folder_get_message_count (folder);
- if (folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX)
- || folder == mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)) {
+ if (folder == local_drafts || folder == local_outbox) {
guint32 junked = 0;
if ((deleted = camel_folder_get_deleted_message_count (folder)) > 0)
@@ -395,6 +425,9 @@ folder_changed (CamelObject *o, gpointer event_data, gpointer user_data)
static time_t last_newmail = 0;
CamelFolderChangeInfo *changes = event_data;
CamelFolder *folder = (CamelFolder *)o;
+ CamelFolder *local_drafts;
+ CamelFolder *local_outbox;
+ CamelFolder *local_sent;
CamelStore *store = folder->parent_store;
CamelMessageInfo *info;
struct _store_info *si;
@@ -405,10 +438,14 @@ folder_changed (CamelObject *o, gpointer event_data, gpointer user_data)
d(printf("folder '%s' changed\n", folder->full_name));
+ local_drafts = e_mail_local_get_folder (E_MAIL_FOLDER_DRAFTS);
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ local_sent = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
+
if (!CAMEL_IS_VEE_FOLDER(folder)
- && folder != mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX)
- && folder != mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)
- && folder != mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT)
+ && folder != local_drafts
+ && folder != local_outbox
+ && folder != local_sent
&& changes && (changes->uid_added->len > 0)) {
/* for each added message, check to see that it is
brand new, not junk and not already deleted */
@@ -596,6 +633,7 @@ rename_folders(struct _store_info *si, const gchar *oldbase, const gchar *newbas
gchar *old, *olduri, *oldfile, *newuri, *newfile;
struct _folder_info *mfi;
struct _folder_update *up;
+ const gchar *config_dir;
up = g_malloc0(sizeof(*up));
@@ -651,17 +689,18 @@ rename_folders(struct _store_info *si, const gchar *oldbase, const gchar *newbas
#endif
/* rename the meta-data we maintain ourselves */
+ config_dir = em_utils_get_config_dir ();
olduri = folder_to_url(si->store, old);
e_filename_make_safe(olduri);
newuri = folder_to_url(si->store, fi->full_name);
e_filename_make_safe(newuri);
- oldfile = g_strdup_printf("%s/config/custom_view-%s.xml", mail_component_peek_base_directory(NULL), olduri);
- newfile = g_strdup_printf("%s/config/custom_view-%s.xml", mail_component_peek_base_directory(NULL), newuri);
+ oldfile = g_strdup_printf("%s/custom_view-%s.xml", config_dir, olduri);
+ newfile = g_strdup_printf("%s/custom_view-%s.xml", config_dir, newuri);
g_rename(oldfile, newfile);
g_free(oldfile);
g_free(newfile);
- oldfile = g_strdup_printf("%s/config/current_view-%s.xml", mail_component_peek_base_directory(NULL), olduri);
- newfile = g_strdup_printf("%s/config/current_view-%s.xml", mail_component_peek_base_directory(NULL), newuri);
+ oldfile = g_strdup_printf("%s/current_view-%s.xml", config_dir, olduri);
+ newfile = g_strdup_printf("%s/current_view-%s.xml", config_dir, newuri);
g_rename(oldfile, newfile);
g_free(oldfile);
g_free(newfile);
@@ -1053,7 +1092,7 @@ mail_folder_cache_get_folder_info_flags (CamelFolder *folder, gint *flags)
if (stores == NULL)
return FALSE;
- fi.url = camel_url_new(uri, NULL);
+ fi.url = camel_url_new (uri, NULL);
LOCK(info_lock);
g_hash_table_foreach(stores, (GHFunc)storeinfo_find_folder_info, &fi);
diff --git a/mail/mail-mt.c b/mail/mail-mt.c
index 9ad326f682..490f54f8e5 100644
--- a/mail/mail-mt.c
+++ b/mail/mail-mt.c
@@ -34,14 +34,13 @@
#include <camel/camel-url.h>
#include <camel/camel-operation.h>
+#include "shell/e-shell.h"
#include "misc/e-gui-utils.h"
#include "e-util/e-error.h"
#include "e-util/e-icon-factory.h"
-
-#include "e-activity-handler.h"
+#include "widgets/misc/e-alert-activity.h"
#include "mail-config.h"
-#include "mail-component.h"
#include "mail-session.h"
#include "mail-mt.h"
@@ -65,7 +64,7 @@ static void mail_operation_status(CamelOperation *op, const gchar *what, gint pc
struct _MailMsgPrivate {
gint activity_state; /* sigh sigh sigh, we need to keep track of the state external to the
pointer itself for locking/race conditions */
- gint activity_id;
+ EActivity *activity;
GtkWidget *error;
gboolean cancelable;
};
@@ -140,19 +139,23 @@ mail_msg_new (MailMsgInfo *info)
}
static void
-end_event_callback (CamelObject *o, gpointer event_data, gpointer error)
+end_event_callback (CamelObject *o, EActivity *activity, gpointer error)
{
- MailComponent *component;
- EActivityHandler *activity_handler;
- guint activity_id = GPOINTER_TO_INT (event_data);
-
- component = mail_component_peek ();
- activity_handler = mail_component_peek_activity_handler (component);
- if (!error) {
- e_activity_handler_operation_finished (activity_handler, activity_id);
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ if (error == NULL) {
+ e_activity_complete (activity);
+ g_object_unref (activity);
} else {
- d(printf("Yahooooo, we got it nonintrusively\n"));
- e_activity_handler_operation_set_error (activity_handler, activity_id, error);
+ if (activity != NULL)
+ g_object_unref (activity);
+ activity = e_alert_activity_new_warning (error);
+ e_shell_backend_add_activity (shell_backend, activity);
+ g_object_unref (activity);
}
}
@@ -183,6 +186,9 @@ checkmem(gpointer p)
static void
mail_msg_free (MailMsg *mail_msg)
{
+ if (mail_msg->priv->activity != NULL)
+ g_object_unref (mail_msg->priv->activity);
+
if (mail_msg->cancel != NULL) {
camel_operation_mute (mail_msg->cancel);
camel_operation_unref (mail_msg->cancel);
@@ -209,7 +215,7 @@ void
mail_msg_unref (gpointer msg)
{
MailMsg *mail_msg = msg;
- gint activity_id;
+ EActivity *activity = NULL;
GtkWidget *error = NULL;
g_return_if_fail (mail_msg != NULL);
@@ -253,24 +259,21 @@ mail_msg_unref (gpointer msg)
MAIL_MT_UNLOCK(mail_msg_lock);
return;
} else {
- activity_id = mail_msg->priv->activity_id;
+ activity = mail_msg->priv->activity;
+ if (activity != NULL)
+ g_object_ref (activity);
error = mail_msg->priv->error;
- if (error && !activity_id) {
- e_activity_handler_make_error (mail_component_peek_activity_handler (mail_component_peek ()), "mail", E_LOG_ERROR, error);
- printf("Making error\n");
- }
-
}
MAIL_MT_UNLOCK(mail_msg_lock);
mail_msg_free (mail_msg);
- if (activity_id != 0)
+ if (activity != NULL)
mail_async_event_emit (
mail_async_event, MAIL_ASYNC_GUI,
(MailAsyncFunc) end_event_callback,
- NULL, GINT_TO_POINTER (activity_id), error);
+ NULL, activity, error);
}
/* hash table of ops->dialogue of active errors */
@@ -937,7 +940,8 @@ struct _op_status_msg {
static void
op_status_exec (struct _op_status_msg *m)
{
- EActivityHandler *activity_handler = mail_component_peek_activity_handler (mail_component_peek ());
+ EShell *shell;
+ EShellBackend *shell_backend;
MailMsg *msg;
MailMsgPrivate *data;
gchar *out, *p, *o, c;
@@ -945,6 +949,9 @@ op_status_exec (struct _op_status_msg *m)
g_return_if_fail (mail_in_main_thread ());
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
MAIL_MT_LOCK (mail_msg_lock);
msg = g_hash_table_lookup (mail_msg_active_table, m->data);
@@ -968,7 +975,7 @@ op_status_exec (struct _op_status_msg *m)
pc = m->pc;
- if (data->activity_id == 0) {
+ if (data->activity == NULL) {
gchar *what;
/* its being created/removed? well leave it be */
@@ -988,28 +995,39 @@ op_status_exec (struct _op_status_msg *m)
what = g_strdup("");
}
- data->activity_id = e_activity_handler_cancelable_operation_started (activity_handler, "evolution-mail", what, TRUE, (void (*) (gpointer)) camel_operation_cancel, msg->cancel);
+ data->activity = e_activity_new (what);
+ e_activity_set_allow_cancel (data->activity, TRUE);
+ e_activity_set_percent (data->activity, 0.0);
+ e_shell_backend_add_activity (shell_backend, data->activity);
+
+ g_signal_connect_swapped (
+ data->activity, "cancelled",
+ G_CALLBACK (camel_operation_cancel),
+ msg->cancel);
g_free (what);
MAIL_MT_LOCK (mail_msg_lock);
if (data->activity_state == 3) {
- gint activity_id = data->activity_id;
+ EActivity *activity;
+
+ activity = g_object_ref (data->activity);
MAIL_MT_UNLOCK (mail_msg_lock);
mail_msg_free (msg);
- if (activity_id != 0)
- mail_async_event_emit (mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) end_event_callback,
- NULL, GINT_TO_POINTER (activity_id), NULL);
+ if (activity != 0)
+ mail_async_event_emit (
+ mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) end_event_callback,
+ NULL, activity, NULL);
} else {
data->activity_state = 2;
MAIL_MT_UNLOCK (mail_msg_lock);
}
return;
}
- } else if (data->activity_id != 0) {
+ } else if (data->activity != NULL) {
MAIL_MT_UNLOCK (mail_msg_lock);
- e_activity_handler_operation_progressing (activity_handler, data->activity_id, out, (double)(pc/100.0));
+ e_activity_set_percent (data->activity, pc / 100.0);
} else {
MAIL_MT_UNLOCK (mail_msg_lock);
}
@@ -1062,6 +1080,5 @@ set_stop (gint sensitive)
if (last == sensitive)
return;
- /*bonobo_ui_component_set_prop (uic, "/commands/MailStop", "sensitive", sensitive ? "1" : "0", NULL);*/
last = sensitive;
}
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 118de487bb..eb3fd0cb00 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -57,11 +57,11 @@
#include <libedataserver/e-data-server-util.h>
#include "e-util/e-util.h"
+#include "e-util/e-account-utils.h"
#include "e-util/e-util-private.h"
#include "em-filter-rule.h"
#include "em-utils.h"
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-mt.h"
#include "mail-ops.h"
@@ -69,10 +69,13 @@
#include "mail-tools.h"
#include "mail-vfolder.h"
+#include "e-mail-local.h"
+
#define w(x)
#define d(x)
-const gchar *x_mailer;
+/* XXX Make this a preprocessor definition. */
+const gchar *x_mailer = "Evolution " VERSION SUB_VERSION " " VERSION_COMMENT;
/* used for both just filtering a folder + uid's, and for filtering a whole folder */
/* used both for fetching mail, and for filtering mail */
@@ -245,7 +248,7 @@ uid_cachename_hack (CamelStore *store)
{
CamelURL *url = CAMEL_SERVICE (store)->url;
gchar *encoded_url, *filename;
- const gchar *evolution_dir;
+ const gchar *data_dir;
encoded_url = g_strdup_printf ("%s%s%s@%s", url->user,
url->authmech ? ";auth=" : "",
@@ -253,8 +256,8 @@ uid_cachename_hack (CamelStore *store)
url->host);
e_filename_make_safe (encoded_url);
- evolution_dir = mail_component_peek_base_directory (mail_component_peek ());
- filename = g_build_filename (evolution_dir, "pop", encoded_url, "uid-cache", NULL);
+ data_dir = em_utils_get_data_dir ();
+ filename = g_build_filename (data_dir, "pop", encoded_url, "uid-cache", NULL);
g_free (encoded_url);
return filename;
@@ -275,9 +278,10 @@ fetch_mail_exec (struct _fetch_mail_msg *m)
if (m->cancel)
camel_operation_register (m->cancel);
- if ((fm->destination = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_LOCAL_INBOX)) == NULL)
+ fm->destination = e_mail_local_get_folder (E_MAIL_FOLDER_LOCAL_INBOX);
+ if (fm->destination == NULL)
goto fail;
- camel_object_ref(fm->destination);
+ camel_object_ref (fm->destination);
/* FIXME: this should support keep_on_server too, which would then perform a spool
access thingy, right? problem is matching raw messages to uid's etc. */
@@ -473,9 +477,9 @@ mail_send_message(CamelFolder *queue, const gchar *uid, const gchar *destination
gchar *name;
name = g_strstrip(g_strdup(tmp));
- if ((account = mail_config_get_account_by_uid(name))
+ if ((account = e_get_account_by_uid (name))
/* 'old' x-evolution-account stored the name, how silly */
- || (account = mail_config_get_account_by_name(name))) {
+ || (account = e_get_account_by_name (name))) {
if (account->transport && account->transport->url)
transport_url = g_strdup (account->transport->url);
@@ -579,7 +583,7 @@ mail_send_message(CamelFolder *queue, const gchar *uid, const gchar *destination
}
if (!folder) {
- folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT);
+ folder = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
camel_object_ref(folder);
}
@@ -590,7 +594,7 @@ mail_send_message(CamelFolder *queue, const gchar *uid, const gchar *destination
if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_USER_CANCEL)
goto exit;
- sent_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT);
+ sent_folder = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
if (folder != sent_folder) {
const gchar *name;
@@ -685,13 +689,15 @@ report_status (struct _send_queue_msg *m, enum camel_filter_status_t status, gin
static void
send_queue_exec (struct _send_queue_msg *m)
{
- CamelFolder *sent_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_SENT);
+ CamelFolder *sent_folder;
GPtrArray *uids, *send_uids = NULL;
CamelException ex;
gint i, j;
d(printf("sending queue\n"));
+ sent_folder = e_mail_local_get_folder (E_MAIL_FOLDER_SENT);
+
if (!(uids = camel_folder_get_uids (m->queue)))
return;
@@ -1267,7 +1273,8 @@ struct _get_quota_msg {
CamelFolder *folder;
CamelFolderQuotaInfo *quota;
- void (*done) (CamelFolder *folder, CamelFolderQuotaInfo *quota, gpointer data);
+ void (*done) (CamelFolder *folder, const gchar *folder_uri, CamelFolderQuotaInfo *quota, gpointer data);
+ gchar *folder_uri;
gpointer data;
};
@@ -1287,7 +1294,7 @@ static void
get_quota_done (struct _get_quota_msg *m)
{
if (m->done)
- m->done (m->folder, m->quota, m->data);
+ m->done (m->folder, m->folder_uri, m->quota, m->data);
}
static void
@@ -1297,6 +1304,7 @@ get_quota_free (struct _get_quota_msg *m)
camel_object_unref (m->folder);
if (m->quota)
camel_folder_quota_info_free (m->quota);
+ g_free (m->folder_uri);
}
static MailMsgInfo get_quota_info = {
@@ -1309,7 +1317,8 @@ static MailMsgInfo get_quota_info = {
gint
mail_get_folder_quota (CamelFolder *folder,
- void (*done)(CamelFolder *folder, CamelFolderQuotaInfo *quota, gpointer data),
+ const gchar *folder_uri,
+ void (*done)(CamelFolder *folder, const gchar *uri, CamelFolderQuotaInfo *quota, gpointer data),
gpointer data, MailMsgDispatchFunc dispatch)
{
struct _get_quota_msg *m;
@@ -1319,6 +1328,7 @@ mail_get_folder_quota (CamelFolder *folder,
m = mail_msg_new (&get_quota_info);
m->folder = folder;
+ m->folder_uri = g_strdup (folder_uri);
m->data = data;
m->done = done;
@@ -1747,15 +1757,15 @@ empty_trash_desc (struct _empty_trash_msg *m)
static void
empty_trash_exec (struct _empty_trash_msg *m)
{
- const gchar *evolution_dir;
+ const gchar *data_dir;
CamelFolder *trash;
gchar *uri;
if (m->account) {
trash = mail_tool_get_trash (m->account->source->url, FALSE, &m->base.ex);
} else {
- evolution_dir = mail_component_peek_base_directory (mail_component_peek ());
- uri = g_strdup_printf ("mbox:%s/local", evolution_dir);
+ data_dir = em_utils_get_data_dir ();
+ uri = g_strdup_printf ("mbox:%s/local", data_dir);
trash = mail_tool_get_trash (uri, TRUE, &m->base.ex);
g_free (uri);
}
diff --git a/mail/mail-ops.h b/mail/mail-ops.h
index 4bc1a9b47d..3233f03219 100644
--- a/mail/mail-ops.h
+++ b/mail/mail-ops.h
@@ -71,7 +71,8 @@ gint mail_get_folder (const gchar *uri, guint32 flags,
/* get quota information for a folder */
gint mail_get_folder_quota (CamelFolder *folder,
- void (*done)(CamelFolder *folder, CamelFolderQuotaInfo *quota, gpointer data),
+ const gchar *folder_uri,
+ void (*done)(CamelFolder *folder, const gchar *folder_uri, CamelFolderQuotaInfo *quota, gpointer data),
gpointer data, MailMsgDispatchFunc dispatch);
/* and for a store */
diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c
index 8411290222..323d21f4d7 100644
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@ -38,7 +38,6 @@
#include "camel/camel-store.h"
#include "mail-mt.h"
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-session.h"
#include "mail-tools.h"
@@ -46,7 +45,12 @@
#include "mail-send-recv.h"
#include "mail-folder-cache.h"
#include "em-event.h"
-#include <e-util/gconf-bridge.h>
+
+#include "shell/e-shell.h"
+#include "e-util/e-account-utils.h"
+#include "e-util/gconf-bridge.h"
+
+#include "e-mail-local.h"
#define d(x)
@@ -160,7 +164,8 @@ setup_send_data(void)
g_str_hash, g_str_equal,
(GDestroyNotify) NULL,
(GDestroyNotify) free_folder_info);
- data->inbox = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_LOCAL_INBOX);
+ data->inbox = e_mail_local_get_folder (
+ E_MAIL_FOLDER_LOCAL_INBOX);
camel_object_ref(data->inbox);
data->active = g_hash_table_new_full (
g_str_hash, g_str_equal,
@@ -360,7 +365,10 @@ get_receive_type(const gchar *url)
}
static struct _send_data *
-build_dialog (EAccountList *accounts, CamelFolder *outbox, const gchar *destination)
+build_dialog (GtkWindow *parent,
+ EAccountList *accounts,
+ CamelFolder *outbox,
+ const gchar *destination)
{
GtkDialog *gd;
GtkWidget *table;
@@ -380,7 +388,10 @@ build_dialog (EAccountList *accounts, CamelFolder *outbox, const gchar *destinat
EIterator *iter;
EMEventTargetSendReceive *target;
- gd = (GtkDialog *)(send_recv_dialog = gtk_dialog_new_with_buttons(_("Send & Receive Mail"), NULL, GTK_DIALOG_NO_SEPARATOR, NULL));
+ send_recv_dialog = gtk_dialog_new_with_buttons (
+ _("Send & Receive Mail"), parent,
+ GTK_DIALOG_NO_SEPARATOR, NULL);
+ gd = GTK_DIALOG (send_recv_dialog);
gtk_window_set_modal ((GtkWindow *) gd, FALSE);
gconf_bridge_bind_window_size (
@@ -679,8 +690,12 @@ receive_done (const gchar *uri, gpointer data)
/* if we've been called to run again - run again */
if (info->type == SEND_SEND && info->state == SEND_ACTIVE && info->again) {
+ CamelFolder *local_outbox;
+
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+
info->again = 0;
- mail_send_queue (mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX),
+ mail_send_queue (local_outbox,
info->uri,
FILTER_SOURCE_OUTGOING,
info->cancel,
@@ -899,16 +914,18 @@ receive_update_got_store (gchar *uri, CamelStore *store, gpointer data)
struct _send_info *info = data;
if (store) {
- mail_note_store(store, info->cancel, receive_update_got_folderinfo, info);
+ mail_note_store(
+ store, info->cancel,
+ receive_update_got_folderinfo, info);
} else {
receive_done("", info);
}
}
GtkWidget *
-mail_send_receive (void)
+mail_send_receive (GtkWindow *parent)
{
- CamelFolder *outbox_folder;
+ CamelFolder *local_outbox;
struct _send_data *data;
EAccountList *accounts;
EAccount *account;
@@ -925,14 +942,15 @@ mail_send_receive (void)
if (!camel_session_is_online (session))
return send_recv_dialog;
- account = mail_config_get_default_account ();
+ account = e_get_default_account ();
if (!account || !account->transport->url)
return send_recv_dialog;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
- outbox_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
- data = build_dialog (accounts, outbox_folder, account->transport->url);
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ data = build_dialog (
+ parent, accounts, local_outbox, account->transport->url);
scan = data->infos;
while (scan) {
struct _send_info *info = scan->data;
@@ -948,7 +966,7 @@ mail_send_receive (void)
break;
case SEND_SEND:
/* todo, store the folder in info? */
- mail_send_queue(outbox_folder, info->uri,
+ mail_send_queue(local_outbox, info->uri,
FILTER_SOURCE_OUTGOING,
info->cancel,
receive_get_folder, info,
@@ -1059,16 +1077,16 @@ auto_account_changed(EAccountList *eal, EAccount *ea, gpointer dummy)
}
static void
-auto_online(CamelObject *o, gpointer ed, gpointer d)
+auto_online (EShell *shell)
{
EIterator *iter;
EAccountList *accounts;
struct _auto_data *info;
- if (!GPOINTER_TO_INT(ed))
+ if (!e_shell_get_online (shell))
return;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
for (iter = e_list_get_iterator((EList *)accounts);e_iterator_is_valid(iter);e_iterator_next(iter)) {
info = g_object_get_data((GObject *)e_iterator_get(iter), "mail-autoreceive");
if (info && info->timeout_id)
@@ -1079,15 +1097,20 @@ auto_online(CamelObject *o, gpointer ed, gpointer d)
/* call to setup initial, and after changes are made to the config */
/* FIXME: Need a cleanup funciton for when object is deactivated */
void
-mail_autoreceive_init (CamelSession *session)
+mail_autoreceive_init (EShellBackend *shell_backend,
+ CamelSession *session)
{
EAccountList *accounts;
EIterator *iter;
+ EShell *shell;
+
+ g_return_if_fail (E_IS_SHELL_BACKEND (shell_backend));
+ g_return_if_fail (CAMEL_IS_SESSION (session));
if (auto_active)
return;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
auto_active = g_hash_table_new(g_str_hash, g_str_equal);
g_signal_connect(accounts, "account-added", G_CALLBACK(auto_account_added), NULL);
@@ -1097,7 +1120,13 @@ mail_autoreceive_init (CamelSession *session)
for (iter = e_list_get_iterator((EList *)accounts);e_iterator_is_valid(iter);e_iterator_next(iter))
auto_account_added(accounts, (EAccount *)e_iterator_get(iter), NULL);
- camel_object_hook_event (session, "online", auto_online, NULL);
+ shell = e_shell_backend_get_shell (shell_backend);
+
+ auto_online (shell);
+
+ g_signal_connect (
+ shell, "notify::online",
+ G_CALLBACK (auto_online), NULL);
}
/* we setup the download info's in a hashtable, if we later need to build the gui, we insert
@@ -1107,7 +1136,7 @@ mail_receive_uri (const gchar *uri, gboolean keep_on_server)
{
struct _send_info *info;
struct _send_data *data;
- CamelFolder *outbox_folder;
+ CamelFolder *local_outbox;
send_info_t type;
data = setup_send_data();
@@ -1152,8 +1181,8 @@ mail_receive_uri (const gchar *uri, gboolean keep_on_server)
break;
case SEND_SEND:
/* todo, store the folder in info? */
- outbox_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
- mail_send_queue (outbox_folder, info->uri,
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ mail_send_queue (local_outbox, info->uri,
FILTER_SOURCE_OUTGOING,
info->cancel,
receive_get_folder, info,
@@ -1171,7 +1200,7 @@ mail_receive_uri (const gchar *uri, gboolean keep_on_server)
void
mail_send (void)
{
- CamelFolder *outbox_folder;
+ CamelFolder *local_outbox;
EAccountService *transport;
struct _send_info *info;
struct _send_data *data;
@@ -1214,8 +1243,8 @@ mail_send (void)
g_hash_table_insert (data->active, (gpointer) SEND_URI_KEY, info);
/* todo, store the folder in info? */
- outbox_folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
- mail_send_queue (outbox_folder, info->uri,
+ local_outbox = e_mail_local_get_folder (E_MAIL_FOLDER_OUTBOX);
+ mail_send_queue (local_outbox, info->uri,
FILTER_SOURCE_OUTGOING,
info->cancel,
receive_get_folder, info,
diff --git a/mail/mail-send-recv.h b/mail/mail-send-recv.h
index a31abe79ed..02be2ce2e0 100644
--- a/mail/mail-send-recv.h
+++ b/mail/mail-send-recv.h
@@ -25,20 +25,22 @@
#include <gtk/gtk.h>
#include <camel/camel-session.h>
+#include <shell/e-shell-backend.h>
G_BEGIN_DECLS
/* send/receive all uri's */
-GtkWidget * mail_send_receive (void);
+GtkWidget * mail_send_receive (GtkWindow *parent);
/* receive a single uri */
-void mail_receive_uri (const gchar *uri,
+void mail_receive_uri (const gchar *uri,
gboolean keep_on_server);
void mail_send (void);
/* setup auto receive stuff */
-void mail_autoreceive_init (CamelSession *session);
+void mail_autoreceive_init (EShellBackend *shell_backend,
+ CamelSession *session);
G_END_DECLS
diff --git a/mail/mail-session.c b/mail/mail-session.c
index 7cc1a7e263..4bd0a5f78d 100644
--- a/mail/mail-session.c
+++ b/mail/mail-session.c
@@ -42,15 +42,16 @@
#include <camel/camel-filter-driver.h>
#include <camel/camel-i18n.h>
+#include "e-util/e-util.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
#include "e-account-combo-box.h"
+#include "shell/e-shell.h"
#include "em-composer-utils.h"
#include "em-filter-context.h"
#include "em-filter-rule.h"
#include "em-utils.h"
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-mt.h"
#include "mail-ops.h"
@@ -82,6 +83,7 @@ typedef struct _MailSessionClass {
} MailSessionClass;
+static EShellBackend *session_shell_backend;
static CamelSessionClass *ms_parent_class;
static gchar *get_password(CamelSession *session, CamelService *service, const gchar *domain, const gchar *prompt, const gchar *item, guint32 flags, CamelException *ex);
@@ -502,13 +504,15 @@ main_get_filter_driver (CamelSession *session, const gchar *type, CamelException
{
CamelFilterDriver *driver;
FilterRule *rule = NULL;
+ const gchar *data_dir;
gchar *user, *system;
GConfClient *gconf;
RuleContext *fc;
gconf = mail_config_get_gconf_client ();
- user = g_strdup_printf ("%s/filters.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = e_shell_backend_get_data_dir (session_shell_backend);
+ user = g_build_filename (data_dir, "filters.xml", NULL);
system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
fc = (RuleContext *) em_filter_context_new ();
rule_context_load (fc, system, user);
@@ -701,12 +705,20 @@ mail_session_check_junk_notify (GConfClient *gconf, guint id, GConfEntry *entry,
}
void
-mail_session_init (const gchar *base_directory)
+mail_session_init (EShellBackend *shell_backend)
{
- gchar *camel_dir;
+ EShell *shell;
GConfClient *gconf;
+ gboolean online;
+ const gchar *data_dir;
- if (camel_init (base_directory, TRUE) != 0)
+ session_shell_backend = shell_backend;
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ online = e_shell_get_online (shell);
+
+ data_dir = e_get_user_data_dir ();
+ if (camel_init (data_dir, TRUE) != 0)
exit (0);
camel_provider_init();
@@ -715,8 +727,8 @@ mail_session_init (const gchar *base_directory)
e_account_combo_box_set_session (session); /* XXX Don't ask... */
e_account_writable(NULL, E_ACCOUNT_SOURCE_SAVE_PASSWD); /* Init the EAccount Setup */
- camel_dir = g_strdup_printf ("%s/mail", base_directory);
- camel_session_construct (session, camel_dir);
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ camel_session_construct (session, data_dir);
gconf = mail_config_get_gconf_client ();
gconf_client_add_dir (gconf, "/apps/evolution/mail/junk", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
@@ -726,10 +738,8 @@ mail_session_init (const gchar *base_directory)
session, NULL, NULL);
session->junk_plugin = NULL;
- /* The shell will tell us to go online. */
- camel_session_set_online ((CamelSession *) session, FALSE);
+ camel_session_set_online ((CamelSession *) session, online);
mail_config_reload_junk_headers ();
- g_free (camel_dir);
}
void
@@ -772,13 +782,6 @@ mail_session_set_interactive (gboolean interactive)
}
void
-mail_session_forget_passwords (BonoboUIComponent *uih, gpointer user_data,
- const gchar *path)
-{
- e_passwords_forget_passwords ();
-}
-
-void
mail_session_flush_filter_log (void)
{
MailSession *ms = (MailSession *) session;
diff --git a/mail/mail-session.h b/mail/mail-session.h
index aa226222d7..b1274403c0 100644
--- a/mail/mail-session.h
+++ b/mail/mail-session.h
@@ -24,12 +24,12 @@
#define MAIL_SESSION_H
#include <glib.h>
-#include <bonobo/bonobo-ui-component.h>
#include <camel/camel-session.h>
+#include <shell/e-shell-backend.h>
G_BEGIN_DECLS
-void mail_session_init (const gchar *base_directory);
+void mail_session_init (EShellBackend *shell_backend);
void mail_session_shutdown (void);
gboolean mail_session_get_interactive (void);
void mail_session_set_interactive (gboolean interactive);
@@ -39,8 +39,6 @@ gboolean mail_session_accept_dialog (const gchar *prompt, const gchar *key,
gboolean async);
gchar *mail_session_get_password (const gchar *url);
void mail_session_add_password (const gchar *url, const gchar *passwd);
-void mail_session_forget_passwords (BonoboUIComponent *uih, gpointer user_data,
- const gchar *path);
void mail_session_remember_password (const gchar *url);
void mail_session_forget_password (const gchar *key);
@@ -56,4 +54,4 @@ extern CamelSession *session;
G_END_DECLS
-#endif /* ! MAIL_SESSION_H */
+#endif /* MAIL_SESSION_H */
diff --git a/mail/mail-signature-editor.c b/mail/mail-signature-editor.c
deleted file mode 100644
index 401f26feed..0000000000
--- a/mail/mail-signature-editor.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * 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:
- * Radek Doulik <rodo@ximian.com>
- * Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include "mail-signature-editor.h"
-
-#include <string.h>
-#include <glib/gi18n.h>
-
-#include <e-util/e-error.h>
-#include <e-util/e-signature-list.h>
-#include <composer/e-msg-composer.h>
-
-#include "mail-config.h"
-
-#define E_SIGNATURE_EDITOR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_SIGNATURE_EDITOR, ESignatureEditorPrivate))
-
-enum {
- PROP_0,
- PROP_SIGNATURE
-};
-
-struct _ESignatureEditorPrivate {
- GtkActionGroup *action_group;
- ESignature *signature;
- GtkWidget *entry;
- gchar *original_name;
-};
-
-static const gchar *ui =
-"<ui>\n"
-" <menubar name='main-menu'>\n"
-" <placeholder name='pre-edit-menu'>\n"
-" <menu action='file-menu'>\n"
-" <menuitem action='save-and-close'/>\n"
-" <separator/>"
-" <menuitem action='close'/>\n"
-" </menu>\n"
-" </placeholder>\n"
-" </menubar>\n"
-" <toolbar name='main-toolbar'>\n"
-" <placeholder name='pre-main-toolbar'>\n"
-" <toolitem action='save-and-close'/>\n"
-" </placeholder>\n"
-" </toolbar>\n"
-"</ui>";
-
-static gpointer parent_class = NULL;
-
-static void
-handle_error (GError **error)
-{
- if (*error != NULL) {
- g_warning ("%s", (*error)->message);
- g_clear_error (error);
- }
-}
-
-static void
-action_close_cb (GtkAction *action,
- ESignatureEditor *editor)
-{
- gboolean something_changed = FALSE;
- const gchar *original_name;
- const gchar *signature_name;
-
- original_name = editor->priv->original_name;
- signature_name = gtk_entry_get_text (GTK_ENTRY (editor->priv->entry));
-
- something_changed |= gtkhtml_editor_has_undo (GTKHTML_EDITOR (editor));
- something_changed |= (strcmp (signature_name, original_name) != 0);
-
- if (something_changed) {
- gint response;
-
- response = e_error_run (
- GTK_WINDOW (editor),
- "mail:ask-signature-changed", NULL);
- if (response == GTK_RESPONSE_YES) {
- GtkActionGroup *action_group;
-
- action_group = editor->priv->action_group;
- action = gtk_action_group_get_action (
- action_group, "save-and-close");
- gtk_action_activate (action);
- return;
- } else if (response == GTK_RESPONSE_CANCEL)
- return;
- }
-
- gtk_widget_destroy (GTK_WIDGET (editor));
-}
-
-static void
-action_save_and_close_cb (GtkAction *action,
- ESignatureEditor *editor)
-{
- GtkWidget *entry;
- ESignatureList *signature_list;
- ESignature *signature;
- ESignature *same_name;
- const gchar *filename;
- gchar *signature_name;
- gboolean html;
- GError *error = NULL;
-
- entry = editor->priv->entry;
- html = gtkhtml_editor_get_html_mode (GTKHTML_EDITOR (editor));
-
- if (editor->priv->signature == NULL)
- signature = mail_config_signature_new (NULL, FALSE, html);
- else {
- signature = g_object_ref (editor->priv->signature);
- signature->html = html;
- }
-
- filename = signature->filename;
- gtkhtml_editor_save (GTKHTML_EDITOR (editor), filename, html, &error);
-
- if (error != NULL) {
- e_error_run (
- GTK_WINDOW (editor),
- "mail:no-save-signature",
- error->message, NULL);
- g_clear_error (&error);
- return;
- }
-
- signature_list = mail_config_get_signatures ();
-
- signature_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
- g_strstrip (signature_name);
-
- /* Make sure the signature name is not blank. */
- if (*signature_name == '\0') {
- e_error_run (
- GTK_WINDOW (editor),
- "mail:blank-signature", NULL);
- gtk_widget_grab_focus (entry);
- g_free (signature_name);
- return;
- }
-
- /* Don't overwrite an existing signature of the same name.
- * XXX ESignatureList misuses const. */
- same_name = (ESignature *) e_signature_list_find (
- signature_list, E_SIGNATURE_FIND_NAME, signature_name);
- if (same_name != NULL && strcmp (signature->uid, same_name->uid) != 0) {
- e_error_run (
- GTK_WINDOW (editor),
- "mail:signature-already-exists",
- signature_name, NULL);
- gtk_widget_grab_focus (entry);
- g_free (signature_name);
- return;
- }
-
- g_free (signature->name);
- signature->name = signature_name;
-
- if (editor->priv->signature != NULL)
- e_signature_list_change (signature_list, signature);
- else
- mail_config_add_signature (signature);
-
- gtk_widget_destroy (GTK_WIDGET (editor));
-}
-
-static GtkActionEntry entries[] = {
-
- { "close",
- GTK_STOCK_CLOSE,
- N_("_Close"),
- "<Control>w",
- NULL,
- G_CALLBACK (action_close_cb) },
-
- { "save-and-close",
- GTK_STOCK_SAVE,
- N_("_Save and Close"),
- "<Control>Return",
- NULL,
- G_CALLBACK (action_save_and_close_cb) },
-
- { "file-menu",
- NULL,
- N_("_File"),
- NULL,
- NULL,
- NULL }
-};
-
-static gboolean
-signature_editor_delete_event_cb (ESignatureEditor *editor,
- GdkEvent *event)
-{
- GtkActionGroup *action_group;
- GtkAction *action;
-
- action_group = editor->priv->action_group;
- action = gtk_action_group_get_action (action_group, "close");
- gtk_action_activate (action);
-
- return TRUE;
-}
-
-static void
-signature_editor_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_SIGNATURE:
- e_signature_editor_set_signature (
- E_SIGNATURE_EDITOR (object),
- g_value_get_object (value));
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-signature_editor_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_SIGNATURE:
- g_value_set_object (
- value, e_signature_editor_get_signature (
- E_SIGNATURE_EDITOR (object)));
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-signature_editor_dispose (GObject *object)
-{
- ESignatureEditorPrivate *priv;
-
- priv = E_SIGNATURE_EDITOR_GET_PRIVATE (object);
-
- if (priv->action_group != NULL) {
- g_object_unref (priv->action_group);
- priv->action_group = NULL;
- }
-
- if (priv->signature != NULL) {
- g_object_unref (priv->signature);
- priv->signature = NULL;
- }
-
- if (priv->entry != NULL) {
- g_object_unref (priv->entry);
- priv->entry = NULL;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
-signature_editor_finalize (GObject *object)
-{
- ESignatureEditorPrivate *priv;
-
- priv = E_SIGNATURE_EDITOR_GET_PRIVATE (object);
-
- g_free (priv->original_name);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-signature_editor_class_init (ESignatureEditorClass *class)
-{
- GObjectClass *object_class;
-
- parent_class = g_type_class_peek_parent (class);
- g_type_class_add_private (class, sizeof (ESignatureEditorPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->set_property = signature_editor_set_property;
- object_class->get_property = signature_editor_get_property;
- object_class->dispose = signature_editor_dispose;
- object_class->finalize = signature_editor_finalize;
-
- g_object_class_install_property (
- object_class,
- PROP_SIGNATURE,
- g_param_spec_object (
- "signature",
- NULL,
- NULL,
- E_TYPE_SIGNATURE,
- G_PARAM_READWRITE));
-}
-
-static void
-signature_editor_init (ESignatureEditor *editor)
-{
- GtkActionGroup *action_group;
- GtkUIManager *ui_manager;
- GtkWidget *container;
- GtkWidget *widget;
- GtkWidget *vbox;
- GError *error = NULL;
-
- editor->priv = E_SIGNATURE_EDITOR_GET_PRIVATE (editor);
- vbox = GTKHTML_EDITOR (editor)->vbox;
-
- ui_manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (editor));
-
- gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
- handle_error (&error);
-
- action_group = gtk_action_group_new ("signature");
- gtk_action_group_set_translation_domain (
- action_group, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (
- action_group, entries,
- G_N_ELEMENTS (entries), editor);
- gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
- editor->priv->action_group = g_object_ref (action_group);
-
- gtk_ui_manager_ensure_update (ui_manager);
-
- gtk_window_set_title (GTK_WINDOW (editor), _("Edit Signature"));
-
- widget = gtk_hbox_new (FALSE, 6);
- gtk_container_set_border_width (GTK_CONTAINER (widget), 6);
- gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
- /* Position 2 should be between the main and style toolbars. */
- gtk_box_reorder_child (GTK_BOX (vbox), widget, 2);
- gtk_widget_show (widget);
- container = widget;
-
- widget = gtk_entry_new ();
- gtk_box_pack_end (GTK_BOX (container), widget, TRUE, TRUE, 0);
- editor->priv->entry = g_object_ref_sink (widget);
- gtk_widget_show (widget);
-
- widget = gtk_label_new_with_mnemonic (_("_Signature Name:"));
- gtk_label_set_mnemonic_widget (GTK_LABEL (widget), editor->priv->entry);
- gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0);
- gtk_widget_show (widget);
-
- g_signal_connect (
- editor, "delete-event",
- G_CALLBACK (signature_editor_delete_event_cb), NULL);
-
- e_signature_editor_set_signature (editor, NULL);
-}
-
-GType
-e_signature_editor_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (ESignatureEditorClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) signature_editor_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (ESignatureEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) signature_editor_init,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- GTKHTML_TYPE_EDITOR, "ESignatureEditor",
- &type_info, 0);
- }
-
- return type;
-}
-
-GtkWidget *
-e_signature_editor_new (void)
-{
- return g_object_new (E_TYPE_SIGNATURE_EDITOR, NULL);
-}
-
-ESignature *
-e_signature_editor_get_signature (ESignatureEditor *editor)
-{
- g_return_val_if_fail (E_IS_SIGNATURE_EDITOR (editor), NULL);
-
- return editor->priv->signature;
-}
-
-void
-e_signature_editor_set_signature (ESignatureEditor *editor,
- ESignature *signature)
-{
- const gchar *filename;
- const gchar *signature_name;
- gchar *contents;
- gsize length;
- GError *error = NULL;
-
- g_return_if_fail (E_IS_SIGNATURE_EDITOR (editor));
-
- if (signature != NULL)
- g_return_if_fail (E_SIGNATURE (signature));
-
- if (editor->priv->signature != NULL) {
- g_object_unref (editor->priv->signature);
- editor->priv->signature = NULL;
- }
-
- if (signature == NULL)
- goto exit;
-
- editor->priv->signature = g_object_ref (signature);
-
- /* Load signature content. */
-
- filename = signature->filename;
-
- if (signature->html)
- g_file_get_contents (filename, &contents, &length, &error);
- else {
- gchar *data;
-
- data = e_msg_composer_get_sig_file_content (filename, FALSE);
- contents = g_strdup_printf ("<PRE>\n%s", data);
- length = -1;
- g_free (data);
- }
-
- if (error == NULL) {
- gtkhtml_editor_set_html_mode (
- GTKHTML_EDITOR (editor), signature->html);
- gtkhtml_editor_set_text_html (
- GTKHTML_EDITOR (editor), contents, length);
- g_free (contents);
- } else {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
-exit:
- if (signature != NULL)
- signature_name = signature->name;
- else
- signature_name = _("Unnamed");
-
- /* Set the entry text before we grab focus. */
- g_free (editor->priv->original_name);
- editor->priv->original_name = g_strdup (signature_name);
- gtk_entry_set_text (GTK_ENTRY (editor->priv->entry), signature_name);
-
- /* Set the focus appropriately. If this is a new signature, draw
- * the user's attention to the signature name entry. Otherwise go
- * straight to the editing area. */
- if (signature == NULL)
- gtk_widget_grab_focus (editor->priv->entry);
- else {
- GtkHTML *html;
-
- html = gtkhtml_editor_get_html (GTKHTML_EDITOR (editor));
- gtk_widget_grab_focus (GTK_WIDGET (html));
- }
-
- g_object_notify (G_OBJECT (editor), "signature");
-}
diff --git a/mail/mail-signature-editor.h b/mail/mail-signature-editor.h
deleted file mode 100644
index 82c786c90e..0000000000
--- a/mail/mail-signature-editor.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *
- * 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:
- * Radek Doulik <rodo@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef MAIL_SIGNATURE_EDITOR_H
-#define MAIL_SIGNATURE_EDITOR_H
-
-#include <gtkhtml-editor.h>
-#include <e-util/e-signature.h>
-
-/* Standard GObject macros */
-#define E_TYPE_SIGNATURE_EDITOR \
- (e_signature_editor_get_type ())
-#define E_SIGNATURE_EDITOR(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_SIGNATURE_EDITOR, ESignatureEditor))
-#define E_SIGNATURE_EDITOR_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_SIGNATURE_EDITOR, ESignatureEditorClass))
-#define E_IS_SIGNATURE_EDITOR(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_SIGNATURE_EDITOR))
-#define E_IS_SIGNATURE_EDITOR_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_SIGNATURE_EDITOR))
-#define E_SIGNATURE_EDITOR_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_SIGNATURE_EDITOR, ESignatureEditorClass))
-
-G_BEGIN_DECLS
-
-typedef struct _ESignatureEditor ESignatureEditor;
-typedef struct _ESignatureEditorClass ESignatureEditorClass;
-typedef struct _ESignatureEditorPrivate ESignatureEditorPrivate;
-
-struct _ESignatureEditor {
- GtkhtmlEditor parent;
- ESignatureEditorPrivate *priv;
-};
-
-struct _ESignatureEditorClass {
- GtkhtmlEditorClass parent_class;
-};
-
-GType e_signature_editor_get_type (void);
-GtkWidget * e_signature_editor_new (void);
-ESignature * e_signature_editor_get_signature (ESignatureEditor *editor);
-void e_signature_editor_set_signature (ESignatureEditor *editor,
- ESignature *signature);
-
-G_END_DECLS
-
-#endif /* MAIL_SIGNATURE_EDITOR_H */
diff --git a/mail/mail-tools.c b/mail/mail-tools.c
index d83aace1ea..a19c3dedb4 100644
--- a/mail/mail-tools.c
+++ b/mail/mail-tools.c
@@ -51,7 +51,6 @@
#include "em-utils.h"
#include "em-vfolder-context.h"
#include "em-vfolder-rule.h"
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-folder-cache.h"
#include "mail-mt.h"
@@ -107,6 +106,7 @@ static gchar *
mail_tool_get_local_movemail_path (const guchar *uri, CamelException *ex)
{
guchar *safe_uri, *c;
+ const gchar *data_dir;
gchar *path, *full;
struct stat st;
@@ -115,7 +115,9 @@ mail_tool_get_local_movemail_path (const guchar *uri, CamelException *ex)
if (strchr("/:;=|%&#!*^()\\, ", *c) || !isprint((gint) *c))
*c = '_';
- path = g_strdup_printf("%s/spool", mail_component_peek_base_directory(NULL));
+ data_dir = em_utils_get_data_dir ();
+ path = g_build_filename (data_dir, "spool", NULL);
+
if (g_stat(path, &st) == -1 && g_mkdir_with_parents(path, 0777) == -1) {
camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Could not create spool directory `%s': %s"),
path, g_strerror(errno));
diff --git a/mail/mail-types.h b/mail/mail-types.h
deleted file mode 100644
index 5d2ef80ef2..0000000000
--- a/mail/mail-types.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *
- * 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)
- *
- */
-
-#ifndef MAIL_TYPES_H
-#define MAIL_TYPES_H 1
-
-G_BEGIN_DECLS
-
-typedef struct _FolderBrowser FolderBrowser;
-typedef struct _MessageBrowser MessageBrowser;
-typedef struct _SubscribeDialog SubscribeDialog;
-typedef struct _MessageList MessageList;
-typedef struct _MailDisplay MailDisplay;
-
-G_END_DECLS
-
-#endif /* MAIL_TYPES_H */
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index 0f49f32cae..96d60ab5f0 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -31,10 +31,11 @@
#include <camel/camel-vee-folder.h>
#include <camel/camel-vee-store.h>
#include <camel/camel-vtrash-folder.h>
+#include <libedataserver/e-account-list.h>
-#include "libedataserver/e-account-list.h"
#include "e-util/e-error.h"
#include "e-util/e-util-private.h"
+#include "e-util/e-account-utils.h"
#include "em-folder-tree-model.h"
#include "em-utils.h"
@@ -42,7 +43,6 @@
#include "em-vfolder-editor.h"
#include "em-vfolder-rule.h"
#include "mail-autofilter.h"
-#include "mail-component.h"
#include "mail-config.h"
#include "mail-folder-cache.h"
#include "mail-mt.h"
@@ -50,6 +50,9 @@
#include "mail-tools.h"
#include "mail-vfolder.h"
+#include "e-mail-local.h"
+#include "e-mail-store.h"
+
#define d(x) /* (printf("%s:%s: ", G_STRLOC, G_STRFUNC), (x))*/
static EMVFolderContext *context; /* context remains open all time */
@@ -224,7 +227,7 @@ vfolder_adduri_desc (struct _adduri_msg *m)
else
uid = g_strdup_printf("%s@%s", url->user, url->host);
- account = e_account_list_find(mail_config_get_accounts(), E_ACCOUNT_FIND_UID, uid);
+ account = e_get_account_by_uid (uid);
g_free(uid);
if (account != NULL)
loc = account->name;
@@ -336,21 +339,28 @@ uri_is_ignore(CamelStore *store, const gchar *uri)
EAccountList *accounts;
EAccount *account;
EIterator *iter;
+ const gchar *local_drafts_uri;
+ const gchar *local_outbox_uri;
+ const gchar *local_sent_uri;
gint found = FALSE;
+ local_drafts_uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_DRAFTS);
+ local_outbox_uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_OUTBOX);
+ local_sent_uri = e_mail_local_get_folder_uri (E_MAIL_FOLDER_SENT);
+
d(printf("checking '%s' against:\n %s\n %s\n %s\n", uri,
- mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_OUTBOX),
- mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_SENT),
- mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS)));
+ local_outbox_uri,
+ local_sent_uri,
+ local_drafts_uri));
- found = camel_store_folder_uri_equal(store, mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_OUTBOX), uri)
- || camel_store_folder_uri_equal(store, mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_SENT), uri)
- || camel_store_folder_uri_equal(store, mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS), uri);
+ found = camel_store_folder_uri_equal(store, local_outbox_uri, uri)
+ || camel_store_folder_uri_equal(store, local_sent_uri, uri)
+ || camel_store_folder_uri_equal(store, local_drafts_uri, uri);
if (found)
return found;
- accounts = mail_config_get_accounts ();
+ accounts = e_get_account_list ();
iter = e_list_get_iterator ((EList *) accounts);
while (e_iterator_is_valid (iter)) {
gchar *curi;
@@ -591,13 +601,14 @@ done:
if (changed->str[0]) {
GtkWidget *dialog;
+ const gchar *data_dir;
gchar *user;
dialog = e_error_new(NULL, "mail:vfolder-updated", changed->str, uri, NULL);
em_utils_show_info_silent (dialog);
- user = g_strdup_printf ("%s/vfolders.xml",
- mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save ((RuleContext *) context, user);
g_free (user);
}
@@ -660,10 +671,12 @@ mail_vfolder_rename_uri(CamelStore *store, const gchar *cfrom, const gchar *cto)
UNLOCK();
if (changed) {
+ const gchar *data_dir;
gchar *user;
d(printf("Vfolders updated from renamed folder\n"));
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save((RuleContext *)context, user);
g_free(user);
}
@@ -784,21 +797,12 @@ static void context_rule_added(RuleContext *ctx, FilterRule *rule)
static void context_rule_removed(RuleContext *ctx, FilterRule *rule)
{
- gchar *path;
-
gpointer key, folder = NULL;
d(printf("rule removed; %s\n", rule->name));
/* TODO: remove from folder info cache? */
- /* FIXME: is this even necessary? if we remove the folder from
- * the CamelStore, the tree should pick it up auto-magically
- * because it listens to CamelStore events... */
- path = g_strdup_printf("/%s", rule->name);
- mail_component_remove_folder (mail_component_peek (), vfolder_store, path);
- g_free(path);
-
LOCK();
if (g_hash_table_lookup_extended (vfolder_hash, rule->name, &key, &folder)) {
g_hash_table_remove (vfolder_hash, key);
@@ -840,6 +844,8 @@ store_folder_deleted(CamelObject *o, gpointer event_data, gpointer data)
/* delete it from our list */
rule = rule_context_find_rule((RuleContext *)context, info->full_name, NULL);
if (rule) {
+ const gchar *data_dir;
+
/* We need to stop listening to removed events, otherwise we'll try and remove it again */
g_signal_handlers_disconnect_matched(context, G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA, 0,
0, NULL, context_rule_removed, context);
@@ -847,7 +853,8 @@ store_folder_deleted(CamelObject *o, gpointer event_data, gpointer data)
g_object_unref(rule);
g_signal_connect(context, "rule_removed", G_CALLBACK(context_rule_removed), context);
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save((RuleContext *)context, user);
g_free(user);
} else {
@@ -874,6 +881,8 @@ store_folder_renamed(CamelObject *o, gpointer event_data, gpointer data)
LOCK();
d(printf("Changing folder name in hash table to '%s'\n", info->new->full_name));
if (g_hash_table_lookup_extended (vfolder_hash, info->old_base, &key, &folder)) {
+ const gchar *data_dir;
+
g_hash_table_remove (vfolder_hash, key);
g_free (key);
g_hash_table_insert (vfolder_hash, g_strdup(info->new->full_name), folder);
@@ -890,7 +899,8 @@ store_folder_renamed(CamelObject *o, gpointer event_data, gpointer data)
filter_rule_set_name(rule, info->new->full_name);
g_signal_connect(rule, "changed", G_CALLBACK(rule_changed), folder);
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save((RuleContext *)context, user);
g_free(user);
@@ -907,6 +917,7 @@ vfolder_load_storage(void)
/* lock for loading storage, it is safe to call it more than once */
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+ const gchar *data_dir;
gchar *user, *storeuri;
FilterRule *rule;
gchar *xmlfile;
@@ -925,7 +936,8 @@ vfolder_load_storage(void)
pthread_mutex_unlock (&lock);
/* first, create the vfolder store, and set it up */
- storeuri = g_strdup_printf("vfolder:%s/vfolder", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ storeuri = g_strdup_printf("vfolder:%s/vfolder", data_dir);
vfolder_store = camel_session_get_store(session, storeuri, NULL);
if (vfolder_store == NULL) {
g_warning("Cannot open vfolder store - no vfolders available");
@@ -942,7 +954,7 @@ vfolder_load_storage(void)
d(printf("got store '%s' = %p\n", storeuri, vfolder_store));
/* load our rules */
- user = g_strdup_printf ("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
context = em_vfolder_context_new ();
xmlfile = g_build_filename (EVOLUTION_PRIVDATADIR, "vfoldertypes.xml", NULL);
@@ -957,7 +969,7 @@ vfolder_load_storage(void)
g_signal_connect(context, "rule_removed", G_CALLBACK(context_rule_removed), context);
/* load store to mail component */
- mail_component_load_store_by_uri (mail_component_peek (), storeuri, _("Search Folders"));
+ e_mail_store_add_by_uri (storeuri, _("Search Folders"));
/* and setup the rules we have */
rule = NULL;
@@ -981,66 +993,66 @@ vfolder_load_storage(void)
void
vfolder_revert(void)
{
+ const gchar *data_dir;
gchar *user;
d(printf("vfolder_revert\n"));
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_revert((RuleContext *)context, user);
g_free(user);
}
-static GtkWidget *vfolder_editor = NULL;
-
-static void
-em_vfolder_editor_response (GtkWidget *dialog, gint button, gpointer data)
+void
+vfolder_edit (EShellView *shell_view)
{
- gchar *user;
+ EShellBackend *shell_backend;
+ EShellWindow *shell_window;
+ GtkWidget *dialog;
+ const gchar *data_dir;
+ gchar *filename;
- user = g_strdup_printf ("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
-
- switch(button) {
- case GTK_RESPONSE_OK:
- rule_context_save((RuleContext *)context, user);
- break;
- default:
- rule_context_revert((RuleContext *)context, user);
- }
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
- vfolder_editor = NULL;
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
- gtk_widget_destroy(dialog);
-
- g_free (user);
-}
-
-void
-vfolder_edit (void)
-{
- if (vfolder_editor) {
- gdk_window_raise (GTK_WIDGET (vfolder_editor)->window);
- return;
- }
+ data_dir = e_shell_backend_get_data_dir (shell_backend);
+ filename = g_build_filename (data_dir, "vfolders.xml", NULL);
/* ensures vfolder is running */
vfolder_load_storage ();
- vfolder_editor = GTK_WIDGET (em_vfolder_editor_new (context));
- gtk_window_set_title (GTK_WINDOW (vfolder_editor), _("Search Folders"));
- g_signal_connect(vfolder_editor, "response", G_CALLBACK(em_vfolder_editor_response), NULL);
+ dialog = em_vfolder_editor_new (context);
+ gtk_window_set_title (
+ GTK_WINDOW (dialog), _("Search Folders"));
+ gtk_window_set_transient_for (
+ GTK_WINDOW (dialog), GTK_WINDOW (shell_window));
+
+ switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
+ case GTK_RESPONSE_OK:
+ rule_context_save ((RuleContext *) context, filename);
+ break;
+ default:
+ rule_context_revert ((RuleContext *) context, filename);
+ break;
+ }
- gtk_widget_show (vfolder_editor);
+ gtk_widget_destroy (dialog);
}
static void
edit_rule_response(GtkWidget *w, gint button, gpointer data)
{
if (button == GTK_RESPONSE_OK) {
+ const gchar *data_dir;
gchar *user;
FilterRule *rule = g_object_get_data (G_OBJECT (w), "rule");
FilterRule *orig = g_object_get_data (G_OBJECT (w), "orig");
filter_rule_copy(orig, rule);
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save((RuleContext *)context, user);
g_free(user);
}
@@ -1097,6 +1109,7 @@ static void
new_rule_clicked(GtkWidget *w, gint button, gpointer data)
{
if (button == GTK_RESPONSE_OK) {
+ const gchar *data_dir;
gchar *user;
FilterRule *rule = g_object_get_data((GObject *)w, "rule");
@@ -1112,7 +1125,8 @@ new_rule_clicked(GtkWidget *w, gint button, gpointer data)
g_object_ref(rule);
rule_context_add_rule((RuleContext *)context, rule);
- user = g_strdup_printf("%s/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ()));
+ data_dir = em_utils_get_data_dir ();
+ user = g_build_filename (data_dir, "vfolders.xml", NULL);
rule_context_save((RuleContext *)context, user);
g_free(user);
}
diff --git a/mail/mail-vfolder.h b/mail/mail-vfolder.h
index 79374348ae..b3299ab834 100644
--- a/mail/mail-vfolder.h
+++ b/mail/mail-vfolder.h
@@ -28,11 +28,12 @@
#include <filter/filter-part.h>
#include <filter/filter-rule.h>
#include <mail/em-vfolder-rule.h>
+#include <shell/e-shell-view.h>
void vfolder_load_storage(void);
void vfolder_revert(void);
-void vfolder_edit (void);
+void vfolder_edit (EShellView *shell_view);
void vfolder_edit_rule(const gchar *name);
FilterPart *vfolder_create_part (const gchar *name);
FilterRule *vfolder_clone_rule (FilterRule *in);
diff --git a/mail/message-list.c b/mail/message-list.c
index b222de4bb1..d3db1f37ba 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -50,10 +50,12 @@
#include "e-util/e-profile-event.h"
#include "e-util/e-util-private.h"
#include "e-util/e-util.h"
-#include "e-util/e-util-labels.h"
#include "misc/e-gui-utils.h"
+#include "shell/e-shell.h"
+#include "shell/e-shell-settings.h"
+
#include "table/e-cell-checkbox.h"
#include "table/e-cell-hbox.h"
#include "table/e-cell-date.h"
@@ -67,6 +69,7 @@
#include "table/e-cell-vbox.h"
#include "table/e-cell-hbox.h"
+#include "e-mail-label-list-store.h"
#include "em-popup.h"
#include "em-utils.h"
#include "mail-config.h"
@@ -97,6 +100,10 @@
#define d(x)
#define t(x)
+#define MESSAGE_LIST_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), MESSAGE_LIST_TYPE, MessageListPrivate))
+
struct _MLSelection {
GPtrArray *uids;
CamelFolder *folder;
@@ -106,6 +113,8 @@ struct _MLSelection {
struct _MessageListPrivate {
GtkWidget *invisible; /* 4 selection */
+ EShellBackend *shell_backend;
+
struct _MLSelection clipboard;
gboolean destroyed;
@@ -113,6 +122,11 @@ struct _MessageListPrivate {
gboolean any_row_changed; /* save state before regen list when this is set to true */
};
+enum {
+ PROP_0,
+ PROP_SHELL_BACKEND
+};
+
static struct {
const gchar *target;
GdkAtom atom;
@@ -808,7 +822,7 @@ message_list_invert_selection (MessageList *message_list)
void
message_list_copy(MessageList *ml, gboolean cut)
{
- struct _MessageListPrivate *p = ml->priv;
+ MessageListPrivate *p = ml->priv;
GPtrArray *uids;
clear_selection(ml, &p->clipboard);
@@ -1220,53 +1234,124 @@ sanitize_recipients (const gchar *string)
}
static gint
-get_all_labels (CamelMessageInfo *msg_info, gchar **label_str, gboolean get_tags)
-{
+get_all_labels (MessageList *message_list,
+ CamelMessageInfo *msg_info,
+ gchar **label_str,
+ gboolean get_tags)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EMailLabelListStore *store;
+ GtkTreeIter iter;
GString *str;
+ const gchar *property_name;
const gchar *old_label;
+ gchar *new_label;
gint count = 0;
const CamelFlag *flag;
- GSList *labels;
- labels = mail_config_get_labels ();
+ shell_backend = message_list_get_shell_backend (message_list);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ property_name = "mail-label-list-store";
+ store = e_shell_settings_get_object (shell_settings, property_name);
+
str = g_string_new ("");
for (flag = camel_message_info_user_flags (msg_info); flag; flag = flag->next) {
- const gchar *name = e_util_labels_get_name (labels, flag->name);
+ gchar *item;
- if (name) {
- if (str->len)
- g_string_append (str, ", ");
+ if (!e_mail_label_list_store_lookup (store, flag->name, &iter))
+ continue;
- if (get_tags)
- name = flag->name;
+ if (get_tags)
+ item = e_mail_label_list_store_get_tag (store, &iter);
+ else
+ item = e_mail_label_list_store_get_name (store, &iter);
- g_string_append (str, name);
- count++;
- }
+ if (str->len)
+ g_string_append (str, ", ");
+
+ g_string_append (str, item);
+ count++;
+
+ g_free (item);
}
- old_label = e_util_labels_get_new_tag (camel_message_info_user_tag (msg_info, "label"));
+ old_label = camel_message_info_user_tag (msg_info, "label");
+ if (old_label == NULL)
+ goto exit;
- if (old_label != NULL) {
- const gchar *name = NULL;
+ /* Convert old-style labels ("<name>") to "$Label<name>". */
+ new_label = g_alloca (strlen (old_label) + 10);
+ g_stpcpy (g_stpcpy (new_label, "$Label"), old_label);
+
+ if (e_mail_label_list_store_lookup (store, new_label, &iter)) {
+ gchar *name = NULL;
if (str->len)
g_string_append (str, ", ");
if (!get_tags)
- name = e_util_labels_get_name (labels, old_label);
+ name = e_mail_label_list_store_get_name (store, &iter);
g_string_append (str, (get_tags || !name) ? old_label : name);
- ++count;
+ count++;
+
+ g_free (name);
}
+exit:
*label_str = g_string_free (str, FALSE);
+ g_object_unref (store);
+
return count;
}
static const gchar *
+get_label_color (MessageList *message_list,
+ const gchar *tag)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellSettings *shell_settings;
+ EMailLabelListStore *store;
+ GtkTreeIter iter;
+ GdkColor color;
+ const gchar *property_name;
+ const gchar *interned = NULL;
+ gchar *color_spec;
+
+ /* FIXME get_all_labels() should return an array of tree iterators,
+ * not strings. Now we just have to lookup the tag again. */
+
+ shell_backend = message_list_get_shell_backend (message_list);
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ property_name = "mail-label-list-store";
+ store = e_shell_settings_get_object (shell_settings, property_name);
+
+ if (!e_mail_label_list_store_lookup (store, tag, &iter))
+ goto exit;
+
+ e_mail_label_list_store_get_color (store, &iter, &color);
+
+ /* XXX Hack to avoid returning an allocated string. */
+ color_spec = gdk_color_to_string (&color);
+ interned = g_intern_string (color_spec);
+ g_free (color_spec);
+
+exit:
+ g_object_unref (store);
+
+ return interned;
+}
+
+static const gchar *
get_trimmed_subject (CamelMessageInfo *info)
{
const gchar *subject;
@@ -1467,9 +1552,8 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, gint col, gpointer model_data
completed = camel_message_info_user_tag(msg_info, "completed-on");
followup = camel_message_info_user_tag(msg_info, "follow-up");
if (colour == NULL) {
- if ((n = get_all_labels (msg_info, &labels_string, TRUE)) == 1) {
-
- colour = e_util_labels_get_color_str (mail_config_get_labels (), labels_string);
+ if ((n = get_all_labels (message_list, msg_info, &labels_string, TRUE)) == 1) {
+ colour = get_label_color (message_list, labels_string);
} else if (camel_message_info_flags(msg_info) & CAMEL_MESSAGE_FLAGGED) {
/* FIXME: extract from the important.xpm somehow. */
colour = "#A7453E";
@@ -1548,7 +1632,7 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, gint col, gpointer model_data
cleansed_str = g_string_new ("");
- if (get_all_labels (msg_info, &str, FALSE)) {
+ if (get_all_labels (message_list, msg_info, &str, FALSE)) {
gint i;
for (i = 0; str[i] != '\0'; ++i) {
if (str[i] != '_') {
@@ -1944,7 +2028,7 @@ ml_selection_get(GtkWidget *widget, GtkSelectionData *data, guint info, guint ti
static gboolean
ml_selection_clear_event(GtkWidget *widget, GdkEventSelection *event, MessageList *ml)
{
- struct _MessageListPrivate *p = ml->priv;
+ MessageListPrivate *p = ml->priv;
clear_selection(ml, &p->clipboard);
@@ -2239,13 +2323,25 @@ on_model_row_changed (ETableModel *model, gint row, MessageList *ml)
/*
* GObject::init
*/
+
+static void
+message_list_set_shell_backend (MessageList *message_list,
+ EShellBackend *shell_backend)
+{
+ g_return_if_fail (message_list->priv->shell_backend == NULL);
+
+ message_list->priv->shell_backend = g_object_ref (shell_backend);
+}
+
static void
message_list_init (MessageList *message_list)
{
- struct _MessageListPrivate *p;
+ MessageListPrivate *p;
GtkAdjustment *adjustment;
GdkAtom matom;
+ message_list->priv = MESSAGE_LIST_GET_PRIVATE (message_list);
+
adjustment = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, G_MAXDOUBLE, 0.0, 0.0, 0.0);
gtk_scrolled_window_set_vadjustment ((GtkScrolledWindow *) message_list, adjustment);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (message_list), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
@@ -2274,7 +2370,7 @@ message_list_init (MessageList *message_list)
message_list->regen_lock = g_mutex_new ();
/* TODO: Should this only get the selection if we're realised? */
- p = message_list->priv = g_malloc0(sizeof(*message_list->priv));
+ p = message_list->priv;
p->invisible = gtk_invisible_new();
p->destroyed = FALSE;
g_object_ref_sink(p->invisible);
@@ -2295,7 +2391,7 @@ static void
message_list_destroy(GtkObject *object)
{
MessageList *message_list = MESSAGE_LIST (object);
- struct _MessageListPrivate *p = message_list->priv;
+ MessageListPrivate *p = message_list->priv;
p->destroyed = TRUE;
@@ -2347,14 +2443,65 @@ message_list_destroy(GtkObject *object)
message_list->seen_id = 0;
}
+ /* Chain up to parent's destroy() method. */
GTK_OBJECT_CLASS (message_list_parent_class)->destroy(object);
}
static void
-message_list_finalise (GObject *object)
+message_list_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_BACKEND:
+ message_list_set_shell_backend (
+ MESSAGE_LIST (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+message_list_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_BACKEND:
+ g_value_set_object (
+ value, message_list_get_shell_backend (
+ MESSAGE_LIST (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+message_list_dispose (GObject *object)
+{
+ MessageListPrivate *priv;
+
+ priv = MESSAGE_LIST_GET_PRIVATE (object);
+
+ if (priv->shell_backend != NULL) {
+ g_object_unref (priv->shell_backend);
+ priv->shell_backend = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (message_list_parent_class)->dispose (object);
+}
+
+static void
+message_list_finalize (GObject *object)
{
MessageList *message_list = MESSAGE_LIST (object);
- struct _MessageListPrivate *p = message_list->priv;
+ MessageListPrivate *priv = message_list->priv;
g_hash_table_destroy (message_list->normalised_hash);
@@ -2384,10 +2531,9 @@ message_list_finalise (GObject *object)
g_free(message_list->folder_uri);
message_list->folder_uri = NULL;
- clear_selection(message_list, &p->clipboard);
-
- g_free(p);
+ clear_selection(message_list, &priv->clipboard);
+ /* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (message_list_parent_class)->finalize (object);
}
@@ -2395,17 +2541,36 @@ message_list_finalise (GObject *object)
* GObjectClass::init
*/
static void
-message_list_class_init (MessageListClass *message_list_class)
+message_list_class_init (MessageListClass *class)
{
- GObjectClass *object_class = (GObjectClass *) message_list_class;
- GtkObjectClass *gtkobject_class = (GtkObjectClass *) message_list_class;
+ GObjectClass *object_class;
+ GtkObjectClass *gtk_object_class;
gint i;
for (i=0;i<sizeof(ml_drag_info)/sizeof(ml_drag_info[0]);i++)
ml_drag_info[i].atom = gdk_atom_intern(ml_drag_info[i].target, FALSE);
- object_class->finalize = message_list_finalise;
- gtkobject_class->destroy = message_list_destroy;
+ g_type_class_add_private (class, sizeof (MessageListPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = message_list_set_property;
+ object_class->get_property = message_list_get_property;
+ object_class->dispose = message_list_dispose;
+ object_class->finalize = message_list_finalize;
+
+ gtk_object_class = GTK_OBJECT_CLASS (class);
+ gtk_object_class->destroy = message_list_destroy;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_BACKEND,
+ g_param_spec_object (
+ "shell-backend",
+ _("Shell Backend"),
+ _("The mail shell backend"),
+ E_TYPE_SHELL_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
message_list_signals[MESSAGE_SELECTED] =
g_signal_new ("message_selected",
@@ -2557,19 +2722,30 @@ message_list_construct (MessageList *message_list)
* Returns a new message-list widget.
**/
GtkWidget *
-message_list_new (void)
+message_list_new (EShellBackend *shell_backend)
{
MessageList *message_list;
+ g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), NULL);
+
message_list = MESSAGE_LIST (g_object_new(message_list_get_type (),
"hadjustment", NULL,
"vadjustment", NULL,
+ "shell-backend", shell_backend,
NULL));
message_list_construct (message_list);
return GTK_WIDGET (message_list);
}
+EShellBackend *
+message_list_get_shell_backend (MessageList *message_list)
+{
+ g_return_val_if_fail (IS_MESSAGE_LIST (message_list), NULL);
+
+ return message_list->priv->shell_backend;
+}
+
static void
clear_info(gchar *key, ETreePath *node, MessageList *ml)
{
@@ -4063,9 +4239,8 @@ regen_list_exec (struct _regen_list_msg *m)
if ((!is_deleted || (is_deleted && !m->hidedel)) && (!is_junk || (is_junk && !m->hidejunk)))
g_ptr_array_add (uids, (gpointer) camel_pstring_strdup (looking_for));
-
- camel_folder_free_message_info (m->folder, looking_info);
}
+
}
}
}
diff --git a/mail/message-list.h b/mail/message-list.h
index 259ec501dd..075c20afe3 100644
--- a/mail/message-list.h
+++ b/mail/message-list.h
@@ -29,6 +29,9 @@
#include <table/e-table-simple.h>
#include <table/e-tree-scrolled.h>
+#include <camel/camel-folder.h>
+#include <shell/e-shell-backend.h>
+
G_BEGIN_DECLS
#define MESSAGE_LIST_TYPE (message_list_get_type ())
@@ -83,11 +86,13 @@ enum {
#define ML_HIDE_SAME (2147483646)
typedef struct _MessageList MessageList;
+typedef struct _MessageListClass MessageListClass;
+typedef struct _MessageListPrivate MessageListPrivate;
struct _MessageList {
ETreeScrolled parent;
- struct _MessageListPrivate *priv;
+ MessageListPrivate *priv;
/* The table */
ETreeModel *model;
@@ -163,14 +168,14 @@ struct _MessageList {
struct _MailAsyncEvent *async_event;
};
-typedef struct {
+struct _MessageListClass {
ETreeScrolledClass parent_class;
/* signals - select a message */
void (*message_selected) (MessageList *ml, const gchar *uid);
void (*message_list_built) (MessageList *ml);
void (*message_list_scrolled) (MessageList *ml);
-} MessageListClass;
+};
typedef enum {
MESSAGE_LIST_SELECT_NEXT = 0,
@@ -180,7 +185,8 @@ typedef enum {
} MessageListSelectDirection;
GType message_list_get_type (void);
-GtkWidget *message_list_new (void);
+GtkWidget *message_list_new (EShellBackend *shell_backend);
+EShellBackend *message_list_get_shell_backend (MessageList *message_list);
void message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder, const gchar *uri, gboolean outgoing);
void message_list_freeze(MessageList *ml);
diff --git a/mail/message-tag-followup.c b/mail/message-tag-followup.c
index 9293205fb3..6ccd74459a 100644
--- a/mail/message-tag-followup.c
+++ b/mail/message-tag-followup.c
@@ -288,6 +288,11 @@ construct (MessageTagEditor *editor)
gtk_widget_reparent (widget, GTK_DIALOG (editor)->vbox);
gtk_box_set_child_packing (GTK_BOX (GTK_DIALOG (editor)->vbox), widget, TRUE, TRUE, 6, GTK_PACK_START);
+ widget = glade_xml_get_widget (gui, "pixmap");
+ gtk_image_set_from_icon_name (
+ GTK_IMAGE (widget), "stock_mail-flag-for-followup",
+ GTK_ICON_SIZE_DIALOG);
+
followup->message_list = GTK_TREE_VIEW (glade_xml_get_widget (gui, "message_list"));
model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
gtk_tree_view_set_model (followup->message_list, (GtkTreeModel *) model);
diff --git a/mail/searchtypes.xml b/mail/searchtypes.xml
index 63a52ca772..ba349993f7 100644
--- a/mail/searchtypes.xml
+++ b/mail/searchtypes.xml
@@ -329,7 +329,7 @@
</code>
</option>
</input>
- <input type="string" name="recipient"/>
+ <input type="address" name="recipient"/>
</part>
<part name="subject">
@@ -569,7 +569,7 @@
</option>
</input>
<input type="optionlist" name="versus">
- <dynamic func="e_util_labels_get_filter_options"/>
+ <dynamic func="e_mail_labels_get_filter_options"/>
</input>
</part>
@@ -764,29 +764,18 @@
</partset>
<ruleset>
+
<rule grouping="any" source="demand">
- <_title>Subject or Addresses contains</_title>
+ <_title>Subject or Sender contains</_title>
<partset>
<part name="subject">
<value name="subject-type" type="option" value="contains"/>
<value name="subject" type="string"/>
- </part>
+ </part>
<part name="sender">
<value name="sender-type" type="option" value="contains"/>
<value name="sender" type="string"/>
</part>
- <part name="to">
- <value name="recipient-type" type="option" value="contains"/>
- <value name="recipient" type="address"/>
- </part>
- <part name="to">
- <value name="recipient-type" type="option" value="contains"/>
- <value name="recipient" type="address"/>
- </part>
- <part name="to">
- <value name="recipient-type" type="option" value="contains"/>
- <value name="recipient" type="address"/>
- </part>
</partset>
<sources/>
</rule>
@@ -807,21 +796,6 @@
</rule>
<rule grouping="any" source="demand">
- <_title>Subject or Sender contains</_title>
- <partset>
- <part name="subject">
- <value name="subject-type" type="option" value="contains"/>
- <value name="subject" type="string"/>
- </part>
- <part name="sender">
- <value name="sender-type" type="option" value="contains"/>
- <value name="sender" type="string"/>
- </part>
- </partset>
- <sources/>
- </rule>
-
- <rule grouping="any" source="demand">
<_title>Recipients contain</_title>
<partset>
<part name="to">
diff --git a/mail/vfoldertypes.xml b/mail/vfoldertypes.xml
index 11ed7cc0af..9fd117b67d 100644
--- a/mail/vfoldertypes.xml
+++ b/mail/vfoldertypes.xml
@@ -569,7 +569,7 @@
</option>
</input>
<input type="optionlist" name="versus">
- <dynamic func="e_util_labels_get_filter_options"/>
+ <dynamic func="e_mail_labels_get_filter_options"/>
</input>
</part>