From e0097e7f47f7bdd546b3d705d2dcf0893d29e3a2 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Tue, 2 Dec 2003 23:29:09 +0000 Subject: Moved here. (drop_folder): Moved here. (import_message_rfc822): Moved 2003-12-02 Jeffrey Stedfast * em-folder-tree-model.c (drop_uid_list): Moved here. (drop_folder): Moved here. (import_message_rfc822): Moved here. (drop_message_rfc822): Moved here. (drop_text_uri_list): Moved here. (model_drag_data_received): Moved the logic from em-folder-tree.c into here. (model_row_drop_possible): Same. (model_row_draggable): Same. (drag_text_uri_list): Moved here. (model_drag_data_get): Moved logic here. (model_drag_data_delete): Moved logic here. * em-folder-tree.c (drag_data_get_cb): Pass the full_name to camel_store_get_folder() rather than the path. (drag_data_received_cb): Same. (drop_uid_list): Removed. (drop_folder): Removed. (import_message_rfc822): Removed. (drop_message_rfc822): Removed. (drop_text_uri_list): Removed. (drag_data_received_cb): Removed. (row_drop_possible_cb): Removed. (row_draggable_cb): Removed. (drag_text_uri_list): Removed. (drag_data_get_cb): Removed. (drag_data_delete_cb): Removed. (em_folder_tree_enable_drag_and_drop): Don't connect to any of the drag & drop signals, they don't exist anymore. * mail-component.c (impl_createControls): Enable drag-and-drop. * em-folder-tree.c (em_folder_tree_new_with_model): Connect to the loading row signal. (loading_row_cb): Expand the path if needed. (em_folder_tree_destroy): Disconnect from the loading-row signal. (em_folder_tree_enable_drag_and_drop): New function to enable drag-and-drop. (em_folder_tree_new): Remove drag-and-drop setup code. * em-folder-tree-model.c (em_folder_tree_model_class_init): Define the loading-row signal. (em_folder_tree_model_set_folder_info): emit the loading-row signal. svn path=/trunk/; revision=23590 --- mail/em-folder-tree.c | 462 ++------------------------------------------------ 1 file changed, 15 insertions(+), 447 deletions(-) (limited to 'mail/em-folder-tree.c') 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) -- cgit