diff options
Diffstat (limited to 'mail')
-rw-r--r-- | mail/ChangeLog | 12 | ||||
-rw-r--r-- | mail/em-folder-tree-model.c | 191 | ||||
-rw-r--r-- | mail/em-folder-tree-model.h | 7 | ||||
-rw-r--r-- | mail/em-folder-tree.c | 10 |
4 files changed, 139 insertions, 81 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index f95ec64f09..fdbf85a0c4 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,15 @@ +2004-02-03 Jeffrey Stedfast <fejj@ximian.com> + + * em-folder-tree.c (tree_drag_data_received): Modified + slightly. The model now calls gtk_drag_finish() for us when it is + done. + + * em-folder-tree-model.c + (em_folder_tree_model_drag_data_received): Make this perform camel + operations in another thread so we don't block. + (em_folder_tree_model_drag_data_get): Updated args to be + consistant with drag_data_received. + 2004-02-03 Radek Doulik <rodo@ximian.com> * em-junk-filter.c: handle the sa prefs here, have own gconf diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c index 5c7ca7333e..ad9768dcd5 100644 --- a/mail/em-folder-tree-model.c +++ b/mail/em-folder-tree-model.c @@ -1030,31 +1030,31 @@ drop_uid_list (CamelFolder *dest, GtkSelectionData *selection, gboolean move, gb } static void -drop_folder (CamelStore *dest_store, const char *dest_name, GtkSelectionData *selection, gboolean move, gboolean *moved, CamelException *ex) +drop_folder (CamelStore *dest_store, const char *name, GtkSelectionData *selection, gboolean move, gboolean *moved, CamelException *ex) { CamelFolder *src; char *new_name; *moved = FALSE; - + /* FIXME: all this stuff needs to run asynchronous */ - + if (!(src = mail_tool_uri_to_folder (selection->data, 0, ex))) return; - + /* handles dropping to the root properly */ - if (dest_name[0]) - new_name = g_strdup_printf ("%s/%s", dest_name, src->name); + if (name[0]) + new_name = g_strdup_printf ("%s/%s", name, src->name); else - new_name = g_strdup(src->name); - + new_name = g_strdup (src->name); + if (src->parent_store == dest_store && move) { /* simple case, rename */ camel_store_rename_folder (dest_store, src->full_name, new_name, ex); *moved = !camel_exception_is_set (ex); } else { CamelFolder *dest; - + /* copy the folder to the new location */ if ((dest = camel_store_get_folder (dest_store, new_name, CAMEL_STORE_FOLDER_CREATE, ex))) { GPtrArray *uids; @@ -1066,8 +1066,8 @@ drop_folder (CamelStore *dest_store, const char *dest_name, GtkSelectionData *se camel_object_unref (dest); } } - - g_free(new_name); + + g_free (new_name); camel_object_unref (src); } @@ -1170,78 +1170,134 @@ drop_text_uri_list (CamelFolder *dest, GtkSelectionData *selection, CamelExcepti g_free (urls); } -gboolean -em_folder_tree_model_drag_data_received (EMFolderTreeModel *model, GtkTreePath *dest_path, GtkSelectionData *selection, - guint info, gboolean move, gboolean *moved) -{ - const char *full_name; - CamelFolder *folder; - CamelStore *store; - CamelException ex; - GtkTreeIter iter; - char *path; - - *moved = FALSE; - - /* this means we are receiving no data */ - if (!selection->data || selection->length == -1) - return FALSE; +struct _DragDataReceivedAsync { + struct _mail_msg msg; - if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, dest_path)) { - d(printf ("\tfailed to get row\n")); - return FALSE; - } - - gtk_tree_model_get ((GtkTreeModel *) model, &iter, - COL_POINTER_CAMEL_STORE, &store, - COL_STRING_FOLDER_PATH, &path, -1); + /* input data */ + GdkDragContext *context; + GtkSelectionData *selection; + CamelStore *store; + char *full_name; + gboolean move; + guint info; - /* make sure user isn't try to drop on a placeholder row */ - if (path == NULL) { - d(printf ("\tdropped on a placeholder row?\n")); - return FALSE; - } - - full_name = path[0] == '/' ? path + 1 : path; - camel_exception_init (&ex); + /* output data */ + gboolean moved; +}; +static void +emftm_drag_data_received_async__drop (struct _mail_msg *mm) +{ + struct _DragDataReceivedAsync *m = (struct _DragDataReceivedAsync *) mm; + CamelFolder *folder; + /* for types other than folder, we can't drop to the root path */ - if (info == DND_DROP_TYPE_FOLDER) { + if (m->info == DND_DROP_TYPE_FOLDER) { /* copy or move (aka rename) a folder */ - drop_folder(store, full_name, selection, move, moved, &ex); - d(printf ("\t* dropped a x-folder ('%s' into '%s')\n", selection->data, full_name)); - } else if (full_name[0] == 0) { - return FALSE; - } else if ((folder = camel_store_get_folder (store, full_name, 0, &ex))) { - switch (info) { + drop_folder (m->store, m->full_name, m->selection, m->move, &m->moved, &mm->ex); + d(printf ("\t* dropped a x-folder ('%s' into '%s')\n", m->selection->data, m->full_name)); + } else if (m->full_name[0] == 0) { + camel_exception_set (&mm->ex, CAMEL_EXCEPTION_SYSTEM, + _("Cannot drop message(s) into toplevel store")); + } else if ((folder = camel_store_get_folder (m->store, m->full_name, 0, &mm->ex))) { + switch (m->info) { case DND_DROP_TYPE_UID_LIST: /* import a list of uids from another evo folder */ - drop_uid_list (folder, selection, move, moved, &ex); + drop_uid_list (folder, m->selection, m->move, &m->moved, &mm->ex); d(printf ("\t* dropped a x-uid-list\n")); break; - /* case DND_DROP_TYPE_FOLDER: handled above special case */ case DND_DROP_TYPE_MESSAGE_RFC822: /* import a message/rfc822 stream */ - drop_message_rfc822 (folder, selection, &ex); + drop_message_rfc822 (folder, m->selection, &mm->ex); d(printf ("\t* dropped a message/rfc822\n")); break; case DND_DROP_TYPE_TEXT_URI_LIST: /* import an mbox, maildir, or mh folder? */ - drop_text_uri_list (folder, selection, &ex); + drop_text_uri_list (folder, m->selection, &mm->ex); d(printf ("\t* dropped a text/uri-list\n")); break; default: g_assert_not_reached (); } } +} + +static void +emftm_drag_data_received_async__done (struct _mail_msg *mm) +{ + struct _DragDataReceivedAsync *m = (struct _DragDataReceivedAsync *) mm; + gboolean success, delete; + + success = !camel_exception_is_set (&mm->ex); + delete = success && m->move && !m->moved; + + gtk_drag_finish (m->context, success, delete, GDK_CURRENT_TIME); +} + +static void +emftm_drag_data_received_async__free (struct _mail_msg *mm) +{ + struct _DragDataReceivedAsync *m = (struct _DragDataReceivedAsync *) mm; + + g_object_unref (m->context); + g_object_unref (m->selection); + camel_object_unref (m->store); + g_free (m->full_name); +} + +static struct _mail_msg_op drag_data_received_async_op = { + NULL, + emftm_drag_data_received_async__drop, + emftm_drag_data_received_async__done, + emftm_drag_data_received_async__free, +}; + +void +em_folder_tree_model_drag_data_received (EMFolderTreeModel *model, GdkDragContext *context, GtkTreePath *dest_path, + GtkSelectionData *selection, guint info) +{ + struct _DragDataReceivedAsync *m; + const char *full_name; + CamelStore *store; + GtkTreeIter iter; + char *path; + + /* this means we are receiving no data */ + if (!selection->data || selection->length == -1) { + gtk_drag_finish (context, FALSE, FALSE, GDK_CURRENT_TIME); + return; + } - if (camel_exception_is_set (&ex)) { - printf ("\t* exception: %s\n", ex.desc); - camel_exception_clear (&ex); - return FALSE; + if (!gtk_tree_model_get_iter ((GtkTreeModel *) model, &iter, dest_path)) { + gtk_drag_finish (context, FALSE, FALSE, GDK_CURRENT_TIME); + return; } - return TRUE; + gtk_tree_model_get ((GtkTreeModel *) model, &iter, + COL_POINTER_CAMEL_STORE, &store, + COL_STRING_FOLDER_PATH, &path, -1); + + /* make sure user isn't try to drop on a placeholder row */ + if (path == NULL) { + gtk_drag_finish (context, FALSE, FALSE, GDK_CURRENT_TIME); + return; + } + + full_name = path[0] == '/' ? path + 1 : path; + + g_object_ref (context); + g_object_ref (selection); + camel_object_ref (store); + + m = mail_msg_new (&drag_data_received_async_op, NULL, sizeof (struct _DragDataReceivedAsync)); + m->context = context; + m->selection = selection; + m->store = store; + m->full_name = g_strdup (full_name); + m->move = context->action == GDK_ACTION_MOVE; + m->info = info; + + e_thread_put (mail_thread_new, (EMsg *) m); } @@ -1383,9 +1439,8 @@ drag_text_uri_list (CamelFolder *src, GtkSelectionData *selection, CamelExceptio g_string_free (url, TRUE); } - -gboolean -em_folder_tree_model_drag_data_get (EMFolderTreeModel *model, GtkTreePath *src_path, GtkSelectionData *selection, guint info) +void +em_folder_tree_model_drag_data_get (EMFolderTreeModel *model, GdkDragContext *context, GtkTreePath *src_path, GtkSelectionData *selection, guint info) { const char *full_name; CamelFolder *folder; @@ -1405,25 +1460,22 @@ em_folder_tree_model_drag_data_get (EMFolderTreeModel *model, GtkTreePath *src_p COL_STRING_URI, &uri, -1); /* make sure user isn't try to drag on a placeholder row */ - if (path == NULL) { - printf ("model_drag_data_get failed to get path\n"); + if (path == NULL) return FALSE; - } full_name = path[0] == '/' ? path + 1 : path; - camel_exception_init (&ex); - switch (info) { case DND_DRAG_TYPE_FOLDER: /* dragging to a new location in the folder tree */ gtk_selection_data_set (selection, drag_atoms[info], 8, uri, strlen (uri) + 1); - printf ("model_drag_data_get setting x-folder data\n"); break; case DND_DRAG_TYPE_TEXT_URI_LIST: /* dragging to nautilus or something, probably */ + /* Note: this doesn't need to be done in another + * thread because the folder should already be + * cached */ if ((folder = camel_store_get_folder (store, full_name, 0, &ex))) { - printf ("model_drag_data_get setting text/uri-list data\n"); drag_text_uri_list (folder, selection, &ex); camel_object_unref (folder); } @@ -1433,7 +1485,6 @@ em_folder_tree_model_drag_data_get (EMFolderTreeModel *model, GtkTreePath *src_p } if (camel_exception_is_set (&ex)) { - printf ("model_drag_data_get failed: %s\n", ex.desc); camel_exception_clear (&ex); return FALSE; } diff --git a/mail/em-folder-tree-model.h b/mail/em-folder-tree-model.h index 2dbe7a2a5b..71cf0dd4bd 100644 --- a/mail/em-folder-tree-model.h +++ b/mail/em-folder-tree-model.h @@ -125,12 +125,13 @@ void em_folder_tree_model_save_expanded (EMFolderTreeModel *model); void em_folder_tree_model_set_unread_count (EMFolderTreeModel *model, CamelStore *store, const char *path, int unread); /* Drag & Drop stuff */ -gboolean em_folder_tree_model_drag_data_received (EMFolderTreeModel *model, GtkTreePath *path, GtkSelectionData *selection, - guint info, gboolean move, gboolean *moved); +void em_folder_tree_model_drag_data_received (EMFolderTreeModel *model, GdkDragContext *context, GtkTreePath *path, + GtkSelectionData *selection, guint info); GdkDragAction em_folder_tree_model_row_drop_possible (EMFolderTreeModel *model, GtkTreePath *path, GList *targets); GdkAtom em_folder_tree_model_row_drop_target (EMFolderTreeModel *model, GtkTreePath *path, GList *targets); gboolean em_folder_tree_model_row_draggable (EMFolderTreeModel *model, GtkTreePath *path); -gboolean em_folder_tree_model_drag_data_get (EMFolderTreeModel *model, GtkTreePath *path, GtkSelectionData *selection, guint info); +void em_folder_tree_model_drag_data_get (EMFolderTreeModel *model, GdkDragContext *context, GtkTreePath *path, + GtkSelectionData *selection, guint info); gboolean em_folder_tree_model_drag_data_delete (EMFolderTreeModel *model, GtkTreePath *path); void em_folder_tree_model_set_drag_drop_types (EMFolderTreeModel *model, GtkWidget *widget); diff --git a/mail/em-folder-tree.c b/mail/em-folder-tree.c index 216c547ff8..2fdd2ff5b9 100644 --- a/mail/em-folder-tree.c +++ b/mail/em-folder-tree.c @@ -551,7 +551,7 @@ tree_drag_data_get (GtkWidget *widget, GdkDragContext *context, GtkSelectionData if (!priv->drag_row || !(path = gtk_tree_row_reference_get_path (priv->drag_row))) return; - em_folder_tree_model_drag_data_get (priv->model, path, selection, info); + em_folder_tree_model_drag_data_get (priv->model, context, path, selection, info); gtk_tree_path_free (path); } @@ -562,17 +562,11 @@ tree_drag_data_received (GtkWidget *widget, GdkDragContext *context, int x, int struct _EMFolderTreePrivate *priv = emft->priv; GtkTreeViewDropPosition pos; GtkTreePath *path; - gboolean success; - gboolean moved; - gboolean move; if (!gtk_tree_view_get_dest_row_at_pos (priv->treeview, x, y, &path, &pos)) return; - move = context->action == GDK_ACTION_MOVE; - success = em_folder_tree_model_drag_data_received (priv->model, path, selection, info, move, &moved); - - gtk_drag_finish (context, success, success && move && !moved, time); + em_folder_tree_model_drag_data_received (priv->model, context, path, selection, info); } static gboolean |