summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog35
-rw-r--r--components/html/ntl-web-browser.c1
-rw-r--r--docs/nautilus.faq3
-rw-r--r--libnautilus-extensions/nautilus-directory-async.c112
-rw-r--r--libnautilus-extensions/nautilus-directory-private.h9
-rw-r--r--libnautilus-extensions/nautilus-directory.c147
-rw-r--r--libnautilus-private/nautilus-directory-async.c112
-rw-r--r--libnautilus-private/nautilus-directory-private.h9
-rw-r--r--libnautilus-private/nautilus-directory.c147
9 files changed, 360 insertions, 215 deletions
diff --git a/ChangeLog b/ChangeLog
index cb4e20ae6..aa7b9db95 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2000-04-26 Darin Adler <darin@eazel.com>
+
+ * libnautilus-extensions/nautilus-directory-async.c
+ (nautilus_directory_schedule_dequeue_pending_idle),
+ (new_files_callback), (nautilus_directory_get_info_for_new_files):
+ * libnautilus-extensions/nautilus-directory-private.h:
+ * libnautilus-extensions/nautilus-directory.c (call_files_added),
+ (call_files_added_free_list) (call_files_changed),
+ (call_fiels_changed_free_list), (call_get_file_info_free_list),
+ (nautilus_directory_notify_files_added),
+ (nautilus_directory_notify_files_removed),
+ (nautilus_directory_notify_files_moved):
+ Implemented async. lookup of information about newly arrived
+ files. Changed moved files to work without a new call to get
+ file information. Fixed some storage leaks.
+
+ * libnautilus-extensions/nautilus-directory-async.c
+ (empty_close_callback), (metafile_read_close),
+ (nautilus_metafile_read_cancel), (metafile_read_callback),
+ (metafile_read_some), (metafile_read_open_callback),
+ (metafile_write_callback): Fixed bug where we were not closing
+ files when cancelling. This requires a bug fix in GNOME VFS to be
+ effective.
+
+ * libnautilus-extensions/nautilus-directory-async.c
+ (dequeue_pending_idle_callback):
+ * libnautilus-extensions/nautilus-directory-private.h:
+ * libnautilus-extensions/nautilus-directory.c
+ (nautilus_directory_destroy):
+ Use new functions in GNOME VFS instead of our own.
+
+ * components/html/ntl-web-browser.c (main): Fixed a warning.
+ * docs/nautilus.faq: Tweak.
+
2000-04-26 John Sullivan <sullivan@eazel.com>
More FIXME-to-bug work.
@@ -878,7 +912,6 @@
* libnautilus-extensions/nautilus-directory.c:
(nautilus_directory_notify_files_moved):
-
Darin helped me finish implementing the missing parts of the call,
including updating the reference to the new directory object,
updating the file info structure to match the file's new location.
diff --git a/components/html/ntl-web-browser.c b/components/html/ntl-web-browser.c
index 630e45482..b97fda4db 100644
--- a/components/html/ntl-web-browser.c
+++ b/components/html/ntl-web-browser.c
@@ -615,7 +615,6 @@ int main(int argc, char *argv[])
{
BonoboGenericFactory *factory;
CORBA_ORB orb;
- CORBA_Environment ev;
if (getenv("NAUTILUS_DEBUG") != NULL)
nautilus_make_warnings_and_criticals_stop_in_debugger
diff --git a/docs/nautilus.faq b/docs/nautilus.faq
index c30fb2948..7719c6e3a 100644
--- a/docs/nautilus.faq
+++ b/docs/nautilus.faq
@@ -9,6 +9,3 @@
2. What are some useful nautilus resources ?
See http://nautilus.eazel.com/
-
-
-
diff --git a/libnautilus-extensions/nautilus-directory-async.c b/libnautilus-extensions/nautilus-directory-async.c
index 15975ff61..cce2eff91 100644
--- a/libnautilus-extensions/nautilus-directory-async.c
+++ b/libnautilus-extensions/nautilus-directory-async.c
@@ -44,6 +44,7 @@
struct MetafileReadState {
GnomeVFSAsyncHandle *handle;
+ gboolean is_open;
gpointer buffer;
size_t bytes_read;
};
@@ -69,9 +70,6 @@ static void directory_load_done
GnomeVFSResult result);
static void directory_load_one (NautilusDirectory *directory,
GnomeVFSFileInfo *info);
-static void metafile_close_callback (GnomeVFSAsyncHandle *handle,
- GnomeVFSResult result,
- gpointer callback_data);
static void metafile_read_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer buffer,
@@ -101,6 +99,27 @@ static GnomeVFSDirectoryListPosition nautilus_gnome_vfs_directory_list_get_next_
static void process_pending_file_attribute_requests (NautilusDirectory *directory);
static void
+empty_close_callback (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer callback_data)
+{
+ /* Do nothing. */
+}
+
+static void
+metafile_read_close (NautilusDirectory *directory)
+{
+ g_assert (directory->details->read_state->handle != NULL);
+ if (directory->details->read_state->is_open) {
+ gnome_vfs_async_close (directory->details->read_state->handle,
+ empty_close_callback,
+ directory);
+ directory->details->read_state->is_open = TRUE;
+ }
+ directory->details->read_state->handle = NULL;
+}
+
+static void
metafile_read_done (NautilusDirectory *directory)
{
GList *p;
@@ -132,7 +151,9 @@ nautilus_metafile_read_cancel (NautilusDirectory *directory)
return;
}
+ g_assert (directory->details->read_state->handle != NULL);
gnome_vfs_async_cancel (directory->details->read_state->handle);
+ metafile_read_close (directory);
g_free (directory->details->read_state);
directory->details->read_state = NULL;
}
@@ -195,14 +216,6 @@ metafile_read_complete (NautilusDirectory *directory)
}
static void
-metafile_close_callback (GnomeVFSAsyncHandle *handle,
- GnomeVFSResult result,
- gpointer callback_data)
-{
- /* Do nothing. */
-}
-
-static void
metafile_read_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer buffer,
@@ -221,6 +234,7 @@ metafile_read_callback (GnomeVFSAsyncHandle *handle,
if (result != GNOME_VFS_OK
&& result != GNOME_VFS_ERROR_EOF) {
+ metafile_read_close (directory);
metafile_read_failed (directory, result);
return;
}
@@ -236,10 +250,7 @@ metafile_read_callback (GnomeVFSAsyncHandle *handle,
return;
}
- gnome_vfs_async_close (directory->details->read_state->handle,
- metafile_close_callback,
- directory);
-
+ metafile_read_close (directory);
metafile_read_complete (directory);
}
@@ -273,6 +284,7 @@ metafile_read_open_callback (GnomeVFSAsyncHandle *handle,
return;
}
+ directory->details->read_state->is_open = TRUE;
metafile_read_some (directory);
}
@@ -356,15 +368,17 @@ metafile_write_callback (GnomeVFSAsyncHandle *handle,
g_assert (directory->details->write_state->buffer == buffer);
g_assert (directory->details->write_state->size == bytes_requested);
+ g_assert (directory->details->write_state->handle != NULL);
+ gnome_vfs_async_close (directory->details->write_state->handle,
+ empty_close_callback,
+ directory);
+ directory->details->write_state->handle = NULL;
+
if (result != GNOME_VFS_OK) {
metafile_write_failed (directory, result);
return;
}
- gnome_vfs_async_close (directory->details->write_state->handle,
- metafile_close_callback,
- directory);
-
metafile_write_complete (directory);
}
@@ -751,7 +765,7 @@ dequeue_pending_idle_callback (gpointer callback_data)
/* If we stopped monitoring, then throw away these. */
if (!nautilus_directory_is_file_list_monitored (directory)) {
- nautilus_gnome_vfs_file_info_list_free (pending_file_info);
+ gnome_vfs_file_info_list_free (pending_file_info);
return FALSE;
}
@@ -775,7 +789,7 @@ dequeue_pending_idle_callback (gpointer callback_data)
pending_files = g_list_prepend (pending_files, file);
}
}
- nautilus_gnome_vfs_file_info_list_free (pending_file_info);
+ gnome_vfs_file_info_list_free (pending_file_info);
/* Tell the objects that are monitoring about these new files. */
nautilus_directory_emit_files_added (directory, pending_files);
@@ -801,8 +815,11 @@ nautilus_directory_schedule_dequeue_pending (NautilusDirectory *directory)
static void
directory_load_one (NautilusDirectory *directory,
- GnomeVFSFileInfo *info)
+ GnomeVFSFileInfo *info)
{
+ if (info == NULL) {
+ return;
+ }
gnome_vfs_file_info_ref (info);
directory->details->pending_file_info
= g_list_prepend (directory->details->pending_file_info, info);
@@ -838,10 +855,10 @@ nautilus_gnome_vfs_directory_list_get_next_position (GnomeVFSDirectoryList *list
static void
directory_load_callback (GnomeVFSAsyncHandle *handle,
- GnomeVFSResult result,
- GnomeVFSDirectoryList *list,
- guint entries_read,
- gpointer callback_data)
+ GnomeVFSResult result,
+ GnomeVFSDirectoryList *list,
+ guint entries_read,
+ gpointer callback_data)
{
NautilusDirectory *directory;
GnomeVFSDirectoryListPosition last_handled, p;
@@ -1149,15 +1166,46 @@ process_pending_file_attribute_requests (NautilusDirectory *directory)
g_free (uri);
}
-void
-nautilus_gnome_vfs_file_info_list_unref (GList *list)
+static void
+new_files_callback (GnomeVFSAsyncHandle *handle,
+ GList *results,
+ gpointer callback_data)
{
- g_list_foreach (list, (GFunc) gnome_vfs_file_info_unref, NULL);
+ GList **handles, *p;
+ NautilusDirectory *directory;
+ GnomeVFSGetFileInfoResult *result;
+
+ directory = NAUTILUS_DIRECTORY (callback_data);
+ handles = &directory->details->get_file_infos_in_progress;
+ g_assert (handle == NULL || g_list_find (*handles, handle) != NULL);
+
+ /* Note that this call is done. */
+ *handles = g_list_remove (*handles, handle);
+
+ /* Queue up the new files. */
+ for (p = results; p != NULL; p = p->next) {
+ result = p->data;
+ directory_load_one (directory, result->file_info);
+ }
}
void
-nautilus_gnome_vfs_file_info_list_free (GList *list)
+nautilus_directory_get_info_for_new_files (NautilusDirectory *directory,
+ GList *vfs_uri_list)
{
- nautilus_gnome_vfs_file_info_list_unref (list);
- g_list_free (list);
+ GnomeVFSAsyncHandle *handle;
+
+ gnome_vfs_async_get_file_info
+ (&handle,
+ vfs_uri_list,
+ (GNOME_VFS_FILE_INFO_GETMIMETYPE
+ | GNOME_VFS_FILE_INFO_FASTMIMETYPE
+ | GNOME_VFS_FILE_INFO_FOLLOWLINKS),
+ NULL,
+ new_files_callback,
+ directory);
+
+ directory->details->get_file_infos_in_progress
+ = g_list_prepend (directory->details->get_file_infos_in_progress,
+ handle);
}
diff --git a/libnautilus-extensions/nautilus-directory-private.h b/libnautilus-extensions/nautilus-directory-private.h
index a81263a4f..e6f88f640 100644
--- a/libnautilus-extensions/nautilus-directory-private.h
+++ b/libnautilus-extensions/nautilus-directory-private.h
@@ -65,9 +65,12 @@ struct NautilusDirectoryDetails
gboolean directory_loaded;
GnomeVFSAsyncHandle *directory_load_in_progress;
GnomeVFSDirectoryListPosition directory_load_list_last_handled;
- GList *pending_file_info;
+
+ GList *pending_file_info; /* list of GnomeVFSFileInfo */
guint dequeue_pending_idle_id;
+ GList *get_file_infos_in_progress; /* list of GnomeVFSAsyncHandle* */
+
GnomeVFSAsyncHandle *count_in_progress;
NautilusFile *count_file;
};
@@ -112,6 +115,8 @@ void nautilus_directory_file_monitor_add_internal (NautilusDirectory
void nautilus_directory_file_monitor_remove_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client);
+void nautilus_directory_get_info_for_new_files (NautilusDirectory *directory,
+ GList *vfs_uris);
gboolean nautilus_directory_is_file_list_monitored (NautilusDirectory *directory);
void nautilus_directory_remove_file_monitor_link (NautilusDirectory *directory,
GList *link);
@@ -149,5 +154,3 @@ int nautilus_directory_number_outstanding (void);
/* Shared functions not directly related to NautilusDirectory/File. */
int nautilus_compare_file_with_name (gconstpointer a,
gconstpointer b);
-void nautilus_gnome_vfs_file_info_list_free (GList *list);
-void nautilus_gnome_vfs_file_info_list_unref (GList *list);
diff --git a/libnautilus-extensions/nautilus-directory.c b/libnautilus-extensions/nautilus-directory.c
index 8fa42ffa8..e84880968 100644
--- a/libnautilus-extensions/nautilus-directory.c
+++ b/libnautilus-extensions/nautilus-directory.c
@@ -154,6 +154,7 @@ nautilus_directory_destroy (GtkObject *object)
g_assert (directory->details->write_state == NULL);
nautilus_metafile_read_cancel (directory);
+ g_assert (directory->details->read_state == NULL);
if (nautilus_directory_is_file_list_monitored (directory)) {
nautilus_directory_stop_monitoring_file_list (directory);
@@ -185,7 +186,7 @@ nautilus_directory_destroy (GtkObject *object)
g_assert (directory->details->directory_load_in_progress == NULL);
g_assert (directory->details->count_in_progress == NULL);
g_assert (directory->details->dequeue_pending_idle_id == 0);
- nautilus_gnome_vfs_file_info_list_unref (directory->details->pending_file_info);
+ gnome_vfs_file_info_list_unref (directory->details->pending_file_info);
g_assert (directory->details->write_metafile_idle_id == 0);
g_free (directory->details);
@@ -852,50 +853,18 @@ get_file_if_exists (const char *uri)
return file;
}
-void
-nautilus_directory_notify_files_added (GList *uris)
+static void
+hash_table_list_prepend (GHashTable *table, gconstpointer key, gpointer data)
{
- GList *p;
- NautilusDirectory *directory;
- GnomeVFSFileInfo *info;
- const char *uri;
- GnomeVFSResult result;
-
- /* FIXME bugzilla.eazel.com 465:
- gnome_vfs_file_info calls need to be
- called asynchronously. We probably need a new gnome_vfs call that
- takes a list of URIs and generates a list of file info structures.
- */
- for (p = uris; p != NULL; p = p->next) {
- uri = (const char *) p->data;
-
- /* See if the directory is already known. */
- directory = get_parent_directory_if_exists (uri);
- if (directory == NULL) {
- continue;
- }
-
- /* If no one is monitoring files in the directory, nothing to do. */
- if (!nautilus_directory_is_file_list_monitored (directory)) {
- continue;
- }
+ GList *list;
- info = gnome_vfs_file_info_new ();
- result = gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_DEFAULT, NULL);
- if (result == GNOME_VFS_OK) {
- gnome_vfs_file_info_ref (info);
- directory->details->pending_file_info
- = g_list_prepend (directory->details->pending_file_info, info);
-
- nautilus_directory_schedule_dequeue_pending (directory);
- }
-
- gnome_vfs_file_info_unref (info);
- }
+ list = g_hash_table_lookup (table, key);
+ list = g_list_prepend (list, data);
+ g_hash_table_insert (table, (gpointer) key, list);
}
static void
-call_files_added (gpointer key, gpointer value, gpointer user_data)
+call_files_added_free_list (gpointer key, gpointer value, gpointer user_data)
{
g_assert (NAUTILUS_IS_DIRECTORY (key));
g_assert (value != NULL);
@@ -904,26 +873,70 @@ call_files_added (gpointer key, gpointer value, gpointer user_data)
gtk_signal_emit (GTK_OBJECT (key),
signals[FILES_ADDED],
value);
+ g_list_free (value);
}
static void
-call_files_changed (gpointer key, gpointer value, gpointer user_data)
+call_files_changed_free_list (gpointer key, gpointer value, gpointer user_data)
{
g_assert (NAUTILUS_IS_DIRECTORY (key));
g_assert (value != NULL);
g_assert (user_data == NULL);
nautilus_directory_emit_files_changed (key, value);
+ g_list_free (value);
}
static void
-hash_table_list_prepend (GHashTable *table, gconstpointer key, gpointer data)
+call_get_file_info_free_list (gpointer key, gpointer value, gpointer user_data)
{
- GList *list;
+ g_assert (NAUTILUS_IS_DIRECTORY (key));
+ g_assert (value != NULL);
+ g_assert (user_data == NULL);
- list = g_hash_table_lookup (table, key);
- list = g_list_prepend (list, data);
- g_hash_table_insert (table, (gpointer) key, list);
+ nautilus_directory_get_info_for_new_files (key, value);
+ gnome_vfs_uri_list_free (value);
+}
+
+void
+nautilus_directory_notify_files_added (GList *uris)
+{
+ GHashTable *added_lists;
+ GList *p;
+ NautilusDirectory *directory;
+ const char *uri;
+ GnomeVFSURI *vfs_uri;
+
+ /* Make a list of added files in each directory. */
+ added_lists = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ for (p = uris; p != NULL; p = p->next) {
+ uri = (const char *) p->data;
+
+ /* See if the directory is already known. */
+ directory = get_parent_directory_if_exists (uri);
+ if (directory == NULL) {
+ continue;
+ }
+
+ /* If no one is monitoring files in the directory, nothing to do. */
+ if (!nautilus_directory_is_file_list_monitored (directory)) {
+ continue;
+ }
+
+ /* Collect the URIs to use. */
+ vfs_uri = gnome_vfs_uri_new (uri);
+ if (vfs_uri == NULL) {
+ g_warning ("bad uri %s", uri);
+ continue;
+ }
+ hash_table_list_prepend (added_lists, directory, vfs_uri);
+ }
+
+
+ /* Now send out the changed signals. */
+ g_hash_table_foreach (added_lists, call_get_file_info_free_list, NULL);
+ g_hash_table_destroy (added_lists);
}
void
@@ -955,7 +968,7 @@ nautilus_directory_notify_files_removed (GList *uris)
}
/* Now send out the changed signals. */
- g_hash_table_foreach (changed_lists, call_files_changed, NULL);
+ g_hash_table_foreach (changed_lists, call_files_changed_free_list, NULL);
g_hash_table_destroy (changed_lists);
}
@@ -970,7 +983,6 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
GHashTable *added_lists, *changed_lists;
GList **files;
GnomeVFSFileInfo *info;
- GnomeVFSResult result;
/* Make a list of added and changed files in each directory. */
new_files_list = NULL;
@@ -1016,28 +1028,23 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
g_assert (g_list_find (*files, file) != NULL);
*files = g_list_remove (*files, file);
- /* FIXME bugzilla.eazel.com 465:
- * Need to call get info in async mode.
- */
+ /* Make a copy and update the file name in the copy. */
info = gnome_vfs_file_info_new ();
- result = gnome_vfs_get_file_info (pair->to_uri, info,
- GNOME_VFS_FILE_INFO_DEFAULT,
- NULL);
- if (result == GNOME_VFS_OK) {
- gnome_vfs_file_info_ref (info);
- nautilus_file_update (file, info);
-
- /* Add to new directory. */
- files = &new_directory->details->files;
- g_assert (g_list_find (*files, file) == NULL);
- *files = g_list_prepend (*files, file);
-
- /* Handle notification in the new directory. */
- hash_table_list_prepend (added_lists,
- new_directory,
- file);
- }
+ gnome_vfs_file_info_copy (info, file->details->info);
+ g_free (info->name);
+ info->name = uri_get_basename (pair->to_uri);
+ nautilus_file_update (file, info);
gnome_vfs_file_info_unref (info);
+
+ /* Add to new directory. */
+ files = &new_directory->details->files;
+ g_assert (g_list_find (*files, file) == NULL);
+ *files = g_list_prepend (*files, file);
+
+ /* Handle notification in the new directory. */
+ hash_table_list_prepend (added_lists,
+ new_directory,
+ file);
}
/* If the old directory was monitoring files, then it
@@ -1053,9 +1060,9 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
}
/* Now send out the changed and added signals for existing file objects. */
- g_hash_table_foreach (changed_lists, call_files_changed, NULL);
+ g_hash_table_foreach (changed_lists, call_files_changed_free_list, NULL);
g_hash_table_destroy (changed_lists);
- g_hash_table_foreach (added_lists, call_files_added, NULL);
+ g_hash_table_foreach (added_lists, call_files_added_free_list, NULL);
g_hash_table_destroy (added_lists);
/* Let the file objects go. */
diff --git a/libnautilus-private/nautilus-directory-async.c b/libnautilus-private/nautilus-directory-async.c
index 15975ff61..cce2eff91 100644
--- a/libnautilus-private/nautilus-directory-async.c
+++ b/libnautilus-private/nautilus-directory-async.c
@@ -44,6 +44,7 @@
struct MetafileReadState {
GnomeVFSAsyncHandle *handle;
+ gboolean is_open;
gpointer buffer;
size_t bytes_read;
};
@@ -69,9 +70,6 @@ static void directory_load_done
GnomeVFSResult result);
static void directory_load_one (NautilusDirectory *directory,
GnomeVFSFileInfo *info);
-static void metafile_close_callback (GnomeVFSAsyncHandle *handle,
- GnomeVFSResult result,
- gpointer callback_data);
static void metafile_read_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer buffer,
@@ -101,6 +99,27 @@ static GnomeVFSDirectoryListPosition nautilus_gnome_vfs_directory_list_get_next_
static void process_pending_file_attribute_requests (NautilusDirectory *directory);
static void
+empty_close_callback (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer callback_data)
+{
+ /* Do nothing. */
+}
+
+static void
+metafile_read_close (NautilusDirectory *directory)
+{
+ g_assert (directory->details->read_state->handle != NULL);
+ if (directory->details->read_state->is_open) {
+ gnome_vfs_async_close (directory->details->read_state->handle,
+ empty_close_callback,
+ directory);
+ directory->details->read_state->is_open = TRUE;
+ }
+ directory->details->read_state->handle = NULL;
+}
+
+static void
metafile_read_done (NautilusDirectory *directory)
{
GList *p;
@@ -132,7 +151,9 @@ nautilus_metafile_read_cancel (NautilusDirectory *directory)
return;
}
+ g_assert (directory->details->read_state->handle != NULL);
gnome_vfs_async_cancel (directory->details->read_state->handle);
+ metafile_read_close (directory);
g_free (directory->details->read_state);
directory->details->read_state = NULL;
}
@@ -195,14 +216,6 @@ metafile_read_complete (NautilusDirectory *directory)
}
static void
-metafile_close_callback (GnomeVFSAsyncHandle *handle,
- GnomeVFSResult result,
- gpointer callback_data)
-{
- /* Do nothing. */
-}
-
-static void
metafile_read_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer buffer,
@@ -221,6 +234,7 @@ metafile_read_callback (GnomeVFSAsyncHandle *handle,
if (result != GNOME_VFS_OK
&& result != GNOME_VFS_ERROR_EOF) {
+ metafile_read_close (directory);
metafile_read_failed (directory, result);
return;
}
@@ -236,10 +250,7 @@ metafile_read_callback (GnomeVFSAsyncHandle *handle,
return;
}
- gnome_vfs_async_close (directory->details->read_state->handle,
- metafile_close_callback,
- directory);
-
+ metafile_read_close (directory);
metafile_read_complete (directory);
}
@@ -273,6 +284,7 @@ metafile_read_open_callback (GnomeVFSAsyncHandle *handle,
return;
}
+ directory->details->read_state->is_open = TRUE;
metafile_read_some (directory);
}
@@ -356,15 +368,17 @@ metafile_write_callback (GnomeVFSAsyncHandle *handle,
g_assert (directory->details->write_state->buffer == buffer);
g_assert (directory->details->write_state->size == bytes_requested);
+ g_assert (directory->details->write_state->handle != NULL);
+ gnome_vfs_async_close (directory->details->write_state->handle,
+ empty_close_callback,
+ directory);
+ directory->details->write_state->handle = NULL;
+
if (result != GNOME_VFS_OK) {
metafile_write_failed (directory, result);
return;
}
- gnome_vfs_async_close (directory->details->write_state->handle,
- metafile_close_callback,
- directory);
-
metafile_write_complete (directory);
}
@@ -751,7 +765,7 @@ dequeue_pending_idle_callback (gpointer callback_data)
/* If we stopped monitoring, then throw away these. */
if (!nautilus_directory_is_file_list_monitored (directory)) {
- nautilus_gnome_vfs_file_info_list_free (pending_file_info);
+ gnome_vfs_file_info_list_free (pending_file_info);
return FALSE;
}
@@ -775,7 +789,7 @@ dequeue_pending_idle_callback (gpointer callback_data)
pending_files = g_list_prepend (pending_files, file);
}
}
- nautilus_gnome_vfs_file_info_list_free (pending_file_info);
+ gnome_vfs_file_info_list_free (pending_file_info);
/* Tell the objects that are monitoring about these new files. */
nautilus_directory_emit_files_added (directory, pending_files);
@@ -801,8 +815,11 @@ nautilus_directory_schedule_dequeue_pending (NautilusDirectory *directory)
static void
directory_load_one (NautilusDirectory *directory,
- GnomeVFSFileInfo *info)
+ GnomeVFSFileInfo *info)
{
+ if (info == NULL) {
+ return;
+ }
gnome_vfs_file_info_ref (info);
directory->details->pending_file_info
= g_list_prepend (directory->details->pending_file_info, info);
@@ -838,10 +855,10 @@ nautilus_gnome_vfs_directory_list_get_next_position (GnomeVFSDirectoryList *list
static void
directory_load_callback (GnomeVFSAsyncHandle *handle,
- GnomeVFSResult result,
- GnomeVFSDirectoryList *list,
- guint entries_read,
- gpointer callback_data)
+ GnomeVFSResult result,
+ GnomeVFSDirectoryList *list,
+ guint entries_read,
+ gpointer callback_data)
{
NautilusDirectory *directory;
GnomeVFSDirectoryListPosition last_handled, p;
@@ -1149,15 +1166,46 @@ process_pending_file_attribute_requests (NautilusDirectory *directory)
g_free (uri);
}
-void
-nautilus_gnome_vfs_file_info_list_unref (GList *list)
+static void
+new_files_callback (GnomeVFSAsyncHandle *handle,
+ GList *results,
+ gpointer callback_data)
{
- g_list_foreach (list, (GFunc) gnome_vfs_file_info_unref, NULL);
+ GList **handles, *p;
+ NautilusDirectory *directory;
+ GnomeVFSGetFileInfoResult *result;
+
+ directory = NAUTILUS_DIRECTORY (callback_data);
+ handles = &directory->details->get_file_infos_in_progress;
+ g_assert (handle == NULL || g_list_find (*handles, handle) != NULL);
+
+ /* Note that this call is done. */
+ *handles = g_list_remove (*handles, handle);
+
+ /* Queue up the new files. */
+ for (p = results; p != NULL; p = p->next) {
+ result = p->data;
+ directory_load_one (directory, result->file_info);
+ }
}
void
-nautilus_gnome_vfs_file_info_list_free (GList *list)
+nautilus_directory_get_info_for_new_files (NautilusDirectory *directory,
+ GList *vfs_uri_list)
{
- nautilus_gnome_vfs_file_info_list_unref (list);
- g_list_free (list);
+ GnomeVFSAsyncHandle *handle;
+
+ gnome_vfs_async_get_file_info
+ (&handle,
+ vfs_uri_list,
+ (GNOME_VFS_FILE_INFO_GETMIMETYPE
+ | GNOME_VFS_FILE_INFO_FASTMIMETYPE
+ | GNOME_VFS_FILE_INFO_FOLLOWLINKS),
+ NULL,
+ new_files_callback,
+ directory);
+
+ directory->details->get_file_infos_in_progress
+ = g_list_prepend (directory->details->get_file_infos_in_progress,
+ handle);
}
diff --git a/libnautilus-private/nautilus-directory-private.h b/libnautilus-private/nautilus-directory-private.h
index a81263a4f..e6f88f640 100644
--- a/libnautilus-private/nautilus-directory-private.h
+++ b/libnautilus-private/nautilus-directory-private.h
@@ -65,9 +65,12 @@ struct NautilusDirectoryDetails
gboolean directory_loaded;
GnomeVFSAsyncHandle *directory_load_in_progress;
GnomeVFSDirectoryListPosition directory_load_list_last_handled;
- GList *pending_file_info;
+
+ GList *pending_file_info; /* list of GnomeVFSFileInfo */
guint dequeue_pending_idle_id;
+ GList *get_file_infos_in_progress; /* list of GnomeVFSAsyncHandle* */
+
GnomeVFSAsyncHandle *count_in_progress;
NautilusFile *count_file;
};
@@ -112,6 +115,8 @@ void nautilus_directory_file_monitor_add_internal (NautilusDirectory
void nautilus_directory_file_monitor_remove_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client);
+void nautilus_directory_get_info_for_new_files (NautilusDirectory *directory,
+ GList *vfs_uris);
gboolean nautilus_directory_is_file_list_monitored (NautilusDirectory *directory);
void nautilus_directory_remove_file_monitor_link (NautilusDirectory *directory,
GList *link);
@@ -149,5 +154,3 @@ int nautilus_directory_number_outstanding (void);
/* Shared functions not directly related to NautilusDirectory/File. */
int nautilus_compare_file_with_name (gconstpointer a,
gconstpointer b);
-void nautilus_gnome_vfs_file_info_list_free (GList *list);
-void nautilus_gnome_vfs_file_info_list_unref (GList *list);
diff --git a/libnautilus-private/nautilus-directory.c b/libnautilus-private/nautilus-directory.c
index 8fa42ffa8..e84880968 100644
--- a/libnautilus-private/nautilus-directory.c
+++ b/libnautilus-private/nautilus-directory.c
@@ -154,6 +154,7 @@ nautilus_directory_destroy (GtkObject *object)
g_assert (directory->details->write_state == NULL);
nautilus_metafile_read_cancel (directory);
+ g_assert (directory->details->read_state == NULL);
if (nautilus_directory_is_file_list_monitored (directory)) {
nautilus_directory_stop_monitoring_file_list (directory);
@@ -185,7 +186,7 @@ nautilus_directory_destroy (GtkObject *object)
g_assert (directory->details->directory_load_in_progress == NULL);
g_assert (directory->details->count_in_progress == NULL);
g_assert (directory->details->dequeue_pending_idle_id == 0);
- nautilus_gnome_vfs_file_info_list_unref (directory->details->pending_file_info);
+ gnome_vfs_file_info_list_unref (directory->details->pending_file_info);
g_assert (directory->details->write_metafile_idle_id == 0);
g_free (directory->details);
@@ -852,50 +853,18 @@ get_file_if_exists (const char *uri)
return file;
}
-void
-nautilus_directory_notify_files_added (GList *uris)
+static void
+hash_table_list_prepend (GHashTable *table, gconstpointer key, gpointer data)
{
- GList *p;
- NautilusDirectory *directory;
- GnomeVFSFileInfo *info;
- const char *uri;
- GnomeVFSResult result;
-
- /* FIXME bugzilla.eazel.com 465:
- gnome_vfs_file_info calls need to be
- called asynchronously. We probably need a new gnome_vfs call that
- takes a list of URIs and generates a list of file info structures.
- */
- for (p = uris; p != NULL; p = p->next) {
- uri = (const char *) p->data;
-
- /* See if the directory is already known. */
- directory = get_parent_directory_if_exists (uri);
- if (directory == NULL) {
- continue;
- }
-
- /* If no one is monitoring files in the directory, nothing to do. */
- if (!nautilus_directory_is_file_list_monitored (directory)) {
- continue;
- }
+ GList *list;
- info = gnome_vfs_file_info_new ();
- result = gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_DEFAULT, NULL);
- if (result == GNOME_VFS_OK) {
- gnome_vfs_file_info_ref (info);
- directory->details->pending_file_info
- = g_list_prepend (directory->details->pending_file_info, info);
-
- nautilus_directory_schedule_dequeue_pending (directory);
- }
-
- gnome_vfs_file_info_unref (info);
- }
+ list = g_hash_table_lookup (table, key);
+ list = g_list_prepend (list, data);
+ g_hash_table_insert (table, (gpointer) key, list);
}
static void
-call_files_added (gpointer key, gpointer value, gpointer user_data)
+call_files_added_free_list (gpointer key, gpointer value, gpointer user_data)
{
g_assert (NAUTILUS_IS_DIRECTORY (key));
g_assert (value != NULL);
@@ -904,26 +873,70 @@ call_files_added (gpointer key, gpointer value, gpointer user_data)
gtk_signal_emit (GTK_OBJECT (key),
signals[FILES_ADDED],
value);
+ g_list_free (value);
}
static void
-call_files_changed (gpointer key, gpointer value, gpointer user_data)
+call_files_changed_free_list (gpointer key, gpointer value, gpointer user_data)
{
g_assert (NAUTILUS_IS_DIRECTORY (key));
g_assert (value != NULL);
g_assert (user_data == NULL);
nautilus_directory_emit_files_changed (key, value);
+ g_list_free (value);
}
static void
-hash_table_list_prepend (GHashTable *table, gconstpointer key, gpointer data)
+call_get_file_info_free_list (gpointer key, gpointer value, gpointer user_data)
{
- GList *list;
+ g_assert (NAUTILUS_IS_DIRECTORY (key));
+ g_assert (value != NULL);
+ g_assert (user_data == NULL);
- list = g_hash_table_lookup (table, key);
- list = g_list_prepend (list, data);
- g_hash_table_insert (table, (gpointer) key, list);
+ nautilus_directory_get_info_for_new_files (key, value);
+ gnome_vfs_uri_list_free (value);
+}
+
+void
+nautilus_directory_notify_files_added (GList *uris)
+{
+ GHashTable *added_lists;
+ GList *p;
+ NautilusDirectory *directory;
+ const char *uri;
+ GnomeVFSURI *vfs_uri;
+
+ /* Make a list of added files in each directory. */
+ added_lists = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ for (p = uris; p != NULL; p = p->next) {
+ uri = (const char *) p->data;
+
+ /* See if the directory is already known. */
+ directory = get_parent_directory_if_exists (uri);
+ if (directory == NULL) {
+ continue;
+ }
+
+ /* If no one is monitoring files in the directory, nothing to do. */
+ if (!nautilus_directory_is_file_list_monitored (directory)) {
+ continue;
+ }
+
+ /* Collect the URIs to use. */
+ vfs_uri = gnome_vfs_uri_new (uri);
+ if (vfs_uri == NULL) {
+ g_warning ("bad uri %s", uri);
+ continue;
+ }
+ hash_table_list_prepend (added_lists, directory, vfs_uri);
+ }
+
+
+ /* Now send out the changed signals. */
+ g_hash_table_foreach (added_lists, call_get_file_info_free_list, NULL);
+ g_hash_table_destroy (added_lists);
}
void
@@ -955,7 +968,7 @@ nautilus_directory_notify_files_removed (GList *uris)
}
/* Now send out the changed signals. */
- g_hash_table_foreach (changed_lists, call_files_changed, NULL);
+ g_hash_table_foreach (changed_lists, call_files_changed_free_list, NULL);
g_hash_table_destroy (changed_lists);
}
@@ -970,7 +983,6 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
GHashTable *added_lists, *changed_lists;
GList **files;
GnomeVFSFileInfo *info;
- GnomeVFSResult result;
/* Make a list of added and changed files in each directory. */
new_files_list = NULL;
@@ -1016,28 +1028,23 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
g_assert (g_list_find (*files, file) != NULL);
*files = g_list_remove (*files, file);
- /* FIXME bugzilla.eazel.com 465:
- * Need to call get info in async mode.
- */
+ /* Make a copy and update the file name in the copy. */
info = gnome_vfs_file_info_new ();
- result = gnome_vfs_get_file_info (pair->to_uri, info,
- GNOME_VFS_FILE_INFO_DEFAULT,
- NULL);
- if (result == GNOME_VFS_OK) {
- gnome_vfs_file_info_ref (info);
- nautilus_file_update (file, info);
-
- /* Add to new directory. */
- files = &new_directory->details->files;
- g_assert (g_list_find (*files, file) == NULL);
- *files = g_list_prepend (*files, file);
-
- /* Handle notification in the new directory. */
- hash_table_list_prepend (added_lists,
- new_directory,
- file);
- }
+ gnome_vfs_file_info_copy (info, file->details->info);
+ g_free (info->name);
+ info->name = uri_get_basename (pair->to_uri);
+ nautilus_file_update (file, info);
gnome_vfs_file_info_unref (info);
+
+ /* Add to new directory. */
+ files = &new_directory->details->files;
+ g_assert (g_list_find (*files, file) == NULL);
+ *files = g_list_prepend (*files, file);
+
+ /* Handle notification in the new directory. */
+ hash_table_list_prepend (added_lists,
+ new_directory,
+ file);
}
/* If the old directory was monitoring files, then it
@@ -1053,9 +1060,9 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
}
/* Now send out the changed and added signals for existing file objects. */
- g_hash_table_foreach (changed_lists, call_files_changed, NULL);
+ g_hash_table_foreach (changed_lists, call_files_changed_free_list, NULL);
g_hash_table_destroy (changed_lists);
- g_hash_table_foreach (added_lists, call_files_added, NULL);
+ g_hash_table_foreach (added_lists, call_files_added_free_list, NULL);
g_hash_table_destroy (added_lists);
/* Let the file objects go. */