summaryrefslogtreecommitdiff
path: root/libnautilus-private/nautilus-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnautilus-private/nautilus-file.c')
-rw-r--r--libnautilus-private/nautilus-file.c145
1 files changed, 92 insertions, 53 deletions
diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c
index 5f630ccc6..b86b0fccb 100644
--- a/libnautilus-private/nautilus-file.c
+++ b/libnautilus-private/nautilus-file.c
@@ -520,58 +520,81 @@ typedef struct {
/* Operation-specific data. */
char *new_name; /* rename */
-} FileOperationState;
+} Operation;
-static FileOperationState *
-file_operation_state_new (NautilusFile *file,
- NautilusFileOperationCallback callback,
- gpointer callback_data)
+static Operation *
+operation_new (NautilusFile *file,
+ NautilusFileOperationCallback callback,
+ gpointer callback_data)
{
- FileOperationState *state;
+ Operation *op;
nautilus_file_ref (file);
- state = g_new0 (FileOperationState, 1);
- state->file = file;
- state->callback = callback;
- state->callback_data = callback_data;
+ op = g_new0 (Operation, 1);
+ op->file = file;
+ op->callback = callback;
+ op->callback_data = callback_data;
- return state;
+ op->file->details->operations_in_progress = g_list_prepend
+ (op->file->details->operations_in_progress, op);
+
+ return op;
}
static void
-file_operation_state_free (FileOperationState *state)
+operation_free (Operation *op)
{
- nautilus_file_unref (state->file);
- g_free (state->new_name);
- g_free (state);
+ op->file->details->operations_in_progress = g_list_remove
+ (op->file->details->operations_in_progress, op);
+
+ nautilus_file_unref (op->file);
+
+ g_free (op->new_name);
+
+ g_free (op);
}
static void
-file_operation_state_complete (FileOperationState *state,
- GnomeVFSResult result)
+operation_complete (Operation *op,
+ GnomeVFSResult result)
{
/* Claim that something changed even if the operation failed.
* This makes it easier for some clients who see the "reverting"
* as "changing back".
*/
- nautilus_file_changed (state->file);
- (* state->callback) (state->file, result, state->callback_data);
- file_operation_state_free (state);
+ nautilus_file_changed (op->file);
+ (* op->callback) (op->file, result, op->callback_data);
+ operation_free (op);
}
static void
-rename_update_info_and_metafile (FileOperationState *state)
+operation_cancel (Operation *op)
+{
+ /* Cancel the operation if it's still in progress. */
+ g_assert (op->handle != NULL);
+ gnome_vfs_async_cancel (op->handle);
+
+ /* Claim that something changed even though the operation was
+ * canceled in case some work was partly done, but don't call
+ * the callback.
+ */
+ nautilus_file_changed (op->file);
+ operation_free (op);
+}
+
+static void
+rename_update_info_and_metafile (Operation *op)
{
nautilus_directory_update_file_metadata
- (state->file->details->directory,
- state->file->details->name,
- state->new_name);
+ (op->file->details->directory,
+ op->file->details->name,
+ op->new_name);
- g_free (state->file->details->name);
- state->file->details->name = g_strdup (state->new_name);
- if (state->file->details->info != NULL) {
- state->file->details->info->name = state->file->details->name;
+ g_free (op->file->details->name);
+ op->file->details->name = g_strdup (op->new_name);
+ if (op->file->details->info != NULL) {
+ op->file->details->info->name = op->file->details->name;
}
}
@@ -580,10 +603,10 @@ rename_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSXferProgressInfo *info,
gpointer callback_data)
{
- FileOperationState *state;
+ Operation *op;
- state = callback_data;
- g_assert (handle == state->handle);
+ op = callback_data;
+ g_assert (handle == op->handle);
g_assert (info != NULL);
/* We aren't really interested in progress, but we do need to see
@@ -594,16 +617,17 @@ rename_callback (GnomeVFSAsyncHandle *handle,
if (info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) {
/* Here's the case where we are done renaming. */
if (info->vfs_status == GNOME_VFS_OK) {
- rename_update_info_and_metafile (state);
+ rename_update_info_and_metafile (op);
}
- file_operation_state_complete (state, info->vfs_status);
+ operation_complete (op, info->vfs_status);
}
break;
case GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR:
/* We have to handle this case because if you pass
* GNOME_VFS_ERROR_MODE_ABORT, you never get the
* error code for a failed rename.
- * FIXME bugzilla.eazel.com 912: I believe this
+ */
+ /* FIXME bugzilla.eazel.com 912: I believe this
* represents a bug in GNOME VFS.
*/
return GNOME_VFS_XFER_ERROR_ACTION_ABORT;
@@ -611,8 +635,10 @@ rename_callback (GnomeVFSAsyncHandle *handle,
break;
}
- /* FIXME bugzilla.eazel.com 886: Pavel says I should return
- * this, but he promises he will fix the API.
+ /* FIXME bugzilla.eazel.com 886: Pavel says we should return
+ * this, but he promises he will fix the API so we don't have
+ * to have special "occult knowledge" to understand this must
+ * be a 1.
*/
return 1;
}
@@ -626,7 +652,7 @@ nautilus_file_rename (NautilusFile *file,
char *directory_uri_text;
GList *source_name_list, *target_name_list;
GnomeVFSResult result;
- FileOperationState *state;
+ Operation *op;
g_return_if_fail (NAUTILUS_IS_FILE (file));
g_return_if_fail (new_name != NULL);
@@ -660,35 +686,48 @@ nautilus_file_rename (NautilusFile *file,
return;
}
- state = file_operation_state_new (file, callback, callback_data);
- state->new_name = g_strdup (new_name);
+ /* Set up a renaming operation. */
+ op = operation_new (file, callback, callback_data);
+ op->new_name = g_strdup (new_name);
directory_uri_text = nautilus_directory_get_uri (file->details->directory);
source_name_list = g_list_prepend (NULL, file->details->name);
target_name_list = g_list_prepend (NULL, (char *) new_name);
result = gnome_vfs_async_xfer
- (&state->handle,
+ (&op->handle,
directory_uri_text, source_name_list,
directory_uri_text, target_name_list,
GNOME_VFS_XFER_SAMEFS | GNOME_VFS_XFER_REMOVESOURCE,
GNOME_VFS_XFER_ERROR_MODE_QUERY,
GNOME_VFS_XFER_OVERWRITE_MODE_ABORT,
- rename_callback, state,
+ rename_callback, op,
NULL, NULL);
g_free (directory_uri_text);
g_list_free (source_name_list);
g_list_free (target_name_list);
if (result != GNOME_VFS_OK) {
- file_operation_state_free (state);
+ operation_complete (op, result);
+ }
+}
- /* Claim that something changed even if the rename failed.
- * This makes it easier for some clients who see the "reverting"
- * to the old name as "changing back".
- */
- nautilus_file_changed (file);
- (* callback) (file, result, callback_data);
- return;
+void
+nautilus_file_cancel (NautilusFile *file,
+ NautilusFileOperationCallback callback,
+ gpointer callback_data)
+{
+ GList *p, *next;
+ Operation *op;
+
+ for (p = file->details->operations_in_progress; p != NULL; p = next) {
+ next = p->next;
+ op = p->data;
+
+ g_assert (op->file == file);
+ if (op->callback == callback
+ && op->callback_data == callback_data) {
+ operation_cancel (op);
+ }
}
}
@@ -1893,7 +1932,7 @@ nautilus_file_set_owner (NautilusFile *file,
if (!nautilus_file_can_set_owner (file)) {
/* Claim that something changed even if the permission change failed.
* This makes it easier for some clients who see the "reverting"
- * to the old permissions as "changing back".
+ * to the old owner as "changing back".
*/
nautilus_file_changed (file);
(* callback) (file, GNOME_VFS_ERROR_ACCESS_DENIED, callback_data);
@@ -3330,9 +3369,9 @@ nautilus_file_call_when_ready (NautilusFile *file,
}
void
-nautilus_file_cancel_callback (NautilusFile *file,
- NautilusFileCallback callback,
- gpointer callback_data)
+nautilus_file_cancel_call_when_ready (NautilusFile *file,
+ NautilusFileCallback callback,
+ gpointer callback_data)
{
g_return_if_fail (callback != NULL);