aboutsummaryrefslogtreecommitdiffstats
path: root/mail/em-folder-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/em-folder-tree.c')
-rw-r--r--mail/em-folder-tree.c462
1 files changed, 15 insertions, 447 deletions
diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c
index 42ffcf0f1d..aac98704c1 100644
--- a/mail/em-folder-tree.c
+++ b/mail/em-folder-tree.c
@@ -75,9 +75,6 @@ struct _EMFolderTreePrivate {
guint save_state_id;
guint loading_row_id;
-
- /* dnd signal ids */
- guint ddr, rdp, rd, ddg, ddd;
};
enum {
@@ -322,36 +319,6 @@ em_folder_tree_destroy (GtkObject *obj)
priv->loading_row_id = 0;
}
- if (priv->ddr != 0) {
- g_signal_handler_disconnect (priv->model, priv->ddr);
- priv->ddr = 0;
- }
-
- if (priv->rdp != 0) {
- g_signal_handler_disconnect (priv->model, priv->rdp);
- priv->rdp = 0;
- }
-
- if (priv->rd != 0) {
- g_signal_handler_disconnect (priv->model, priv->rd);
- priv->rd = 0;
- }
-
- if (priv->ddg != 0) {
- g_signal_handler_disconnect (priv->model, priv->ddg);
- priv->ddg = 0;
- }
-
- if (priv->ddd != 0) {
- g_signal_handler_disconnect (priv->model, priv->ddd);
- priv->ddd = 0;
- }
-
- if (priv->save_state_id != 0) {
- em_folder_tree_save_state ((EMFolderTree *) obj);
- priv->save_state_id = 0;
- }
-
priv->treeview = NULL;
priv->model = NULL;
@@ -418,411 +385,9 @@ em_folder_tree_construct (EMFolderTree *emft, EMFolderTreeModel *model)
}
-static void
-drop_uid_list (EMFolderTree *emft, CamelFolder *dest, gboolean move, GtkSelectionData *selection, CamelException *ex)
-{
- CamelFolder *src;
- GPtrArray *uids;
- char *src_uri;
-
- em_utils_selection_get_uidlist (selection, &src_uri, &uids);
-
- if (!(src = mail_tool_uri_to_folder (src_uri, 0, ex))) {
- em_utils_uids_free (uids);
- g_free (src_uri);
- return;
- }
-
- g_free (src_uri);
-
- camel_folder_transfer_messages_to (src, uids, dest, NULL, move, ex);
- em_utils_uids_free (uids);
- camel_object_unref (src);
-}
-
-static void
-drop_folder (EMFolderTree *emft, CamelFolder *dest, gboolean move, GtkSelectionData *selection, CamelException *ex)
-{
- CamelFolder *src;
-
- /* get the folder being dragged */
- if (!(src = mail_tool_uri_to_folder (selection->data, 0, ex)))
- 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_store_rename_folder (dest->parent_store, old_name, new_name, ex);
-
- g_free (old_name);
- g_free (new_name);
- } else {
- /* copy the folder to the new location */
- CamelFolder *folder;
- char *path;
-
- path = g_strdup_printf ("%s/%s", dest->full_name, src->name);
- if ((folder = camel_store_get_folder (dest->parent_store, path, CAMEL_STORE_FOLDER_CREATE, ex))) {
- GPtrArray *uids;
-
- uids = camel_folder_get_uids (src);
- camel_folder_transfer_messages_to (src, uids, folder, NULL, FALSE, ex);
- camel_folder_free_uids (src, uids);
-
- camel_object_unref (folder);
- }
-
- g_free (path);
- }
-
- 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 (EMFolderTree *emft, CamelFolder *dest, GtkSelectionData *selection, CamelException *ex)
-{
- CamelStream *stream;
- gboolean scan_from;
-
- scan_from = selection->length > 5 && !strncmp (selection->data, "From ", 5);
- stream = camel_stream_mem_new_with_buffer (selection->data, selection->length);
-
- import_message_rfc822 (dest, stream, scan_from, ex);
-
- camel_object_unref (stream);
-}
-
-static void
-drop_text_uri_list (EMFolderTree *emft, CamelFolder *dest, GtkSelectionData *selection, CamelException *ex)
-{
- char **urls, *url, *tmp;
- CamelStream *stream;
- CamelURL *uri;
- int fd, i;
-
- tmp = g_strndup (selection->data, selection->length);
- urls = g_strsplit (tmp, "\n", 0);
- g_free (tmp);
-
- for (i = 0; urls[i] != NULL; i++) {
- /* 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 (dest, stream, TRUE, ex)) {
- /* FIXME: should we abort now? or continue? */
- /* for now lets just continue... */
- camel_exception_clear (ex);
- }
-
- camel_object_unref (stream);
- g_free (url);
- }
-
- g_free (urls);
-}
-
-static gboolean
-drag_data_received_cb (EMFolderTreeModel *model, GtkTreePath *dest_path, GtkSelectionData *selection, EMFolderTree *emft)
-{
- CamelFolder *folder;
- CamelStore *store;
- CamelException ex;
- GtkTreeIter iter;
- char *path;
-
- /* this means we are receiving no data */
- if (!selection->data || selection->length == -1)
- return FALSE;
-
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, dest_path))
- return FALSE;
-
- gtk_tree_model_get ((GtkTreeModel *) model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_FOLDER_PATH, &path, -1);
-
- camel_exception_init (&ex);
- if ((folder = camel_store_get_folder (store, path, 0, &ex))) {
- /* FIXME: would have been nicer if we could 'move'
- * messages and/or folders. but alas, gtktreeview
- * drag&drop sucks ass and doesn't give us the
- * context->action to check for GDK_ACTION_MOVE, so we
- * can't. Yay. */
- gboolean move = FALSE;
-
- if (selection->target == gdk_atom_intern ("x-uid-list", FALSE)) {
- /* import a list of uids from another evo folder */
- drop_uid_list (emft, folder, move, selection, &ex);
- d(printf ("* dropped a x-uid-list\n"));
- } else if (selection->target == gdk_atom_intern ("x-folder", FALSE)) {
- /* copy or move (aka rename) a folder */
- drop_folder (emft, folder, move, selection, &ex);
- d(printf ("* dropped a x-folder\n"));
- } else if (selection->target == gdk_atom_intern ("message/rfc822", FALSE)) {
- /* import a message/rfc822 stream */
- drop_message_rfc822 (emft, folder, selection, &ex);
- d(printf ("* dropped a message/rfc822\n"));
- } else if (selection->target == gdk_atom_intern ("text/uri-list", FALSE)) {
- /* import an mbox, maildir, or mh folder? */
- drop_text_uri_list (emft, folder, selection, &ex);
- d(printf ("* dropped a text/uri-list\n"));
- } else {
- g_assert_not_reached ();
- }
- }
-
- if (camel_exception_is_set (&ex)) {
- /* FIXME: error dialog? */
- camel_exception_clear (&ex);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-row_drop_possible_cb (EMFolderTreeModel *model, GtkTreePath *dest_path, GtkSelectionData *selection, EMFolderTree *emft)
-{
- GtkTreeIter iter;
- gboolean is_store;
-
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, dest_path))
- return FALSE;
-
- gtk_tree_model_get ((GtkTreeModel *) model, &iter, COL_BOOL_IS_STORE, &is_store, -1);
-
- if (selection->target == gdk_atom_intern ("x-uid-list", FALSE)) {
- if (is_store)
- return FALSE;
-
- return TRUE;
- } else if (selection->target == gdk_atom_intern ("x-folder", FALSE)) {
- return TRUE;
- } else if (selection->target == gdk_atom_intern ("message/rfc822", FALSE)) {
- if (is_store)
- return FALSE;
-
- return TRUE;
- } else if (selection->target == gdk_atom_intern ("text/uri-list", FALSE)) {
- if (is_store)
- return FALSE;
-
- return TRUE;
- } else {
- g_assert_not_reached ();
- return FALSE;
- }
-}
-
-static gboolean
-row_draggable_cb (EMFolderTreeModel *model, GtkTreePath *src_path, EMFolderTree *emft)
-{
- GtkTreeIter iter;
- gboolean is_store;
-
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, src_path))
- return FALSE;
-
- gtk_tree_model_get ((GtkTreeModel *) model, &iter, COL_BOOL_IS_STORE, &is_store, -1);
-
- return !is_store;
-}
-
-static void
-drag_text_uri_list (EMFolderTree *emft, CamelFolder *src, GtkSelectionData *selection, CamelException *ex)
-{
- CamelFolder *dest;
- const char *tmpdir;
- CamelStore *store;
- GPtrArray *uids;
- GString *url;
-
- if (!(tmpdir = e_mkdtemp ("drag-n-drop-XXXXXX"))) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create temporary directory: %s"),
- g_strerror (errno));
- return;
- }
-
- url = g_string_new ("mbox:");
- g_string_append (url, tmpdir);
- if (!(store = camel_session_get_store (session, url->str, ex))) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create temporary mbox store: %s"),
- camel_exception_get_description (ex));
- g_string_free (url, TRUE);
-
- return;
- }
-
- if (!(dest = camel_store_get_folder (store, "mbox", CAMEL_STORE_FOLDER_CREATE, ex))) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not create temporary mbox folder: %s"),
- camel_exception_get_description (ex));
-
- camel_object_unref (store);
- g_string_free (url, TRUE);
-
- 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)) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
- _("Could not copy messages to temporary mbox folder: %s"),
- camel_exception_get_description (ex));
- } else {
- /* replace "mbox:" with "file:" */
- memcpy (url->str, "file", 4);
- g_string_append (url, "\r\n");
- gtk_selection_data_set (selection, selection->target, 8, url->str, url->len);
- }
-
- camel_folder_free_uids (src, uids);
- camel_object_unref (dest);
- g_string_free (url, TRUE);
-}
-
-static gboolean
-drag_data_get_cb (EMFolderTreeModel *model, GtkTreePath *src_path, GtkSelectionData *selection, EMFolderTree *emft)
-{
- CamelFolder *folder;
- CamelStore *store;
- CamelException ex;
- GtkTreeIter iter;
- char *path, *uri;
-
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, src_path))
- return FALSE;
-
- gtk_tree_model_get ((GtkTreeModel *) model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_FOLDER_PATH, &path,
- COL_STRING_URI, &uri, -1);
-
- camel_exception_init (&ex);
-
- if (selection->target == gdk_atom_intern ("x-folder", FALSE)) {
- /* dragging to a new location in the folder tree */
- gtk_selection_data_set (selection, selection->target, 8, uri, strlen (uri) + 1);
- } else if (selection->target == gdk_atom_intern ("text/uri-list", FALSE)) {
- /* dragging to nautilus or something, probably */
- if ((folder = camel_store_get_folder (store, path, 0, &ex))) {
- drag_text_uri_list (emft, folder, selection, &ex);
- camel_object_unref (folder);
- }
- } else {
- g_assert_not_reached ();
- }
-
- if (camel_exception_is_set (&ex)) {
- /* FIXME: error dialog? */
- camel_exception_clear (&ex);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-drag_data_delete_cb (EMFolderTreeModel *model, GtkTreePath *src_path, EMFolderTree *emft)
-{
- gboolean is_store;
- CamelStore *store;
- CamelException ex;
- GtkTreeIter iter;
- char *path;
-
- if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, src_path))
- return FALSE;
-
- gtk_tree_model_get ((GtkTreeModel *) model, &iter,
- COL_POINTER_CAMEL_STORE, &store,
- COL_STRING_FOLDER_PATH, &path,
- COL_BOOL_IS_STORE, &is_store, -1);
-
- if (is_store)
- return FALSE;
-
- camel_exception_init (&ex);
- camel_store_delete_folder (store, path, &ex);
- if (camel_exception_is_set (&ex)) {
- /* FIXME: error dialog? */
- camel_exception_clear (&ex);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
GtkWidget *
em_folder_tree_new (void)
{
- struct _EMFolderTreePrivate *priv;
EMFolderTreeModel *model;
EMFolderTree *emft;
@@ -830,18 +395,6 @@ em_folder_tree_new (void)
emft = (EMFolderTree *) em_folder_tree_new_with_model (model);
g_object_unref (model);
- priv = emft->priv;
- priv->ddr = g_signal_connect (model, "drag-data-received", G_CALLBACK (drag_data_received_cb), emft);
- priv->rdp = g_signal_connect (model, "row-drop-possible", G_CALLBACK (row_drop_possible_cb), emft);
- priv->rd = g_signal_connect (model, "row-draggable", G_CALLBACK (row_draggable_cb), emft);
- priv->ddg = g_signal_connect (model, "drag-data-get", G_CALLBACK (drag_data_get_cb), emft);
- priv->ddd = g_signal_connect (model, "drag-data-delete", G_CALLBACK (drag_data_delete_cb), emft);
-
- gtk_tree_view_enable_model_drag_source (priv->treeview, 0, drag_types, num_drag_types,
- GDK_ACTION_COPY | GDK_ACTION_MOVE);
- gtk_tree_view_enable_model_drag_dest (priv->treeview, drop_types, num_drop_types,
- GDK_ACTION_COPY | GDK_ACTION_MOVE);
-
return (GtkWidget *) emft;
}
@@ -959,6 +512,21 @@ em_folder_tree_new_with_model (EMFolderTreeModel *model)
}
+void
+em_folder_tree_enable_drag_and_drop (EMFolderTree *emft)
+{
+ struct _EMFolderTreePrivate *priv;
+
+ g_return_if_fail (EM_IS_FOLDER_TREE (emft));
+
+ priv = emft->priv;
+ gtk_tree_view_enable_model_drag_source (priv->treeview, 0, drag_types, num_drag_types,
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+ gtk_tree_view_enable_model_drag_dest (priv->treeview, drop_types, num_drop_types,
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+}
+
+
#if 0
static void
dump_fi (CamelFolderInfo *fi, int depth)