aboutsummaryrefslogtreecommitdiffstats
path: root/mail/mail-component.c
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2003-11-14 03:02:07 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2003-11-14 03:02:07 +0800
commitfd244132adb4225b6982422632bd69bc57b4e589 (patch)
treee6f706c7bb025b7bd90498aa3a6517924955a6a7 /mail/mail-component.c
parent4e093efda9886a3c51cdefd3fc236807a34e11f9 (diff)
downloadgsoc2013-evolution-fd244132adb4225b6982422632bd69bc57b4e589.tar
gsoc2013-evolution-fd244132adb4225b6982422632bd69bc57b4e589.tar.gz
gsoc2013-evolution-fd244132adb4225b6982422632bd69bc57b4e589.tar.bz2
gsoc2013-evolution-fd244132adb4225b6982422632bd69bc57b4e589.tar.lz
gsoc2013-evolution-fd244132adb4225b6982422632bd69bc57b4e589.tar.xz
gsoc2013-evolution-fd244132adb4225b6982422632bd69bc57b4e589.tar.zst
gsoc2013-evolution-fd244132adb4225b6982422632bd69bc57b4e589.zip
New folder-tree widget that replaces the shell's folder-tree widget.
2003-11-13 Jeffrey Stedfast <fejj@ximian.com> * em-folder-tree.[c,h]: New folder-tree widget that replaces the shell's folder-tree widget. * em-folder-tree-model.[c,h]: New source files subclassing GtkTreeStore for handling the mess that is drag&drop. * em-folder-selection-button.c: Ported to use EMFolderTree. * em-folder-selection.c: Ported to use EMFolderTree. * em-folder-selector.c: Ported to use EMFolderTree. * mail-component.c: Ported to use EMFolderTree. * mail-offline-handler.c (storage_go_online): Updated to not pass a storage argument. * mail-folder-cache.c: Removed storage stuff. * mail-send-recv.c (receive_update_got_store): Don't do EStorage* stuff anymore. svn path=/trunk/; revision=23331
Diffstat (limited to 'mail/mail-component.c')
-rw-r--r--mail/mail-component.c1515
1 files changed, 105 insertions, 1410 deletions
diff --git a/mail/mail-component.c b/mail/mail-component.c
index 12cc03ca78..f2e6a903c4 100644
--- a/mail/mail-component.c
+++ b/mail/mail-component.c
@@ -33,10 +33,8 @@
#include <fcntl.h>
#include <errno.h>
-#include "e-storage.h"
-#include "e-storage-set.h"
-#include "e-storage-browser.h"
-#include "e-storage-set-view.h"
+#include "em-folder-tree.h"
+#include "em-folder-browser.h"
#include "em-folder-selector.h"
#include "em-folder-selection.h"
@@ -72,164 +70,38 @@
#define d(x) x
-#define MESSAGE_RFC822_TYPE "message/rfc822"
-#define TEXT_URI_LIST_TYPE "text/uri-list"
-#define UID_LIST_TYPE "x-uid-list"
-#define FOLDER_TYPE "x-folder"
-
-/* Drag & Drop types */
-enum DndDragType {
- DND_DRAG_TYPE_FOLDER, /* drag an evo folder */
- DND_DRAG_TYPE_TEXT_URI_LIST, /* drag to an mbox file */
-};
-
-enum DndDropType {
- DND_DROP_TYPE_UID_LIST, /* drop a list of message uids */
- DND_DROP_TYPE_FOLDER, /* drop an evo folder */
- DND_DROP_TYPE_MESSAGE_RFC822, /* drop a message/rfc822 stream */
- DND_DROP_TYPE_TEXT_URI_LIST, /* drop an mbox file */
-};
-
-static GtkTargetEntry drag_types[] = {
- { UID_LIST_TYPE, 0, DND_DRAG_TYPE_FOLDER },
- { TEXT_URI_LIST_TYPE, 0, DND_DRAG_TYPE_TEXT_URI_LIST },
-};
-
-static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
-
-static GtkTargetEntry drop_types[] = {
- { UID_LIST_TYPE, 0, DND_DROP_TYPE_UID_LIST },
- { FOLDER_TYPE, 0, DND_DROP_TYPE_FOLDER },
- { MESSAGE_RFC822_TYPE, 0, DND_DROP_TYPE_MESSAGE_RFC822 },
- { TEXT_URI_LIST_TYPE, 0, DND_DROP_TYPE_TEXT_URI_LIST },
-};
-
-static const int num_drop_types = sizeof (drop_types) / sizeof (drop_types[0]);
-
#define PARENT_TYPE bonobo_object_get_type ()
static BonoboObjectClass *parent_class = NULL;
struct _MailComponentPrivate {
char *base_directory;
-
+
+ EMFolderTree *emft;
+
MailAsyncEvent *async_event;
- GHashTable *storages_hash; /* storage by store */
-
- EFolderTypeRegistry *folder_type_registry;
- EStorageSet *storage_set;
-
+ GHashTable *store_hash; /* display_name by store */
+
RuleContext *search_context;
-
+
char *context_path; /* current path for right-click menu */
-
+
CamelStore *local_store;
};
-static int emc_tree_right_click(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, MailComponent *component);
-
/* Utility functions. */
-/* EPFIXME: Eeek, this totally sucks. See comment in e-storage.h,
- async_open_folder() should NOT be a signal. */
-
-struct _StorageConnectedData {
- EStorage *storage;
- char *path;
- EStorageDiscoveryCallback callback;
- void *callback_data;
-};
-typedef struct _StorageConnectedData StorageConnectedData;
-
-static void
-storage_connected_callback (CamelStore *store,
- CamelFolderInfo *info,
- StorageConnectedData *data)
-{
- EStorageResult result;
-
- if (info != NULL)
- result = E_STORAGE_OK;
- else
- result = E_STORAGE_GENERICERROR;
-
- (* data->callback) (data->storage, result, data->path, data->callback_data);
-
- g_object_unref (data->storage);
- g_free (data->path);
- g_free (data);
-}
-
static void
-storage_async_open_folder_callback (EStorage *storage,
- const char *path,
- EStorageDiscoveryCallback callback,
- void *callback_data,
- CamelStore *store)
+add_storage (MailComponent *component, const char *name, CamelService *store, CamelException *ex)
{
- StorageConnectedData *storage_connected_data = g_new0 (StorageConnectedData, 1);
-
- g_object_ref (storage);
-
- storage_connected_data->storage = storage;
- storage_connected_data->path = g_strdup (path);
- storage_connected_data->callback = callback;
- storage_connected_data->callback_data = callback_data;
-
- mail_note_store (store, NULL, storage,
- (void *) storage_connected_callback, storage_connected_data);
+ camel_object_ref (store);
+ g_hash_table_insert (component->priv->store_hash, store, g_strdup (name));
+ em_folder_tree_add_store (component->priv->emft, (CamelStore *) store, name);
+ mail_note_store ((CamelStore *) store, NULL, NULL, NULL);
}
static void
-add_storage (MailComponent *component,
- const char *name,
- CamelService *store,
- CamelException *ex)
-{
- EStorage *storage;
- EFolder *root_folder;
-
- root_folder = e_folder_new (name, "noselect", "");
- storage = e_storage_new (name, root_folder);
- e_storage_declare_has_subfolders(storage, "/", _("Connecting..."));
-
- camel_object_ref(store);
-
- g_object_set_data((GObject *)storage, "em-store", store);
- g_hash_table_insert (component->priv->storages_hash, store, storage);
-
- g_signal_connect(storage, "async_open_folder",
- G_CALLBACK (storage_async_open_folder_callback), store);
-
-#if 0 /* Some private test code - zed */
- {
- static void *model;
-
- if (model == NULL) {
- model = em_store_model_new();
- em_store_model_view_new(model);
- }
-
- em_store_model_add_store(model, store);
- }
-#endif
-
-#if 0
- /* EPFIXME these are not needed anymore. */
- g_signal_connect(storage, "create_folder", G_CALLBACK(storage_create_folder), store);
- g_signal_connect(storage, "remove_folder", G_CALLBACK(storage_remove_folder), store);
- g_signal_connect(storage, "xfer_folder", G_CALLBACK(storage_xfer_folder), store);
-#endif
-
- e_storage_set_add_storage (component->priv->storage_set, storage);
-
- mail_note_store ((CamelStore *) store, NULL, storage, NULL, NULL);
-
- g_object_unref (storage);
-}
-
-static void
-load_accounts(MailComponent *component, EAccountList *accounts)
+load_accounts (MailComponent *component, EAccountList *accounts)
{
EIterator *iter;
@@ -247,7 +119,7 @@ load_accounts(MailComponent *component, EAccountList *accounts)
account = (EAccount *) e_iterator_get (iter);
service = account->source;
name = account->name;
-
+
if (account->enabled && service->url != NULL)
mail_component_load_storage_by_uri (component, service->url, name);
@@ -257,39 +129,21 @@ load_accounts(MailComponent *component, EAccountList *accounts)
g_object_unref (iter);
}
-static inline gboolean
-type_is_mail (const char *type)
-{
- return !strcmp (type, "mail") || !strcmp (type, "mail/public");
-}
-
-static inline gboolean
-type_is_vtrash (const char *type)
-{
- return !strcmp (type, "vtrash");
-}
-
-static inline gboolean
-type_is_vjunk (const char *type)
-{
- return !strcmp (type, "vjunk");
-}
-
static void
storage_go_online (gpointer key, gpointer value, gpointer data)
{
CamelStore *store = key;
CamelService *service = CAMEL_SERVICE (store);
-
+
if (! (service->provider->flags & CAMEL_PROVIDER_IS_REMOTE)
|| (service->provider->flags & CAMEL_PROVIDER_IS_EXTERNAL))
return;
-
+
if ((CAMEL_IS_DISCO_STORE (service)
&& camel_disco_store_status (CAMEL_DISCO_STORE (service)) == CAMEL_DISCO_STORE_OFFLINE)
|| service->status != CAMEL_SERVICE_DISCONNECTED) {
mail_store_set_offline (store, FALSE, NULL, NULL);
- mail_note_store (store, NULL, NULL, NULL, NULL);
+ mail_note_store (store, NULL, NULL, NULL);
}
}
@@ -369,7 +223,6 @@ setup_local_store(MailComponent *component)
g_free(store_uri);
}
-/* EStorageBrowser callbacks. */
static BonoboControl *
create_noselect_control (void)
@@ -378,498 +231,51 @@ create_noselect_control (void)
label = gtk_label_new (_("This folder cannot contain messages."));
gtk_widget_show (label);
+
return bonobo_control_new (label);
}
static GtkWidget *
-create_view_callback (EStorageBrowser *browser,
- const char *path,
- void *unused_data)
+create_view_widget (EMFolderTree *emft, const char *path, const char *uri)
{
BonoboControl *control;
- EFolder *folder;
- const char *folder_type;
- const char *physical_uri;
-
- folder = e_storage_set_get_folder (e_storage_browser_peek_storage_set (browser), path);
- if (folder == NULL) {
- g_warning ("No folder at %s", path);
- return gtk_label_new ("(You should not be seeing this label)");
- }
-
- folder_type = e_folder_get_type_string (folder);
- physical_uri = e_folder_get_physical_uri (folder);
-
- if (type_is_mail (folder_type)) {
- const char *noselect;
- CamelURL *url;
-
- url = camel_url_new (physical_uri, NULL);
- noselect = url ? camel_url_get_param (url, "noselect") : NULL;
- if (noselect && !strcasecmp (noselect, "yes"))
- control = create_noselect_control ();
- else
- control = folder_browser_factory_new_control (physical_uri);
- camel_url_free (url);
- } else if (type_is_vtrash (folder_type)) {
- if (!strncasecmp (physical_uri, "file:", 5))
- control = folder_browser_factory_new_control ("vtrash:file:/");
- else
- control = folder_browser_factory_new_control (physical_uri);
- } else if (type_is_vjunk (folder_type)) {
- if (!strncasecmp (physical_uri, "file:", 5))
- control = folder_browser_factory_new_control ("vjunk:file:/");
- else
- control = folder_browser_factory_new_control (physical_uri);
- } else
- return NULL;
+ const char *noselect;
+ CamelURL *url;
+
+ url = camel_url_new (uri, NULL);
+ noselect = url ? camel_url_get_param (url, "noselect") : NULL;
+ if (noselect && !strcasecmp (noselect, "yes"))
+ control = create_noselect_control ();
+ else
+ control = folder_browser_factory_new_control (uri);
+ camel_url_free (url);
if (!control)
return NULL;
-
- /* EPFIXME: This leaks the control. */
- return bonobo_widget_new_control_from_objref (BONOBO_OBJREF (control), CORBA_OBJECT_NIL);
-}
-
-static void
-browser_page_switched_callback (EStorageBrowser *browser,
- GtkWidget *old_page,
- GtkWidget *new_page,
- BonoboControl *parent_control)
-{
- if (BONOBO_IS_WIDGET (old_page)) {
- BonoboControlFrame *control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (old_page));
-
- bonobo_control_frame_control_deactivate (control_frame);
- }
-
- if (BONOBO_IS_WIDGET (new_page)) {
- BonoboControlFrame *control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (new_page));
- Bonobo_UIContainer ui_container = bonobo_control_get_remote_ui_container (parent_control, NULL);
-
- /* This is necessary because we are not embedding the folder browser control
- directly; we are putting the folder browser control into a notebook which
- is then exported to the shell as a control. So we need to forward the
- notebook's UIContainer to the folder browser. */
- bonobo_control_frame_set_ui_container (control_frame, ui_container, NULL);
-
- bonobo_control_frame_control_activate (control_frame);
- }
-}
-
-static CamelFolder *
-foo_get_folder (EStorageSetView *view, const char *path, CamelException *ex)
-{
- /* <NotZed> either do
- mail_tool_uri_to_folder(ess_get_folder(path).physicaluri),
- or split the path into 'path' and 'storage name' and do get
- ess_get_storage() -> store -> open_folder
- */
- CamelFolder *folder;
- EStorageSet *set;
- EFolder *efolder;
- const char *uri;
-
- set = e_storage_set_view_get_storage_set (view);
- efolder = e_storage_set_get_folder (set, path);
- uri = e_folder_get_physical_uri (efolder);
-
- folder = mail_tool_uri_to_folder (uri, 0, ex);
-
- return folder;
-}
-
-static void
-drag_text_uri_list (EStorageSetView *view, const char *path, GtkSelectionData *selection, gpointer user_data)
-{
- CamelFolder *src, *dest;
- const char *tmpdir;
- CamelStore *store;
- CamelException ex;
- GtkWidget *dialog;
- GPtrArray *uids;
- char *uri;
-
- camel_exception_init (&ex);
-
- if (!(src = foo_get_folder (view, path, &ex))) {
- dialog = gtk_message_dialog_new ((GtkWindow *) view, GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- _("Could not open source folder: %s"),
- camel_exception_get_description (&ex));
-
- gtk_dialog_run ((GtkDialog *) dialog);
- gtk_widget_destroy (dialog);
-
- camel_exception_clear (&ex);
-
- return;
- }
- if (!(tmpdir = e_mkdtemp ("drag-n-drop-XXXXXX"))) {
- dialog = gtk_message_dialog_new ((GtkWindow *) view, GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- _("Could not create temporary directory: %s"),
- g_strerror (errno));
-
- gtk_dialog_run ((GtkDialog *) dialog);
- gtk_widget_destroy (dialog);
-
- camel_object_unref (src);
-
- return;
- }
-
- uri = g_strdup_printf ("mbox:%s", tmpdir);
- if (!(store = camel_session_get_store (session, uri, &ex))) {
- dialog = gtk_message_dialog_new ((GtkWindow *) view, GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- _("Could not create temporary mbox store: %s"),
- camel_exception_get_description (&ex));
-
- gtk_dialog_run ((GtkDialog *) dialog);
- gtk_widget_destroy (dialog);
-
- camel_exception_clear (&ex);
- camel_object_unref (src);
- g_free (uri);
-
- return;
- }
-
- if (!(dest = camel_store_get_folder (store, "mbox", CAMEL_STORE_FOLDER_CREATE, &ex))) {
- dialog = gtk_message_dialog_new ((GtkWindow *) view, GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- _("Could not create temporary mbox folder: %s"),
- camel_exception_get_description (&ex));
-
- gtk_dialog_run ((GtkDialog *) dialog);
- gtk_widget_destroy (dialog);
-
- camel_exception_clear (&ex);
- camel_object_unref (store);
- camel_object_unref (src);
- g_free (uri);
-
- return;
- }
-
- camel_object_unref (store);
- uids = camel_folder_get_uids (src);
-
- camel_folder_transfer_messages_to (src, uids, dest, NULL, FALSE, &ex);
- if (camel_exception_is_set (&ex)) {
- dialog = gtk_message_dialog_new ((GtkWindow *) view, GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- _("Could not copy messages to temporary mbox folder: %s"),
- camel_exception_get_description (&ex));
-
- gtk_dialog_run ((GtkDialog *) dialog);
- gtk_widget_destroy (dialog);
-
- camel_folder_free_uids (src, uids);
- camel_exception_clear (&ex);
- camel_object_unref (dest);
- camel_object_unref (src);
- g_free (uri);
-
- return;
- }
-
- camel_folder_free_uids (src, uids);
- camel_object_unref (dest);
- camel_object_unref (src);
-
- memcpy (uri, "file", 4);
-
- gtk_selection_data_set (selection, selection->target, 8,
- uri, strlen (uri));
-
- g_free (uri);
-}
-
-static void
-folder_dragged_cb (EStorageSetView *view, const char *path, GdkDragContext *context,
- GtkSelectionData *selection, guint info, guint time, gpointer user_data)
-{
- printf ("dragging folder `%s'\n", path);
-
- switch (info) {
- case DND_DRAG_TYPE_FOLDER:
- /* dragging @path to a new location in the folder tree */
- gtk_selection_data_set (selection, selection->target, 8, path, strlen (path) + 1);
- break;
- case DND_DRAG_TYPE_TEXT_URI_LIST:
- /* dragging @path to some place external to evolution */
- drag_text_uri_list (view, path, selection, user_data);
- break;
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
-drop_uid_list (EStorageSetView *view, const char *path, gboolean move, GtkSelectionData *selection, gpointer user_data)
-{
- CamelFolder *src, *dest;
- CamelException ex;
- GPtrArray *uids;
- char *src_uri;
-
- em_utils_selection_get_uidlist (selection, &src_uri, &uids);
-
- camel_exception_init (&ex);
-
- if (!(src = mail_tool_uri_to_folder (src_uri, 0, &ex))) {
- /* FIXME: report error to user? */
- camel_exception_clear (&ex);
- em_utils_uids_free (uids);
- g_free (src_uri);
- return;
- }
-
- g_free (src_uri);
-
- if (!(dest = foo_get_folder (view, path, &ex))) {
- /* FIXME: report error to user? */
- camel_exception_clear (&ex);
- em_utils_uids_free (uids);
- camel_object_unref (src);
- return;
- }
-
- camel_folder_transfer_messages_to (src, uids, dest, NULL, move, &ex);
- if (camel_exception_is_set (&ex)) {
- /* FIXME: report error to user? */
- camel_exception_clear (&ex);
- em_utils_uids_free (uids);
- camel_object_unref (dest);
- camel_object_unref (src);
- return;
- }
-
- em_utils_uids_free (uids);
- camel_object_unref (dest);
- camel_object_unref (src);
-}
-
-static void
-drop_folder (EStorageSetView *view, const char *path, gboolean move, GtkSelectionData *selection, gpointer user_data)
-{
- CamelFolder *src, *dest;
- CamelFolder *store;
- CamelException ex;
-
- camel_exception_init (&ex);
-
- /* get the destination folder (where the user dropped). this
- * will become the parent folder of the folder that got
- * dragged */
- if (!(dest = foo_get_folder (view, path, &ex))) {
- /* FIXME: report error to user? */
- camel_exception_clear (&ex);
- return;
- }
-
- /* get the folder being dragged */
- if (!(src = foo_get_folder (view, selection->data, &ex))) {
- /* FIXME: report error to user? */
- camel_exception_clear (&ex);
- camel_object_unref (dest);
- return;
- }
-
- if (src->parent_store == dest->parent_store && move) {
- /* simple rename() action */
- char *old_name, *new_name;
-
- old_name = g_strdup (src->full_name);
- new_name = g_strdup_printf ("%s/%s", dest->full_name, src->name);
- camel_object_unref (src);
-
- camel_store_rename_folder (dest->parent_store, old_name, new_name, &ex);
- if (camel_exception_is_set (&ex)) {
- /* FIXME: report error to user? */
- camel_exception_clear (&ex);
- camel_object_unref (dest);
- g_free (old_name);
- g_free (new_name);
- return;
- }
-
- camel_object_unref (dest);
- g_free (old_name);
- g_free (new_name);
- } else {
- /* copy the folder */
- camel_object_unref (dest);
- camel_object_unref (src);
- }
-}
-
-static gboolean
-import_message_rfc822 (CamelFolder *dest, CamelStream *stream, gboolean scan_from, CamelException *ex)
-{
- CamelMimeParser *mp;
-
- mp = camel_mime_parser_new ();
- camel_mime_parser_scan_from (mp, scan_from);
- camel_mime_parser_init_with_stream (mp, stream);
-
- while (camel_mime_parser_step (mp, 0, 0) == CAMEL_MIME_PARSER_STATE_FROM) {
- CamelMessageInfo *info;
- CamelMimeMessage *msg;
-
- msg = camel_mime_message_new ();
- if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), mp) == -1) {
- camel_object_unref (msg);
- camel_object_unref (mp);
- return FALSE;
- }
-
- /* append the message to the folder... */
- info = g_new0 (CamelMessageInfo, 1);
- camel_folder_append_message (dest, msg, info, NULL, ex);
- camel_object_unref (msg);
-
- if (camel_exception_is_set (ex)) {
- camel_object_unref (mp);
- return FALSE;
- }
-
- /* skip over the FROM_END state */
- camel_mime_parser_step (mp, 0, 0);
- }
-
- camel_object_unref (mp);
-
- return TRUE;
-}
-
-static void
-drop_message_rfc822 (EStorageSetView *view, const char *path, GtkSelectionData *selection, gpointer user_data)
-{
- CamelFolder *folder;
- CamelStream *stream;
- CamelException ex;
- gboolean scan_from;
-
- camel_exception_init (&ex);
-
- if (!(folder = foo_get_folder (view, path, &ex))) {
- /* FIXME: report error to user? */
- camel_exception_clear (&ex);
- return;
- }
-
- scan_from = selection->length > 5 && !strncmp (selection->data, "From ", 5);
- stream = camel_stream_mem_new_with_buffer (selection->data, selection->length);
-
- if (!import_message_rfc822 (folder, stream, scan_from, &ex)) {
- /* FIXME: report to user? */
- }
-
- camel_exception_clear (&ex);
-
- camel_object_unref (stream);
- camel_object_unref (folder);
+ /* EPFIXME: This leaks the control. */
+ return bonobo_widget_new_control_from_objref (BONOBO_OBJREF (control), CORBA_OBJECT_NIL);
}
static void
-drop_text_uri_list (EStorageSetView *view, const char *path, GtkSelectionData *selection, gpointer user_data)
+folder_selected_cb (EMFolderTree *emft, const char *path, const char *uri, GtkBox *vbox)
{
- CamelFolder *folder;
- CamelStream *stream;
- CamelException ex;
- char **urls, *tmp;
- int i;
-
- camel_exception_init (&ex);
-
- if (!(folder = foo_get_folder (view, path, &ex))) {
- /* FIXME: report to user? */
- camel_exception_clear (&ex);
- return;
- }
-
- tmp = g_strndup (selection->data, selection->length);
- urls = g_strsplit (tmp, "\n", 0);
- g_free (tmp);
+ GtkWidget *view;
+ GList *l, *n;
- for (i = 0; urls[i] != NULL; i++) {
- CamelURL *uri;
- char *url;
- int fd;
-
- /* get the path component */
- url = g_strstrip (urls[i]);
- uri = camel_url_new (url, NULL);
- g_free (url);
-
- if (!uri || strcmp (uri->protocol, "file") != 0) {
- camel_url_free (uri);
- continue;
- }
-
- url = uri->path;
- uri->path = NULL;
- camel_url_free (uri);
-
- if ((fd = open (url, O_RDONLY)) == -1) {
- g_free (url);
- continue;
- }
-
- stream = camel_stream_fs_new_with_fd (fd);
- if (!import_message_rfc822 (folder, stream, TRUE, &ex)) {
- /* FIXME: report to user? */
- }
-
- camel_exception_clear (&ex);
- camel_object_unref (stream);
- g_free (url);
+ /* there should only ever be 1 child */
+ l = gtk_container_get_children (GTK_CONTAINER (vbox));
+ while (l != NULL) {
+ n = l->next;
+ gtk_widget_destroy (l->data);
+ g_list_free_1 (l);
+ l = n;
}
- camel_object_unref (folder);
- g_free (urls);
-}
-
-static void
-folder_receive_drop_cb (EStorageSetView *view, const char *path, GdkDragContext *context,
- GtkSelectionData *selection, guint info, guint time, gpointer user_data)
-{
- gboolean move = context->action == GDK_ACTION_MOVE;
-
- /* this means we are receiving no data */
- if (!selection->data || selection->length == -1)
- return;
-
- switch (info) {
- case DND_DROP_TYPE_UID_LIST:
- /* import a list of uids from another evo folder */
- drop_uid_list (view, path, move, selection, user_data);
- printf ("* dropped a x-uid-list\n");
- break;
- case DND_DROP_TYPE_FOLDER:
- /* rename a folder */
- drop_folder (view, path, move, selection, user_data);
- printf ("* dropped a x-folder\n");
- break;
- case DND_DROP_TYPE_MESSAGE_RFC822:
- /* import a message/rfc822 stream */
- drop_message_rfc822 (view, path, selection, user_data);
- printf ("* dropped a message/rfc822\n");
- break;
- case DND_DROP_TYPE_TEXT_URI_LIST:
- /* import an mbox, maildir, or mh folder? */
- drop_text_uri_list (view, path, selection, user_data);
- printf ("* dropped a text/uri-list\n");
- break;
- default:
- g_assert_not_reached ();
- }
+ view = create_view_widget (emft, path, uri);
+ gtk_widget_show (view);
- gtk_drag_finish (context, TRUE, TRUE, time);
+ gtk_box_pack_start_defaults (vbox, view);
}
@@ -879,49 +285,50 @@ static void
impl_dispose (GObject *object)
{
MailComponentPrivate *priv = MAIL_COMPONENT (object)->priv;
-
- if (priv->storage_set != NULL) {
- g_object_unref (priv->storage_set);
- priv->storage_set = NULL;
- }
-
- if (priv->folder_type_registry != NULL) {
- g_object_unref (priv->folder_type_registry);
- priv->folder_type_registry = NULL;
- }
-
+
if (priv->search_context != NULL) {
g_object_unref (priv->search_context);
priv->search_context = NULL;
}
-
+
if (priv->local_store != NULL) {
camel_object_unref (CAMEL_OBJECT (priv->local_store));
priv->local_store = NULL;
}
-
+
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
static void
+store_hash_free (gpointer key, gpointer value, gpointer user_data)
+{
+ CamelStore *store = key;
+ char *name = value;
+
+ g_free (name);
+ camel_object_unref (store);
+}
+
+static void
impl_finalize (GObject *object)
{
MailComponentPrivate *priv = MAIL_COMPONENT (object)->priv;
-
+
g_free (priv->base_directory);
-
+
mail_async_event_destroy (priv->async_event);
-
- g_hash_table_destroy (priv->storages_hash); /* EPFIXME free the data within? */
-
+
+ g_hash_table_foreach (priv->store_hash, store_hash_free, NULL);
+ g_hash_table_destroy (priv->store_hash);
+
if (mail_async_event_destroy (priv->async_event) == -1) {
g_warning("Cannot destroy async event: would deadlock");
g_warning(" system may be unstable at exit");
}
-
- g_free(priv->context_path);
+
+ g_free (priv->context_path);
g_free (priv);
-
+
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
@@ -930,45 +337,30 @@ impl_finalize (GObject *object)
static void
impl_createControls (PortableServer_Servant servant,
- Bonobo_Control *corba_sidebar_control,
+ Bonobo_Control *corba_tree_control,
Bonobo_Control *corba_view_control,
CORBA_Environment *ev)
{
MailComponent *mail_component = MAIL_COMPONENT (bonobo_object_from_servant (servant));
MailComponentPrivate *priv = mail_component->priv;
- EStorageBrowser *browser;
+ BonoboControl *tree_control;
+ BonoboControl *view_control;
GtkWidget *tree_widget;
- GtkWidget *tree_widget_scrolled;
GtkWidget *view_widget;
- BonoboControl *sidebar_control;
- BonoboControl *view_control;
-
- browser = e_storage_browser_new (priv->storage_set, "/", create_view_callback, NULL);
-
- tree_widget = e_storage_browser_peek_tree_widget (browser);
- tree_widget_scrolled = e_storage_browser_peek_tree_widget_scrolled (browser);
- view_widget = e_storage_browser_peek_view_widget (browser);
-
- e_storage_set_view_set_drag_types ((EStorageSetView *) tree_widget, drag_types, num_drag_types);
- e_storage_set_view_set_drop_types ((EStorageSetView *) tree_widget, drop_types, num_drop_types);
- e_storage_set_view_set_allow_dnd ((EStorageSetView *) tree_widget, TRUE);
- g_signal_connect (tree_widget, "folder_dragged", G_CALLBACK (folder_dragged_cb), browser);
- g_signal_connect (tree_widget, "folder_receive_drop", G_CALLBACK (folder_receive_drop_cb), browser);
+ tree_widget = (GtkWidget *) priv->emft;
+ view_widget = gtk_vbox_new (0, TRUE);
- gtk_widget_show (tree_widget_scrolled);
+ gtk_widget_show (tree_widget);
gtk_widget_show (view_widget);
-
- sidebar_control = bonobo_control_new (tree_widget_scrolled);
+
+ tree_control = bonobo_control_new (tree_widget);
view_control = bonobo_control_new (view_widget);
-
- *corba_sidebar_control = CORBA_Object_duplicate (BONOBO_OBJREF (sidebar_control), ev);
+
+ *corba_tree_control = CORBA_Object_duplicate (BONOBO_OBJREF (tree_control), ev);
*corba_view_control = CORBA_Object_duplicate (BONOBO_OBJREF (view_control), ev);
-
- g_signal_connect_object (browser, "page_switched",
- G_CALLBACK (browser_page_switched_callback), view_control, 0);
-
- g_signal_connect(tree_widget, "right_click", G_CALLBACK(emc_tree_right_click), mail_component);
+
+ g_signal_connect (tree_widget, "folder-selected", G_CALLBACK (folder_selected_cb), view_widget);
}
@@ -1042,14 +434,13 @@ mail_component_init (MailComponent *component)
if (camel_mkdir (priv->base_directory, 0777) == -1 && errno != EEXIST)
abort ();
+ priv->emft = em_folder_tree_new ();
+
/* EPFIXME: Turn into an object? */
mail_session_init (priv->base_directory);
priv->async_event = mail_async_event_new();
- priv->storages_hash = g_hash_table_new (NULL, NULL);
-
- priv->folder_type_registry = e_folder_type_registry_new ();
- priv->storage_set = e_storage_set_new (priv->folder_type_registry);
+ priv->store_hash = g_hash_table_new (NULL, NULL);
/* migrate evolution 1.x folders to 2.0's location/format */
mail_dir = g_strdup_printf ("%s/mail", priv->base_directory);
@@ -1218,35 +609,34 @@ store_disconnect (CamelStore *store,
void *data)
{
camel_service_disconnect (CAMEL_SERVICE (store), TRUE, NULL);
- camel_object_unref (CAMEL_OBJECT (store));
+ camel_object_unref (store);
}
void
-mail_component_remove_storage (MailComponent *component,
- CamelStore *store)
+mail_component_remove_storage (MailComponent *component, CamelStore *store)
{
MailComponentPrivate *priv = component->priv;
- EStorage *storage;
+ char *name;
- /* Because the storages_hash holds a reference to each store
+ /* Because the store_hash holds a reference to each store
* used as a key in it, none of them will ever be gc'ed, meaning
* any call to camel_session_get_{service,store} with the same
* URL will always return the same object. So this works.
*/
- storage = g_hash_table_lookup (priv->storages_hash, store);
- if (!storage)
+ if (!(name = g_hash_table_lookup (priv->store_hash, store)))
return;
- g_hash_table_remove (priv->storages_hash, store);
+ g_hash_table_remove (priv->store_hash, store);
+ g_free (name);
/* so i guess potentially we could have a race, add a store while one
being removed. ?? */
mail_note_store_remove (store);
-
- e_storage_set_remove_storage (priv->storage_set, storage);
- mail_async_event_emit(priv->async_event, MAIL_ASYNC_THREAD, (MailAsyncFunc) store_disconnect, store, NULL, NULL);
+ em_folder_tree_remove_store (priv->emft, store);
+
+ mail_async_event_emit (priv->async_event, MAIL_ASYNC_THREAD, (MailAsyncFunc) store_disconnect, store, NULL, NULL);
}
@@ -1272,46 +662,29 @@ mail_component_remove_storage_by_uri (MailComponent *component,
}
-EStorage *
-mail_component_lookup_storage (MailComponent *component,
- CamelStore *store)
-{
- EStorage *storage;
-
- /* Because the storages_hash holds a reference to each store
- * used as a key in it, none of them will ever be gc'ed, meaning
- * any call to camel_session_get_{service,store} with the same
- * URL will always return the same object. So this works.
- */
-
- storage = g_hash_table_lookup (component->priv->storages_hash, store);
- if (storage)
- g_object_ref (storage);
-
- return storage;
-}
-
-
int
mail_component_get_storage_count (MailComponent *component)
{
- return g_hash_table_size (component->priv->storages_hash);
+ return g_hash_table_size (component->priv->store_hash);
}
-EStorageSet *
-mail_component_peek_storage_set (MailComponent *component)
+void
+mail_component_storages_foreach (MailComponent *component, GHFunc func, void *user_data)
{
- return component->priv->storage_set;
+ g_hash_table_foreach (component->priv->store_hash, func, user_data);
}
-void
-mail_component_storages_foreach (MailComponent *component,
- GHFunc func,
- void *data)
+EMFolderTreeModel *
+mail_component_get_tree_model (MailComponent *component)
{
- g_hash_table_foreach (component->priv->storages_hash, func, data);
+ EMFolderTreeModel *model;
+
+ model = (EMFolderTreeModel *) gtk_tree_view_get_model ((GtkTreeView *) component->priv->emft);
+ g_object_ref (model);
+
+ return model;
}
extern struct _CamelSession *session;
@@ -1502,681 +875,3 @@ mail_component_evomail_uri_from_folder (MailComponent *component,
BONOBO_TYPE_FUNC_FULL (MailComponent, GNOME_Evolution_Component, PARENT_TYPE, mail_component)
-
-
-/* ********************************************************************** */
-#if 0
-static void
-emc_popup_view(GtkWidget *w, MailComponent *mc)
-{
-
-}
-
-static void
-emc_popup_open_new(GtkWidget *w, MailComponent *mc)
-{
-}
-#endif
-
-/* FIXME: This must be done in another thread */
-static void
-em_copy_folders(CamelStore *tostore, const char *tobase, CamelStore *fromstore, const char *frombase, int delete)
-{
- GString *toname, *fromname;
- CamelFolderInfo *fi;
- GList *pending = NULL, *deleting = NULL, *l;
- guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE;
- CamelException *ex = camel_exception_new();
- int fromlen;
- const char *tmp;
-
- if (camel_store_supports_subscriptions(fromstore))
- flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
-
- fi = camel_store_get_folder_info(fromstore, frombase, flags, ex);
- if (camel_exception_is_set(ex))
- goto done;
-
- pending = g_list_append(pending, fi);
-
- toname = g_string_new("");
- fromname = g_string_new("");
-
- tmp = strrchr(frombase, '/');
- if (tmp == NULL)
- fromlen = 0;
- else
- fromlen = tmp-frombase+1;
-
- 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;
-
- if (info->child)
- pending = g_list_append(pending, info->child);
- if (tobase[0])
- g_string_printf(toname, "%s/%s", tobase, info->full_name + fromlen);
- else
- g_string_printf(toname, "%s", info->full_name + fromlen);
-
- 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) {
- printf("this folder is selectable\n");
- fromfolder = camel_store_get_folder(fromstore, info->full_name, 0, ex);
- if (fromfolder == NULL)
- goto exception;
-
- tofolder = camel_store_get_folder(tostore, toname->str, CAMEL_STORE_FOLDER_CREATE, ex);
- if (tofolder == NULL) {
- camel_object_unref(fromfolder);
- goto exception;
- }
-
- if (camel_store_supports_subscriptions(tostore)
- && !camel_store_folder_subscribed(tostore, toname->str))
- camel_store_subscribe_folder(tostore, toname->str, NULL);
-
- uids = camel_folder_get_uids(fromfolder);
- camel_folder_transfer_messages_to(fromfolder, uids, tofolder, NULL, delete, ex);
- camel_folder_free_uids(fromfolder, uids);
-
- camel_object_unref(fromfolder);
- camel_object_unref(tofolder);
- }
-
- if (camel_exception_is_set(ex))
- goto exception;
- else if (delete)
- deleting = g_list_prepend(deleting, info);
-
- info = info->sibling;
- }
- }
-
- /* delete the folders in reverse order from how we copyied them, if we are deleting any */
- l = deleting;
- while (l) {
- CamelFolderInfo *info = l->data;
-
- printf("deleting folder '%s'\n", info->full_name);
-
- if (camel_store_supports_subscriptions(fromstore))
- camel_store_unsubscribe_folder(fromstore, info->full_name, NULL);
-
- camel_store_delete_folder(fromstore, info->full_name, NULL);
- l = l->next;
- }
-
-exception:
- camel_store_free_folder_info(fromstore, fi);
- g_list_free(deleting);
-
- g_string_free(toname, TRUE);
- g_string_free(fromname, TRUE);
-done:
- printf("exception: %s\n", ex->desc?ex->desc:"<none>");
- camel_exception_free(ex);
-}
-
-struct _copy_folder_data {
- MailComponent *mc;
- int delete;
-};
-
-static void
-emc_popup_copy_folder_selected(const char *uri, void *data)
-{
- struct _copy_folder_data *d = data;
-
- if (uri == NULL) {
- g_free(d);
- return;
- }
-
- if (uri) {
- EFolder *folder = e_storage_set_get_folder(d->mc->priv->storage_set, d->mc->priv->context_path);
- CamelException *ex = camel_exception_new();
- CamelStore *fromstore, *tostore;
- char *tobase, *frombase;
- CamelURL *url;
-
- printf("copying folder '%s' to '%s'\n", d->mc->priv->context_path, uri);
-
- fromstore = camel_session_get_store(session, e_folder_get_physical_uri(folder), ex);
- frombase = strchr(d->mc->priv->context_path+1, '/')+1;
-
- tostore = camel_session_get_store(session, uri, ex);
- url = camel_url_new(uri, NULL);
- if (url->fragment)
- tobase = url->fragment;
- else if (url->path && url->path[0])
- tobase = url->path+1;
- else
- tobase = "";
-
- em_copy_folders(tostore, tobase, fromstore, frombase, d->delete);
-
- camel_url_free(url);
- camel_exception_free(ex);
- }
- g_free(d);
-}
-
-static void
-emc_popup_copy(GtkWidget *w, MailComponent *mc)
-{
- struct _copy_folder_data *d;
-
- d = g_malloc(sizeof(*d));
- d->mc = mc;
- d->delete = 0;
- em_select_folder(NULL, _("Select folder"), _("Select destination to copy folder into"), NULL, emc_popup_copy_folder_selected, d);
-}
-
-static void
-emc_popup_move(GtkWidget *w, MailComponent *mc)
-{
- struct _copy_folder_data *d;
-
- d = g_malloc(sizeof(*d));
- d->mc = mc;
- d->delete = 1;
- em_select_folder(NULL, _("Select folder"), _("Select destination to move folder into"), NULL, emc_popup_copy_folder_selected, d);
-}
-static void
-emc_popup_new_folder_create(EStorageSet *ess, EStorageResult result, void *data)
-{
- printf("folder created %s\n", result == E_STORAGE_OK?"ok":"failed");
-}
-
-static void
-emc_popup_new_folder_response(EMFolderSelector *emfs, guint response, MailComponent *mc)
-{
- if (response == GTK_RESPONSE_OK) {
- char *path, *tmp, *name, *full;
- EStorage *storage;
- CamelStore *store;
- CamelException *ex;
-
- printf("Creating folder: %s (%s)\n", em_folder_selector_get_selected(emfs),
- em_folder_selector_get_selected_uri(emfs));
-
- path = g_strdup(em_folder_selector_get_selected(emfs));
- tmp = strchr(path+1, '/');
- *tmp++ = 0;
- /* FIXME: camel_store_create_folder should just take full path names */
- full = g_strdup(tmp);
- name = strrchr(tmp, '/');
- if (name == NULL) {
- name = tmp;
- tmp = "";
- } else
- *name++ = 0;
-
- storage = e_storage_set_get_storage(mc->priv->storage_set, path+1);
- store = g_object_get_data((GObject *)storage, "em-store");
-
- printf("creating folder '%s' / '%s' on '%s'\n", tmp, name, path+1);
-
- ex = camel_exception_new();
- camel_store_create_folder(store, tmp, name, ex);
- if (camel_exception_is_set(ex)) {
- printf("Create failed: %s\n", ex->desc);
- } else if (camel_store_supports_subscriptions(store)) {
- camel_store_subscribe_folder(store, full, ex);
- if (camel_exception_is_set(ex)) {
- printf("Subscribe failed: %s\n", ex->desc);
- }
- }
-
- camel_exception_free(ex);
-
- g_free(full);
- g_free(path);
-
- /* Blah, this should just use camel, we get better error reporting if we do too */
- /*e_storage_set_async_create_folder(mc->priv->storage_set, path, "mail", "", emc_popup_new_folder_create, mc);*/
- }
- gtk_widget_destroy((GtkWidget *)emfs);
-}
-
-static void
-emc_popup_new_folder (GtkWidget *w, MailComponent *mc)
-{
- GtkWidget *dialog;
-
- dialog = em_folder_selector_create_new(mc->priv->storage_set, 0, _("Create folder"), _("Specify where to create the folder:"));
- em_folder_selector_set_selected((EMFolderSelector *)dialog, mc->priv->context_path);
- g_signal_connect(dialog, "response", G_CALLBACK(emc_popup_new_folder_response), mc);
- gtk_widget_show(dialog);
-}
-
-static void
-em_delete_rec(CamelStore *store, CamelFolderInfo *fi, CamelException *ex)
-{
- while (fi) {
- CamelFolder *folder;
-
- if (fi->child)
- em_delete_rec(store, fi->child, ex);
- if (camel_exception_is_set(ex))
- return;
-
- 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);
-
- folder = camel_store_get_folder(store, fi->full_name, 0, NULL);
- if (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_sync(folder, TRUE, NULL);
- camel_folder_thaw(folder);
- camel_folder_free_uids(folder, uids);
- }
-
- camel_store_delete_folder(store, fi->full_name, ex);
- if (camel_exception_is_set(ex))
- return;
- fi = fi->sibling;
- }
-}
-
-static void
-em_delete_folders(CamelStore *store, const char *base, CamelException *ex)
-{
- CamelFolderInfo *fi;
- guint32 flags = CAMEL_STORE_FOLDER_INFO_RECURSIVE;
-
- if (camel_store_supports_subscriptions(store))
- flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
-
- fi = camel_store_get_folder_info(store, base, flags, ex);
- if (camel_exception_is_set(ex))
- return;
-
- em_delete_rec(store, fi, ex);
- camel_store_free_folder_info(store, fi);
-}
-
-static void
-emc_popup_delete_response(GtkWidget *w, guint response, MailComponent *mc)
-{
- gtk_widget_destroy(w);
-
- if (response == GTK_RESPONSE_OK) {
- const char *path = strchr(mc->priv->context_path+1, '/')+1;
- EFolder *folder = e_storage_set_get_folder(mc->priv->storage_set, mc->priv->context_path);
- CamelException *ex = camel_exception_new();
- CamelStore *store;
-
- /* FIXME: need to hook onto store changed event and delete view as well, somewhere else tho */
- store = camel_session_get_store(session, e_folder_get_physical_uri(folder), ex);
- if (camel_exception_is_set(ex))
- goto exception;
-
- em_delete_folders(store, path, ex);
- if (!camel_exception_is_set(ex))
- goto noexception;
- exception:
- e_notice(NULL, GTK_MESSAGE_ERROR,
- _("Could not delete folder: %s"), ex->desc);
- noexception:
- camel_exception_free(ex);
- if (store)
- camel_object_unref(store);
- }
-}
-
-static void
-emc_popup_delete_folder(GtkWidget *w, MailComponent *mc)
-{
- GtkWidget *dialog;
- char *title;
- const char *path = strchr(mc->priv->context_path+1, '/')+1;
- EFolder *folder;
-
- folder = e_storage_set_get_folder(mc->priv->storage_set, mc->priv->context_path);
- if (folder == NULL)
- return;
-
- dialog = gtk_message_dialog_new(NULL,
- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE,
- _("Really delete folder \"%s\" and all of its subfolders?"), path);
-
- gtk_dialog_add_button((GtkDialog *)dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
- gtk_dialog_add_button((GtkDialog *)dialog, GTK_STOCK_DELETE, GTK_RESPONSE_OK);
-
- gtk_dialog_set_default_response((GtkDialog *)dialog, GTK_RESPONSE_OK);
- gtk_container_set_border_width((GtkContainer *)dialog, 6);
- gtk_box_set_spacing((GtkBox *)((GtkDialog *)dialog)->vbox, 6);
-
- title = g_strdup_printf(_("Delete \"%s\""), path);
- gtk_window_set_title((GtkWindow *)dialog, title);
- g_free(title);
-
- g_signal_connect(dialog, "response", G_CALLBACK(emc_popup_delete_response), mc);
- gtk_widget_show(dialog);
-}
-
-static void
-emc_popup_rename_folder(GtkWidget *w, MailComponent *mc)
-{
- char *prompt, *new;
- EFolder *folder;
- const char *old, *why;
- int done = 0;
-
- folder = e_storage_set_get_folder(mc->priv->storage_set, mc->priv->context_path);
- if (folder == NULL)
- return;
-
- old = e_folder_get_name(folder);
- prompt = g_strdup_printf (_("Rename the \"%s\" folder to:"), e_folder_get_name(folder));
- while (!done) {
- new = e_request_string(NULL, _("Rename Folder"), prompt, old);
- if (new == NULL || strcmp(old, new) == 0)
- done = 1;
-#if 0
- else if (!e_shell_folder_name_is_valid(new, &why))
- e_notice(NULL, GTK_MESSAGE_ERROR, _("The specified folder name is not valid: %s"), why);
-#endif
- else {
- char *base, *path;
-
- /* FIXME: we can't use the os independent path crap here, since we want to control the format */
- base = g_path_get_dirname(mc->priv->context_path);
- path = g_build_filename(base, new, NULL);
-
- if (e_storage_set_get_folder(mc->priv->storage_set, path) != NULL) {
- e_notice(NULL, GTK_MESSAGE_ERROR,
- _("A folder named \"%s\" already exists. Please use a different name."), new);
- } else {
- CamelStore *store;
- CamelException *ex = camel_exception_new();
- const char *oldpath, *newpath;
-
- oldpath = strchr(mc->priv->context_path+1, '/');
- g_assert(oldpath);
- newpath = strchr(path+1, '/');
- g_assert(newpath);
- oldpath++;
- newpath++;
-
- printf("renaming %s to %s\n", oldpath, newpath);
-
- store = camel_session_get_store(session, e_folder_get_physical_uri(folder), ex);
- if (camel_exception_is_set(ex))
- goto exception;
-
- camel_store_rename_folder(store, oldpath, newpath, ex);
- if (!camel_exception_is_set(ex))
- goto noexception;
-
- exception:
- e_notice(NULL, GTK_MESSAGE_ERROR,
- _("Could not rename folder: %s"), ex->desc);
- noexception:
- if (store)
- camel_object_unref(store);
- camel_exception_free(ex);
-
- done = 1;
- }
- g_free(path);
- g_free(base);
- }
- g_free(new);
- }
-}
-
-struct _prop_data {
- void *object;
- CamelArgV *argv;
- GtkWidget **widgets;
-};
-
-static void
-emc_popup_properties_response(GtkWidget *dialog, int response, struct _prop_data *prop_data)
-{
- int i;
- CamelArgV *argv = prop_data->argv;
-
- if (response != GTK_RESPONSE_OK) {
- gtk_widget_destroy(dialog);
- return;
- }
-
- for (i=0;i<argv->argc;i++) {
- CamelArg *arg = &argv->argv[i];
-
- switch (arg->tag & CAMEL_ARG_TYPE) {
- case CAMEL_ARG_BOO:
- arg->ca_int = gtk_toggle_button_get_active ((GtkToggleButton *) prop_data->widgets[i]);
- break;
- case CAMEL_ARG_STR:
- g_free(arg->ca_str);
- arg->ca_str = gtk_entry_get_text ((GtkEntry *) prop_data->widgets[i]);
- break;
- default:
- printf("unknown property type set\n");
- }
- }
-
- camel_object_setv(prop_data->object, NULL, argv);
- gtk_widget_destroy(dialog);
-}
-
-static void
-emc_popup_properties_free(void *data)
-{
- struct _prop_data *prop_data = data;
- int i;
-
- for (i=0; i<prop_data->argv->argc; i++) {
- if ((prop_data->argv->argv[i].tag & CAMEL_ARG_TYPE) == CAMEL_ARG_STR)
- g_free(prop_data->argv->argv[i].ca_str);
- }
- camel_object_unref(prop_data->object);
- g_free(prop_data->argv);
- g_free(prop_data);
-}
-
-static void
-emc_popup_properties_got_folder (char *uri, CamelFolder *folder, void *data)
-{
- if (folder) {
- GtkWidget *dialog, *w, *table, *label;
- GSList *list, *l;
- char *name;
- int row = 1;
- gint32 count, i;
- struct _prop_data *prop_data;
- CamelArgV *argv;
- CamelArgGetV *arggetv;
-
- camel_object_get(folder, NULL, CAMEL_FOLDER_PROPERTIES, &list, CAMEL_FOLDER_NAME, &name, NULL);
-
- dialog = gtk_dialog_new_with_buttons(_("Folder properties"),
- NULL,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_OK,
- GTK_RESPONSE_OK,
- NULL);
-
- /* TODO: maybe we want some basic properties here, like message counts/approximate size/etc */
- w = gtk_frame_new(_("Properties"));
- gtk_box_pack_start ((GtkBox *) ((GtkDialog *)dialog)->vbox, w, TRUE, TRUE, 6);
- table = gtk_table_new(g_slist_length(list)+1, 2, FALSE);
- gtk_container_add((GtkContainer *)w, table);
- label = gtk_label_new(_("Folder Name"));
- gtk_misc_set_alignment ((GtkMisc *) label, 1.0, 0.5);
- gtk_table_attach ((GtkTable *) table, label, 0, 1, 0, 1, GTK_FILL|GTK_EXPAND, 0, 3, 0);
- label = gtk_label_new(name);
- gtk_misc_set_alignment ((GtkMisc *) label, 0.0, 0.5);
- gtk_table_attach ((GtkTable *) table, label, 1, 2, 0, 1, GTK_FILL|GTK_EXPAND, 0, 3, 0);
-
- /* build an arggetv/argv to retrieve/store the results */
- count = g_slist_length(list);
- arggetv = g_malloc0(sizeof(*arggetv) + (count - CAMEL_ARGV_MAX) * sizeof(arggetv->argv[0]));
- arggetv->argc = count;
- argv = g_malloc0(sizeof(*argv) + (count - CAMEL_ARGV_MAX) * sizeof(argv->argv[0]));
- argv->argc = count;
- i = 0;
- l = list;
- while (l) {
- CamelProperty *prop = l->data;
-
- argv->argv[i].tag = prop->tag;
- arggetv->argv[i].tag = prop->tag;
- arggetv->argv[i].ca_ptr = &argv->argv[i].ca_ptr;
-
- l = l->next;
- i++;
- }
- camel_object_getv(folder, NULL, arggetv);
- g_free(arggetv);
-
- prop_data = g_malloc0(sizeof(*prop_data));
- prop_data->widgets = g_malloc0(sizeof(prop_data->widgets[0]) * count);
- prop_data->argv = argv;
-
- /* setup the ui with the values retrieved */
- l = list;
- i = 0;
- while (l) {
- CamelProperty *prop = l->data;
-
- switch (prop->tag & CAMEL_ARG_TYPE) {
- case CAMEL_ARG_BOO:
- w = gtk_check_button_new_with_label(prop->description);
- gtk_toggle_button_set_active((GtkToggleButton *)w, argv->argv[i].ca_int != 0);
- gtk_table_attach ((GtkTable *) table, w, 0, 2, row, row+1, 0, 0, 3, 3);
- prop_data->widgets[i] = w;
- break;
- case CAMEL_ARG_STR:
- label = gtk_label_new(prop->description);
- gtk_misc_set_alignment ((GtkMisc *) label, 1.0, 0.5);
- gtk_table_attach ((GtkTable *) table, label, 0, 1, row, row+1, GTK_FILL|GTK_EXPAND, 0, 3, 3);
-
- w = gtk_entry_new();
- if (argv->argv[i].ca_str) {
- gtk_entry_set_text((GtkEntry *)w, argv->argv[i].ca_str);
- camel_object_free(folder, argv->argv[i].tag, argv->argv[i].ca_str);
- argv->argv[i].ca_str = NULL;
- }
- gtk_table_attach ((GtkTable *) table, w, 1, 2, row, row+1, GTK_FILL, 0, 3, 3);
- prop_data->widgets[i] = w;
- break;
- default:
- w = gtk_label_new("CamelFolder error: unsupported propery type");
- gtk_table_attach ((GtkTable *) table, w, 0, 2, row, row+1, 0, 0, 3, 3);
- break;
- }
-
- row++;
- l = l->next;
- }
-
- prop_data->object = folder;
- camel_object_ref(folder);
-
- camel_object_free(folder, CAMEL_FOLDER_PROPERTIES, list);
- camel_object_free(folder, CAMEL_FOLDER_NAME, name);
-
- /* we do 'apply on ok' ... since instant apply may apply some very long running tasks */
-
- g_signal_connect(dialog, "response", G_CALLBACK(emc_popup_properties_response), prop_data);
- g_object_set_data_full((GObject *)dialog, "e-prop-data", prop_data, emc_popup_properties_free);
- gtk_widget_show_all(dialog);
- }
-}
-
-static void
-emc_popup_properties(GtkWidget *w, MailComponent *mc)
-{
- EFolder *efolder;
-
- /* TODO: Make sure we only have one dialog open for any given folder */
-
- efolder = e_storage_set_get_folder(mc->priv->storage_set, mc->priv->context_path);
- if (efolder == NULL)
- return;
-
- mail_get_folder(e_folder_get_physical_uri(efolder), 0, emc_popup_properties_got_folder, mc, mail_thread_new);
-}
-
-static EMPopupItem emc_popup_menu[] = {
-#if 0
- { EM_POPUP_ITEM, "00.emc.00", N_("_View"), G_CALLBACK(emc_popup_view), NULL, NULL, 0 },
- { EM_POPUP_ITEM, "00.emc.01", N_("Open in _New Window"), G_CALLBACK(emc_popup_open_new), NULL, NULL, 0 },
-
- { EM_POPUP_BAR, "10.emc" },
-#endif
- { EM_POPUP_ITEM, "10.emc.00", N_("_Copy"), G_CALLBACK(emc_popup_copy), NULL, "folder-copy-16.png", 0 },
- { EM_POPUP_ITEM, "10.emc.01", N_("_Move"), G_CALLBACK(emc_popup_move), NULL, "folder-move-16.png", 0 },
-
- { EM_POPUP_BAR, "20.emc" },
- { EM_POPUP_ITEM, "20.emc.00", N_("_New Folder..."), G_CALLBACK(emc_popup_new_folder), NULL, "folder-mini.png", 0 },
- { EM_POPUP_ITEM, "20.emc.01", N_("_Delete"), G_CALLBACK(emc_popup_delete_folder), NULL, "evolution-trash-mini.png", 0 },
- { EM_POPUP_ITEM, "20.emc.01", N_("_Rename"), G_CALLBACK(emc_popup_rename_folder), NULL, NULL, 0 },
-
- { EM_POPUP_BAR, "80.emc" },
- { EM_POPUP_ITEM, "80.emc.00", N_("_Properties..."), G_CALLBACK(emc_popup_properties), NULL, "configure_16_folder.xpm", 0 },
-};
-
-
-static int
-emc_tree_right_click(ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event, MailComponent *component)
-{
- char *name;
- ETreeModel *model = e_tree_get_model(tree);
- EMPopup *emp;
- int i;
- GSList *menus = NULL;
- struct _GtkMenu *menu;
-
- name = e_tree_memory_node_get_data((ETreeMemory *)model, path);
- g_free(component->priv->context_path);
- component->priv->context_path = g_strdup(name);
- printf("right click, path = '%s'\n", name);
-
- emp = em_popup_new("com.ximian.mail.storageset.popup.select");
-
- for (i=0;i<sizeof(emc_popup_menu)/sizeof(emc_popup_menu[0]);i++) {
- EMPopupItem *item = &emc_popup_menu[i];
-
- item->activate_data = component;
- menus = g_slist_prepend(menus, item);
- }
-
- em_popup_add_items(emp, menus, (GDestroyNotify)g_slist_free);
-
- menu = em_popup_create_menu_once(emp, NULL, 0, 0);
-
- if (event == NULL || event->type == GDK_KEY_PRESS) {
- /* FIXME: menu pos function */
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 0, event->key.time);
- } else {
- gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event->button.button, event->button.time);
- }
-
- return TRUE;
-}