aboutsummaryrefslogtreecommitdiffstats
path: root/mail/em-folder-browser.c
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2003-09-18 05:19:04 +0800
committerMichael Zucci <zucchi@src.gnome.org>2003-09-18 05:19:04 +0800
commit81a0ff5bc44a3bd11399e6b3c985735737606c8c (patch)
tree54b5ed4342a6843c1db4c7e75f2e1b1fe9b82dff /mail/em-folder-browser.c
parenta36a1bb70b6ebcb51ac39304370c89bda63e11b9 (diff)
downloadgsoc2013-evolution-81a0ff5bc44a3bd11399e6b3c985735737606c8c.tar
gsoc2013-evolution-81a0ff5bc44a3bd11399e6b3c985735737606c8c.tar.gz
gsoc2013-evolution-81a0ff5bc44a3bd11399e6b3c985735737606c8c.tar.bz2
gsoc2013-evolution-81a0ff5bc44a3bd11399e6b3c985735737606c8c.tar.lz
gsoc2013-evolution-81a0ff5bc44a3bd11399e6b3c985735737606c8c.tar.xz
gsoc2013-evolution-81a0ff5bc44a3bd11399e6b3c985735737606c8c.tar.zst
gsoc2013-evolution-81a0ff5bc44a3bd11399e6b3c985735737606c8c.zip
cvs removed.
2003-09-17 Not Zed <NotZed@Ximian.com> * folder-browser.c, folder-browser.h, folder-browser-ui.c folder-browser-ui.h, mail-callbacks.c, mail-callbacks.h mail-display.c, mail-display.h, mail-display-stream.c mail-display-stream.h, mail-format.c, mail-format.h mail-identify.c, mail-search.c, mail-search.h message-browser.c, message-browser.h, subscribe-dialog.c subscribe-dialog.h, mail-font-prefs.c, mail-font-prefs.h: cvs removed. * Makefile.am: Removed mail-font-prefs.[ch], hasn't been built for ages. * em-*.c: killed a bunch of printfs. * em-format-html-display.c (efhd_html_button_press_event): update for html object api chagnes. ** Merge in mail-refactor-2 branch. svn path=/trunk/; revision=22602
Diffstat (limited to 'mail/em-folder-browser.c')
-rw-r--r--mail/em-folder-browser.c933
1 files changed, 933 insertions, 0 deletions
diff --git a/mail/em-folder-browser.c b/mail/em-folder-browser.c
new file mode 100644
index 0000000000..7341f91543
--- /dev/null
+++ b/mail/em-folder-browser.c
@@ -0,0 +1,933 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Michael Zucchi <notzed@ximian.com>
+ * Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2003 Ximian, Inc. (www.ximian.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkvpaned.h>
+#include <gtkhtml/gtkhtml.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <libgnomeprintui/gnome-print-dialog.h>
+
+#include "mail-mt.h"
+#include "mail-ops.h"
+#include "mail-tools.h"
+#include "mail-config.h"
+
+#include <e-util/e-passwords.h>
+#include <e-util/e-dialog-utils.h>
+
+#include <camel/camel-mime-message.h>
+#include <camel/camel-stream.h>
+#include <camel/camel-stream-filter.h>
+#include <camel/camel-mime-filter.h>
+#include <camel/camel-mime-filter-tohtml.h>
+#include <camel/camel-mime-filter-enriched.h>
+#include <camel/camel-multipart.h>
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-url.h>
+
+#include <bonobo/bonobo-main.h>
+#include <bonobo/bonobo-object.h>
+#include <bonobo/bonobo-generic-factory.h>
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-ui-component.h>
+#include <bonobo/bonobo-ui-util.h>
+
+/* for efilterbar stuff */
+#include <e-util/e-sexp.h>
+#include "mail-vfolder.h"
+#include "filter/vfolder-rule.h"
+#include <widgets/misc/e-filter-bar.h>
+#include <camel/camel-search-private.h>
+
+/* gal view crap */
+#include <gal/menus/gal-view-etable.h>
+#include <gal/menus/gal-view-instance.h>
+#include <gal/menus/gal-view-factory-etable.h>
+#include "widgets/menus/gal-view-menus.h"
+
+#include "e-util/e-dialog-utils.h"
+#include "em-utils.h"
+#include "em-format-html-display.h"
+#include "em-format-html-print.h"
+#include "em-folder-browser.h"
+#include "em-subscribe-editor.h"
+#include "message-list.h"
+
+#include "mail-ops.h"
+
+#include "evolution-shell-component-utils.h" /* Pixmap stuff, sigh */
+
+#define d(x)
+
+struct _EMFolderBrowserPrivate {
+ GtkWidget *preview; /* container for message display */
+
+ GtkWidget *subscribe_editor;
+
+ GalViewInstance *view_instance;
+ GalViewMenus *view_menus;
+
+ guint vpane_resize_id;
+ guint list_built_id; /* hook onto list-built for delayed 'select first unread' stuff */
+};
+
+static void emfb_activate(EMFolderView *emfv, BonoboUIComponent *uic, int state);
+static void emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const char *uri);
+
+/* FilterBar stuff ... */
+static void emfb_search_config_search(EFilterBar *efb, FilterRule *rule, int id, const char *query, void *data);
+static void emfb_search_menu_activated(ESearchBar *esb, int id, EMFolderBrowser *fb);
+static void emfb_search_search_activated(ESearchBar *esb, EMFolderBrowser *emfb);
+static void emfb_search_query_changed(ESearchBar *esb, EMFolderBrowser *fb);
+
+static int emfb_list_key_press(ETree *tree, int row, ETreePath path, int col, GdkEvent *ev, EMFolderBrowser *fb);
+
+static const EMFolderViewEnable emfb_enable_map[];
+
+enum {
+ ESB_SAVE,
+};
+
+static ESearchBarItem emfb_search_items[] = {
+ E_FILTERBAR_ADVANCED,
+ { NULL, 0, NULL },
+ E_FILTERBAR_SAVE,
+ E_FILTERBAR_EDIT,
+ { NULL, 0, NULL },
+ { N_("Create _Virtual Folder From Search..."), ESB_SAVE, NULL },
+ { NULL, -1, NULL }
+};
+
+static EMFolderViewClass *emfb_parent;
+
+/* Needed since the paned wont take the position its given otherwise ... */
+static void
+emfb_pane_realised(GtkWidget *w, EMFolderBrowser *emfb)
+{
+ GConfClient *gconf;
+
+ gconf = mail_config_get_gconf_client ();
+ gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int(gconf, "/apps/evolution/mail/display/paned_size", NULL));
+}
+
+static gboolean
+emfb_pane_button_release_event(GtkWidget *w, GdkEventButton *e, EMFolderBrowser *emfb)
+{
+ GConfClient *gconf = mail_config_get_gconf_client ();
+
+ if (GTK_WIDGET_REALIZED (w))
+ gconf_client_set_int(gconf, "/apps/evolution/mail/display/paned_size",
+ gtk_paned_get_position(GTK_PANED(w)), NULL);
+
+ return FALSE;
+}
+
+static void
+emfb_init(GObject *o)
+{
+ EMFolderBrowser *emfb = (EMFolderBrowser *)o;
+ struct _EMFolderBrowserPrivate *p;
+ /* FIXME ... */
+ extern RuleContext *search_context;
+
+ p = emfb->priv = g_malloc0(sizeof(struct _EMFolderBrowserPrivate));
+
+ emfb->view.preview_active = TRUE;
+
+ g_slist_free(emfb->view.ui_files);
+ emfb->view.ui_files = g_slist_append(NULL, EVOLUTION_UIDIR "/evolution-mail-global.xml");
+ emfb->view.ui_files = g_slist_append(emfb->view.ui_files, EVOLUTION_UIDIR "/evolution-mail-list.xml");
+ emfb->view.ui_files = g_slist_append(emfb->view.ui_files, EVOLUTION_UIDIR "/evolution-mail-message.xml");
+
+ emfb->view.enable_map = g_slist_prepend(emfb->view.enable_map, (void *)emfb_enable_map);
+
+ if (search_context) {
+ const char *systemrules = g_object_get_data (G_OBJECT (search_context), "system");
+ const char *userrules = g_object_get_data (G_OBJECT (search_context), "user");
+
+ emfb->search = e_filter_bar_new(search_context, systemrules, userrules, emfb_search_config_search, emfb);
+ e_search_bar_set_menu ((ESearchBar *)emfb->search, emfb_search_items);
+ gtk_widget_show((GtkWidget *)emfb->search);
+
+ g_signal_connect(emfb->search, "menu_activated", G_CALLBACK(emfb_search_menu_activated), emfb);
+ g_signal_connect(emfb->search, "search_activated", G_CALLBACK(emfb_search_search_activated), emfb);
+ g_signal_connect(emfb->search, "query_changed", G_CALLBACK(emfb_search_query_changed), emfb);
+
+ gtk_box_pack_start((GtkBox *)emfb, (GtkWidget *)emfb->search, FALSE, TRUE, 0);
+ }
+
+ emfb->vpane = gtk_vpaned_new();
+ g_signal_connect(emfb->vpane, "realize", G_CALLBACK(emfb_pane_realised), emfb);
+ emfb->priv->vpane_resize_id = g_signal_connect(emfb->vpane, "button_release_event", G_CALLBACK(emfb_pane_button_release_event), emfb);
+
+ gtk_widget_show(emfb->vpane);
+
+ gtk_box_pack_start_defaults((GtkBox *)emfb, emfb->vpane);
+
+ gtk_paned_add1((GtkPaned *)emfb->vpane, (GtkWidget *)emfb->view.list);
+ gtk_widget_show((GtkWidget *)emfb->view.list);
+
+ /* currently: just use a scrolledwindow for preview widget */
+ p->preview = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy((GtkScrolledWindow *)p->preview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type((GtkScrolledWindow *)p->preview, GTK_SHADOW_IN);
+ gtk_widget_show(p->preview);
+
+ gtk_container_add((GtkContainer *)p->preview, (GtkWidget *)emfb->view.preview->formathtml.html);
+ gtk_widget_show((GtkWidget *)emfb->view.preview->formathtml.html);
+
+ gtk_paned_add2((GtkPaned *)emfb->vpane, p->preview);
+ gtk_widget_show(p->preview);
+
+ g_signal_connect(emfb->view.list->tree, "key_press", G_CALLBACK(emfb_list_key_press), emfb);
+}
+
+static void
+emfb_finalise(GObject *o)
+{
+ EMFolderBrowser *emfb = (EMFolderBrowser *)o;
+
+ g_free(emfb->priv);
+
+ ((GObjectClass *)emfb_parent)->finalize(o);
+}
+
+static void
+emfb_destroy(GtkObject *o)
+{
+ EMFolderBrowser *emfb = (EMFolderBrowser *)o;
+
+ if (emfb->priv->list_built_id) {
+ g_signal_handler_disconnect(((EMFolderView *)emfb)->list, emfb->priv->list_built_id);
+ emfb->priv->list_built_id = 0;
+ }
+
+ ((GtkObjectClass *)emfb_parent)->destroy(o);
+}
+
+static void
+emfb_class_init(GObjectClass *klass)
+{
+ klass->finalize = emfb_finalise;
+ ((GtkObjectClass *)klass)->destroy = emfb_destroy;
+ ((EMFolderViewClass *)klass)->set_folder = emfb_set_folder;
+ ((EMFolderViewClass *)klass)->activate = emfb_activate;
+}
+
+GType
+em_folder_browser_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ static const GTypeInfo info = {
+ sizeof(EMFolderBrowserClass),
+ NULL, NULL,
+ (GClassInitFunc)emfb_class_init,
+ NULL, NULL,
+ sizeof(EMFolderBrowser), 0,
+ (GInstanceInitFunc)emfb_init
+ };
+ emfb_parent = g_type_class_ref(em_folder_view_get_type());
+ type = g_type_register_static(em_folder_view_get_type(), "EMFolderBrowser", &info, 0);
+ }
+
+ return type;
+}
+
+GtkWidget *em_folder_browser_new(void)
+{
+ EMFolderBrowser *emfb = g_object_new(em_folder_browser_get_type(), 0);
+
+ return (GtkWidget *)emfb;
+}
+
+void em_folder_browser_show_preview(EMFolderBrowser *emfb, gboolean state)
+{
+ if ((emfb->view.preview_active ^ state) == 0
+ || emfb->view.list == NULL)
+ return;
+
+ emfb->view.preview_active = state;
+
+ if (state) {
+ GConfClient *gconf = mail_config_get_gconf_client ();
+ int paned_size /*, y*/;
+
+ paned_size = gconf_client_get_int(gconf, "/apps/evolution/mail/display/paned_size", NULL);
+
+ /*y = save_cursor_pos (emfb);*/
+ gtk_paned_set_position (GTK_PANED (emfb->vpane), paned_size);
+ gtk_widget_show (GTK_WIDGET (emfb->priv->preview));
+
+ if (emfb->view.list->cursor_uid)
+ message_list_select_uid(emfb->view.list, emfb->view.list->cursor_uid);
+
+ /* need to load/show the current message? */
+ /*do_message_selected (emfb);*/
+ /*set_cursor_pos (emfb, y);*/
+ } else {
+ em_format_format((EMFormat *)emfb->view.preview, NULL);
+ gtk_widget_hide(emfb->priv->preview);
+ /*
+ mail_display_set_message (emfb->mail_display, NULL, NULL, NULL);
+ emfb_ui_message_loaded (emfb);*/
+ }
+
+ /* FIXME: need to update menu's to reflect ui changes */
+}
+
+/* ********************************************************************** */
+
+/* FIXME: Need to separate system rules from user ones */
+/* FIXME: Ugh! */
+
+static void
+emfb_search_menu_activated(ESearchBar *esb, int id, EMFolderBrowser *emfb)
+{
+ EFilterBar *efb = (EFilterBar *)esb;
+
+ d(printf("menu activated\n"));
+
+ switch (id) {
+ case ESB_SAVE:
+ d(printf("Save vfolder\n"));
+ if (efb->current_query) {
+ FilterRule *rule = vfolder_clone_rule(efb->current_query);
+ char *name, *text;
+
+ text = e_search_bar_get_text(esb);
+ name = g_strdup_printf("%s %s", rule->name, (text&&text[0])?text:"''");
+ g_free (text);
+ filter_rule_set_name(rule, name);
+ g_free (name);
+
+ filter_rule_set_source(rule, FILTER_SOURCE_INCOMING);
+ vfolder_rule_add_source((VfolderRule *)rule, emfb->view.folder_uri);
+ vfolder_gui_add_rule((VfolderRule *)rule);
+ }
+ break;
+ }
+}
+
+static void
+emfb_search_config_search(EFilterBar *efb, FilterRule *rule, int id, const char *query, void *data)
+{
+ EMFolderBrowser *emfb = data;
+ GList *partl;
+ struct _camel_search_words *words;
+ int i;
+ GSList *strings = NULL;
+
+ /* we scan the parts of a rule, and set all the types we know about to the query string */
+ partl = rule->parts;
+ while (partl) {
+ FilterPart *part = partl->data;
+
+ if (!strcmp(part->name, "subject")) {
+ FilterInput *input = (FilterInput *)filter_part_find_element(part, "subject");
+ if (input)
+ filter_input_set_value(input, query);
+ } else if (!strcmp(part->name, "body")) {
+ FilterInput *input = (FilterInput *)filter_part_find_element(part, "word");
+ if (input)
+ filter_input_set_value(input, query);
+
+ words = camel_search_words_split(query);
+ for (i=0;i<words->len;i++)
+ strings = g_slist_prepend(strings, g_strdup(words->words[i]->word));
+ camel_search_words_free (words);
+ } else if(!strcmp(part->name, "sender")) {
+ FilterInput *input = (FilterInput *)filter_part_find_element(part, "sender");
+ if (input)
+ filter_input_set_value(input, query);
+ } else if(!strcmp(part->name, "to")) {
+ FilterInput *input = (FilterInput *)filter_part_find_element(part, "recipient");
+ if (input)
+ filter_input_set_value(input, query);
+ }
+
+ partl = partl->next;
+ }
+
+ em_format_html_display_set_search(emfb->view.preview,
+ EM_FORMAT_HTML_DISPLAY_SEARCH_SECONDARY|EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE,
+ strings);
+ while (strings) {
+ GSList *n = strings->next;
+
+ g_free(strings->data);
+ g_slist_free_1(strings);
+ strings = n;
+ }
+}
+
+static void
+emfb_search_search_activated(ESearchBar *esb, EMFolderBrowser *emfb)
+{
+ char *search_word;
+
+ if (emfb->view.list == NULL)
+ return;
+
+ g_object_get (esb, "query", &search_word, NULL);
+ message_list_set_search(emfb->view.list, search_word);
+ g_free(search_word);
+}
+
+static void
+emfb_search_query_changed(ESearchBar *esb, EMFolderBrowser *emfb)
+{
+ int id;
+
+ id = e_search_bar_get_item_id(esb);
+ if (id == E_FILTERBAR_ADVANCED_ID)
+ emfb_search_search_activated(esb, emfb);
+}
+
+/* ********************************************************************** */
+
+static int
+emfb_list_key_press(ETree *tree, int row, ETreePath path, int col, GdkEvent *ev, EMFolderBrowser *emfb)
+{
+ if ((ev->key.state & GDK_CONTROL_MASK) != 0)
+ return FALSE;
+
+ switch (ev->key.keyval) {
+ case GDK_space:
+ em_utils_adjustment_page(gtk_scrolled_window_get_vadjustment((GtkScrolledWindow *)emfb->priv->preview), TRUE);
+ break;
+ case GDK_BackSpace:
+ em_utils_adjustment_page(gtk_scrolled_window_get_vadjustment((GtkScrolledWindow *)emfb->priv->preview), FALSE);
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* ********************************************************************** */
+
+static void
+emfb_edit_invert_selection(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+
+ message_list_invert_selection(emfv->list);
+}
+
+static void
+emfb_edit_select_all(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+
+ message_list_select_all(emfv->list);
+}
+
+static void
+emfb_edit_select_thread(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+
+ message_list_select_thread(emfv->list);
+}
+
+static void
+emfb_folder_properties(BonoboUIComponent *uid, void *data, const char *path)
+{
+ /* If only we could remove this ... */
+ /* Should it be part of the factory? */
+ printf("FIXME: folderproperties\n");
+}
+
+static void
+emfb_folder_expunge(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderBrowser *emfb = data;
+
+ em_utils_expunge_folder ((GtkWidget *) emfb, emfb->view.folder);
+}
+
+static void
+emfb_mark_all_read(BonoboUIComponent *uid, void *data, const char *path)
+{
+ /* FIXME: make a 'mark messages' function? */
+ EMFolderView *emfv = data;
+ GPtrArray *uids;
+ int i;
+
+ uids = camel_folder_get_uids(emfv->folder);
+ camel_folder_freeze(emfv->folder);
+ for (i=0;i<uids->len;i++)
+ camel_folder_set_message_flags(emfv->folder, uids->pdata[i], CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
+ camel_folder_thaw(emfv->folder);
+ camel_folder_free_uids(emfv->folder, uids);
+}
+
+static void
+emfb_view_hide_read(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+
+ message_list_hide_add(emfv->list, "(match-all (system-flag \"seen\"))", ML_HIDE_SAME, ML_HIDE_SAME);
+}
+
+static void
+emfb_view_hide_selected(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+ GPtrArray *uids;
+
+ /* TODO: perhaps this should sit directly on message_list? */
+ /* is it worth it, it's so trivial */
+ uids = message_list_get_selected(emfv->list);
+ message_list_hide_uids(emfv->list, uids);
+ message_list_free_uids(emfv->list, uids);
+}
+
+static void
+emfb_view_show_all(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+
+ message_list_hide_clear(emfv->list);
+}
+
+/* ********************************************************************** */
+
+static void
+emfb_empty_trash(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+
+ em_utils_empty_trash ((GtkWidget *) emfv);
+}
+
+static void
+emfb_forget_passwords(BonoboUIComponent *uid, void *data, const char *path)
+{
+ e_passwords_forget_passwords();
+}
+
+static void
+emfb_mail_compose(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderBrowser *emfb = data;
+
+ em_utils_compose_new_message ((GtkWidget *) emfb);
+}
+
+static void
+emfb_mail_stop(BonoboUIComponent *uid, void *data, const char *path)
+{
+ camel_operation_cancel(NULL);
+}
+
+static void
+emfb_mail_post(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+ char *url;
+
+ url = mail_tools_folder_to_url (emfv->folder);
+ em_utils_post_to_url ((GtkWidget *) emfv, url);
+ g_free (url);
+}
+
+static void
+emfb_tools_filters(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderBrowser *emfb = data;
+
+ em_utils_edit_filters ((GtkWidget *) emfb);
+}
+
+static void
+emfb_subscribe_editor_destroy(GtkWidget *w, EMFolderBrowser *emfb)
+{
+ emfb->priv->subscribe_editor = NULL;
+}
+
+static void
+emfb_tools_subscriptions(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderBrowser *emfb = data;
+
+ if (emfb->priv->subscribe_editor) {
+ gdk_window_show(emfb->priv->subscribe_editor->window);
+ } else {
+ emfb->priv->subscribe_editor = (GtkWidget *)em_subscribe_editor_new();
+ e_dialog_set_transient_for((GtkWindow *)emfb->priv->subscribe_editor, (GtkWidget *)emfb);
+ g_signal_connect(emfb->priv->subscribe_editor, "destroy", G_CALLBACK(emfb_subscribe_editor_destroy), emfb);
+ gtk_widget_show(emfb->priv->subscribe_editor);
+ }
+}
+
+static void
+emfb_tools_vfolders(BonoboUIComponent *uid, void *data, const char *path)
+{
+ /* FIXME: rename/refactor this */
+ vfolder_edit();
+}
+
+static BonoboUIVerb emfb_verbs[] = {
+ BONOBO_UI_UNSAFE_VERB ("EditInvertSelection", emfb_edit_invert_selection),
+ BONOBO_UI_UNSAFE_VERB ("EditSelectAll", emfb_edit_select_all),
+ BONOBO_UI_UNSAFE_VERB ("EditSelectThread", emfb_edit_select_thread),
+ BONOBO_UI_UNSAFE_VERB ("ChangeFolderProperties", emfb_folder_properties),
+ BONOBO_UI_UNSAFE_VERB ("FolderExpunge", emfb_folder_expunge),
+ /* HideDeleted is a toggle */
+ BONOBO_UI_UNSAFE_VERB ("MessageMarkAllAsRead", emfb_mark_all_read),
+ BONOBO_UI_UNSAFE_VERB ("ViewHideRead", emfb_view_hide_read),
+ BONOBO_UI_UNSAFE_VERB ("ViewHideSelected", emfb_view_hide_selected),
+ BONOBO_UI_UNSAFE_VERB ("ViewShowAll", emfb_view_show_all),
+ /* ViewThreaded is a toggle */
+
+ BONOBO_UI_UNSAFE_VERB ("EmptyTrash", emfb_empty_trash),
+ BONOBO_UI_UNSAFE_VERB ("ForgetPasswords", emfb_forget_passwords),
+ BONOBO_UI_UNSAFE_VERB ("MailCompose", emfb_mail_compose),
+ BONOBO_UI_UNSAFE_VERB ("MailPost", emfb_mail_post),
+ BONOBO_UI_UNSAFE_VERB ("MailStop", emfb_mail_stop),
+ BONOBO_UI_UNSAFE_VERB ("ToolsFilters", emfb_tools_filters),
+ BONOBO_UI_UNSAFE_VERB ("ToolsSubscriptions", emfb_tools_subscriptions),
+ BONOBO_UI_UNSAFE_VERB ("ToolsVFolders", emfb_tools_vfolders),
+ /* ViewPreview is a toggle */
+
+ BONOBO_UI_VERB_END
+};
+
+static EPixmap emfb_pixmaps[] = {
+ E_PIXMAP ("/commands/ChangeFolderProperties", "configure_16_folder.xpm"),
+ E_PIXMAP ("/commands/ViewHideRead", "hide_read_messages.xpm"),
+ E_PIXMAP ("/commands/ViewHideSelected", "hide_selected_messages.xpm"),
+ E_PIXMAP ("/commands/ViewShowAll", "show_all_messages.xpm"),
+
+ E_PIXMAP ("/commands/MailCompose", "new-message.xpm"),
+
+ E_PIXMAP_END
+};
+
+static const EMFolderViewEnable emfb_enable_map[] = {
+ { "EditSelectThread", EM_FOLDER_VIEW_SELECT_THREADED },
+ { "ViewHideSelected", EM_POPUP_SELECT_MANY },
+ { "ViewShowAll", EM_FOLDER_VIEW_SELECT_HIDDEN },
+ { NULL },
+};
+
+static void
+emfb_hide_deleted(BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_EventType type, const char *state, void *data)
+{
+ GConfClient *gconf;
+ EMFolderView *emfv = data;
+
+ if (type != Bonobo_UIComponent_STATE_CHANGED)
+ return;
+
+ gconf = mail_config_get_gconf_client ();
+ gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_deleted", state[0] == '0', NULL);
+ if (!(emfv->folder && (emfv->folder->folder_flags & CAMEL_FOLDER_IS_TRASH)))
+ message_list_set_hidedeleted(emfv->list, state[0] != '0');
+}
+
+static void
+emfb_view_threaded(BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_EventType type, const char *state, void *data)
+{
+ GConfClient *gconf;
+ EMFolderView *emfv = data;
+
+ if (type != Bonobo_UIComponent_STATE_CHANGED)
+ return;
+
+ gconf = mail_config_get_gconf_client ();
+ gconf_client_set_bool(gconf, "/apps/evolution/mail/display/thread_list", state[0] != '0', NULL);
+
+ if (camel_object_meta_set(emfv->folder, "evolution:thread_list", state))
+ camel_object_state_write(emfv->folder);
+
+ /* FIXME: do set_threaded via meta-data listener on folder? */
+ message_list_set_threaded(emfv->list, state[0] != '0');
+
+ /* FIXME: update selection state? */
+}
+
+static void
+emfb_view_preview(BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_EventType type, const char *state, void *data)
+{
+ GConfClient *gconf;
+ EMFolderView *emfv = data;
+
+ if (type != Bonobo_UIComponent_STATE_CHANGED)
+ return;
+
+ gconf = mail_config_get_gconf_client ();
+ gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_preview", state[0] != '0', NULL);
+
+ if (camel_object_meta_set(emfv->folder, "evolution:show_preview", state))
+ camel_object_state_write(emfv->folder);
+
+ /* FIXME: do this via folder listener */
+ em_folder_browser_show_preview((EMFolderBrowser *)emfv, state[0] != '0');
+}
+
+/* TODO: This should probably be handled by message-list, by storing/queueing
+ up the select operation if its busy rebuilding the message-list */
+static void
+emfb_list_built(MessageList *ml, EMFolderBrowser *emfb)
+{
+ g_signal_handler_disconnect(ml, emfb->priv->list_built_id);
+ emfb->priv->list_built_id = 0;
+
+ if (((EMFolderView *)emfb)->list->cursor_uid == NULL)
+ message_list_select(((EMFolderView *)emfb)->list,
+ MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN, TRUE);
+}
+
+static void
+emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const char *uri)
+{
+ /* This is required since we get activated the first time
+ before the folder is open and need to override the
+ defaults */
+ if (folder) {
+ char *sstate;
+
+ if ((sstate = camel_object_meta_get(folder, "evolution:show_preview")))
+ em_folder_browser_show_preview((EMFolderBrowser *)emfv, sstate[0] != '0');
+
+ if ((sstate = camel_object_meta_get(folder, "evolution:thread_list")))
+ message_list_set_threaded(emfv->list, sstate[0] == '1');
+
+ if (emfv->list->cursor_uid == NULL && ((EMFolderBrowser *)emfv)->priv->list_built_id == 0)
+ ((EMFolderBrowser *)emfv)->priv->list_built_id =
+ g_signal_connect(emfv->list, "message_list_built", G_CALLBACK(emfb_list_built), emfv);
+ }
+
+ emfb_parent->set_folder(emfv, folder, uri);
+}
+
+/* TODO: All this mess should sit directly on MessageList, but it would
+ need to become BonoboUIComponent aware ... */
+
+static void
+emfb_list_display_view(GalViewInstance *instance, GalView *view, EMFolderBrowser *emfb)
+{
+ if (GAL_IS_VIEW_ETABLE(view))
+ gal_view_etable_attach_tree(GAL_VIEW_ETABLE(view), emfb->view.list->tree);
+}
+
+static void
+emfb_create_view_menus(EMFolderBrowser *emfb, BonoboUIComponent *uic)
+{
+ struct _EMFolderBrowserPrivate *p = emfb->priv;
+ static GalViewCollection *collection = NULL;
+ char *id;
+ gboolean outgoing;
+
+ g_assert(p->view_instance == NULL);
+ g_assert(p->view_menus == NULL);
+
+ outgoing = em_utils_folder_is_drafts(emfb->view.folder, emfb->view.folder_uri)
+ || em_utils_folder_is_sent(emfb->view.folder, emfb->view.folder_uri)
+ || em_utils_folder_is_outbox(emfb->view.folder, emfb->view.folder_uri);
+
+ if (collection == NULL) {
+ ETableSpecification *spec;
+ char *dir;
+ GalViewFactory *factory;
+
+ collection = gal_view_collection_new();
+
+ gal_view_collection_set_title(collection, _("Mail"));
+
+ dir = g_build_filename(g_get_home_dir(), "/evolution/views/mail/", NULL);
+ gal_view_collection_set_storage_directories(collection, EVOLUTION_GALVIEWSDIR "/mail/", dir);
+ g_free(dir);
+
+ spec = e_table_specification_new();
+ e_table_specification_load_from_file(spec, EVOLUTION_ETSPECDIR "/message-list.etspec");
+
+ factory = gal_view_factory_etable_new(spec);
+ g_object_unref(spec);
+ gal_view_collection_add_factory(collection, factory);
+ g_object_unref(factory);
+
+ gal_view_collection_load(collection);
+ }
+
+ /* TODO: should this go through mail-config api? */
+ id = mail_config_folder_to_safe_url(emfb->view.folder);
+ p->view_instance = gal_view_instance_new(collection, id);
+ g_free(id);
+
+ if (outgoing)
+ gal_view_instance_set_default_view(p->view_instance, "As_Sent_Folder");
+
+ if (!gal_view_instance_exists(p->view_instance)) {
+ char *path;
+ struct stat st;
+
+ gal_view_instance_load(p->view_instance);
+
+ path = mail_config_folder_to_cachename(emfb->view.folder, "et-header-");
+ if (path && stat (path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) {
+ ETableSpecification *spec;
+ ETableState *state;
+ GalView *view;
+
+ spec = e_table_specification_new();
+ e_table_specification_load_from_file(spec, EVOLUTION_ETSPECDIR "/message-list.etspec");
+ view = gal_view_etable_new(spec, "");
+ g_object_unref(spec);
+
+ state = e_table_state_new();
+ e_table_state_load_from_file(state, path);
+ gal_view_etable_set_state(GAL_VIEW_ETABLE (view), state);
+ g_object_unref(state);
+
+ gal_view_instance_set_custom_view(p->view_instance, view);
+ g_object_unref(view);
+ }
+ g_free(path);
+ }
+
+ p->view_menus = gal_view_menus_new(p->view_instance);
+ gal_view_menus_apply(p->view_menus, uic, NULL);
+
+ /* Due to CORBA reentrancy, the view could be gone now. */
+ if (p->view_instance == NULL)
+ return;
+
+ g_signal_connect(p->view_instance, "display_view", G_CALLBACK(emfb_list_display_view), emfb);
+ emfb_list_display_view(p->view_instance, gal_view_instance_get_current_view(p->view_instance), emfb);
+}
+
+static void
+emfb_activate(EMFolderView *emfv, BonoboUIComponent *uic, int act)
+{
+ struct _EMFolderBrowserPrivate *p = ((EMFolderBrowser *)emfv)->priv;
+
+ if (act) {
+ GConfClient *gconf;
+ gboolean state;
+ char *sstate;
+
+ gconf = mail_config_get_gconf_client ();
+
+ /* parent loads all ui files via ui_files */
+ emfb_parent->activate(emfv, uic, act);
+
+ bonobo_ui_component_add_verb_list_with_data(uic, emfb_verbs, emfv);
+ e_pixmaps_update(uic, emfb_pixmaps);
+
+#if 0
+ /* FIXME: finish */
+ /* (Pre)view pane size (do this first because it affects the
+ preview settings - see folder_browser_set_message_preview()
+ internals for details) */
+ g_signal_handler_block(emfb->vpane, emfb->priv->vpane_resize_id);
+ gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int (gconf, "/apps/evolution/mail/display/paned_size", NULL));
+ g_signal_handler_unblock(emfb->vpane, emfb->priv->vpane_resize_id);
+#endif
+
+ /* (Pre)view toggle */
+ if (emfv->folder
+ && (sstate = camel_object_meta_get(emfv->folder, "evolution:show_preview"))) {
+ state = sstate[0] == '1';
+ g_free(sstate);
+ } else {
+ state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_preview", NULL);
+ }
+
+ bonobo_ui_component_set_prop(uic, "/commands/ViewPreview", "state", state?"1":"0", NULL);
+ em_folder_browser_show_preview((EMFolderBrowser *)emfv, state);
+ bonobo_ui_component_add_listener(uic, "ViewPreview", emfb_view_preview, emfv);
+
+ /* Stop button */
+ state = mail_msg_active((unsigned int)-1);
+ bonobo_ui_component_set_prop(uic, "/commands/MailStop", "sensitive", state?"1":"0", NULL);
+
+ /* HideDeleted */
+ state = !gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_deleted", NULL);
+ bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "state", state ? "1" : "0", NULL);
+ bonobo_ui_component_add_listener(uic, "HideDeleted", emfb_hide_deleted, emfv);
+ if (!(emfv->folder && (emfv->folder->folder_flags & CAMEL_FOLDER_IS_TRASH)))
+ message_list_set_hidedeleted (emfv->list, state);
+ else
+ bonobo_ui_component_set_prop(uic, "/commands/HideDeleted", "sensitive", state?"1":"0", NULL);
+
+ /* FIXME: If we have no folder, we can't do a few of the lookups we need,
+ perhaps we should postpone till we can */
+
+ /* ViewThreaded */
+ if (emfv->folder
+ && (sstate = camel_object_meta_get(emfv->folder, "evolution:thread_list"))) {
+ state = sstate[0] == '1';
+ g_free(sstate);
+ } else {
+ state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/thread_list", NULL);
+ }
+
+ bonobo_ui_component_set_prop(uic, "/commands/ViewThreaded", "state", state?"1":"0", NULL);
+ bonobo_ui_component_add_listener(uic, "ViewThreaded", emfb_view_threaded, emfv);
+ message_list_set_threaded(emfv->list, state);
+
+ /* FIXME: Selection state */
+
+ /* FIXME: property menu customisation */
+ /*folder_browser_setup_property_menu (fb, fb->uicomp);*/
+
+ if (((EMFolderBrowser *)emfv)->search)
+ e_search_bar_set_ui_component((ESearchBar *)((EMFolderBrowser *)emfv)->search, uic);
+
+ if (emfv->folder)
+ emfb_create_view_menus((EMFolderBrowser *)emfv, uic);
+ } else {
+ const BonoboUIVerb *v;
+
+ for (v = &emfb_verbs[0]; v->cname; v++)
+ bonobo_ui_component_remove_verb(uic, v->cname);
+
+ if (p->view_instance) {
+ g_object_unref(p->view_instance);
+ p->view_instance = NULL;
+ g_object_unref(p->view_menus);
+ p->view_menus = NULL;
+ }
+
+ if (((EMFolderBrowser *)emfv)->search)
+ e_search_bar_set_ui_component((ESearchBar *)((EMFolderBrowser *)emfv)->search, NULL);
+
+ emfb_parent->activate(emfv, uic, act);
+ }
+}