Implemented async. lookup of information about newly arrived files.

* 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.
This commit is contained in:
Darin Adler 2000-04-27 01:20:35 +00:00
parent 3199885e39
commit 3bb72b2e4b
9 changed files with 364 additions and 219 deletions

View file

@ -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.

View file

@ -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

View file

@ -9,6 +9,3 @@
2. What are some useful nautilus resources ?
See http://nautilus.eazel.com/

View file

@ -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,
@ -100,6 +98,27 @@ static GnomeVFSDirectoryListPosition nautilus_gnome_vfs_directory_list_get_next_
GnomeVFSDirectoryListPosition position);
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)
{
@ -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;
}
@ -194,14 +215,6 @@ metafile_read_complete (NautilusDirectory *directory)
metafile_read_done (directory);
}
static void
metafile_close_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer callback_data)
{
/* Do nothing. */
}
static void
metafile_read_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
@ -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);
}

View file

@ -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);

View file

@ -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,20 +853,63 @@ get_file_if_exists (const char *uri)
return file;
}
static void
hash_table_list_prepend (GHashTable *table, gconstpointer key, gpointer data)
{
GList *list;
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_free_list (gpointer key, gpointer value, gpointer user_data)
{
g_assert (NAUTILUS_IS_DIRECTORY (key));
g_assert (value != NULL);
g_assert (user_data == NULL);
gtk_signal_emit (GTK_OBJECT (key),
signals[FILES_ADDED],
value);
g_list_free (value);
}
static void
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
call_get_file_info_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_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;
GnomeVFSFileInfo *info;
const char *uri;
GnomeVFSResult result;
GnomeVFSURI *vfs_uri;
/* Make a list of added files in each directory. */
added_lists = g_hash_table_new (g_direct_hash, g_direct_equal);
/* 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;
@ -880,50 +924,19 @@ nautilus_directory_notify_files_added (GList *uris)
continue;
}
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);
/* Collect the URIs to use. */
vfs_uri = gnome_vfs_uri_new (uri);
if (vfs_uri == NULL) {
g_warning ("bad uri %s", uri);
continue;
}
gnome_vfs_file_info_unref (info);
hash_table_list_prepend (added_lists, directory, vfs_uri);
}
}
static void
call_files_added (gpointer key, gpointer value, gpointer user_data)
{
g_assert (NAUTILUS_IS_DIRECTORY (key));
g_assert (value != NULL);
g_assert (user_data == NULL);
gtk_signal_emit (GTK_OBJECT (key),
signals[FILES_ADDED],
value);
}
static void
call_files_changed (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);
}
static void
hash_table_list_prepend (GHashTable *table, gconstpointer key, gpointer data)
{
GList *list;
list = g_hash_table_lookup (table, key);
list = g_list_prepend (list, data);
g_hash_table_insert (table, (gpointer) key, list);
/* 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. */

View file

@ -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,
@ -100,6 +98,27 @@ static GnomeVFSDirectoryListPosition nautilus_gnome_vfs_directory_list_get_next_
GnomeVFSDirectoryListPosition position);
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)
{
@ -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;
}
@ -194,14 +215,6 @@ metafile_read_complete (NautilusDirectory *directory)
metafile_read_done (directory);
}
static void
metafile_close_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
gpointer callback_data)
{
/* Do nothing. */
}
static void
metafile_read_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
@ -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);
}

View file

@ -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);

View file

@ -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,20 +853,63 @@ get_file_if_exists (const char *uri)
return file;
}
static void
hash_table_list_prepend (GHashTable *table, gconstpointer key, gpointer data)
{
GList *list;
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_free_list (gpointer key, gpointer value, gpointer user_data)
{
g_assert (NAUTILUS_IS_DIRECTORY (key));
g_assert (value != NULL);
g_assert (user_data == NULL);
gtk_signal_emit (GTK_OBJECT (key),
signals[FILES_ADDED],
value);
g_list_free (value);
}
static void
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
call_get_file_info_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_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;
GnomeVFSFileInfo *info;
const char *uri;
GnomeVFSResult result;
GnomeVFSURI *vfs_uri;
/* Make a list of added files in each directory. */
added_lists = g_hash_table_new (g_direct_hash, g_direct_equal);
/* 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;
@ -880,50 +924,19 @@ nautilus_directory_notify_files_added (GList *uris)
continue;
}
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);
/* Collect the URIs to use. */
vfs_uri = gnome_vfs_uri_new (uri);
if (vfs_uri == NULL) {
g_warning ("bad uri %s", uri);
continue;
}
gnome_vfs_file_info_unref (info);
hash_table_list_prepend (added_lists, directory, vfs_uri);
}
}
static void
call_files_added (gpointer key, gpointer value, gpointer user_data)
{
g_assert (NAUTILUS_IS_DIRECTORY (key));
g_assert (value != NULL);
g_assert (user_data == NULL);
gtk_signal_emit (GTK_OBJECT (key),
signals[FILES_ADDED],
value);
}
static void
call_files_changed (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);
}
static void
hash_table_list_prepend (GHashTable *table, gconstpointer key, gpointer data)
{
GList *list;
list = g_hash_table_lookup (table, key);
list = g_list_prepend (list, data);
g_hash_table_insert (table, (gpointer) key, list);
/* 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. */