Commit a49e9119 authored by Pavel Cisler's avatar Pavel Cisler Committed by Pavel Cisler

This checkin requires new gnome-vfs.


2000-04-17  Pavel Cisler  <pavel@eazel.com>

	This checkin requires new gnome-vfs.

	Plumbing for making copied/moved/deleted files show up update
	in their respective new locations.

	* libnautilus-extensions/nautilus-file-changes-queue.h
	* libnautilus-extensions/nautilus-file-changes-queue.c
	* libnautilus-extensions/Makefile.am
	Shared queue used by the copy engine to send update notification
	requests to NautilusDirectory during file copy/move/delete operations.

	* libnautilus-extensions/nautilus-directory-private.h:
	* libnautilus-extensions/nautilus-directory.c:
	(nautilus_directory_notify_files_added),
	(nautilus_directory_notify_files_removed),
	(nautilus_directory_notify_files_moved):
	Stub calls that will be hooked up to the NautilusDirectory
	notification calls to dispatch the notification updates.

	* src/file-manager/dfos-xfer.c:
	(sync_xfer_callback):
	New callback that gets called in the async copy engine context
	and produces change entries stuffing them into the file changes
	queue.

	* src/file-manager/dfos-xfer.c:
	(handle_xfer_ok):
	Added calls to the new nautilus_file_changes_consume_changes
	from the progress update callback. This callback is called in
	the user interface context and consumes the change entries
	from the file changes queue, sending them in chunks to be
	dispatched by to the individual Nautilus directory objects.

	* src/file-manager/dfos-xfer.c:
	(handle_xfer_ok):
	Updated to use new progress enum values.

	* src/file-manager/dfos-xfer.c:
	(update_xfer_callback):
	Renamed from sync_xfer_callback.

	* src/file-manager/dfos-xfer.c:
	(gnome_vfs_async_xfer):
	Pass in new sync_xfer_callback parameters.
parent 4393e962
2000-04-17 Pavel Cisler <pavel@eazel.com>
This checkin requires new gnome-vfs.
Plumbing for making copied/moved/deleted files show up update
in their respective new locations.
* libnautilus-extensions/nautilus-file-changes-queue.h
* libnautilus-extensions/nautilus-file-changes-queue.c
* libnautilus-extensions/Makefile.am
Shared queue used by the copy engine to send update notification
requests to NautilusDirectory during file copy/move/delete operations.
* libnautilus-extensions/nautilus-directory-private.h:
* libnautilus-extensions/nautilus-directory.c:
(nautilus_directory_notify_files_added),
(nautilus_directory_notify_files_removed),
(nautilus_directory_notify_files_moved):
Stub calls that will be hooked up to the NautilusDirectory
notification calls to dispatch the notification updates.
* src/file-manager/dfos-xfer.c:
(sync_xfer_callback):
New callback that gets called in the async copy engine context
and produces change entries stuffing them into the file changes
queue.
* src/file-manager/dfos-xfer.c:
(handle_xfer_ok):
Added calls to the new nautilus_file_changes_consume_changes
from the progress update callback. This callback is called in
the user interface context and consumes the change entries
from the file changes queue, sending them in chunks to be
dispatched by to the individual Nautilus directory objects.
* src/file-manager/dfos-xfer.c:
(handle_xfer_ok):
Updated to use new progress enum values.
* src/file-manager/dfos-xfer.c:
(update_xfer_callback):
Renamed from sync_xfer_callback.
* src/file-manager/dfos-xfer.c:
(gnome_vfs_async_xfer):
Pass in new sync_xfer_callback parameters.
2000-04-17 Darin Adler <darin@eazel.com>
* components/services/install/.cvsignore: Generated files.
......
......@@ -75,6 +75,7 @@ libnautilus_extensions_la_SOURCES = \
nautilus-entry.c \
nautilus-file-utilities.c \
nautilus-file.c \
nautilus-file-changes-queue.c \
nautilus-gdk-extensions.c \
nautilus-gdk-pixbuf-extensions.c \
nautilus-glib-extensions.c \
......
......@@ -81,6 +81,11 @@ typedef struct {
gpointer callback_data;
} QueuedCallback;
typedef struct {
char *from_uri;
char *to_uri;
} URIPair;
NautilusFile *nautilus_directory_find_file (NautilusDirectory *directory,
const char *file_name);
char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
......@@ -103,5 +108,10 @@ void nautilus_directory_cancel_callback_internal (NautilusDirectory
void nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
const QueuedCallback *callback);
/* Change notification calls */
void nautilus_directory_notify_files_added (GList *uris);
void nautilus_directory_notify_files_removed (GList *uris);
void nautilus_directory_notify_files_moved (GList *uri_pairs);
/* debugging functions */
int nautilus_directory_number_outstanding (void);
......@@ -1658,6 +1658,86 @@ process_pending_file_attribute_requests (NautilusDirectory *directory)
g_free (uri);
}
void
nautilus_directory_notify_files_added (GList *uris)
{
GList *p;
for (p = uris; p != NULL; p = p->next) {
#ifdef COPY_NOTIFY_TESTING
printf("added %s\n", (const char *)p->data);
#endif
/*
FIXME:
Find the parent directory of uri in directory_objects.
Create a new NautilusFile and add it to the directory.
Notify all observers of directory about new NautilusFile.
*/
}
nautilus_g_list_free_deep (uris);
}
void
nautilus_directory_notify_files_removed (GList *uris)
{
GList *p;
for (p = uris; p != NULL; p = p->next) {
#ifdef COPY_NOTIFY_TESTING
printf("removed %s\n", (const char *)p->data);
#endif
/*
FIXME:
Find the parent directory of uri in directory_objects.
Look up NautilusFile for uri.
Notify all observers of directory that the NautilusFile is
being removed.
Remove the NautilusFile from directory and delete it.
*/
}
nautilus_g_list_free_deep (uris);
}
void
nautilus_directory_notify_files_moved (GList *uri_pairs)
{
GList *p;
for (p = uri_pairs; p != NULL; p = p->next) {
#ifdef COPY_NOTIFY_TESTING
URIPair *pair;
pair = p->data;
printf("moved %s to %s \n", pair->from_uri, pair->to_uri);
#endif
/*
FIXME:
Find the parent directory of pair->from_uri in directory_objects.
Find the parent directory of pair->from_to in directory_objects.
Look up NautilusFile for pair->from_uri.
???
*/
}
/* deep delete the list of pairs */
for (p = uri_pairs; p != NULL; p = p->next) {
URIPair *pair;
/* delete the strings in each pair */
pair = p->data;
g_free (pair->from_uri);
g_free (pair->to_uri);
}
/* delete the list and the now empty pair structs */
nautilus_g_list_free_deep (uri_pairs);
}
#if !defined (NAUTILUS_OMIT_SELF_CHECK)
static int data_dummy;
......
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-directory.h: Nautilus directory model.
Copyright (C) 1999, 2000 Eazel, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "nautilus-file-changes-queue-private.h"
#include "nautilus-directory-private.h"
#ifdef G_THREADS_ENABLED
#define MUTEX_LOCK(a) if ((a) != NULL) g_mutex_lock (a)
#define MUTEX_UNLOCK(a) if ((a) != NULL) g_mutex_unlock (a)
#else
#define MUTEX_LOCK(a)
#define MUTEX_UNLOCK(a)
#endif
static NautilusFileChangesQueue *file_changes_queue;
static void
nautilus_file_change_free (NautilusFileChange *change)
{
g_free (change->from_uri);
g_free (change->to_uri);
}
static NautilusFileChangesQueue *
nautilus_file_changes_queue_new (void)
{
NautilusFileChangesQueue *result = g_new (NautilusFileChangesQueue, 1);
result->details = g_new0 (NautilusFileChangesQueueDetails, 1);
#ifdef G_THREADS_ENABLED
result->details->mutex = g_mutex_new ();
#endif
return result;
}
static NautilusFileChangesQueue *
nautilus_file_changes_queue_get (void)
{
if (file_changes_queue == NULL)
file_changes_queue = nautilus_file_changes_queue_new();
return file_changes_queue;
}
void
nautilus_file_changes_queue_free (NautilusFileChangesQueue *queue)
{
GList *p;
if (queue == NULL) {
return;
}
#ifdef G_THREADS_ENABLED
/* if lock on a defunct mutext were defined (returning a failure)
* we would lock here
*/
#endif
for (p = queue->details->head; p != NULL; p = p->next) {
nautilus_file_change_free (p->data);
}
g_list_free (queue->details->head);
#ifdef G_THREADS_ENABLED
g_mutex_free (queue->details->mutex);
#endif
g_free (queue->details);
g_free (queue);
}
static void
nautilus_file_changes_queue_add_common (NautilusFileChangesQueue *queue,
NautilusFileChange *new_item)
{
/* enqueue the new queue item while locking down the list */
MUTEX_LOCK (queue->details->mutex);
queue->details->head = g_list_prepend (queue->details->head, new_item);
if (queue->details->tail == NULL)
queue->details->tail = queue->details->head;
MUTEX_UNLOCK (queue->details->mutex);
}
void
nautilus_file_changes_queue_file_added (const char *uri)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
queue = nautilus_file_changes_queue_get();
g_assert (queue);
new_item = g_new0 (NautilusFileChange, 1);
new_item->kind = CHANGE_FILE_ADDED;
new_item->from_uri = g_strdup (uri);
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_file_removed (const char *uri)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
queue = nautilus_file_changes_queue_get();
g_assert (queue);
new_item = g_new0 (NautilusFileChange, 1);
new_item->kind = CHANGE_FILE_REMOVED;
new_item->from_uri = g_strdup (uri);
nautilus_file_changes_queue_add_common (queue, new_item);
}
void
nautilus_file_changes_queue_file_moved (const char *from, const char *to)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
queue = nautilus_file_changes_queue_get();
g_assert (queue);
new_item = g_new (NautilusFileChange, 1);
new_item->kind = CHANGE_FILE_REMOVED;
new_item->from_uri = g_strdup (from);
new_item->to_uri = g_strdup (to);
nautilus_file_changes_queue_add_common (queue, new_item);
}
static NautilusFileChange *
nautilus_file_changes_queue_get_change (NautilusFileChangesQueue *queue)
{
GList *new_tail;
NautilusFileChange *result;
/* dequeue the tail item while locking down the list */
MUTEX_LOCK (queue->details->mutex);
if (queue->details->tail == NULL) {
result = NULL;
} else {
new_tail = queue->details->tail->prev;
result = queue->details->tail->data;
queue->details->head = g_list_remove_link (queue->details->head,
queue->details->tail);
queue->details->tail = new_tail;
}
MUTEX_UNLOCK (queue->details->mutex);
return result;
}
enum {
CONSUME_CHANGES_MAX_CHUNK = 10
};
/* go through changes in the change queue, send ones with the same kind
* in a list to the different nautilus_directory_notify calls
*/
void
nautilus_file_changes_consume_changes (gboolean consume_all)
{
NautilusFileChange *change;
GList *additions;
GList *deletions;
GList *moves;
URIPair *pair;
int kind;
int chunk_count;
additions = NULL;
deletions = NULL;
moves = NULL;
kind = CHANGE_FILE_INITIAL;
if (file_changes_queue == NULL)
return;
for (chunk_count = 0; ; chunk_count++) {
change = nautilus_file_changes_queue_get_change (file_changes_queue);
if (change == NULL
/* no changes left */
|| change->kind != kind
/* all the changes we have are different that the new one */
|| (!consume_all && chunk_count >= CONSUME_CHANGES_MAX_CHUNK)) {
/* we have reached the chunk maximum */
/* send changes we collected off */
if (additions != NULL) {
nautilus_directory_notify_files_added (additions);
additions = NULL;
}
if (deletions != NULL) {
nautilus_directory_notify_files_removed (deletions);
deletions = NULL;
}
if (moves != NULL) {
nautilus_directory_notify_files_moved (moves);
moves = NULL;
}
}
if (change == NULL) {
/* we are done */
break;
}
kind = change->kind;
/* add the new change to the list */
switch (kind) {
case CHANGE_FILE_ADDED:
additions = g_list_append (additions, change->from_uri);
break;
case CHANGE_FILE_REMOVED:
deletions = g_list_append (deletions, change->from_uri);
break;
case CHANGE_FILE_MOVED:
pair = g_new (URIPair, 1);
pair->from_uri = change->from_uri;
pair->to_uri = change->to_uri;
moves = g_list_append (moves, pair);
break;
default:
g_assert_not_reached ();
break;
}
change->from_uri = NULL;
change->to_uri = NULL;
}
}
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-directory.h: Nautilus directory model.
Copyright (C) 1999, 2000 Eazel, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef NAUTILUS_FILE_CHANGES_QUEUE_H
#define NAUTILUS_FILE_CHANGES_QUEUE_H
typedef struct NautilusFileChangesQueue NautilusFileChangesQueue;
typedef struct NautilusFileChangesQueueDetails NautilusFileChangesQueueDetails;
void nautilus_file_changes_queue_free (NautilusFileChangesQueue *queue);
void nautilus_file_changes_queue_file_added (const char *uri);
void nautilus_file_changes_queue_file_removed (const char *uri);
void nautilus_file_changes_queue_file_moved (const char *from_uri,
const char *to_uri);
void nautilus_file_changes_consume_changes (gboolean consume_all);
struct NautilusFileChangesQueue {
NautilusFileChangesQueueDetails *details;
};
#endif
......@@ -27,6 +27,7 @@
#include <gnome.h>
#include "dfos-xfer.h"
#include "libnautilus-extensions/nautilus-file-changes-queue.h"
#include "fm-directory-view.h"
......@@ -122,9 +123,14 @@ handle_xfer_ok (const GnomeVFSXferProgressInfo *progress_info,
progress_info->bytes_total);
return TRUE;
case GNOME_VFS_XFER_PHASE_XFERRING:
case GNOME_VFS_XFER_PHASE_MOVING:
case GNOME_VFS_XFER_PHASE_DELETESOURCE:
case GNOME_VFS_XFER_PHASE_OPENSOURCE:
case GNOME_VFS_XFER_PHASE_OPENTARGET:
nautilus_file_changes_consume_changes (FALSE);
/* fall through */
case GNOME_VFS_XFER_PHASE_COPYING:
if (progress_info->bytes_copied == 0) {
dfos_xfer_progress_dialog_new_file
(DFOS_XFER_PROGRESS_DIALOG
......@@ -149,6 +155,7 @@ handle_xfer_ok (const GnomeVFSXferProgressInfo *progress_info,
return TRUE;
case GNOME_VFS_XFER_PHASE_COMPLETED:
nautilus_file_changes_consume_changes (TRUE);
gtk_widget_destroy (xfer_info->progress_dialog);
g_free (xfer_info);
return TRUE;
......@@ -249,7 +256,7 @@ handle_xfer_duplicate (GnomeVFSXferProgressInfo *progress_info,
}
static int
sync_xfer_callback (
update_xfer_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSXferProgressInfo *progress_info,
gpointer data)
{
......@@ -269,16 +276,40 @@ sync_xfer_callback (
default:
g_warning (_("Unknown GnomeVFSXferProgressStatus %d"),
progress_info->status);
return FALSE;
return 0;
}
}
/* Low-level callback, called for every copy engine operation.
* Generates notifications about new, deleted and moved files.
*/
static int
xfer_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSXferProgressInfo *progress_info,
gpointer data)
sync_xfer_callback (GnomeVFSXferProgressInfo *progress_info, gpointer data)
{
return sync_xfer_callback (progress_info, data);
XferInfo *xfer_info;
xfer_info = (XferInfo *) data;
if (progress_info->status == GNOME_VFS_XFER_PROGRESS_STATUS_OK) {
switch (progress_info->phase) {
case GNOME_VFS_XFER_PHASE_OPENTARGET:
nautilus_file_changes_queue_file_added (progress_info->target_name);
break;
case GNOME_VFS_XFER_PHASE_MOVING:
nautilus_file_changes_queue_file_moved (progress_info->source_name,
progress_info->target_name);
break;
case GNOME_VFS_XFER_PHASE_DELETESOURCE:
nautilus_file_changes_queue_file_removed (progress_info->source_name);
break;
default:
break;
}
}
return 1;
}
......@@ -305,8 +336,9 @@ dfos_xfer (DFOS *dfos,
options,
GNOME_VFS_XFER_ERROR_MODE_QUERY,
overwrite_mode,
xfer_callback,
xfer_info);
update_xfer_callback,
xfer_info,
NULL, NULL);
if (result != GNOME_VFS_OK) {
gchar *message;
......@@ -441,7 +473,8 @@ fs_xfer (const GList *item_uris,
target_dir_uri_text, NULL,
move_options, GNOME_VFS_XFER_ERROR_MODE_QUERY,
GNOME_VFS_XFER_OVERWRITE_MODE_QUERY,
&xfer_callback, xfer_info);
&update_xfer_callback, xfer_info,
&sync_xfer_callback, xfer_info);
if (!target_dir)
g_free ((char *)target_dir_uri_text);
......
......@@ -75,6 +75,7 @@ libnautilus_extensions_la_SOURCES = \
nautilus-entry.c \
nautilus-file-utilities.c \
nautilus-file.c \
nautilus-file-changes-queue.c \
nautilus-gdk-extensions.c \
nautilus-gdk-pixbuf-extensions.c \
nautilus-glib-extensions.c \
......
......@@ -81,6 +81,11 @@ typedef struct {
gpointer callback_data;
} QueuedCallback;
typedef struct {
char *from_uri;
char *to_uri;
} URIPair;
NautilusFile *nautilus_directory_find_file (NautilusDirectory *directory,
const char *file_name);
char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
......@@ -103,5 +108,10 @@ void nautilus_directory_cancel_callback_internal (NautilusDirectory
void nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
const QueuedCallback *callback);
/* Change notification calls */
void nautilus_directory_notify_files_added (GList *uris);
void nautilus_directory_notify_files_removed (GList *uris);
void nautilus_directory_notify_files_moved (GList *uri_pairs);
/* debugging functions */
int nautilus_directory_number_outstanding (void);
......@@ -1658,6 +1658,86 @@ process_pending_file_attribute_requests (NautilusDirectory *directory)
g_free (uri);
}
void
nautilus_directory_notify_files_added (GList *uris)
{
GList *p;
for (p = uris; p != NULL; p = p->next) {
#ifdef COPY_NOTIFY_TESTING
printf("added %s\n", (const char *)p->data);
#endif
/*
FIXME:
Find the parent directory of uri in directory_objects.
Create a new NautilusFile and add it to the directory.
Notify all observers of directory about new NautilusFile.
*/
}
nautilus_g_list_free_deep (uris);
}
void
nautilus_directory_notify_files_removed (GList *uris)
{
GList *p;
for (p = uris; p != NULL; p = p->next) {
#ifdef COPY_NOTIFY_TESTING
printf("removed %s\n", (const char *)p->data);
#endif
/*
FIXME:
Find the parent directory of uri in directory_objects.
Look up NautilusFile for uri.
Notify all observers of directory that the NautilusFile is
being removed.
Remove the NautilusFile from directory and delete it.
*/
}
nautilus_g_list_free_deep (uris);
}
void
nautilus_directory_notify_files_moved (GList *uri_pairs)
{
GList *p;
for (p = uri_pairs; p != NULL; p = p->next) {
#ifdef COPY_NOTIFY_TESTING
URIPair *pair;
pair = p->data;
printf("moved %s to %s \n", pair->from_uri, pair->to_uri);
#endif
/*
FIXME:
Find the parent directory of pair->from_uri in directory_objects.
Find the parent directory of pair->from_to in directory_objects.
Look up NautilusFile for pair->from_uri.
???
*/
}
/* deep delete the list of pairs */
for (p = uri_pairs; p != NULL; p = p->next) {
URIPair *pair;
/* delete the strings in each pair */
pair = p->data;
g_free (pair->from_uri);
g_free (pair->to_uri);
}
/* delete the list and the now empty pair structs */
nautilus_g_list_free_deep (uri_pairs);
}
#if !defined (NAUTILUS_OMIT_SELF_CHECK)
static int data_dummy;
......
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-directory.h: Nautilus directory model.
Copyright (C) 1999, 2000 Eazel, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "nautilus-file-changes-queue-private.h"