aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog29
-rw-r--r--mail/Makefile.am2
-rw-r--r--mail/em-folder-browser.c125
-rw-r--r--mail/em-folder-selector.c32
-rw-r--r--mail/em-folder-tree.c800
-rw-r--r--mail/em-folder-tree.h3
-rw-r--r--mail/em-folder-utils.c744
-rw-r--r--mail/em-folder-utils.h32
-rw-r--r--mail/em-folder-view.c117
-rw-r--r--mail/mail-component.c27
10 files changed, 1093 insertions, 818 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index e477b2797e..b247d8cdde 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,32 @@
+2005-05-13 Rodney Dawes <dobey@novell.com>
+
+ * Makefile.am: Add new em-folder-utils.[ch] abstraction
+
+ * em-folder-browser.c: Update for new menu layout
+ Add new methods to handle the actions that were previously only
+ available from the context menu when right-clicking on a folder
+
+ * em-folder-selector.c (emfs_response): Just call emfu_folder_create
+ if the user wants to create a new folder in the selector dialog
+ (em_folder_selector_get_selected_path): Clean up the code to fix a
+ couple potential crashes
+
+ * em-folder-tree.[ch]: Add methods to get pointers to a CamelFolder or
+ CamelFolderInfo object for the selected item in the tree
+ Add a method to get a pointer to an EMFolderTreeModelStoreInfo object
+ for the selected store in the tree
+ Move folder operations out into em-folder-utils.[ch] so that they
+ are abstracted from the tree and can be used by methods other than
+ the internal context menu
+
+ * em-folder-utils.[ch]: Move the folder operations code to here
+
+ * em-folder-view.c: Update for the new menu layout
+ Fix Mark as Read/Unread in the context menu to only show up in the list
+
+ * mail-component.c (create_item): Just call emfu_folder_create here
+ when the user requests to create a new folder from the New toolbar item
+
2005-05-13 Shreyas Srinivasan <sshreyas@novell.com>
* Fixes bug #273868, #300113, #302831.
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 567e2256b9..b32973ad58 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -93,6 +93,8 @@ libevolution_mail_la_SOURCES = \
em-folder-tree-model.h \
em-folder-tree.c \
em-folder-tree.h \
+ em-folder-utils.c \
+ em-folder-utils.h \
em-folder-view.c \
em-folder-view.h \
em-format-hook.c \
diff --git a/mail/em-folder-browser.c b/mail/em-folder-browser.c
index 582546facb..257ac8ad38 100644
--- a/mail/em-folder-browser.c
+++ b/mail/em-folder-browser.c
@@ -73,6 +73,7 @@
#include "em-format-html-print.h"
#include "em-folder-browser.h"
#include "em-folder-properties.h"
+#include "em-folder-utils.h"
#include "em-subscribe-editor.h"
#include "em-menu.h"
#include "message-list.h"
@@ -569,6 +570,91 @@ emfb_folder_properties(BonoboUIComponent *uid, void *data, const char *path)
}
static void
+emfb_folder_copy(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderBrowser *emfb = data;
+ CamelFolderInfo *fi = NULL;
+ CamelException ex;
+
+ camel_exception_init (&ex);
+
+ if ((fi = camel_store_get_folder_info (emfb->view.folder->parent_store,
+ emfb->view.folder->full_name,
+ CAMEL_STORE_FOLDER_INFO_FAST,
+ &ex)) != NULL)
+ emfu_copy_folder (fi);
+
+ camel_exception_clear (&ex);
+
+ return;
+}
+
+static void
+emfb_folder_move(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderBrowser *emfb = data;
+ CamelFolderInfo *fi = NULL;
+ CamelException ex;
+
+ camel_exception_init (&ex);
+
+ if ((fi = camel_store_get_folder_info (emfb->view.folder->parent_store,
+ emfb->view.folder->full_name,
+ CAMEL_STORE_FOLDER_INFO_FAST,
+ &ex)) != NULL)
+ emfu_move_folder (fi);
+
+ camel_exception_clear (&ex);
+
+ return;
+}
+
+static void
+emfb_folder_delete(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderBrowser *emfb = data;
+
+ emfu_delete_folder (emfb->view.folder);
+
+ return;
+}
+
+static void
+emfb_folder_rename(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderBrowser *emfb = data;
+
+ emfu_rename_folder (emfb->view.folder);
+
+ return;
+}
+
+static void
+emfb_folder_create(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderBrowser *emfb = data;
+ CamelFolderInfo *fi = NULL;
+ CamelException ex;
+
+ camel_exception_init (&ex);
+
+ if (emfb->view.folder) {
+ if ((fi = camel_store_get_folder_info (emfb->view.folder->parent_store,
+ emfb->view.folder->full_name,
+ CAMEL_STORE_FOLDER_INFO_FAST,
+ &ex)) != NULL)
+ emfu_folder_create (fi);
+ } else {
+ emfu_folder_create (NULL);
+ }
+
+
+ camel_exception_clear (&ex);
+
+ return;
+}
+
+static void
emfb_folder_expunge(BonoboUIComponent *uid, void *data, const char *path)
{
EMFolderBrowser *emfb = data;
@@ -628,25 +714,6 @@ emfb_view_show_all(BonoboUIComponent *uid, void *data, const char *path)
/* ********************************************************************** */
static void
-emfb_empty_trash(BonoboUIComponent *uid, void *data, const char *path)
-{
- EMFolderView *emfv = data;
-
- em_utils_empty_trash (gtk_widget_get_toplevel ((GtkWidget *) emfv));
-}
-
-static void
-emfb_mail_compose(BonoboUIComponent *uid, void *data, const char *path)
-{
- EMFolderView *emfv = data;
-
- if (!em_utils_check_user_can_send_mail((GtkWidget *)emfv))
- return;
-
- em_utils_compose_new_message(emfv->folder_uri);
-}
-
-static void
emfb_mail_stop(BonoboUIComponent *uid, void *data, const char *path)
{
mail_cancel_all();
@@ -712,8 +779,12 @@ static BonoboUIVerb emfb_verbs[] = {
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 ("MailCompose", emfb_mail_compose),
+ BONOBO_UI_UNSAFE_VERB ("FolderCopy", emfb_folder_copy),
+ BONOBO_UI_UNSAFE_VERB ("FolderMove", emfb_folder_move),
+ BONOBO_UI_UNSAFE_VERB ("FolderDelete", emfb_folder_delete),
+ BONOBO_UI_UNSAFE_VERB ("FolderRename", emfb_folder_rename),
+ BONOBO_UI_UNSAFE_VERB ("FolderCreate", emfb_folder_create),
+
BONOBO_UI_UNSAFE_VERB ("MailPost", emfb_mail_post),
BONOBO_UI_UNSAFE_VERB ("MailStop", emfb_mail_stop),
BONOBO_UI_UNSAFE_VERB ("ToolsFilters", emfb_tools_filters),
@@ -726,11 +797,8 @@ static BonoboUIVerb emfb_verbs[] = {
static EPixmap emfb_pixmaps[] = {
E_PIXMAP ("/commands/ChangeFolderProperties", "stock_folder-properties", E_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ViewHideRead", "stock_mail-hide-read", E_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ViewHideSelected", "stock_mail-hide-selected", E_ICON_SIZE_MENU),
- E_PIXMAP ("/commands/ViewShowAll", "stock_show-all", E_ICON_SIZE_MENU),
-
- E_PIXMAP ("/commands/MailCompose", "stock_mail-compose", E_ICON_SIZE_MENU),
+ E_PIXMAP ("/commands/FolderCopy", "stock_folder-copy", E_ICON_SIZE_MENU),
+ E_PIXMAP ("/commands/FolderMove", "stock_folder-move", E_ICON_SIZE_MENU),
E_PIXMAP_END
};
@@ -740,10 +808,13 @@ static const EMFolderViewEnable emfb_enable_map[] = {
{ "EditSelectAll", EM_POPUP_SELECT_FOLDER },
{ "EditSelectThread", EM_FOLDER_VIEW_SELECT_THREADED },
{ "FolderExpunge", EM_POPUP_SELECT_FOLDER },
+ { "FolderCopy", EM_POPUP_SELECT_FOLDER },
+ { "FolderMove", EM_POPUP_SELECT_FOLDER },
+ { "FolderDelete", EM_POPUP_SELECT_FOLDER },
+ { "FolderRename", EM_POPUP_SELECT_FOLDER },
{ "MailPost", EM_POPUP_SELECT_FOLDER },
{ "MessageMarkAllAsRead", EM_POPUP_SELECT_FOLDER },
{ "ViewHideSelected", EM_POPUP_SELECT_MANY },
- { "ViewShowAll", EM_FOLDER_VIEW_SELECT_HIDDEN },
{ NULL },
};
diff --git a/mail/em-folder-selector.c b/mail/em-folder-selector.c
index 69f4662d79..4a88e29ad9 100644
--- a/mail/em-folder-selector.c
+++ b/mail/em-folder-selector.c
@@ -161,28 +161,7 @@ emfs_response (GtkWidget *dialog, int response, EMFolderSelector *emfs)
if (response != EM_FOLDER_SELECTOR_RESPONSE_NEW)
return;
- model = em_folder_tree_get_model (emfs->emft);
- emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
- dialog = em_folder_selector_create_new (emft, 0, _("Create New Folder"), _("Specify where to create the folder:"));
- gtk_window_set_transient_for ((GtkWindow *) dialog, (GtkWindow *) emfs);
- uri = em_folder_selector_get_selected_uri (emfs);
- if (uri)
- em_folder_tree_set_selected (emft, uri);
-
- if (gtk_dialog_run ((GtkDialog *) dialog) == GTK_RESPONSE_OK) {
- uri = em_folder_selector_get_selected_uri ((EMFolderSelector *) dialog);
- path = em_folder_selector_get_selected_path ((EMFolderSelector *) dialog);
-
- g_free (emfs->created_uri);
- emfs->created_uri = g_strdup (uri);
-
- if (emfs->created_id == 0)
- emfs->created_id = g_signal_connect (model, "folder-added", G_CALLBACK (folder_created_cb), emfs);
-
- em_folder_tree_create_folder (emfs->emft, path, uri);
- }
-
- gtk_widget_destroy (dialog);
+ emfu_folder_create (NULL);
g_signal_stop_emission_by_name (emfs, "response");
}
@@ -421,13 +400,10 @@ em_folder_selector_get_selected_path (EMFolderSelector *emfs)
char *newpath;
name = gtk_entry_get_text (emfs->name_entry);
- if (strcmp (path, "") != 0)
- newpath = g_strdup_printf ("%s/%s", path?path:"", name);
- else
- newpath = g_strdup (name);
-
+ newpath = g_strdup_printf ("%s/%s", path?path:"", name);
+
g_free(path);
- emfs->selected_path = newpath;
+ emfs->selected_path = g_strdup (newpath);
} else {
g_free(emfs->selected_path);
emfs->selected_path = path?path:g_strdup("");
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index d0e34e9e83..c584f1f138 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -67,6 +67,7 @@
#include "em-popup.h"
#include "em-marshal.h"
#include "em-folder-tree.h"
+#include "em-folder-utils.h"
#include "em-folder-selector.h"
#include "em-folder-selection.h"
#include "em-folder-properties.h"
@@ -2003,597 +2004,40 @@ emft_popup_open_new (GtkWidget *item, EMFolderTree *emft)
#endif
-struct _EMCopyFolders {
- struct _mail_msg msg;
-
- /* input data */
- CamelStore *fromstore;
- CamelStore *tostore;
-
- char *frombase;
- char *tobase;
-
- int delete;
-};
-
-static char *
-emft_copy_folders__desc (struct _mail_msg *mm, int complete)
-{
- struct _EMCopyFolders *m = (struct _EMCopyFolders *) mm;
-
- return g_strdup_printf (_("Copying `%s' to `%s'"), m->frombase, m->tobase);
-}
-
-static void
-emft_copy_folders__copy (struct _mail_msg *mm)
-{
- struct _EMCopyFolders *m = (struct _EMCopyFolders *) mm;
- guint32 flags = CAMEL_STORE_FOLDER_INFO_FAST | CAMEL_STORE_FOLDER_INFO_RECURSIVE;
- GList *pending = NULL, *deleting = NULL, *l;
- GString *fromname, *toname;
- CamelFolderInfo *fi;
- const char *tmp;
- int fromlen;
-
- if (camel_store_supports_subscriptions (m->fromstore))
- flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
-
- if (!(fi = camel_store_get_folder_info (m->fromstore, m->frombase, flags, &mm->ex)))
- return;
-
- pending = g_list_append (pending, fi);
-
- toname = g_string_new ("");
- fromname = g_string_new ("");
-
- tmp = strrchr (m->frombase, '/');
- if (tmp == NULL)
- fromlen = 0;
- else
- fromlen = tmp - m->frombase + 1;
-
- d(printf ("top name is '%s'\n", fi->full_name));
-
- while (pending) {
- CamelFolderInfo *info = pending->data;
-
- pending = g_list_remove_link (pending, pending);
- while (info) {
- CamelFolder *fromfolder, *tofolder;
- GPtrArray *uids;
- int deleted = 0;
-
- if (info->child)
- pending = g_list_append (pending, info->child);
-
- if (m->tobase[0])
- g_string_printf (toname, "%s/%s", m->tobase, info->full_name + fromlen);
- else
- g_string_printf (toname, "%s", info->full_name + fromlen);
-
- d(printf ("Copying from '%s' to '%s'\n", info->full_name, toname->str));
-
- /* This makes sure we create the same tree, e.g. from a nonselectable source */
- /* Not sure if this is really the 'right thing', e.g. for spool stores, but it makes the ui work */
- if ((info->flags & CAMEL_FOLDER_NOSELECT) == 0) {
- d(printf ("this folder is selectable\n"));
- if (m->tostore == m->fromstore && m->delete) {
- camel_store_rename_folder (m->fromstore, info->full_name, toname->str, &mm->ex);
- if (camel_exception_is_set (&mm->ex))
- goto exception;
-
- /* this folder no longer exists, unsubscribe it */
- if (camel_store_supports_subscriptions (m->fromstore))
- camel_store_unsubscribe_folder (m->fromstore, info->full_name, NULL);
-
- deleted = 1;
- } else {
- if (!(fromfolder = camel_store_get_folder (m->fromstore, info->full_name, 0, &mm->ex)))
- goto exception;
-
- if (!(tofolder = camel_store_get_folder (m->tostore, toname->str, CAMEL_STORE_FOLDER_CREATE, &mm->ex))) {
- camel_object_unref (fromfolder);
- goto exception;
- }
-
- uids = camel_folder_get_uids (fromfolder);
- camel_folder_transfer_messages_to (fromfolder, uids, tofolder, NULL, m->delete, &mm->ex);
- camel_folder_free_uids (fromfolder, uids);
-
- if (m->delete)
- camel_folder_sync(fromfolder, TRUE, NULL);
-
- camel_object_unref (fromfolder);
- camel_object_unref (tofolder);
- }
- }
-
- if (camel_exception_is_set (&mm->ex))
- goto exception;
- else if (m->delete && !deleted)
- deleting = g_list_prepend (deleting, info);
-
- /* subscribe to the new folder if appropriate */
- if (camel_store_supports_subscriptions (m->tostore)
- && !camel_store_folder_subscribed (m->tostore, toname->str))
- camel_store_subscribe_folder (m->tostore, toname->str, NULL);
-
- info = info->next;
- }
- }
-
- /* delete the folders in reverse order from how we copyied them, if we are deleting any */
- l = deleting;
- while (l) {
- CamelFolderInfo *info = l->data;
-
- d(printf ("deleting folder '%s'\n", info->full_name));
-
- /* FIXME: we need to do something with the exception
- since otherwise the users sees a failed operation
- with no error message or even any warnings */
- if (camel_store_supports_subscriptions (m->fromstore))
- camel_store_unsubscribe_folder (m->fromstore, info->full_name, NULL);
-
- camel_store_delete_folder (m->fromstore, info->full_name, NULL);
- l = l->next;
- }
-
- exception:
-
- camel_store_free_folder_info (m->fromstore, fi);
- g_list_free (deleting);
-
- g_string_free (toname, TRUE);
- g_string_free (fromname, TRUE);
-}
-
-static void
-emft_copy_folders__free (struct _mail_msg *mm)
-{
- struct _EMCopyFolders *m = (struct _EMCopyFolders *) mm;
-
- camel_object_unref (m->fromstore);
- camel_object_unref (m->tostore);
-
- g_free (m->frombase);
- g_free (m->tobase);
-}
-
-static struct _mail_msg_op copy_folders_op = {
- emft_copy_folders__desc,
- emft_copy_folders__copy,
- NULL,
- emft_copy_folders__free,
-};
-
-static void
-emft_copy_folders (CamelStore *tostore, const char *tobase, CamelStore *fromstore, const char *frombase, int delete)
-{
- struct _EMCopyFolders *m;
-
- m = mail_msg_new (&copy_folders_op, NULL, sizeof (struct _EMCopyFolders));
- camel_object_ref (fromstore);
- m->fromstore = fromstore;
- camel_object_ref (tostore);
- m->tostore = tostore;
- m->frombase = g_strdup (frombase);
- m->tobase = g_strdup (tobase);
- m->delete = delete;
-
- e_thread_put (mail_thread_new, (EMsg *) m);
-}
-
-struct _copy_folder_data {
- EMFolderTree *emft;
- gboolean delete;
-};
-
-static void
-emft_popup_copy_folder_selected (const char *uri, void *data)
-{
- struct _copy_folder_data *cfd = data;
- struct _EMFolderTreePrivate *priv;
- CamelStore *fromstore = NULL, *tostore = NULL;
- char *tobase = NULL, *frombase = NULL, *fromuri = NULL;
- CamelException ex;
- CamelURL *url;
-
- if (uri == NULL) {
- g_free (cfd);
- return;
- }
-
- priv = cfd->emft->priv;
-
- camel_exception_init (&ex);
-
- fromuri = em_folder_tree_get_selected_uri(cfd->emft);
- g_return_if_fail(fromuri != NULL);
- frombase = em_folder_tree_get_selected_path(cfd->emft);
- g_return_if_fail(frombase != NULL);
-
- if (!(fromstore = camel_session_get_store (session, fromuri, &ex))) {
- e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *) cfd->emft),
- cfd->delete?"mail:no-move-folder-notexist":"mail:no-copy-folder-notexist", frombase, uri, ex.desc, NULL);
- goto fail;
- }
-
- if (cfd->delete && fromstore == mail_component_peek_local_store (NULL) && is_special_local_folder (frombase)) {
- e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *) cfd->emft),
- "mail:no-rename-special-folder", frombase, NULL);
- goto fail;
- }
-
- if (!(tostore = camel_session_get_store (session, uri, &ex))) {
- e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *) cfd->emft),
- cfd->delete?"mail:no-move-folder-to-notexist":"mail:no-copy-folder-to-notexist", frombase, uri, ex.desc, NULL);
- goto fail;
- }
-
- url = camel_url_new (uri, NULL);
- if (((CamelService *)tostore)->provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH)
- tobase = url->fragment;
- else if (url->path && url->path[0])
- tobase = url->path+1;
- if (tobase == NULL)
- tobase = "";
-
- emft_copy_folders (tostore, tobase, fromstore, frombase, cfd->delete);
-
- camel_url_free (url);
-fail:
- if (fromstore)
- camel_object_unref(fromstore);
- if (tostore)
- camel_object_unref(tostore);
- g_free(frombase);
- g_free(fromuri);
- camel_exception_clear (&ex);
- g_free (cfd);
-}
-
-/* tree here is the 'destination' selector, not 'self' */
-static gboolean
-emft_popup_copy_folder_exclude(EMFolderTree *tree, GtkTreeModel *model, GtkTreeIter *iter, void *data)
-{
- struct _copy_folder_data *cfd = data;
- int fromvfolder, tovfolder;
- char *fromuri, *touri;
- guint flags;
- gboolean is_store;
-
- /* handles moving to/from vfolders */
-
- fromuri = em_folder_tree_get_selected_uri(cfd->emft);
- fromvfolder = strncmp(fromuri, "vfolder:", 8) == 0;
- gtk_tree_model_get(model, iter, COL_STRING_URI, &touri, COL_UINT_FLAGS, &flags, COL_BOOL_IS_STORE, &is_store, -1);
- tovfolder = strncmp(touri, "vfolder:", 8) == 0;
- g_free(fromuri);
- g_free(touri);
-
- /* moving from vfolder to normal- not allowed */
- if (fromvfolder && !tovfolder && cfd->delete)
- return FALSE;
- /* copy/move from normal folder to vfolder - not allowed */
- if (!fromvfolder && tovfolder)
- return FALSE;
- /* copying to vfolder - not allowed */
- if (tovfolder && !cfd->delete)
- return FALSE;
-
- return (flags & EMFT_EXCLUDE_NOINFERIORS) == 0;
-}
-
static void
emft_popup_copy(EPopup *ep, EPopupItem *item, void *data)
{
EMFolderTree *emft = data;
- struct _copy_folder_data *cfd;
-
- cfd = g_malloc (sizeof (*cfd));
- cfd->emft = emft;
- cfd->delete = FALSE;
-
- em_select_folder (NULL, _("Select folder"), _("C_opy"),
- NULL, emft_popup_copy_folder_exclude, emft_popup_copy_folder_selected, cfd);
-}
+ CamelFolderInfo *fi = NULL;
-static void
-emft_popup_move(EPopup *ep, EPopupItem *item, void *data)
-{
- EMFolderTree *emft = data;
- struct _copy_folder_data *cfd;
-
- cfd = g_malloc (sizeof (*cfd));
- cfd->emft = emft;
- cfd->delete = TRUE;
-
- em_select_folder (NULL, _("Select folder"), _("_Move"),
- NULL, emft_popup_copy_folder_exclude, emft_popup_copy_folder_selected, cfd);
-}
-
-
-struct _EMCreateFolder {
- struct _mail_msg msg;
-
- /* input data */
- CamelStore *store;
- char *full_name;
- char *parent;
- char *name;
-
- /* output data */
- CamelFolderInfo *fi;
-
- /* callback data */
- void (* done) (CamelFolderInfo *fi, void *user_data);
- void *user_data;
-};
-
-static char *
-emft_create_folder__desc (struct _mail_msg *mm, int done)
-{
- struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm;
-
- return g_strdup_printf (_("Creating folder `%s'"), m->full_name);
-}
-
-static void
-emft_create_folder__create (struct _mail_msg *mm)
-{
- struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm;
-
- d(printf ("creating folder parent='%s' name='%s' full_name='%s'\n", m->parent, m->name, m->full_name));
-
- if ((m->fi = camel_store_create_folder (m->store, m->parent, m->name, &mm->ex))) {
- if (camel_store_supports_subscriptions (m->store))
- camel_store_subscribe_folder (m->store, m->full_name, &mm->ex);
+ if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL) {
+ emfu_copy_folder (fi);
}
}
static void
-emft_create_folder__created (struct _mail_msg *mm)
-{
- struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm;
-
- if (m->done)
- m->done (m->fi, m->user_data);
-}
-
-static void
-emft_create_folder__free (struct _mail_msg *mm)
-{
- struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm;
-
- camel_store_free_folder_info (m->store, m->fi);
- camel_object_unref (m->store);
- g_free (m->full_name);
- g_free (m->parent);
- g_free (m->name);
-}
-
-static struct _mail_msg_op create_folder_op = {
- emft_create_folder__desc,
- emft_create_folder__create,
- emft_create_folder__created,
- emft_create_folder__free,
-};
-
-
-static int
-emft_create_folder (CamelStore *store, const char *full_name, void (* done) (CamelFolderInfo *fi, void *user_data), void *user_data)
-{
- char *name, *namebuf = NULL;
- struct _EMCreateFolder *m;
- const char *parent;
- int id;
-
- namebuf = g_strdup (full_name);
- if (!(name = strrchr (namebuf, '/'))) {
- name = namebuf;
- parent = "";
- } else {
- *name++ = '\0';
- parent = namebuf;
- }
-
- m = mail_msg_new (&create_folder_op, NULL, sizeof (struct _EMCreateFolder));
- camel_object_ref (store);
- m->store = store;
- m->full_name = g_strdup (full_name);
- m->parent = g_strdup (parent);
- m->name = g_strdup (name);
- m->user_data = user_data;
- m->done = done;
-
- g_free (namebuf);
-
- id = m->msg.seq;
- e_thread_put (mail_thread_new, (EMsg *) m);
-
- return id;
-}
-
-static void
-created_cb (CamelFolderInfo *fi, void *user_data)
-{
- gboolean *created = user_data;
-
- *created = fi ? TRUE : FALSE;
-}
-
-gboolean
-em_folder_tree_create_folder (EMFolderTree *emft, const char *full_name, const char *uri)
-{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
- gboolean created = FALSE;
- CamelStore *store;
- CamelException ex;
-
- d(printf ("Creating folder: %s (%s)\n", full_name, uri));
-
- camel_exception_init (&ex);
- if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
- e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)emft),
- "mail:no-create-folder-nostore", full_name, ex.desc, NULL);
- goto fail;
- }
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
- abort();
- camel_object_unref (store);
- goto fail;
- }
-
- camel_object_unref (store);
-
- mail_msg_wait (emft_create_folder (si->store, full_name, created_cb, &created));
-fail:
- camel_exception_clear(&ex);
-
- return created;
-}
-
-static void
-new_folder_created_cb (CamelFolderInfo *fi, void *user_data)
-{
- EMFolderSelector *emfs = user_data;
-
- if (fi)
- gtk_widget_destroy ((GtkWidget *) emfs);
-
- g_object_unref (emfs);
-}
-
-static void
-emft_popup_new_folder_response (EMFolderSelector *emfs, int response, EMFolderTree *emft)
+emft_popup_move(EPopup *ep, EPopupItem *item, void *data)
{
- struct _EMFolderTreePrivate *priv = emft->priv;
- struct _EMFolderTreeModelStoreInfo *si;
- const char *uri, *path;
- CamelException ex;
- CamelStore *store;
-
- if (response != GTK_RESPONSE_OK) {
- gtk_widget_destroy ((GtkWidget *) emfs);
- return;
- }
-
- uri = em_folder_selector_get_selected_uri (emfs);
- path = em_folder_selector_get_selected_path (emfs);
-
- d(printf ("Creating new folder: %s (%s)\n", path, uri));
-
- camel_exception_init (&ex);
- if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
- camel_exception_clear (&ex);
- return;
- }
-
- if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
- g_assert_not_reached ();
- camel_object_unref (store);
- return;
- }
-
- /* HACK: we need to create vfolders using the vfolder editor */
- if (CAMEL_IS_VEE_STORE(store)) {
- EMVFolderRule *rule;
+ EMFolderTree *emft = data;
+ CamelFolderInfo *fi = NULL;
- rule = em_vfolder_rule_new();
- filter_rule_set_name((FilterRule *)rule, path);
- vfolder_gui_add_rule(rule);
- gtk_widget_destroy((GtkWidget *)emfs);
- } else {
- g_object_ref (emfs);
- emft_create_folder (si->store, path, new_folder_created_cb, emfs);
+ if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL) {
+ emfu_copy_folder (fi);
}
-
- camel_object_unref (store);
}
static void
emft_popup_new_folder (EPopup *ep, EPopupItem *pitem, void *data)
{
EMFolderTree *emft = data;
+ CamelFolderInfo *fi;
- EMFolderTree *folder_tree;
- GtkWidget *dialog;
- char *uri;
-
- folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (emft->priv->model);
-
- dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:"));
- uri = em_folder_tree_get_selected_uri(emft);
- em_folder_selector_set_selected ((EMFolderSelector *) dialog, uri);
- g_free(uri);
- g_signal_connect (dialog, "response", G_CALLBACK (emft_popup_new_folder_response), emft);
- gtk_widget_show (dialog);
-}
-
-static void
-emft_popup_delete_rec (CamelStore *store, CamelFolderInfo *fi, CamelException *ex)
-{
- while (fi) {
- CamelFolder *folder;
-
- if (fi->child) {
- emft_popup_delete_rec (store, fi->child, ex);
- if (camel_exception_is_set (ex))
- return;
- }
-
- d(printf ("deleting folder '%s'\n", fi->full_name));
-
- /* shouldn't camel do this itself? */
- if (camel_store_supports_subscriptions (store))
- camel_store_unsubscribe_folder (store, fi->full_name, NULL);
-
- if (!(folder = camel_store_get_folder (store, fi->full_name, 0, ex)))
- return;
-
- if (!CAMEL_IS_VEE_FOLDER (folder)) {
- GPtrArray *uids = camel_folder_get_uids (folder);
- int i;
-
- camel_folder_freeze (folder);
- for (i = 0; i < uids->len; i++)
- camel_folder_delete_message (folder, uids->pdata[i]);
-
- camel_folder_free_uids (folder, uids);
-
- camel_folder_sync (folder, TRUE, NULL);
- camel_folder_thaw (folder);
- }
-
- camel_store_delete_folder (store, fi->full_name, ex);
- if (camel_exception_is_set (ex))
- return;
-
- fi = fi->next;
+ if ((fi = em_folder_tree_get_selected_folder_info (emft)) != NULL) {
+ emfu_folder_create (fi);
}
}
static void
-emft_popup_delete_folders (CamelStore *store, const char *full_name, CamelException *ex)
-{
- guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_FAST;
- CamelFolderInfo *fi;
-
- if (camel_store_supports_subscriptions (store))
- flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
-
- fi = camel_store_get_folder_info (store, full_name, flags, ex);
- if (camel_exception_is_set (ex))
- return;
-
- emft_popup_delete_rec (store, fi, ex);
- camel_store_free_folder_info (store, fi);
-}
-
-static void
selfunc (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
struct _emft_selection_data *dat = (struct _emft_selection_data *) data;
@@ -2620,163 +2064,25 @@ emft_selection_get_selected (GtkTreeSelection *selection, GtkTreeModel **model,
}
static void
-emft_popup_delete_response (GtkWidget *dialog, int response, EMFolderTree *emft)
-{
- CamelStore *store;
- CamelException ex;
- char *full_name;
-
- full_name = g_object_get_data ((GObject *) dialog, "full_name");
- store = g_object_get_data ((GObject *) dialog, "store");
-
- if (response == GTK_RESPONSE_OK) {
- camel_exception_init (&ex);
- emft_popup_delete_folders (store, full_name, &ex);
- if (camel_exception_is_set (&ex)) {
- e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)emft),
- "mail:no-delete-folder", full_name, ex.desc, NULL);
- camel_exception_clear (&ex);
- }
- }
-
- gtk_widget_destroy (dialog);
-}
-
-static void
emft_popup_delete_folder (EPopup *ep, EPopupItem *pitem, void *data)
{
EMFolderTree *emft = data;
- struct _EMFolderTreePrivate *priv = emft->priv;
- GtkTreeSelection *selection;
- CamelStore *local, *store;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkWidget *dialog;
- char *full_name;
-
- selection = gtk_tree_view_get_selection (priv->treeview);
- if (!emft_selection_get_selected (selection, &model, &iter))
- return;
-
- gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_FULL_NAME, &full_name, -1);
-
- local = mail_component_peek_local_store (NULL);
-
- if (store == local && is_special_local_folder (full_name)) {
- e_error_run(NULL, "mail:no-delete-special-folder", full_name, NULL);
- return;
- }
-
- camel_object_ref (store);
+ CamelFolder *folder;
- dialog = e_error_new((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)emft),
- (store && CAMEL_IS_VEE_STORE(store))?"mail:ask-delete-vfolder":"mail:ask-delete-folder",
- full_name, NULL);
- g_object_set_data_full ((GObject *) dialog, "full_name", full_name, g_free);
- g_object_set_data_full ((GObject *) dialog, "store", store, camel_object_unref);
- g_signal_connect (dialog, "response", G_CALLBACK (emft_popup_delete_response), emft);
- gtk_widget_show (dialog);
+ if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
+ emfu_delete_folder (folder);
+ }
}
static void
emft_popup_rename_folder (EPopup *ep, EPopupItem *pitem, void *data)
{
EMFolderTree *emft = data;
- struct _EMFolderTreePrivate *priv = emft->priv;
- char *prompt, *full_name, *name, *new_name, *uri;
- GtkTreeSelection *selection;
- const char *p;
- CamelStore *local, *store;
- gboolean done = FALSE;
- GtkTreeModel *model;
- GtkTreeIter iter;
- size_t base_len;
-
- local = mail_component_peek_local_store (NULL);
-
- selection = gtk_tree_view_get_selection (priv->treeview);
- if (!emft_selection_get_selected (selection, &model, &iter))
- return;
-
- gtk_tree_model_get (model, &iter, COL_STRING_FULL_NAME, &full_name,
- COL_STRING_DISPLAY_NAME, &name,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_URI, &uri, -1);
-
- /* don't allow user to rename one of the special local folders */
- if (store == local && is_special_local_folder (full_name)) {
- e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)emft),
- "mail:no-rename-special-folder", full_name, NULL);
- g_free (full_name);
- g_free (name);
- g_free (uri);
- return;
- }
-
- if ((p = strrchr (full_name, '/')))
- base_len = (size_t) (p - full_name);
- else
- base_len = 0;
-
- prompt = g_strdup_printf (_("Rename the \"%s\" folder to:"), name);
- while (!done) {
- new_name = e_request_string (NULL, _("Rename Folder"), prompt, name);
- if (new_name == NULL || !strcmp (name, new_name)) {
- /* old name == new name */
- done = TRUE;
- } else if (strchr(new_name, '/') != NULL) {
- e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)emft),
- "mail:no-rename-folder", name, new_name, _("Folder names cannot contain '/'"), NULL);
- done = TRUE;
- } else {
- CamelFolderInfo *fi;
- CamelException ex;
- char *path, *p;
-
- if (base_len > 0) {
- path = g_malloc (base_len + strlen (new_name) + 2);
- memcpy (path, full_name, base_len);
- p = path + base_len;
- *p++ = '/';
- strcpy (p, new_name);
- } else {
- path = g_strdup (new_name);
- }
-
- camel_exception_init (&ex);
- if ((fi = camel_store_get_folder_info (store, path, CAMEL_STORE_FOLDER_INFO_FAST, &ex)) != NULL) {
- camel_store_free_folder_info (store, fi);
- e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)emft),
- "mail:no-rename-folder-exists", name, new_name, NULL);
- } else {
- const char *oldpath, *newpath;
-
- oldpath = full_name;
- newpath = path;
-
- d(printf ("renaming %s to %s\n", oldpath, newpath));
-
- camel_exception_clear (&ex);
- camel_store_rename_folder (store, oldpath, newpath, &ex);
- if (camel_exception_is_set (&ex)) {
- e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)emft),
- "mail:no-rename-folder", oldpath, newpath, ex.desc, NULL);
- camel_exception_clear (&ex);
- }
-
- done = TRUE;
- }
-
- g_free (path);
- }
-
- g_free (new_name);
+ CamelFolder *folder;
+
+ if ((folder = em_folder_tree_get_selected_folder (emft)) != NULL) {
+ emfu_rename_folder (folder);
}
-
- g_free (full_name);
- g_free (name);
- g_free (uri);
}
@@ -3030,6 +2336,60 @@ em_folder_tree_get_selected_path (EMFolderTree *emft)
return name;
}
+CamelFolder *
+em_folder_tree_get_selected_folder (EMFolderTree *emft)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ char *full_name = NULL;
+ CamelException ex;
+ CamelStore *store = NULL;
+ CamelFolder *folder = NULL;
+
+ g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
+
+ camel_exception_init (&ex);
+
+ selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_FULL_NAME, &full_name, -1);
+
+ folder = camel_store_get_folder (store, full_name, CAMEL_STORE_FOLDER_INFO_FAST, &ex);
+
+ camel_exception_clear (&ex);
+
+ return folder;
+}
+
+CamelFolderInfo *
+em_folder_tree_get_selected_folder_info (EMFolderTree *emft)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ char *full_name = NULL;
+ CamelException ex;
+ CamelStore *store = NULL;
+ CamelFolderInfo *fi = NULL;
+
+ g_return_val_if_fail (EM_IS_FOLDER_TREE (emft), NULL);
+
+ camel_exception_init (&ex);
+
+ selection = gtk_tree_view_get_selection(emft->priv->treeview);
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ gtk_tree_model_get (model, &iter, COL_POINTER_CAMEL_STORE, &store,
+ COL_STRING_FULL_NAME, &full_name, -1);
+
+ fi = camel_store_get_folder_info (store, full_name, CAMEL_STORE_FOLDER_INFO_FAST, &ex);
+
+ camel_exception_clear (&ex);
+
+ return fi;
+}
+
EMFolderTreeModel *
em_folder_tree_get_model (EMFolderTree *emft)
{
@@ -3038,6 +2398,18 @@ em_folder_tree_get_model (EMFolderTree *emft)
return emft->priv->model;
}
+EMFolderTreeModelStoreInfo *
+em_folder_tree_get_model_storeinfo (EMFolderTree *emft, CamelStore *store)
+{
+ struct _EMFolderTreePrivate *priv = emft->priv;
+ struct _EMFolderTreeModelStoreInfo *si;
+
+ if (!(si = g_hash_table_lookup (priv->model->store_hash, store))) {
+ g_assert_not_reached ();
+ return NULL;
+ }
+ return si;
+}
static gboolean
emft_save_state (EMFolderTree *emft)
diff --git a/mail/em-folder-tree.h b/mail/em-folder-tree.h
index e7c465998b..35381dbfa3 100644
--- a/mail/em-folder-tree.h
+++ b/mail/em-folder-tree.h
@@ -85,8 +85,11 @@ GList *em_folder_tree_get_selected_paths (EMFolderTree *emft);
void em_folder_tree_set_selected (EMFolderTree *emft, const char *uri);
char *em_folder_tree_get_selected_uri (EMFolderTree *emft);
char *em_folder_tree_get_selected_path (EMFolderTree *emft);
+CamelFolder *em_folder_tree_get_selected_folder (EMFolderTree *emft);
+CamelFolderInfo *em_folder_tree_get_selected_folder_info (EMFolderTree *emft);
EMFolderTreeModel *em_folder_tree_get_model (EMFolderTree *emft);
+EMFolderTreeModelStoreInfo *em_folder_tree_get_model_storeinfo (EMFolderTree *emft, CamelStore *store);
gboolean em_folder_tree_create_folder (EMFolderTree *emft, const char *full_name, const char *uri);
diff --git a/mail/em-folder-utils.c b/mail/em-folder-utils.c
new file mode 100644
index 0000000000..1e836fa661
--- /dev/null
+++ b/mail/em-folder-utils.c
@@ -0,0 +1,744 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <libxml/tree.h>
+
+#include <gtk/gtk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <libgnome/gnome-i18n.h>
+
+#include <camel/camel-session.h>
+#include <camel/camel-store.h>
+#include <camel/camel-folder.h>
+#include <camel/camel-vee-store.h>
+#include <camel/camel-vtrash-folder.h>
+#include <camel/camel-stream-mem.h>
+#include <camel/camel-file-utils.h>
+#include <camel/camel-stream-fs.h>
+
+#include "e-util/e-mktemp.h"
+#include "e-util/e-request.h"
+#include "e-util/e-icon-factory.h"
+
+#include "widgets/misc/e-error.h"
+
+#include "em-vfolder-rule.h"
+
+#include "mail-mt.h"
+#include "mail-ops.h"
+#include "mail-tools.h"
+#include "mail-config.h"
+#include "mail-component.h"
+#include "mail-vfolder.h"
+
+#include "em-utils.h"
+#include "em-popup.h"
+#include "em-marshal.h"
+#include "em-folder-tree.h"
+#include "em-folder-tree-model.h"
+#include "em-folder-utils.h"
+#include "em-folder-selector.h"
+#include "em-folder-selection.h"
+#include "em-folder-properties.h"
+
+#define d(x)
+
+extern CamelSession *session;
+
+static gboolean
+emfu_is_special_local_folder (const char *name)
+{
+ return (!strcmp (name, "Drafts") || !strcmp (name, "Inbox") || !strcmp (name, "Outbox") || !strcmp (name, "Sent"));
+}
+
+struct _EMCopyFolders {
+ struct _mail_msg msg;
+
+ /* input data */
+ CamelStore *fromstore;
+ CamelStore *tostore;
+
+ char *frombase;
+ char *tobase;
+
+ int delete;
+};
+
+static char *
+emft_copy_folders__desc (struct _mail_msg *mm, int complete)
+{
+ struct _EMCopyFolders *m = (struct _EMCopyFolders *) mm;
+
+ return g_strdup_printf (_("Copying `%s' to `%s'"), m->frombase, m->tobase);
+}
+
+static void
+emft_copy_folders__copy (struct _mail_msg *mm)
+{
+ struct _EMCopyFolders *m = (struct _EMCopyFolders *) mm;
+ guint32 flags = CAMEL_STORE_FOLDER_INFO_FAST | CAMEL_STORE_FOLDER_INFO_RECURSIVE;
+ GList *pending = NULL, *deleting = NULL, *l;
+ GString *fromname, *toname;
+ CamelFolderInfo *fi;
+ const char *tmp;
+ int fromlen;
+
+ if (camel_store_supports_subscriptions (m->fromstore))
+ flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
+
+ if (!(fi = camel_store_get_folder_info (m->fromstore, m->frombase, flags, &mm->ex)))
+ return;
+
+ pending = g_list_append (pending, fi);
+
+ toname = g_string_new ("");
+ fromname = g_string_new ("");
+
+ tmp = strrchr (m->frombase, '/');
+ if (tmp == NULL)
+ fromlen = 0;
+ else
+ fromlen = tmp - m->frombase + 1;
+
+ d(printf ("top name is '%s'\n", fi->full_name));
+
+ while (pending) {
+ CamelFolderInfo *info = pending->data;
+
+ pending = g_list_remove_link (pending, pending);
+ while (info) {
+ CamelFolder *fromfolder, *tofolder;
+ GPtrArray *uids;
+ int deleted = 0;
+
+ if (info->child)
+ pending = g_list_append (pending, info->child);
+
+ if (m->tobase[0])
+ g_string_printf (toname, "%s/%s", m->tobase, info->full_name + fromlen);
+ else
+ g_string_printf (toname, "%s", info->full_name + fromlen);
+
+ d(printf ("Copying from '%s' to '%s'\n", info->full_name, toname->str));
+
+ /* This makes sure we create the same tree, e.g. from a nonselectable source */
+ /* Not sure if this is really the 'right thing', e.g. for spool stores, but it makes the ui work */
+ if ((info->flags & CAMEL_FOLDER_NOSELECT) == 0) {
+ d(printf ("this folder is selectable\n"));
+ if (m->tostore == m->fromstore && m->delete) {
+ camel_store_rename_folder (m->fromstore, info->full_name, toname->str, &mm->ex);
+ if (camel_exception_is_set (&mm->ex))
+ goto exception;
+
+ /* this folder no longer exists, unsubscribe it */
+ if (camel_store_supports_subscriptions (m->fromstore))
+ camel_store_unsubscribe_folder (m->fromstore, info->full_name, NULL);
+
+ deleted = 1;
+ } else {
+ if (!(fromfolder = camel_store_get_folder (m->fromstore, info->full_name, 0, &mm->ex)))
+ goto exception;
+
+ if (!(tofolder = camel_store_get_folder (m->tostore, toname->str, CAMEL_STORE_FOLDER_CREATE, &mm->ex))) {
+ camel_object_unref (fromfolder);
+ goto exception;
+ }
+
+ uids = camel_folder_get_uids (fromfolder);
+ camel_folder_transfer_messages_to (fromfolder, uids, tofolder, NULL, m->delete, &mm->ex);
+ camel_folder_free_uids (fromfolder, uids);
+
+ if (m->delete)
+ camel_folder_sync(fromfolder, TRUE, NULL);
+
+ camel_object_unref (fromfolder);
+ camel_object_unref (tofolder);
+ }
+ }
+
+ if (camel_exception_is_set (&mm->ex))
+ goto exception;
+ else if (m->delete && !deleted)
+ deleting = g_list_prepend (deleting, info);
+
+ /* subscribe to the new folder if appropriate */
+ if (camel_store_supports_subscriptions (m->tostore)
+ && !camel_store_folder_subscribed (m->tostore, toname->str))
+ camel_store_subscribe_folder (m->tostore, toname->str, NULL);
+
+ info = info->next;
+ }
+ }
+
+ /* delete the folders in reverse order from how we copyied them, if we are deleting any */
+ l = deleting;
+ while (l) {
+ CamelFolderInfo *info = l->data;
+
+ d(printf ("deleting folder '%s'\n", info->full_name));
+
+ /* FIXME: we need to do something with the exception
+ since otherwise the users sees a failed operation
+ with no error message or even any warnings */
+ if (camel_store_supports_subscriptions (m->fromstore))
+ camel_store_unsubscribe_folder (m->fromstore, info->full_name, NULL);
+
+ camel_store_delete_folder (m->fromstore, info->full_name, NULL);
+ l = l->next;
+ }
+
+ exception:
+
+ camel_store_free_folder_info (m->fromstore, fi);
+ g_list_free (deleting);
+
+ g_string_free (toname, TRUE);
+ g_string_free (fromname, TRUE);
+}
+
+static void
+emft_copy_folders__free (struct _mail_msg *mm)
+{
+ struct _EMCopyFolders *m = (struct _EMCopyFolders *) mm;
+
+ camel_object_unref (m->fromstore);
+ camel_object_unref (m->tostore);
+
+ g_free (m->frombase);
+ g_free (m->tobase);
+}
+
+static struct _mail_msg_op copy_folders_op = {
+ emft_copy_folders__desc,
+ emft_copy_folders__copy,
+ NULL,
+ emft_copy_folders__free,
+};
+
+static void
+emfu_copy_folders (CamelStore *tostore, const char *tobase, CamelStore *fromstore, const char *frombase, int delete)
+{
+ struct _EMCopyFolders *m;
+
+ m = mail_msg_new (&copy_folders_op, NULL, sizeof (struct _EMCopyFolders));
+ camel_object_ref (fromstore);
+ m->fromstore = fromstore;
+ camel_object_ref (tostore);
+ m->tostore = tostore;
+ m->frombase = g_strdup (frombase);
+ m->tobase = g_strdup (tobase);
+ m->delete = delete;
+
+ e_thread_put (mail_thread_new, (EMsg *) m);
+}
+
+struct _copy_folder_data {
+ CamelFolderInfo *fi;
+ gboolean delete;
+};
+
+static void
+emfu_copy_folder_selected (const char *uri, void *data)
+{
+ struct _copy_folder_data *cfd = data;
+ CamelStore *fromstore = NULL, *tostore = NULL;
+ char *tobase = NULL;
+ CamelException ex;
+ CamelURL *url;
+
+ if (uri == NULL) {
+ g_free (cfd);
+ return;
+ }
+
+ camel_exception_init (&ex);
+
+ if (!(fromstore = camel_session_get_store (session, cfd->fi->uri, &ex))) {
+ e_error_run(NULL,
+ cfd->delete?"mail:no-move-folder-notexist":"mail:no-copy-folder-notexist", cfd->fi->full_name, uri, ex.desc, NULL);
+ goto fail;
+ }
+
+ if (cfd->delete && fromstore == mail_component_peek_local_store (NULL) && emfu_is_special_local_folder (cfd->fi->full_name)) {
+ e_error_run(NULL,
+ "mail:no-rename-special-folder", cfd->fi->full_name, NULL);
+ goto fail;
+ }
+
+ if (!(tostore = camel_session_get_store (session, uri, &ex))) {
+ e_error_run(NULL,
+ cfd->delete?"mail:no-move-folder-to-notexist":"mail:no-copy-folder-to-notexist", cfd->fi->full_name, uri, ex.desc, NULL);
+ goto fail;
+ }
+
+ url = camel_url_new (uri, NULL);
+ if (((CamelService *)tostore)->provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH)
+ tobase = url->fragment;
+ else if (url->path && url->path[0])
+ tobase = url->path+1;
+ if (tobase == NULL)
+ tobase = "";
+
+ emfu_copy_folders (tostore, tobase, fromstore, cfd->fi->full_name, cfd->delete);
+
+ camel_url_free (url);
+fail:
+ if (fromstore)
+ camel_object_unref(fromstore);
+ if (tostore)
+ camel_object_unref(tostore);
+ camel_exception_clear (&ex);
+ g_free (cfd);
+}
+
+/* tree here is the 'destination' selector, not 'self' */
+static gboolean
+emfu_copy_folder_exclude(EMFolderTree *tree, GtkTreeModel *model, GtkTreeIter *iter, void *data)
+{
+ struct _copy_folder_data *cfd = data;
+ int fromvfolder, tovfolder;
+ char *touri;
+ guint flags;
+ gboolean is_store;
+
+ /* handles moving to/from vfolders */
+
+ fromvfolder = strncmp(cfd->fi->uri, "vfolder:", 8) == 0;
+ gtk_tree_model_get(model, iter, COL_STRING_URI, &touri, COL_UINT_FLAGS, &flags, COL_BOOL_IS_STORE, &is_store, -1);
+ tovfolder = strncmp(touri, "vfolder:", 8) == 0;
+ g_free(touri);
+
+ /* moving from vfolder to normal- not allowed */
+ if (fromvfolder && !tovfolder && cfd->delete)
+ return FALSE;
+ /* copy/move from normal folder to vfolder - not allowed */
+ if (!fromvfolder && tovfolder)
+ return FALSE;
+ /* copying to vfolder - not allowed */
+ if (tovfolder && !cfd->delete)
+ return FALSE;
+
+ return (flags & EMFT_EXCLUDE_NOINFERIORS) == 0;
+}
+
+void
+emfu_copy_folder (CamelFolderInfo *folderinfo)
+{
+ struct _copy_folder_data *cfd;
+
+ cfd = g_malloc (sizeof (*cfd));
+ cfd->fi = folderinfo;
+ cfd->delete = FALSE;
+
+ em_select_folder (NULL, _("Select folder"), _("C_opy"),
+ NULL, emfu_copy_folder_exclude,
+ emfu_copy_folder_selected, cfd);}
+
+void
+emfu_move_folder (CamelFolderInfo *folderinfo)
+{
+ struct _copy_folder_data *cfd;
+
+ cfd = g_malloc (sizeof (*cfd));
+ cfd->fi = folderinfo;
+ cfd->delete = TRUE;
+
+ em_select_folder (NULL, _("Select folder"), _("_Move"),
+ NULL, emfu_copy_folder_exclude,
+ emfu_copy_folder_selected, cfd);
+}
+
+static void
+emfu_delete_rec (CamelStore *store, CamelFolderInfo *fi, CamelException *ex)
+{
+ while (fi) {
+ CamelFolder *folder;
+
+ if (fi->child) {
+ emfu_delete_rec (store, fi->child, ex);
+ if (camel_exception_is_set (ex))
+ return;
+ }
+
+ d(printf ("deleting folder '%s'\n", fi->full_name));
+
+ /* shouldn't camel do this itself? */
+ if (camel_store_supports_subscriptions (store))
+ camel_store_unsubscribe_folder (store, fi->full_name, NULL);
+
+ if (!(folder = camel_store_get_folder (store, fi->full_name, 0, ex)))
+ return;
+
+ if (!CAMEL_IS_VEE_FOLDER (folder)) {
+ GPtrArray *uids = camel_folder_get_uids (folder);
+ int i;
+
+ camel_folder_freeze (folder);
+ for (i = 0; i < uids->len; i++)
+ camel_folder_delete_message (folder, uids->pdata[i]);
+
+ camel_folder_free_uids (folder, uids);
+
+ camel_folder_sync (folder, TRUE, NULL);
+ camel_folder_thaw (folder);
+ }
+
+ camel_store_delete_folder (store, fi->full_name, ex);
+ if (camel_exception_is_set (ex))
+ return;
+
+ fi = fi->next;
+ }
+}
+
+static void
+emfu_delete_folders (CamelStore *store, const char *full_name, CamelException *ex)
+{
+ guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE | CAMEL_STORE_FOLDER_INFO_FAST;
+ CamelFolderInfo *fi;
+
+ if (camel_store_supports_subscriptions (store))
+ flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
+
+ fi = camel_store_get_folder_info (store, full_name, flags, ex);
+ if (camel_exception_is_set (ex))
+ return;
+
+ emfu_delete_rec (store, fi, ex);
+ camel_store_free_folder_info (store, fi);
+}
+
+static void
+emfu_delete_response (GtkWidget *dialog, int response, gpointer data)
+{
+ CamelStore *store;
+ CamelException ex;
+ char *full_name;
+
+ full_name = g_object_get_data ((GObject *) dialog, "full_name");
+ store = g_object_get_data ((GObject *) dialog, "store");
+
+ if (response == GTK_RESPONSE_OK) {
+ camel_exception_init (&ex);
+ emfu_delete_folders (store, full_name, &ex);
+ if (camel_exception_is_set (&ex)) {
+ e_error_run(NULL,
+ "mail:no-delete-folder", full_name, ex.desc, NULL);
+ camel_exception_clear (&ex);
+ }
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+void
+emfu_delete_folder (CamelFolder *folder)
+{
+ CamelStore *local;
+ GtkWidget *dialog;
+
+ local = mail_component_peek_local_store (NULL);
+
+ if (folder->parent_store == local && emfu_is_special_local_folder (folder->full_name)) {
+ e_error_run(NULL, "mail:no-delete-special-folder", folder->full_name, NULL);
+ return;
+ }
+
+ camel_object_ref (folder->parent_store);
+
+ dialog = e_error_new(NULL,
+ (folder->parent_store && CAMEL_IS_VEE_STORE(folder->parent_store))?"mail:ask-delete-vfolder":"mail:ask-delete-folder",
+ folder->full_name, NULL);
+ g_object_set_data_full ((GObject *) dialog, "full_name", folder->full_name, g_free);
+ g_object_set_data_full ((GObject *) dialog, "store", folder->parent_store, camel_object_unref);
+ g_signal_connect (dialog, "response", G_CALLBACK (emfu_delete_response), NULL);
+ gtk_widget_show (dialog);
+}
+
+void
+emfu_rename_folder (CamelFolder *folder)
+{
+ char *prompt, *new_name;
+ const char *p;
+ CamelStore *local;
+ gboolean done = FALSE;
+ size_t base_len;
+
+ local = mail_component_peek_local_store (NULL);
+
+ /* don't allow user to rename one of the special local folders */
+ if (folder->parent_store == local && emfu_is_special_local_folder (folder->full_name)) {
+ e_error_run(NULL,
+ "mail:no-rename-special-folder", folder->full_name, NULL);
+ return;
+ }
+
+ if ((p = strrchr (folder->full_name, '/')))
+ base_len = (size_t) (p - folder->full_name);
+ else
+ base_len = 0;
+
+ prompt = g_strdup_printf (_("Rename the \"%s\" folder to:"), folder->name);
+ while (!done) {
+ new_name = e_request_string (NULL, _("Rename Folder"), prompt, folder->name);
+ if (new_name == NULL || !strcmp (folder->name, new_name)) {
+ /* old name == new name */
+ done = TRUE;
+ } else if (strchr(new_name, '/') != NULL) {
+ e_error_run(NULL,
+ "mail:no-rename-folder", folder->name, new_name, _("Folder names cannot contain '/'"), NULL);
+ done = TRUE;
+ } else {
+ CamelFolderInfo *fi;
+ CamelException ex;
+ char *path, *p;
+
+ if (base_len > 0) {
+ path = g_malloc (base_len + strlen (new_name) + 2);
+ memcpy (path, folder->full_name, base_len);
+ p = path + base_len;
+ *p++ = '/';
+ strcpy (p, new_name);
+ } else {
+ path = g_strdup (new_name);
+ }
+
+ camel_exception_init (&ex);
+ if ((fi = camel_store_get_folder_info (folder->parent_store, path, CAMEL_STORE_FOLDER_INFO_FAST, &ex)) != NULL) {
+ camel_store_free_folder_info (folder->parent_store, fi);
+ e_error_run(NULL,
+ "mail:no-rename-folder-exists", folder->name, new_name, NULL);
+ } else {
+ const char *oldpath, *newpath;
+
+ oldpath = folder->full_name;
+ newpath = path;
+
+ d(printf ("renaming %s to %s\n", oldpath, newpath));
+
+ camel_exception_clear (&ex);
+ camel_store_rename_folder (folder->parent_store, oldpath, newpath, &ex);
+ if (camel_exception_is_set (&ex)) {
+ e_error_run(NULL,
+ "mail:no-rename-folder", oldpath, newpath, ex.desc, NULL);
+ camel_exception_clear (&ex);
+ }
+
+ done = TRUE;
+ }
+
+ g_free (path);
+ }
+
+ g_free (new_name);
+ }
+}
+
+struct _EMCreateFolder {
+ struct _mail_msg msg;
+
+ /* input data */
+ CamelStore *store;
+ char *full_name;
+ char *parent;
+ char *name;
+
+ /* output data */
+ CamelFolderInfo *fi;
+
+ /* callback data */
+ void (* done) (CamelFolderInfo *fi, void *user_data);
+ void *user_data;
+};
+
+static char *
+emfu_create_folder__desc (struct _mail_msg *mm, int done)
+{
+ struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm;
+
+ return g_strdup_printf (_("Creating folder `%s'"), m->full_name);
+}
+
+static void
+emfu_create_folder__create (struct _mail_msg *mm)
+{
+ struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm;
+
+ d(printf ("creating folder parent='%s' name='%s' full_name='%s'\n", m->parent, m->name, m->full_name));
+
+ if ((m->fi = camel_store_create_folder (m->store, m->parent, m->name, &mm->ex))) {
+ if (camel_store_supports_subscriptions (m->store))
+ camel_store_subscribe_folder (m->store, m->full_name, &mm->ex);
+ }
+}
+
+static void
+emfu_create_folder__created (struct _mail_msg *mm)
+{
+ struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm;
+
+ if (m->done)
+ m->done (m->fi, m->user_data);
+}
+
+static void
+emfu_create_folder__free (struct _mail_msg *mm)
+{
+ struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm;
+
+ camel_store_free_folder_info (m->store, m->fi);
+ camel_object_unref (m->store);
+ g_free (m->full_name);
+ g_free (m->parent);
+ g_free (m->name);
+}
+
+static struct _mail_msg_op create_folder_op = {
+ emfu_create_folder__desc,
+ emfu_create_folder__create,
+ emfu_create_folder__created,
+ emfu_create_folder__free,
+};
+
+
+static int
+emfu_create_folder_real (CamelStore *store, const char *full_name, void (* done) (CamelFolderInfo *fi, void *user_data), void *user_data)
+{
+ char *name, *namebuf = NULL;
+ struct _EMCreateFolder *m;
+ const char *parent;
+ int id;
+
+ namebuf = g_strdup (full_name);
+ if (!(name = strrchr (namebuf, '/'))) {
+ name = namebuf;
+ parent = "";
+ } else {
+ *name++ = '\0';
+ parent = namebuf;
+ }
+
+ m = mail_msg_new (&create_folder_op, NULL, sizeof (struct _EMCreateFolder));
+ camel_object_ref (store);
+ m->store = store;
+ m->full_name = g_strdup (full_name);
+ m->parent = g_strdup (parent);
+ m->name = g_strdup (name);
+ m->user_data = user_data;
+ m->done = done;
+
+ g_free (namebuf);
+
+ id = m->msg.seq;
+ e_thread_put (mail_thread_new, (EMsg *) m);
+
+ return id;
+}
+
+static void
+new_folder_created_cb (CamelFolderInfo *fi, void *user_data)
+{
+ EMFolderSelector *emfs = user_data;
+
+ if (fi)
+ gtk_widget_destroy ((GtkWidget *) emfs);
+
+ g_object_unref (emfs);
+}
+
+static void
+emfu_popup_new_folder_response (EMFolderSelector *emfs, int response, gpointer data)
+{
+ EMFolderTreeModelStoreInfo *si;
+ const char *uri, *path;
+ CamelException ex;
+ CamelStore *store;
+
+ if (response != GTK_RESPONSE_OK) {
+ gtk_widget_destroy ((GtkWidget *) emfs);
+ return;
+ }
+
+ uri = em_folder_selector_get_selected_uri (emfs);
+ path = em_folder_selector_get_selected_path (emfs);
+
+ d(printf ("Creating new folder: %s (%s)\n", path, uri));
+
+ g_print ("DEBUG: %s (%s)\n", path, uri);
+
+ camel_exception_init (&ex);
+ if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) {
+ camel_exception_clear (&ex);
+ return;
+ }
+
+ if (!(si = em_folder_tree_get_model_storeinfo (emfs->emft, store))) {
+ g_assert_not_reached ();
+ camel_object_unref (store);
+ return;
+ }
+
+ /* HACK: we need to create vfolders using the vfolder editor */
+ if (CAMEL_IS_VEE_STORE(store)) {
+ EMVFolderRule *rule;
+
+ rule = em_vfolder_rule_new();
+ filter_rule_set_name((FilterRule *)rule, path);
+ vfolder_gui_add_rule(rule);
+ gtk_widget_destroy((GtkWidget *)emfs);
+ } else {
+ g_object_ref (emfs);
+ emfu_create_folder_real (si->store, path, new_folder_created_cb, emfs);
+ }
+
+ camel_object_unref (store);
+ camel_exception_clear (&ex);
+}
+
+void
+emfu_folder_create (CamelFolderInfo *folderinfo) {
+ EMFolderTree *folder_tree;
+ EMFolderTreeModel *model;
+ GtkWidget *dialog;
+
+ model = mail_component_peek_tree_model (mail_component_peek ());
+ folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model);
+
+ dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:"));
+ if (folderinfo != NULL)
+ em_folder_selector_set_selected ((EMFolderSelector *) dialog, folderinfo->uri);
+ g_signal_connect (dialog, "response", G_CALLBACK (emfu_popup_new_folder_response), folder_tree);
+ gtk_widget_show (dialog);
+}
diff --git a/mail/em-folder-utils.h b/mail/em-folder-utils.h
new file mode 100644
index 0000000000..ceec49ced1
--- /dev/null
+++ b/mail/em-folder-utils.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ * Rodney Dawes <dobey@novell.com>
+ *
+ * Copyright 2003-2005 Novell, Inc. (www.novell.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.
+ *
+ */
+
+#include <camel/camel-store.h>
+
+void emfu_copy_folder (CamelFolderInfo *folderinfo);
+void emfu_move_folder (CamelFolderInfo *folderinfo);
+
+void emfu_delete_folder (CamelFolder *folder);
+void emfu_rename_folder (CamelFolder *folder);
+
+void emfu_folder_create (CamelFolderInfo *folderinfo);
diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c
index f4c5b737f2..2ba14951a4 100644
--- a/mail/em-folder-view.c
+++ b/mail/em-folder-view.c
@@ -694,6 +694,22 @@ emfv_popup_saveas(EPopup *ep, EPopupItem *pitem, void *data)
}
static void
+emfv_view_load_images(BonoboUIComponent *uic, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+
+ if (emfv->preview)
+ em_format_html_load_http((EMFormatHTML *)emfv->preview);
+}
+
+static void
+emfv_popup_load_images(EPopup *ep, EPopupItem *pitem, void *data)
+{
+ EMFolderView *emfv = data;
+ emfv_view_load_images(NULL, data, NULL);
+}
+
+static void
emfv_popup_print(EPopup *ep, EPopupItem *pitem, void *data)
{
EMFolderView *emfv = data;
@@ -708,6 +724,44 @@ emfv_popup_copy_text(EPopup *ep, EPopupItem *pitem, void *data)
}
static void
+emfv_popup_source(EPopup *ep, EPopupItem *pitem, void *data)
+{
+ EMFolderView *emfv = data;
+ EMMessageBrowser *emmb;
+ GPtrArray *uids;
+
+ uids = message_list_get_selected(emfv->list);
+
+ emmb = (EMMessageBrowser *)em_message_browser_window_new();
+ em_format_set_session((EMFormat *)((EMFolderView *)emmb)->preview, ((EMFormat *)emfv->preview)->session);
+ em_folder_view_set_folder((EMFolderView *)emmb, emfv->folder, emfv->folder_uri);
+ em_format_set_mode((EMFormat *)((EMFolderView *)emmb)->preview, EM_FORMAT_SOURCE);
+ em_folder_view_set_message((EMFolderView *)emmb, uids->pdata[0], FALSE);
+ gtk_widget_show(emmb->window);
+
+ message_list_free_uids(emfv->list, uids);
+}
+
+static void
+emfv_mail_compose(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+
+ if (!em_utils_check_user_can_send_mail((GtkWidget *)emfv))
+ return;
+
+ em_utils_compose_new_message(emfv->folder_uri);
+}
+
+static void
+emfv_popup_selectall(EPopup *ep, EPopupItem *pitem, void *data)
+{
+ EMFolderView *emfv = data;
+ gtk_html_select_all (((EMFormatHTML *)emfv->preview)->html);
+
+}
+
+static void
emfv_popup_reply_sender(EPopup *ep, EPopupItem *pitem, void *data)
{
EMFolderView *emfv = data;
@@ -1009,8 +1063,8 @@ static EPopupItem emfv_popup_items[] = {
{ E_POPUP_ITEM, "40.emfv.03", N_("_Copy to Folder..."), emfv_popup_copy, NULL, "stock_mail-copy", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
{ E_POPUP_BAR, "50.emfv", NULL, NULL, NULL, NULL },
- { E_POPUP_ITEM, "50.emfv.00", N_("Mar_k as Read"), emfv_popup_mark_read, NULL, "stock_mail-open", EM_POPUP_SELECT_MARK_READ },
- { E_POPUP_ITEM, "50.emfv.01", N_("Mark as U_nread"), emfv_popup_mark_unread, NULL, "stock_mail-unread", EM_POPUP_SELECT_MARK_UNREAD },
+ { E_POPUP_ITEM, "50.emfv.00", N_("Mar_k as Read"), emfv_popup_mark_read, NULL, "stock_mail-open", EM_POPUP_SELECT_MARK_READ|EM_FOLDER_VIEW_SELECT_LISTONLY },
+ { E_POPUP_ITEM, "50.emfv.01", N_("Mark as U_nread"), emfv_popup_mark_unread, NULL, "stock_mail-unread", EM_POPUP_SELECT_MARK_UNREAD|EM_FOLDER_VIEW_SELECT_LISTONLY },
{ E_POPUP_ITEM, "50.emfv.02", N_("Mark as _Important"), emfv_popup_mark_important, NULL, "stock_mail-priority-high", EM_POPUP_SELECT_MARK_IMPORTANT|EM_FOLDER_VIEW_SELECT_LISTONLY },
{ E_POPUP_ITEM, "50.emfv.03", N_("_Mark as Unimportant"), emfv_popup_mark_unimportant, NULL, NULL, EM_POPUP_SELECT_MARK_UNIMPORTANT|EM_FOLDER_VIEW_SELECT_LISTONLY },
{ E_POPUP_ITEM, "50.emfv.04", N_("Mark as _Junk"), emfv_popup_mark_junk, NULL, "stock_spam", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_LISTONLY },
@@ -1169,6 +1223,16 @@ EMFV_MAP_CALLBACK(emfv_message_open, emfv_popup_open)
EMFV_MAP_CALLBACK(emfv_message_edit, emfv_popup_edit)
EMFV_MAP_CALLBACK(emfv_message_saveas, emfv_popup_saveas)
EMFV_MAP_CALLBACK(emfv_print_message, emfv_popup_print)
+EMFV_MAP_CALLBACK(emfv_message_source, emfv_popup_source)
+
+static void
+emfv_empty_trash(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+
+ em_utils_empty_trash (gtk_widget_get_toplevel ((GtkWidget *) emfv));
+}
+
static void
emfv_edit_cut(BonoboUIComponent *uid, void *data, const char *path)
@@ -1201,6 +1265,14 @@ emfv_edit_paste(BonoboUIComponent *uid, void *data, const char *path)
}
static void
+emfv_select_all_text(BonoboUIComponent *uid, void *data, const char *path)
+{
+ EMFolderView *emfv = data;
+
+ html_engine_select_all (((EMFormatHTML *)emfv->preview)->html->engine);
+}
+
+static void
emfv_mail_next(BonoboUIComponent *uid, void *data, const char *path)
{
EMFolderView *emfv = data;
@@ -1561,20 +1633,15 @@ EMFV_MAP_CALLBACK(emfv_tools_vfolder_mlist, emfv_popup_vfolder_mlist)
/* ********************************************************************** */
-static void
-emfv_view_load_images(BonoboUIComponent *uic, void *data, const char *path)
-{
- EMFolderView *emfv = data;
-
- if (emfv->preview)
- em_format_html_load_http((EMFormatHTML *)emfv->preview);
-}
-
static BonoboUIVerb emfv_message_verbs[] = {
+ BONOBO_UI_UNSAFE_VERB ("EmptyTrash", emfv_empty_trash),
+
BONOBO_UI_UNSAFE_VERB ("EditCut", emfv_edit_cut),
BONOBO_UI_UNSAFE_VERB ("EditCopy", emfv_edit_copy),
BONOBO_UI_UNSAFE_VERB ("EditPaste", emfv_edit_paste),
+ BONOBO_UI_UNSAFE_VERB ("SelectAllText", emfv_select_all_text),
+
BONOBO_UI_UNSAFE_VERB ("MailNext", emfv_mail_next),
BONOBO_UI_UNSAFE_VERB ("MailNextFlagged", emfv_mail_next_flagged),
BONOBO_UI_UNSAFE_VERB ("MailNextUnread", emfv_mail_next_unread),
@@ -1619,6 +1686,10 @@ static BonoboUIVerb emfv_message_verbs[] = {
BONOBO_UI_UNSAFE_VERB ("TextZoomOut", emfv_text_zoom_out),
BONOBO_UI_UNSAFE_VERB ("TextZoomReset", emfv_text_zoom_reset),
+ BONOBO_UI_UNSAFE_VERB ("ViewSource", emfv_message_source),
+
+ BONOBO_UI_UNSAFE_VERB ("MailCompose", emfv_mail_compose),
+
/* TODO: This stuff should just be 1 item that runs a wizard */
BONOBO_UI_UNSAFE_VERB ("ToolsFilterMailingList", emfv_tools_filter_mlist),
BONOBO_UI_UNSAFE_VERB ("ToolsFilterRecipient", emfv_tools_filter_recipient),
@@ -1659,6 +1730,8 @@ static EPixmap emfv_message_pixmaps[] = {
E_PIXMAP ("/commands/MessageMarkAsJunk", "stock_spam", E_ICON_SIZE_MENU),
E_PIXMAP ("/commands/MessageMarkAsNotJunk", "stock_not-spam", E_ICON_SIZE_MENU),
E_PIXMAP ("/commands/MessageFollowUpFlag", "stock_mail-flag-for-followup", E_ICON_SIZE_MENU),
+ E_PIXMAP ("/commands/ViewLoadImages", "stock_insert_image", E_ICON_SIZE_MENU),
+ E_PIXMAP ("/commands/MailCompose", "stock_mail-compose", E_ICON_SIZE_MENU),
E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageReplySender", "stock_mail-reply", E_ICON_SIZE_LARGE_TOOLBAR),
E_PIXMAP ("/Toolbar/MailMessageToolbar/MessageReplyAll", "stock_mail-reply-to-all", E_ICON_SIZE_LARGE_TOOLBAR),
@@ -1679,8 +1752,9 @@ static EPixmap emfv_message_pixmaps[] = {
/* this is added to emfv->enable_map in :init() */
static const EMFolderViewEnable emfv_enable_map[] = {
{ "EditCut", EM_POPUP_SELECT_MANY },
- { "EditCopy", EM_POPUP_SELECT_MANY },
+ { "EditCopy", EM_FOLDER_VIEW_SELECT_SELECTION },
{ "EditPaste", EM_POPUP_SELECT_FOLDER },
+ { "SelectAllText", EM_POPUP_SELECT_ONE },
/* FIXME: should these be single-selection? */
{ "MailNext", EM_POPUP_SELECT_MANY|EM_FOLDER_VIEW_SELECT_NEXT_MSG },
@@ -1736,6 +1810,7 @@ static const EMFolderViewEnable emfv_enable_map[] = {
{ "ToolsVFolderSubject", EM_POPUP_SELECT_ONE },
{ "ViewLoadImages", EM_POPUP_SELECT_ONE },
+ { "ViewSource", EM_POPUP_SELECT_ONE },
/* always enabled */
{ "MailStop", 0 },
@@ -1814,16 +1889,15 @@ emfv_view_mode(BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_Even
EMFolderView *emfv = data;
int i;
- if (type != Bonobo_UIComponent_STATE_CHANGED
- || state[0] == '0')
+ if (type != Bonobo_UIComponent_STATE_CHANGED)
return;
/* TODO: I don't like this stuff much, is there any way we can move listening for such events
elsehwere? Probably not I guess, unless there's a EMFolderViewContainer for bonobo usage
of a folder view */
- for (i=0;i<= EM_FORMAT_SOURCE;i++) {
- if (strcmp(emfv_display_styles[i]+strlen("/commands/"), path) == 0) {
+ i = state[0] != '0';
+
em_format_set_mode((EMFormat *)emfv->preview, i);
if (EM_FOLDER_VIEW_GET_CLASS (emfv)->update_message_style) {
@@ -1831,9 +1905,6 @@ emfv_view_mode(BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_Even
gconf_client_set_int (gconf, "/apps/evolution/mail/display/message_style", i, NULL);
}
- break;
- }
- }
}
static void
@@ -1894,11 +1965,11 @@ emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, int act)
bonobo_ui_component_set_prop(uic, "/commands/CaretMode", "state", state?"1":"0", NULL);
bonobo_ui_component_add_listener(uic, "CaretMode", emfv_caret_mode, emfv);
- style = ((EMFormat *)emfv->preview)->mode;
- bonobo_ui_component_set_prop(uic, emfv_display_styles[style], "state", "1", NULL);
- bonobo_ui_component_add_listener(uic, "ViewNormal", emfv_view_mode, emfv);
+ style = ((EMFormat *)emfv->preview)->mode?EM_FORMAT_ALLHEADERS:EM_FORMAT_NORMAL;
+ bonobo_ui_component_set_prop(uic, emfv_display_styles[style], "state", style?"1":"0", NULL);
+ /* bonobo_ui_component_add_listener(uic, "ViewNormal", emfv_view_mode, emfv); */
bonobo_ui_component_add_listener(uic, "ViewFullHeaders", emfv_view_mode, emfv);
- bonobo_ui_component_add_listener(uic, "ViewSource", emfv_view_mode, emfv);
+ /* bonobo_ui_component_add_listener(uic, "ViewSource", emfv_view_mode, emfv); */
em_format_set_mode((EMFormat *)emfv->preview, style);
if (emfv->folder && !em_utils_folder_is_sent(emfv->folder, emfv->folder_uri))
diff --git a/mail/mail-component.c b/mail/mail-component.c
index e831978235..34713baeab 100644
--- a/mail/mail-component.c
+++ b/mail/mail-component.c
@@ -737,23 +737,6 @@ impl__get_userCreatableItems (PortableServer_Servant servant, CORBA_Environment
return list;
}
-static void
-emc_new_folder_response(EMFolderSelector *emfs, int response, void *dummy)
-{
- const char *uri, *path;
-
- if (response != GTK_RESPONSE_OK) {
- gtk_widget_destroy((GtkWidget *)emfs);
- return;
- }
-
- uri = em_folder_selector_get_selected_uri(emfs);
- path = em_folder_selector_get_selected_path(emfs);
-
- if (em_folder_tree_create_folder(emfs->emft, path, uri))
- gtk_widget_destroy((GtkWidget *)emfs);
-}
-
static int
create_item(const char *type, EMFolderTreeModel *model, const char *uri)
{
@@ -763,15 +746,7 @@ create_item(const char *type, EMFolderTreeModel *model, const char *uri)
em_utils_compose_new_message(uri);
} else if (strcmp(type, "folder") == 0) {
- EMFolderTree *folder_tree;
- GtkWidget *dialog;
-
- folder_tree = (EMFolderTree *)em_folder_tree_new_with_model(model);
- dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:"));
- if (uri)
- em_folder_selector_set_selected ((EMFolderSelector *) dialog, uri);
- g_signal_connect (dialog, "response", G_CALLBACK(emc_new_folder_response), NULL);
- gtk_widget_show(dialog);
+ emfu_folder_create (NULL);
} else
return -1;