[evolution/kill-bonobo: 55/55] Merge commit 'EVOLUTION_2_27_5' into kill-bonobo
- From: Matthew Barnes <mbarnes src gnome org>
- To: svn-commits-list gnome org
- Subject: [evolution/kill-bonobo: 55/55] Merge commit 'EVOLUTION_2_27_5' into kill-bonobo
- Date: Tue, 28 Jul 2009 15:25:15 +0000 (UTC)
commit 2c4510e858fcf96e8f3d02f3f92564460752e983
Merge: 3fe8269... 067ef55...
Author: Matthew Barnes <mbarnes redhat com>
Date: Mon Jul 27 22:31:47 2009 -0400
Merge commit 'EVOLUTION_2_27_5' into kill-bonobo
NEWS | 135 +
addressbook/gui/contact-editor/e-contact-editor.c | 2 +-
addressbook/gui/widgets/eab-gui-util.c | 3 +-
calendar/gui/e-cal-event.c | 5 +-
calendar/gui/e-cal-event.h | 4 +-
calendar/gui/e-calendar-view.c | 4 +-
calendar/gui/e-day-view-time-item.c | 4 +-
composer/e-composer-from-header.c | 10 +
composer/e-composer-from-header.h | 3 +
composer/e-composer-header-table.c | 71 +-
composer/e-composer-header.c | 11 +-
composer/e-composer-private.c | 4 +
composer/e-composer-private.h | 1 +
configure.ac | 5 +-
help/de/de.po | 3481 ++++----
mail/e-mail-reader.c | 2 +-
mail/em-account-editor.c | 7 +-
mail/em-account-editor.h | 2 +-
mail/em-composer-utils.c | 35 +-
mail/em-composer-utils.h | 2 +-
mail/em-event.c | 7 +-
mail/em-event.h | 7 +-
mail/em-folder-browser.c | 29 +-
mail/em-folder-view.c | 2 +-
mail/em-format-html-print.c | 6 +
mail/em-sync-stream.c | 9 +-
mail/em-sync-stream.h | 1 +
mail/mail-component.c | 5 +-
mail/mail-component.h | 1 +
mail/mail-mt.c | 3 +-
mail/mail-send-recv.c | 10 +-
mail/mail-send-recv.h | 2 +-
mail/message-list.c | 2 +
modules/calendar/e-cal-shell-migrate.c | 2 +-
plugins/calendar-file/calendar-file.c | 268 +-
.../org-gnome-calendar-file.eplug.xml | 4 +-
plugins/google-account-setup/Makefile.am | 8 +-
plugins/google-account-setup/google-source.c | 223 +-
.../org-gnome-evolution-google.eplug.xml | 4 +
plugins/groupwise-features/Makefile.am | 2 +
plugins/groupwise-features/mail-send-options.c | 20 +
.../org-gnome-groupwise-features.eplug.xml | 11 +-
plugins/groupwise-features/proxy-login.c | 4 +-
plugins/pst-import/pst-importer.c | 328 +-
po/POTFILES.in | 2 +
po/es.po | 4014 ++++----
po/sv.po | 4829 +++++-----
po/ta.po | 4202 ++++----
po/zh_HK.po |10539 ++++++++++----------
po/zh_TW.po |10580 ++++++++++----------
widgets/e-timezone-dialog/e-timezone-dialog.c | 9 +-
widgets/misc/e-account-manager.c | 11 +-
widgets/misc/e-attachment-icon-view.c | 9 +-
widgets/misc/e-attachment-icon-view.h | 3 +-
widgets/misc/e-attachment-paned.c | 10 +-
widgets/misc/e-attachment-paned.h | 2 +
widgets/misc/e-gui-utils.c | 183 +-
widgets/misc/e-gui-utils.h | 26 +-
widgets/misc/e-image-chooser.c | 3 +-
widgets/table/e-table.c | 2 +-
60 files changed, 19513 insertions(+), 19660 deletions(-)
---
diff --cc calendar/gui/e-cal-event.c
index a05711a,86bd20e..eb37ae1
--- a/calendar/gui/e-cal-event.c
+++ b/calendar/gui/e-cal-event.c
@@@ -43,10 -43,10 +43,12 @@@ static voi
ece_target_free (EEvent *ev, EEventTarget *t)
{
switch (t->type) {
- case E_CAL_EVENT_TARGET_COMPONENT: {
- ECalEventTargetComponent *s = (ECalEventTargetComponent *) t;
- if (s->component)
- g_object_unref (s->component);
+ case E_CAL_EVENT_TARGET_MODULE: {
+ ECalEventTargetModule *s = (ECalEventTargetModule *) t;
+ if (s->shell_backend)
+ g_object_unref (s->shell_backend);
++ if (s->source_list)
++ g_object_unref (s->source_list);
break; }
}
@@@ -92,12 -92,12 +94,13 @@@ e_cal_event_peek (void
return e_cal_event;
}
-ECalEventTargetComponent *
-e_cal_event_target_new_component (ECalEvent *ece, struct _CalendarComponent *component, guint32 flags)
+ECalEventTargetModule *
- e_cal_event_target_new_module (ECalEvent *ece, EShellBackend *shell_backend, guint32 flags)
++e_cal_event_target_new_module (ECalEvent *ece, EShellBackend *shell_backend, ESourceList *source_list, guint32 flags)
{
- ECalEventTargetComponent *t = e_event_target_new (&ece->event, E_CAL_EVENT_TARGET_COMPONENT, sizeof (*t));
+ ECalEventTargetModule *t = e_event_target_new (&ece->event, E_CAL_EVENT_TARGET_MODULE, sizeof (*t));
- t->component = g_object_ref (component);
+ t->shell_backend = g_object_ref (shell_backend);
++ t->source_list = g_object_ref (source_list);
t->target.mask = ~flags;
return t;
diff --cc calendar/gui/e-cal-event.h
index e219679,8fb28df..e9f5987
--- a/calendar/gui/e-cal-event.h
+++ b/calendar/gui/e-cal-event.h
@@@ -25,9 -25,8 +25,10 @@@
#define __E_CAL_EVENT_H__
#include <glib-object.h>
++#include <libedataserver/e-source-list.h>
#include "e-util/e-event.h"
+#include "shell/e-shell-backend.h"
G_BEGIN_DECLS
@@@ -35,19 -34,20 +36,20 @@@ typedef struct _ECalEvent ECalEvent
typedef struct _ECalEventClass ECalEventClass;
enum _e_cal_event_target_t {
- E_CAL_EVENT_TARGET_COMPONENT
+ E_CAL_EVENT_TARGET_MODULE,
};
-/* Flags that describe TARGET_COMPONENT */
+/* Flags that describe TARGET_MODULE */
enum {
- E_CAL_EVENT_COMPONENT_MIGRATION = 1 << 0
+ E_CAL_EVENT_MODULE_MIGRATION = 1 << 0,
};
-typedef struct _ECalEventTargetComponent ECalEventTargetComponent;
+typedef struct _ECalEventTargetModule ECalEventTargetModule;
-struct _ECalEventTargetComponent {
+struct _ECalEventTargetModule {
EEventTarget target;
-
- struct _CalendarComponent *component;
+ EShellBackend *shell_backend;
++ ESourceList *source_list;
};
struct _ECalEvent {
@@@ -62,7 -62,7 +64,7 @@@ struct _ECalEventClass
GType e_cal_event_get_type (void);
ECalEvent* e_cal_event_peek (void);
- ECalEventTargetModule* e_cal_event_target_new_module (ECalEvent *ece, EShellBackend *shell_backend, guint32 flags);
-ECalEventTargetComponent* e_cal_event_target_new_component (ECalEvent *ece, struct _CalendarComponent *component, guint32 flags);
++ECalEventTargetModule* e_cal_event_target_new_module (ECalEvent *ece, EShellBackend *shell_backend, ESourceList *source_list, guint32 flags);
/* ********************************************************************** */
diff --cc composer/e-composer-from-header.c
index 4dadfa7,320768c..cade5bf
--- a/composer/e-composer-from-header.c
+++ b/composer/e-composer-from-header.c
@@@ -110,6 -110,14 +110,16 @@@ e_composer_from_header_new (const gcha
"button", FALSE, NULL);
}
+ EComposerHeader *
-e_composer_from_header_new_with_action (const gchar *label, const gchar *action)
++e_composer_from_header_new_with_action (const gchar *label,
++ const gchar *action)
+ {
+ return g_object_new (
+ E_TYPE_COMPOSER_FROM_HEADER, "label", label,
- "button", FALSE, "addaction_text", action, "addaction", action!= NULL, NULL);
++ "button", FALSE, "addaction_text", action,
++ "addaction", action != NULL, NULL);
+ }
+
EAccountList *
e_composer_from_header_get_account_list (EComposerFromHeader *header)
{
diff --cc composer/e-composer-from-header.h
index d2603bd,3fbf5a7..9f9a0e0
--- a/composer/e-composer-from-header.h
+++ b/composer/e-composer-from-header.h
@@@ -63,6 -63,7 +63,9 @@@ struct _EComposerFromHeaderClass
GType e_composer_from_header_get_type (void);
EComposerHeader * e_composer_from_header_new (const gchar *label);
-EComposerHeader * e_composer_from_header_new_with_action (const gchar *label, const gchar *action);
++EComposerHeader * e_composer_from_header_new_with_action
++ (const gchar *label,
++ const gchar *action);
EAccountList * e_composer_from_header_get_account_list
(EComposerFromHeader *header);
void e_composer_from_header_set_account_list
diff --cc composer/e-composer-header-table.c
index d883d8e,55dc6a6..47885df
--- a/composer/e-composer-header-table.c
+++ b/composer/e-composer-header-table.c
@@@ -160,7 -160,11 +160,11 @@@ composer_header_table_notify_header (EC
{
GtkWidget *parent;
- parent = gtk_widget_get_parent (header->input_widget);
- if (strcmp (property_name, "destinations-to") == 0) {
- parent = g_object_get_data((GObject *)header->input_widget, "parent");
- } else {
++ if (strcmp (property_name, "destinations-to") == 0)
++ parent = g_object_get_data (
++ G_OBJECT (header->input_widget), "parent");
++ else
+ parent = gtk_widget_get_parent (header->input_widget);
- }
g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (parent));
g_object_notify (G_OBJECT (parent), property_name);
}
@@@ -171,7 -175,11 +175,11 @@@ composer_header_table_notify_widget (Gt
{
GtkWidget *parent;
- parent = gtk_widget_get_parent (widget);
+ if (composer_lite) {
+ parent = gtk_widget_get_parent (widget);
- parent = g_object_get_data ((GObject *)parent, "pdata");
++ parent = g_object_get_data (G_OBJECT (parent), "pdata");
+ } else
+ parent = gtk_widget_get_parent (widget);
g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (parent));
g_object_notify (G_OBJECT (parent), property_name);
}
@@@ -531,24 -552,22 +551,27 @@@ composer_header_table_constructor (GTyp
G_OBJECT (priv->signature_combo_box), "visible");
/* Now add the signature stuff. */
- gtk_table_attach (
- GTK_TABLE (object), priv->signature_label,
- 2, 3, ii, ii + 1, 0, 0, 0, 3);
- gtk_table_attach (
- GTK_TABLE (object), priv->signature_combo_box,
- 3, 4, ii, ii + 1, 0, 0, 0, 3);
-
- if (composer_lite) {
- ii = E_COMPOSER_HEADER_TO;
-
- /* Leave room for the action buttons. */
- gtk_container_child_set (
- GTK_CONTAINER (object),
- priv->headers[ii]->input_widget,
- "right-attach", 2, NULL);
-
- gtk_table_attach (GTK_TABLE (object), (GtkWidget *)priv->actions_container, 2, 4, E_COMPOSER_HEADER_TO,
- E_COMPOSER_HEADER_TO + 1, GTK_FILL, 0, 0, 3);
+ if (!composer_lite) {
+ gtk_table_attach (
+ GTK_TABLE (object), priv->signature_label,
+ 2, 3, ii, ii + 1, 0, 0, 0, 3);
+ gtk_table_attach (
+ GTK_TABLE (object), priv->signature_combo_box,
+ 3, 4, ii, ii + 1, composer_lite ? GTK_FILL: 0, 0, 0, 3);
- } else {
++ } else {
+ GtkWidget *box = gtk_hbox_new (FALSE, 0);
- gtk_box_pack_start ((GtkBox *)box, priv->signature_label, FALSE, FALSE, 4);
- gtk_box_pack_end ((GtkBox *)box, priv->signature_combo_box, TRUE, TRUE, 0);
- g_object_set_data ((GObject *)box, "pdata", object);
++
++ gtk_box_pack_start (
++ GTK_BOX (box), priv->signature_label,
++ FALSE, FALSE, 4);
++ gtk_box_pack_end (
++ GTK_BOX (box), priv->signature_combo_box,
++ TRUE, TRUE, 0);
++ g_object_set_data (G_OBJECT (box), "pdata", object);
+ gtk_table_attach (
+ GTK_TABLE (object), box,
+ 3, 4, ii, ii + 1, GTK_FILL, 0, 0, 3);
+ gtk_widget_hide (box);
}
return object;
diff --cc composer/e-composer-private.h
index 3d8a1b9,49d9ae6..1d0c19f
--- a/composer/e-composer-private.h
+++ b/composer/e-composer-private.h
@@@ -29,9 -29,7 +29,10 @@@
#include "e-composer-autosave.h"
#include "e-composer-header-table.h"
#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 "widgets/misc/e-attachment-icon-view.h"
#include "widgets/misc/e-attachment-paned.h"
#include "widgets/misc/e-attachment-store.h"
diff --cc mail/e-mail-reader.c
index 0e20dbb,0000000..0362cb1
mode 100644,000000..100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@@ -1,2744 -1,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);
++ event, folder, message, message_uid, 0, NULL);
+ 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 --cc mail/em-account-editor.c
index 6c67446,21650d0..6c55a65
--- a/mail/em-account-editor.c
+++ b/mail/em-account-editor.c
@@@ -197,54 -188,20 +197,55 @@@ 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;
++ if (emae->type != EMAE_PAGES)
++ 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
diff --cc mail/em-account-editor.h
index 0c2f5e3,12e7506..b8913e2
--- a/mail/em-account-editor.h
+++ b/mail/em-account-editor.h
@@@ -74,45 -59,27 +74,45 @@@ struct _EMAccountEditor
};
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);
-gboolean 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,
++gboolean 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 --cc mail/em-composer-utils.c
index 8370496,e76159a..818654d
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@@ -712,7 -710,7 +712,7 @@@ em_utils_compose_new_message (const gch
* Opens a new composer window as a child window of @parent's toplevel
* window.
**/
--struct _EMsgComposer *
++EMsgComposer *
em_utils_compose_lite_new_message (const gchar *fromuri)
{
GtkWidget *composer;
@@@ -723,7 -721,7 +723,7 @@@
composer_set_no_change (E_MSG_COMPOSER (composer), TRUE, TRUE);
-- return (struct _EMsgComposer *)composer;
++ return E_MSG_COMPOSER (composer);
}
/**
@@@ -1033,14 -1030,14 +1033,14 @@@ setup_forward_attached_callbacks (EMsgC
g_object_weak_ref ((GObject *) composer, (GWeakNotify) composer_destroy_fad_cb, fad);
}
- static void
-static struct _EMsgComposer *
++static EMsgComposer *
forward_attached (CamelFolder *folder, GPtrArray *uids, GPtrArray *messages, CamelMimePart *part, gchar *subject, const gchar *fromuri)
{
EMsgComposer *composer;
- composer = create_new_composer (subject, fromuri, TRUE, FALSE);
+ composer = create_new_composer (subject, fromuri, FALSE);
if (composer == NULL)
- return;
+ return NULL;
e_msg_composer_attach (composer, part);
@@@ -1199,7 -1195,7 +1202,7 @@@ em_utils_forward_quoted (CamelFolder *f
*
* Forwards a message in the user's configured default style.
**/
- void
-struct _EMsgComposer *
++EMsgComposer *
em_utils_forward_message (CamelMimeMessage *message, const gchar *fromuri)
{
GPtrArray *messages;
@@@ -1207,7 -1203,7 +1210,7 @@@
GConfClient *gconf;
gchar *subject;
gint mode;
-
- struct _EMsgComposer *composer = NULL;
++ EMsgComposer *composer = NULL;
messages = g_ptr_array_new ();
g_ptr_array_add (messages, message);
@@@ -2311,7 -2311,7 +2316,7 @@@ reply_to_message(CamelFolder *folder, c
* may be supplied in order to update the message flags once it has
* been replied to.
**/
--struct _EMsgComposer *
++EMsgComposer *
em_utils_reply_to_message(CamelFolder *folder, const gchar *uid, CamelMimeMessage *message, gint mode, EMFormat *source)
{
CamelInternetAddress *to, *cc;
diff --cc mail/em-event.h
index 6680e88,6b36184..d653e35
--- a/mail/em-event.h
+++ b/mail/em-event.h
@@@ -133,8 -150,10 +135,9 @@@ 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);
+ EMEventTargetMessage *em_event_target_new_message(EMEvent *emp, CamelFolder *folder, CamelMimeMessage *message, const gchar *uid, guint32 flags,
+ EMsgComposer *composer);
EMEventTargetSendReceive * em_event_target_new_send_receive(EMEvent *eme, GtkWidget *table, gpointer data, gint row, guint32 flags);
EMEventTargetCustomIcon * em_event_target_new_custom_icon(EMEvent *eme, GtkTreeStore *store, GtkTreeIter *iter, const gchar *uri, guint32 flags);
diff --cc mail/em-format-html-print.c
index 773bc04,86242b1..fb9b1a7
--- a/mail/em-format-html-print.c
+++ b/mail/em-format-html-print.c
@@@ -232,6 -228,11 +232,12 @@@ em_format_html_print_message (EMFormatH
{
g_object_ref (efhp);
+ /* Wrap flags to display all entries by default.*/
- ((EMFormatHTML *) efhp)->header_wrap_flags |= EM_FORMAT_HTML_HEADER_TO
- | EM_FORMAT_HTML_HEADER_CC
- | EM_FORMAT_HTML_HEADER_BCC;
++ EM_FORMAT_HTML (efhp)->header_wrap_flags |=
++ EM_FORMAT_HTML_HEADER_TO |
++ EM_FORMAT_HTML_HEADER_CC |
++ EM_FORMAT_HTML_HEADER_BCC;
+
mail_get_message (
folder, uid, emfhp_got_message, efhp, mail_msg_unordered_push);
}
diff --cc mail/mail-mt.c
index 93fb40a,0032a21..012bca1
--- a/mail/mail-mt.c
+++ b/mail/mail-mt.c
@@@ -332,10 -331,12 +332,11 @@@ mail_msg_check_error (gpointer msg
g_hash_table_insert(active_errors, m->info, gd);
g_signal_connect(gd, "response", G_CALLBACK(error_response), m->info);
g_signal_connect(gd, "destroy", G_CALLBACK(error_destroy), m->info);
- if (m->priv->cancelable) {
+ if (m->priv->cancelable)
m->priv->error = (GtkWidget *) gd;
- mail_component_show_status_bar (TRUE);
- } else
+ else
gtk_widget_show((GtkWidget *)gd);
+
}
void mail_msg_cancel(guint msgid)
@@@ -485,7 -486,7 +486,6 @@@ mail_msg_idle_cb (void
G_LOCK (idle_source_id);
idle_source_id = 0;
G_UNLOCK (idle_source_id);
-
- mail_component_show_status_bar (TRUE);
/* check the main loop queue */
while ((msg = g_async_queue_try_pop (main_loop_queue)) != NULL) {
if (msg->info->exec != NULL)
@@@ -502,7 -503,7 +502,6 @@@
mail_msg_check_error (msg);
mail_msg_unref (msg);
}
-
- mail_component_show_status_bar (FALSE);
return FALSE;
}
diff --cc mail/mail-send-recv.c
index 39fc67e,04a5def..7f7c997
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@@ -622,7 -611,8 +622,9 @@@ build_dialog (GtkWindow *parent
}
gtk_widget_show_all (table);
- gtk_widget_show (GTK_WIDGET (gd));
- if (show_dialog)
++
++ if (parent != NULL)
+ gtk_widget_show (GTK_WIDGET (gd));
g_signal_connect (gd, "response", G_CALLBACK (dialog_response), data);
@@@ -932,9 -916,9 +934,9 @@@ mail_send_receive (GtkWindow *parent
GList *scan;
if (send_recv_dialog != NULL) {
- if (GTK_WIDGET_REALIZED(send_recv_dialog)) {
- gdk_window_show(send_recv_dialog->window);
- gdk_window_raise(send_recv_dialog->window);
- if (show_dialog && GTK_WIDGET_REALIZED(send_recv_dialog)) {
- gdk_window_show(send_recv_dialog->window);
- gdk_window_raise(send_recv_dialog->window);
++ if (parent != NULL && GTK_WIDGET_REALIZED (send_recv_dialog)) {
++ gdk_window_show (send_recv_dialog->window);
++ gdk_window_raise (send_recv_dialog->window);
}
return send_recv_dialog;
}
diff --cc mail/mail-send-recv.h
index 02be2ce,08ab233..2ba1f01
--- a/mail/mail-send-recv.h
+++ b/mail/mail-send-recv.h
@@@ -36,11 -36,10 +36,11 @@@ GtkWidget * mail_send_receive (GtkWind
void mail_receive_uri (const gchar *uri,
gboolean keep_on_server);
- void mail_send (void);
+ 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 --cc modules/calendar/e-cal-shell-migrate.c
index 9f611f9,0000000..8eb8e14
mode 100644,000000..100644
--- a/modules/calendar/e-cal-shell-migrate.c
+++ b/modules/calendar/e-cal-shell-migrate.c
@@@ -1,795 -1,0 +1,795 @@@
+/*
+ * e-cal-shell-backend-migrate.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-cal-shell-migrate.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <libebackend/e-dbhash.h>
+#include <libedataserver/e-source.h>
+#include <libedataserver/e-source-group.h>
+#include <libedataserver/e-source-list.h>
+#include <libedataserver/e-xml-hash-utils.h>
+
+#include "e-util/e-bconf-map.h"
+#include "e-util/e-folder-map.h"
+#include "e-util/e-util-private.h"
+#include "calendar/gui/calendar-config.h"
+#include "calendar/gui/calendar-config-keys.h"
+#include "calendar/gui/e-cal-event.h"
+#include "shell/e-shell.h"
+
+#define WEBCAL_BASE_URI "webcal://"
+#define CONTACTS_BASE_URI "contacts://"
+#define BAD_CONTACTS_BASE_URI "contact://"
+#define PERSONAL_RELATIVE_URI "system"
+
+static e_gconf_map_t calendar_display_map[] = {
+ /* /Calendar/Display */
+ { "Timezone", "calendar/display/timezone", E_GCONF_MAP_STRING },
+ { "Use24HourFormat", "calendar/display/use_24hour_format", E_GCONF_MAP_BOOL },
+ { "WeekStartDay", "calendar/display/week_start_day", E_GCONF_MAP_INT },
+ { "DayStartHour", "calendar/display/day_start_hour", E_GCONF_MAP_INT },
+ { "DayStartMinute", "calendar/display/day_start_minute", E_GCONF_MAP_INT },
+ { "DayEndHour", "calendar/display/day_end_hour", E_GCONF_MAP_INT },
+ { "DayEndMinute", "calendar/display/day_end_minute", E_GCONF_MAP_INT },
+ { "TimeDivisions", "calendar/display/time_divisions", E_GCONF_MAP_INT },
+ { "View", "calendar/display/default_view", E_GCONF_MAP_INT },
+ { "HPanePosition", "calendar/display/hpane_position", E_GCONF_MAP_FLOAT },
+ { "VPanePosition", "calendar/display/vpane_position", E_GCONF_MAP_FLOAT },
+ { "MonthHPanePosition", "calendar/display/month_hpane_position", E_GCONF_MAP_FLOAT },
+ { "MonthVPanePosition", "calendar/display/month_vpane_position", E_GCONF_MAP_FLOAT },
+ { "CompressWeekend", "calendar/display/compress_weekend", E_GCONF_MAP_BOOL },
+ { "ShowEventEndTime", "calendar/display/show_event_end", E_GCONF_MAP_BOOL },
+ { "WorkingDays", "calendar/display/working_days", E_GCONF_MAP_INT },
+ { NULL },
+};
+
+static e_gconf_map_t calendar_other_map[] = {
+ /* /Calendar/Other */
+ { "ConfirmDelete", "calendar/prompts/confirm_delete", E_GCONF_MAP_BOOL },
+ { "ConfirmExpunge", "calendar/prompts/confirm_purge", E_GCONF_MAP_BOOL },
+ { "UseDefaultReminder", "calendar/other/use_default_reminder", E_GCONF_MAP_BOOL },
+ { "DefaultReminderInterval", "calendar/other/default_reminder_interval", E_GCONF_MAP_INT },
+ { "DefaultReminderUnits", "calendar/other/default_reminder_units", E_GCONF_MAP_STRING },
+ { NULL },
+};
+
+static e_gconf_map_t calendar_datenavigator_map[] = {
+ /* /Calendar/DateNavigator */
+ { "ShowWeekNumbers", "calendar/date_navigator/show_week_numbers", E_GCONF_MAP_BOOL },
+ { NULL },
+};
+
+static e_gconf_map_t calendar_alarmnotify_map[] = {
+ /* /Calendar/AlarmNotify */
+ { "LastNotificationTime", "calendar/notify/last_notification_time", E_GCONF_MAP_INT },
+ { "CalendarToLoad%i", "calendar/notify/calendars", E_GCONF_MAP_STRING|E_GCONF_MAP_LIST },
+ { "BlessedProgram%i", "calendar/notify/programs", E_GCONF_MAP_STRING|E_GCONF_MAP_LIST },
+ { NULL },
+};
+
+static e_gconf_map_list_t calendar_remap_list[] = {
+
+ { "/Calendar/Display", calendar_display_map },
+ { "/Calendar/Other/Map", calendar_other_map },
+ { "/Calendar/DateNavigator", calendar_datenavigator_map },
+ { "/Calendar/AlarmNotify", calendar_alarmnotify_map },
+
+ { NULL },
+};
+
+static GtkWidget *window;
+static GtkLabel *label;
+static GtkProgressBar *progress;
+
+#ifndef G_OS_WIN32
+
+/* No previous versions have been available on Win32, so don't
+ * bother with upgrade support from 1.x on Win32.
+ */
+
+static void
+setup_progress_dialog (void)
+{
+ GtkWidget *vbox, *hbox, *w;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title ((GtkWindow *) window, _("Migrating..."));
+ gtk_window_set_modal ((GtkWindow *) window, TRUE);
+ gtk_container_set_border_width ((GtkContainer *) window, 6);
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox);
+ gtk_container_add ((GtkContainer *) window, vbox);
+
+ w = gtk_label_new (_("The location and hierarchy of the Evolution calendar "
+ "folders has changed since Evolution 1.x.\n\nPlease be "
+ "patient while Evolution migrates your folders..."));
+
+ gtk_label_set_line_wrap ((GtkLabel *) w, TRUE);
+ gtk_widget_show (w);
+ gtk_box_pack_start_defaults ((GtkBox *) vbox, w);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_widget_show (hbox);
+ gtk_box_pack_start_defaults ((GtkBox *) vbox, hbox);
+
+ label = (GtkLabel *) gtk_label_new ("");
+ gtk_widget_show ((GtkWidget *) label);
+ gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) label);
+
+ progress = (GtkProgressBar *) gtk_progress_bar_new ();
+ gtk_widget_show ((GtkWidget *) progress);
+ gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) progress);
+
+ gtk_widget_show (window);
+}
+
+static void
+dialog_close (void)
+{
+ gtk_widget_destroy ((GtkWidget *) window);
+}
+
+static void
+dialog_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
+dialog_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 ();
+}
+
+static gboolean
+check_for_conflict (ESourceGroup *group, gchar *name)
+{
+ GSList *sources;
+ GSList *s;
+
+ sources = e_source_group_peek_sources (group);
+
+ for (s = sources; s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+
+ if (!strcmp (e_source_peek_name (source), name))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gchar *
+get_source_name (ESourceGroup *group, const gchar *path)
+{
+ gchar **p = g_strsplit (path, "/", 0);
+ gint i, j, starting_index;
+ gint num_elements;
+ gboolean conflict;
+ GString *s = g_string_new (NULL);
+
+ for (i = 0; p[i]; i ++);
+
+ num_elements = i;
+ i--;
+
+ /* p[i] is now the last path element */
+
+ /* check if it conflicts */
+ starting_index = i;
+ do {
+ for (j = starting_index; j < num_elements; j += 2) {
+ if (j != starting_index)
+ g_string_append_c (s, '_');
+ g_string_append (s, p[j]);
+ }
+
+ conflict = check_for_conflict (group, s->str);
+
+ /* if there was a conflict back up 2 levels (skipping the /subfolder/ element) */
+ if (conflict)
+ starting_index -= 2;
+
+ /* we always break out if we can't go any further,
+ regardless of whether or not we conflict. */
+ if (starting_index < 0)
+ break;
+
+ } while (conflict);
+ g_strfreev (p);
+
+ return g_string_free (s, FALSE);
+}
+
+static gboolean
+migrate_ical (ECal *old_ecal, ECal *new_ecal)
+{
+ GList *l, *objects;
+ gint num_added = 0;
+ gint num_objects;
+ gboolean retval = TRUE;
+
+ /* both ecals are loaded, start the actual migration */
+ if (!e_cal_get_object_list (old_ecal, "#t", &objects, NULL))
+ return FALSE;
+
+ num_objects = g_list_length (objects);
+ for (l = objects; l; l = l->next) {
+ icalcomponent *ical_comp = l->data;
+ GError *error = NULL;
+
+ if (!e_cal_create_object (new_ecal, ical_comp, NULL, &error)) {
+ g_warning ("Migration of object failed: %s", error->message);
+ retval = FALSE;
+ }
+
+ g_clear_error (&error);
+
+ num_added ++;
+ dialog_set_progress ((double)num_added / num_objects);
+ }
+
+ g_list_foreach (objects, (GFunc) icalcomponent_free, NULL);
+ g_list_free (objects);
+
+ return retval;
+}
+
+static gboolean
+migrate_ical_folder_to_source (gchar *old_path, ESource *new_source, ECalSourceType type)
+{
+ ECal *old_ecal = NULL, *new_ecal = NULL;
+ ESource *old_source;
+ ESourceGroup *group;
+ gchar *old_uri = g_strdup_printf ("file://%s", old_path);
+ GError *error = NULL;
+ gboolean retval = FALSE;
+
+ group = e_source_group_new ("", old_uri);
+ old_source = e_source_new ("", "");
+ e_source_group_add_source (group, old_source, -1);
+
+ dialog_set_folder_name (e_source_peek_name (new_source));
+
+ if (!(old_ecal = e_cal_new (old_source, type))) {
+ g_warning ("could not find a backend for '%s'", e_source_get_uri (old_source));
+ goto finish;
+ }
+ if (!e_cal_open (old_ecal, FALSE, &error)) {
+ g_warning ("failed to load source ecal for migration: '%s' (%s)", error->message,
+ e_source_get_uri (old_source));
+ goto finish;
+ }
+
+ if (!(new_ecal = e_cal_new (new_source, type))) {
+ g_warning ("could not find a backend for '%s'", e_source_get_uri (new_source));
+ goto finish;
+ }
+ if (!e_cal_open (new_ecal, FALSE, &error)) {
+ g_warning ("failed to load destination ecal for migration: '%s' (%s)", error->message,
+ e_source_get_uri (new_source));
+ goto finish;
+ }
+
+ retval = migrate_ical (old_ecal, new_ecal);
+
+finish:
+ g_clear_error (&error);
+ if (old_ecal)
+ g_object_unref (old_ecal);
+ g_object_unref (group);
+ if (new_ecal)
+ g_object_unref (new_ecal);
+ g_free (old_uri);
+
+ return retval;
+}
+
+static gboolean
+migrate_ical_folder (gchar *old_path, ESourceGroup *dest_group, gchar *source_name, ECalSourceType type)
+{
+ ESource *new_source;
+ gboolean retval;
+
+ new_source = e_source_new (source_name, source_name);
+ e_source_set_relative_uri (new_source, e_source_peek_uid (new_source));
+ e_source_group_add_source (dest_group, new_source, -1);
+
+ retval = migrate_ical_folder_to_source (old_path, new_source, type);
+
+ g_object_unref (new_source);
+
+ return retval;
+}
+
+#endif /* !G_OS_WIN32 */
+
+#ifndef G_OS_WIN32
+
+static void
+migrate_pilot_db_key (const gchar *key, gpointer user_data)
+{
+ EXmlHash *xmlhash = user_data;
+
+ e_xmlhash_add (xmlhash, key, "");
+}
+
+static void
+migrate_pilot_data (const gchar *component, const gchar *conduit, const gchar *old_path, const gchar *new_path)
+{
+ gchar *changelog, *map;
+ const gchar *dent;
+ const gchar *ext;
+ gchar *filename;
+ GDir *dir;
+
+ if (!(dir = g_dir_open (old_path, 0, NULL)))
+ return;
+
+ map = g_alloca (12 + strlen (conduit));
+ sprintf (map, "pilot-map-%s-", conduit);
+
+ changelog = g_alloca (24 + strlen (conduit));
+ sprintf (changelog, "pilot-sync-evolution-%s-", conduit);
+
+ while ((dent = g_dir_read_name (dir))) {
+ if (!strncmp (dent, map, strlen (map)) &&
+ ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) {
+ /* pilot map file - src and dest file formats are identical */
+ guchar inbuf[4096];
+ gsize nread, nwritten;
+ gint fd0, fd1;
+ gssize n;
+
+ filename = g_build_filename (old_path, dent, NULL);
+ if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) {
+ g_free (filename);
+ continue;
+ }
+
+ g_free (filename);
+ filename = g_build_filename (new_path, dent, NULL);
+ if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) {
+ g_free (filename);
+ close (fd0);
+ continue;
+ }
+
+ do {
+ do {
+ n = read (fd0, inbuf, sizeof (inbuf));
+ } while (n == -1 && errno == EINTR);
+
+ if (n < 1)
+ break;
+
+ nread = n;
+ nwritten = 0;
+ do {
+ do {
+ n = write (fd1, inbuf + nwritten, nread - nwritten);
+ } while (n == -1 && errno == EINTR);
+
+ if (n > 0)
+ nwritten += n;
+ } while (nwritten < nread && n != -1);
+
+ if (n == -1)
+ break;
+ } while (1);
+
+ if (n != -1)
+ n = fsync (fd1);
+
+ if (n == -1) {
+ g_warning ("Failed to migrate %s: %s", dent, strerror (errno));
+ g_unlink (filename);
+ }
+
+ close (fd0);
+ close (fd1);
+ g_free (filename);
+ } else if (!strncmp (dent, changelog, strlen (changelog)) &&
+ ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) {
+ /* src and dest formats differ, src format is db3 while dest format is xml */
+ EXmlHash *xmlhash;
+ EDbHash *dbhash;
+ struct stat st;
+
+ filename = g_build_filename (old_path, dent, NULL);
+ if (g_stat (filename, &st) == -1) {
+ g_free (filename);
+ continue;
+ }
+
+ dbhash = e_dbhash_new (filename);
+ g_free (filename);
+
+ filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent);
+ if (g_stat (filename, &st) != -1)
+ g_unlink (filename);
+ xmlhash = e_xmlhash_new (filename);
+ g_free (filename);
+
+ e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash);
+
+ e_dbhash_destroy (dbhash);
+
+ e_xmlhash_write (xmlhash);
+ e_xmlhash_destroy (xmlhash);
+ }
+ }
+
+ g_dir_close (dir);
+}
+
+#endif
+
+static ESourceGroup *
+create_calendar_contact_source (ESourceList *source_list)
+{
+ ESourceGroup *group;
+ ESource *source;
+
+ /* Create the contacts group */
+ group = e_source_group_new (_("Contacts"), CONTACTS_BASE_URI);
+ e_source_list_add_group (source_list, group, -1);
+
+ source = e_source_new (_("Birthdays & Anniversaries"), "/");
+ e_source_group_add_source (group, source, -1);
+ g_object_unref (source);
+
+ e_source_set_color_spec (source, "#FED4D3");
+ e_source_group_set_readonly (group, TRUE);
+
+ return group;
+}
+
+static void
+create_calendar_sources (EShellBackend *shell_backend,
+ ESourceList *source_list,
+ ESourceGroup **on_this_computer,
+ ESource **personal_source,
+ ESourceGroup **on_the_web,
+ ESourceGroup **contacts)
+{
+ EShell *shell;
+ EShellSettings *shell_settings;
+ GSList *groups;
+ ESourceGroup *group;
+ gchar *base_uri, *base_uri_proto;
+ const gchar *base_dir;
+
+ *on_this_computer = NULL;
+ *on_the_web = NULL;
+ *contacts = NULL;
+ *personal_source = NULL;
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
+
+ base_dir = e_shell_backend_get_config_dir (shell_backend);
+ base_uri = g_build_filename (base_dir, "local", NULL);
+
+ base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);
+
+ groups = e_source_list_peek_groups (source_list);
+ if (groups) {
+ /* groups are already there, we need to search for things... */
+ GSList *g;
+
+ for (g = groups; g; g = g->next) {
+
+ group = E_SOURCE_GROUP (g->data);
+
+ if (!strcmp (BAD_CONTACTS_BASE_URI, e_source_group_peek_base_uri (group)))
+ e_source_group_set_base_uri (group, CONTACTS_BASE_URI);
+
+ if (!strcmp (base_uri, e_source_group_peek_base_uri (group)))
+ e_source_group_set_base_uri (group, base_uri_proto);
+
+ if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group)))
+ *on_this_computer = g_object_ref (group);
+ else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group)))
+ *on_the_web = g_object_ref (group);
+ else if (!*contacts && !strcmp (CONTACTS_BASE_URI, e_source_group_peek_base_uri (group)))
+ *contacts = g_object_ref (group);
+ }
+ }
+
+ if (*on_this_computer) {
+ /* make sure "Personal" shows up as a source under
+ this group */
+ GSList *sources = e_source_group_peek_sources (*on_this_computer);
+ GSList *s;
+ for (s = sources; s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+ const gchar *relative_uri;
+
+ relative_uri = e_source_peek_relative_uri (source);
+ if (relative_uri == NULL)
+ continue;
+ if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
+ *personal_source = g_object_ref (source);
+ break;
+ }
+ }
+ } else {
+ /* create the local source group */
+ group = e_source_group_new (_("On This Computer"), base_uri_proto);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_this_computer = group;
+ }
+
+ if (!*personal_source) {
+ gchar *primary_calendar;
+
+ /* Create the default Person calendar */
+ ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
+ e_source_group_add_source (*on_this_computer, source, -1);
+
+ primary_calendar = e_shell_settings_get_string (
+ shell_settings, "cal-primary-calendar");
+
+ if (!primary_calendar && !calendar_config_get_calendars_selected ()) {
+ GSList selected;
+
+ e_shell_settings_set_string (
+ shell_settings, "cal-primary-calendar",
+ e_source_peek_uid (source));
+
+ selected.data = (gpointer)e_source_peek_uid (source);
+ selected.next = NULL;
+ calendar_config_set_calendars_selected (&selected);
+ }
+
+ g_free (primary_calendar);
+ e_source_set_color_spec (source, "#BECEDD");
+ *personal_source = source;
+ }
+
+ if (!*on_the_web) {
+ /* Create the Webcal source group */
+ group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_the_web = group;
+ }
+
+ if (!*contacts) {
+ group = create_calendar_contact_source (source_list);
+
+ *contacts = group;
+ }
+
+ g_free (base_uri_proto);
+ g_free (base_uri);
+}
+
+gboolean
+e_cal_shell_backend_migrate (EShellBackend *shell_backend,
+ gint major,
+ gint minor,
+ gint micro,
+ GError **error)
+{
+ ESourceGroup *on_this_computer = NULL, *on_the_web = NULL, *contacts = NULL;
+ ESource *personal_source = NULL;
+ ESourceList *source_list;
+ ECalEvent *ece;
+ ECalEventTargetModule *target;
+ gboolean retval = FALSE;
+
+ source_list = g_object_get_data (
+ G_OBJECT (shell_backend), "source-list");
+
+ /* we call this unconditionally now - create_groups either
+ creates the groups/sources or it finds the necessary
+ groups/sources. */
+ create_calendar_sources (
+ shell_backend, source_list, &on_this_computer,
+ &personal_source, &on_the_web, &contacts);
+
+#ifndef G_OS_WIN32
+ if (major == 1) {
+ xmlDocPtr config_doc = NULL;
+ gchar *conf_file;
+ struct stat st;
+
+ conf_file = g_build_filename (g_get_home_dir (), "evolution", "config.xmldb", NULL);
+ if (lstat (conf_file, &st) == 0 && S_ISREG (st.st_mode))
+ config_doc = xmlParseFile (conf_file);
+ g_free (conf_file);
+
+ if (config_doc && minor <= 2) {
+ GConfClient *gconf;
+ gint res = 0;
+
+ /* move bonobo config to gconf */
+ gconf = gconf_client_get_default ();
+
+ res = e_bconf_import (gconf, config_doc, calendar_remap_list);
+
+ g_object_unref (gconf);
+
+ xmlFreeDoc(config_doc);
+
+ if (res != 0) {
+ /* FIXME: set proper domain/code */
+ g_set_error(error, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb"));
+ goto fail;
+ }
+ }
+
+ if (minor <= 4) {
+ GSList *migration_dirs, *l;
+ gchar *path, *local_cal_folder;
+
+ setup_progress_dialog ();
+
+ path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL);
+ migration_dirs = e_folder_map_local_folders (path, "calendar");
+ local_cal_folder = g_build_filename (path, "Calendar", NULL);
+ g_free (path);
+
+ if (personal_source)
+ migrate_ical_folder_to_source (local_cal_folder, personal_source, E_CAL_SOURCE_TYPE_EVENT);
+
+ for (l = migration_dirs; l; l = l->next) {
+ gchar *source_name;
+
+ if (personal_source && !strcmp ((gchar *)l->data, local_cal_folder))
+ continue;
+
+ source_name = get_source_name (on_this_computer, (gchar *)l->data);
+
+ if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_EVENT)) {
+ /* FIXME: domain/code */
+ g_set_error(error, 0, 0, _("Unable to migrate calendar `%s'"), source_name);
+ g_free(source_name);
+ goto fail;
+ }
+
+ g_free (source_name);
+ }
+
+ g_free (local_cal_folder);
+
+ dialog_close ();
+ }
+
+ if (minor <= 4 || (minor == 5 && micro < 5)) {
+ GConfClient *gconf;
+ GConfValue *gconf_val;
+ gint i;
+ const gchar *keys[] = {
+ CALENDAR_CONFIG_HPANE_POS,
+ CALENDAR_CONFIG_VPANE_POS,
+ CALENDAR_CONFIG_MONTH_HPANE_POS,
+ CALENDAR_CONFIG_MONTH_VPANE_POS,
+ NULL
+ };
+
+ gconf = gconf_client_get_default ();
+
+ for (i = 0; keys[i]; i++) {
+ gconf_val = gconf_client_get (gconf, keys[i], NULL);
+ if (gconf_val) {
+ if (gconf_val->type != GCONF_VALUE_INT)
+ gconf_client_unset (gconf, keys[i], NULL);
+ gconf_value_free (gconf_val);
+ }
+ }
+
+ g_object_unref (gconf);
+ }
+
+ if (minor < 5 || (minor == 5 && micro <= 10)) {
+ gchar *old_path, *new_path;
+
+ old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Calendar", NULL);
+ new_path = g_build_filename (e_shell_backend_get_config_dir (shell_backend),
+ "local", "system", NULL);
+ migrate_pilot_data ("calendar", "calendar", old_path, new_path);
+ g_free (new_path);
+ g_free (old_path);
+ }
+
+ /* we only need to do this next step if people ran
+ older versions of 1.5. We need to clear out the
+ absolute URI's that were assigned to ESources
+ during one phase of development, as they take
+ precedent over relative uris (but aren't updated
+ when editing an ESource). */
+ if (minor == 5 && micro <= 11) {
+ GSList *g;
+ for (g = e_source_list_peek_groups (source_list); g; g = g->next) {
+ ESourceGroup *group = g->data;
+ GSList *s;
+
+ for (s = e_source_group_peek_sources (group); s; s = s->next) {
+ ESource *source = s->data;
+ e_source_set_absolute_uri (source, NULL);
+ }
+ }
+ }
+
+ }
+#endif /* !G_OS_WIN32 */
+
+ e_source_list_sync (source_list, NULL);
+
+ /** @Event: component.migration
+ * @Title: Migration step in component initialization
+ * @Target: ECalEventTargetComponent
+ *
+ * component.migration is emitted during the calendar component
+ * initialization process. This allows new calendar backend types
+ * to be distributed as an e-d-s backend and a plugin without
+ * reaching their grubby little fingers into migration.c
+ */
+ /* Fire off migration event */
+ ece = e_cal_event_peek ();
- target = e_cal_event_target_new_module (ece, shell_backend, 0);
++ target = e_cal_event_target_new_module (ece, shell_backend, source_list, 0);
+ e_event_emit ((EEvent *) ece, "module.migration", (EEventTarget *) target);
+
+ retval = TRUE;
+fail:
+ if (on_this_computer)
+ g_object_unref (on_this_computer);
+ if (on_the_web)
+ g_object_unref (on_the_web);
+ if (contacts)
+ g_object_unref (contacts);
+ if (personal_source)
+ g_object_unref (personal_source);
+
+ return retval;
+}
+
diff --cc plugins/google-account-setup/Makefile.am
index ed452c0,67a7c2c..d6d6c36
--- a/plugins/google-account-setup/Makefile.am
+++ b/plugins/google-account-setup/Makefile.am
@@@ -1,6 -1,7 +1,7 @@@
AM_CPPFLAGS = \
-I . \
-- -I$(top_srcdir) \
- -I$(top_builddir)/shell \
++ -I$(top_srcdir) \
++ -I$(top_srcdir)/widgets \
-DCALDAV_GLADEDIR=\""$(gladedir)"\" \
$(EVOLUTION_CALENDAR_CFLAGS) \
$(EVOLUTION_ADDRESSBOOK_CFLAGS)
@@@ -15,8 -16,9 +16,9 @@@ liborg_gnome_evolution_google_la_SOURCE
google-contacts-source.h \
google-contacts-source.c
- liborg_gnome_evolution_google_la_LIBADD = \
- $(EVOLUTION_CALENDAR_LIBS) \
+ liborg_gnome_evolution_google_la_LIBADD = \
- $(top_builddir)/calendar/gui/libevolution-calendar.la \
++ $(top_builddir)/calendar/gui/libcal-gui.la \
+ $(EVOLUTION_CALENDAR_LIBS) \
$(EPLUGIN_LIBS)
liborg_gnome_evolution_google_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
diff --cc plugins/google-account-setup/google-source.c
index e0655ce,2a8b6c4..8867cf3
--- a/plugins/google-account-setup/google-source.c
+++ b/plugins/google-account-setup/google-source.c
@@@ -36,6 -36,8 +36,7 @@@
#include <e-util/e-plugin.h>
#include <calendar/gui/e-cal-config.h>
+ #include <calendar/gui/e-cal-event.h>
-#include <calendar/gui/calendar-component.h>
#include <libedataserver/e-url.h>
#include <libedataserver/e-account-list.h>
@@@ -57,11 -61,9 +60,9 @@@
/*****************************************************************************/
/* prototypes */
- gint e_plugin_lib_enable (EPluginLib *ep,
- gint enable);
-
- GtkWidget * plugin_google (EPlugin *epl,
- EConfigHookItemFactoryData *data);
+ gint e_plugin_lib_enable (EPluginLib *ep, gint enable);
+ GtkWidget *plugin_google (EPlugin *epl, EConfigHookItemFactoryData *data);
-void e_calendar_google_migrate (EPlugin *epl, ECalEventTargetComponent *data);
++void e_calendar_google_migrate (EPlugin *epl, ECalEventTargetModule *data);
/*****************************************************************************/
/* plugin intialization */
@@@ -734,3 -783,36 +782,34 @@@ plugin_google (EPlugi
return widget;
}
+
+ void
-e_calendar_google_migrate (EPlugin *epl, ECalEventTargetComponent *data)
++e_calendar_google_migrate (EPlugin *epl, ECalEventTargetModule *data)
+ {
- CalendarComponent *component;
+ ESourceList *source_list;
+ ESourceGroup *google = NULL;
+ gboolean changed = FALSE;
+
- component = data->component;
- source_list = calendar_component_peek_source_list (component);
++ source_list = data->source_list;
+
+ google = e_source_list_peek_group_by_base_uri (source_list, GOOGLE_BASE_URI);
+ if (google) {
+ GSList *s;
+
+ for (s = e_source_group_peek_sources (google); s; s = s->next) {
+ ESource *source = E_SOURCE (s->data);
+
+ if (!source)
+ continue;
+
+ /* new source through CalDAV uses absolute uri, thus it should be migrated if not set */
+ if (!e_source_peek_absolute_uri (source)) {
+ update_user_in_source (source, e_source_get_property (source, "username"));
+ changed = TRUE;
+ }
+ }
+ }
+
+ if (changed)
+ e_source_list_sync (source_list, NULL);
+ }
diff --cc widgets/e-timezone-dialog/e-timezone-dialog.c
index 4625a63,22eaabf..8f22695
--- a/widgets/e-timezone-dialog/e-timezone-dialog.c
+++ b/widgets/e-timezone-dialog/e-timezone-dialog.c
@@@ -342,9 -343,15 +343,15 @@@ static icaltimezone
get_local_timezone(void)
{
icaltimezone *zone;
+ gchar *location;
tzset();
- zone = icaltimezone_get_builtin_timezone_from_offset (-timezone, tzname[0]);
+ location = e_cal_system_timezone_get_location ();
+
+ if (location)
- zone = icaltimezone_get_builtin_timezone (location);
++ zone = icaltimezone_get_builtin_timezone (location);
+
+ g_free (location);
return zone;
}
diff --cc widgets/misc/e-account-manager.c
index 24b579d,0000000..8d3d2d2
mode 100644,000000..100644
--- a/widgets/misc/e-account-manager.c
+++ b/widgets/misc/e-account-manager.c
@@@ -1,461 -1,0 +1,454 @@@
+/*
+ * e-account-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-account-manager.h"
+
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include "e-util/e-binding.h"
+#include "e-account-tree-view.h"
+
+#define E_ACCOUNT_MANAGER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ACCOUNT_MANAGER, EAccountManagerPrivate))
+
+struct _EAccountManagerPrivate {
+ EAccountList *account_list;
+
+ GtkWidget *tree_view;
+ GtkWidget *add_button;
+ GtkWidget *edit_button;
+ GtkWidget *delete_button;
+ GtkWidget *default_button;
+};
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT_LIST
+};
+
+enum {
+ ADD_ACCOUNT,
+ EDIT_ACCOUNT,
+ DELETE_ACCOUNT,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+account_manager_default_clicked_cb (EAccountManager *manager)
+{
+ EAccountTreeView *tree_view;
+ EAccountList *account_list;
+ EAccount *account;
+
+ tree_view = e_account_manager_get_tree_view (manager);
+ account_list = e_account_manager_get_account_list (manager);
+ account = e_account_tree_view_get_selected (tree_view);
+ g_return_if_fail (account != NULL);
+
+ e_account_list_set_default (account_list, account);
+
+ /* This signals the tree view to refresh. */
+ e_account_list_change (account_list, account);
+}
+
+static gboolean
+account_manager_key_press_event_cb (EAccountManager *manager,
+ GdkEventKey *event)
+{
+ if (event->keyval == GDK_Delete) {
+ e_account_manager_delete_account (manager);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+account_manager_selection_changed_cb (EAccountManager *manager,
+ GtkTreeSelection *selection)
+{
+ EAccountTreeView *tree_view;
+ EAccountList *account_list;
+ EAccount *default_account;
+ EAccount *account;
+ GtkWidget *add_button;
+ GtkWidget *edit_button;
+ GtkWidget *delete_button;
+ GtkWidget *default_button;
- const gchar *url = NULL;
- gboolean has_proxies;
+ gboolean sensitive;
+
+ add_button = manager->priv->add_button;
+ edit_button = manager->priv->edit_button;
+ delete_button = manager->priv->delete_button;
+ default_button = manager->priv->default_button;
+
+ tree_view = e_account_manager_get_tree_view (manager);
+ account = e_account_tree_view_get_selected (tree_view);
+ account_list = e_account_tree_view_get_account_list (tree_view);
+
- if (account != NULL)
- url = e_account_get_string (account, E_ACCOUNT_SOURCE_URL);
- else
++ if (account == NULL)
+ gtk_widget_grab_focus (add_button);
+
- has_proxies = (url != NULL) &&
- e_account_list_account_has_proxies (account_list, account);
-
+ /* XXX EAccountList misuses const */
+ default_account = (EAccount *)
+ e_account_list_get_default (account_list);
+
- sensitive = (account != NULL) && !has_proxies;
++ sensitive = (account != NULL);
+ gtk_widget_set_sensitive (edit_button, sensitive);
+
+ sensitive = (account != NULL);
+ gtk_widget_set_sensitive (delete_button, sensitive);
+
+ sensitive = (account != NULL && account != default_account);
+ gtk_widget_set_sensitive (default_button, sensitive);
+}
+
+static void
+account_manager_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_LIST:
+ e_account_manager_set_account_list (
+ E_ACCOUNT_MANAGER (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+account_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_LIST:
+ g_value_set_object (
+ value,
+ e_account_manager_get_account_list (
+ E_ACCOUNT_MANAGER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+account_manager_dispose (GObject *object)
+{
+ EAccountManagerPrivate *priv;
+
+ priv = E_ACCOUNT_MANAGER_GET_PRIVATE (object);
+
+ if (priv->account_list != NULL) {
+ g_object_unref (priv->account_list);
+ priv->account_list = NULL;
+ }
+
+ 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->delete_button != NULL) {
+ g_object_unref (priv->delete_button);
+ priv->delete_button = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+account_manager_class_init (EAccountManagerClass *class)
+{
+ GObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EAccountManagerPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = account_manager_set_property;
+ object_class->get_property = account_manager_get_property;
+ object_class->dispose = account_manager_dispose;
+
+ /* XXX If we moved the account editor to /widgets/misc we
+ * could handle adding and editing accounts directly. */
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_LIST,
+ g_param_spec_object (
+ "account-list",
+ "Account List",
+ NULL,
+ E_TYPE_ACCOUNT_LIST,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ signals[ADD_ACCOUNT] = g_signal_new (
+ "add-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EAccountManagerClass, add_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[EDIT_ACCOUNT] = g_signal_new (
+ "edit-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EAccountManagerClass, edit_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DELETE_ACCOUNT] = g_signal_new (
+ "delete-account",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EAccountManagerClass, delete_account),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+account_manager_init (EAccountManager *manager)
+{
+ GtkTreeSelection *selection;
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ manager->priv = E_ACCOUNT_MANAGER_GET_PRIVATE (manager);
+
+ gtk_table_resize (GTK_TABLE (manager), 1, 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_account_tree_view_new ();
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ manager->priv->tree_view = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ e_mutual_binding_new (
+ G_OBJECT (manager), "account-list",
+ G_OBJECT (widget), "account-list");
+
+ g_signal_connect_swapped (
+ widget, "key-press-event",
+ G_CALLBACK (account_manager_key_press_event_cb),
+ manager);
+
+ g_signal_connect_swapped (
+ widget, "row-activated",
+ G_CALLBACK (e_account_manager_edit_account),
+ manager);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+
+ g_signal_connect_swapped (
+ selection, "changed",
+ G_CALLBACK (account_manager_selection_changed_cb),
+ manager);
+
+ container = GTK_WIDGET (manager);
+
+ 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_account_manager_add_account), 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_account_manager_edit_account), manager);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_DELETE);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->delete_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (e_account_manager_delete_account), manager);
+
+ widget = gtk_button_new_with_mnemonic (_("De_fault"));
+ gtk_button_set_image (
+ GTK_BUTTON (widget), gtk_image_new_from_icon_name (
+ "emblem-default", GTK_ICON_SIZE_BUTTON));
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ manager->priv->default_button = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (account_manager_default_clicked_cb), manager);
+}
+
+GType
+e_account_manager_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ static const GTypeInfo type_info = {
+ sizeof (EAccountManagerClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) account_manager_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_init */
+ sizeof (EAccountManager),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) account_manager_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ GTK_TYPE_TABLE, "EAccountManager", &type_info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *
+e_account_manager_new (EAccountList *account_list)
+{
+ g_return_val_if_fail (E_IS_ACCOUNT_LIST (account_list), NULL);
+
+ return g_object_new (
+ E_TYPE_ACCOUNT_MANAGER,
+ "account-list", account_list, NULL);
+}
+
+void
+e_account_manager_add_account (EAccountManager *manager)
+{
+ g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager));
+
+ g_signal_emit (manager, signals[ADD_ACCOUNT], 0);
+}
+
+void
+e_account_manager_edit_account (EAccountManager *manager)
+{
+ g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager));
+
+ g_signal_emit (manager, signals[EDIT_ACCOUNT], 0);
+}
+
+void
+e_account_manager_delete_account (EAccountManager *manager)
+{
+ g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager));
+
+ g_signal_emit (manager, signals[DELETE_ACCOUNT], 0);
+}
+
+EAccountList *
+e_account_manager_get_account_list (EAccountManager *manager)
+{
+ g_return_val_if_fail (E_IS_ACCOUNT_MANAGER (manager), NULL);
+
+ return manager->priv->account_list;
+}
+
+void
+e_account_manager_set_account_list (EAccountManager *manager,
+ EAccountList *account_list)
+{
+ g_return_if_fail (E_IS_ACCOUNT_MANAGER (manager));
+
+ if (account_list != NULL) {
+ g_return_if_fail (E_IS_ACCOUNT_LIST (account_list));
+ g_object_ref (account_list);
+ }
+
+ if (manager->priv->account_list != NULL)
+ g_object_unref (manager->priv->account_list);
+
+ manager->priv->account_list = account_list;
+
+ g_object_notify (G_OBJECT (manager), "account-list");
+}
+
+EAccountTreeView *
+e_account_manager_get_tree_view (EAccountManager *manager)
+{
+ g_return_val_if_fail (E_IS_ACCOUNT_MANAGER (manager), NULL);
+
+ return E_ACCOUNT_TREE_VIEW (manager->priv->tree_view);
+}
diff --cc widgets/misc/e-image-chooser.c
index 2f45154,e5a20e5..32a3f2a
--- a/widgets/misc/e-image-chooser.c
+++ b/widgets/misc/e-image-chooser.c
@@@ -233,38 -392,44 +233,39 @@@ image_drag_drop_cb (GtkWidget *widget
static void
image_drag_data_received_cb (GtkWidget *widget,
- GdkDragContext *context,
- gint x, gint y,
- GtkSelectionData *selection_data,
- guint info, guint time, EImageChooser *chooser)
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ EImageChooser *chooser)
{
- gchar *target_type;
gboolean handled = FALSE;
+ gchar **uris;
+ gchar *buf = NULL;
+ gsize read = 0;
+ GError *error = NULL;
- target_type = gdk_atom_name (selection_data->target);
+ uris = gtk_selection_data_get_uris (selection_data);
- if (!strcmp (target_type, URI_LIST_TYPE)) {
- GError *error = NULL;
- gchar *uri;
- gchar *nl = strstr ((gchar *)selection_data->data, "\r\n");
- gchar *buf = NULL;
- gsize read = 0;
+ if (uris == NULL)
+ goto exit;
- if (nl)
- uri = g_strndup ((gchar *)selection_data->data, nl - (gchar *)selection_data->data);
- else
- uri = g_strdup ((gchar *)selection_data->data);
+ if (e_util_read_file (uris[0], TRUE, &buf, &read, &error) && read > 0 && buf)
+ handled = set_image_from_data (chooser, buf, read);
- g_free (buf);
- if (e_util_read_file (uri, TRUE, &buf, &read, &error) && read > 0 && buf) {
- if (set_image_from_data (chooser, buf, read)) {
- handled = TRUE;
- }
- }
++ if (!handled)
++ g_free (buf);
- if (!handled)
- g_free (buf);
- g_free (uri);
+ g_strfreev (uris);
- if (error) {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
+ if (error) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
}
+exit:
gtk_drag_finish (context, handled, FALSE, time);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]