Changed to the new Nautilus list instead of the old secret list.

* MAINTAINERS: Changed to the new Nautilus list instead of the
	old secret list.

	* components/notes/ntl-notes.c (notes_load_metainfo):
	* src/file-manager/fm-directory-view.c
	(fm_directory_view_load_uri), (metadata_ready_callback):
	* src/ntl-uri-map.c (got_metadata_callback),
	(nautilus_navigation_info_new):
	Change calls to use new API, but not to use any of the new features,
	which are not yet implemented.

	* libnautilus-extensions/nautilus-directory.h:
	* libnautilus-extensions/nautilus-directory.c
	* libnautilus-extensions/nautilus-directory-private.h:
	* libnautilus-extensions/nautilus-directory-async.c
	* libnautilus-extensions/nautilus-file.c
	* libnautilus-extensions/nautilus-file.h:
	Added the new API and moved functions around a bit to prepare
	for the new feature needed by Maciej for getting a list of files.

	* libnautilus-extensions/nautilus-file-attributes.h:
	Added an attribute constant for MIME type.
This commit is contained in:
Darin Adler 2000-04-27 22:54:19 +00:00
parent f7fd50aafc
commit 6397f17caa
21 changed files with 710 additions and 546 deletions

View file

@ -1,11 +1,37 @@
2000-04-27 Darin Adler <darin@eazel.com>
* MAINTAINERS: Changed to the new Nautilus list instead of the
old secret list.
* components/notes/ntl-notes.c (notes_load_metainfo):
* src/file-manager/fm-directory-view.c
(fm_directory_view_load_uri), (metadata_ready_callback):
* src/ntl-uri-map.c (got_metadata_callback),
(nautilus_navigation_info_new):
Change calls to use new API, but not to use any of the new features,
which are not yet implemented.
* libnautilus-extensions/nautilus-directory.h:
* libnautilus-extensions/nautilus-directory.c
* libnautilus-extensions/nautilus-directory-private.h:
* libnautilus-extensions/nautilus-directory-async.c
* libnautilus-extensions/nautilus-file.c
* libnautilus-extensions/nautilus-file.h:
Added the new API and moved functions around a bit to prepare
for the new feature needed by Maciej for getting a list of files.
* libnautilus-extensions/nautilus-file-attributes.h:
Added an attribute constant for MIME type.
2000-04-27 J. Shane Culpepper <pepper@eazel.com>
*components/services/install/genpkg_list.example
*components/services/install/eazel-install.c
*components/services/install/eazel-install-protocols.c
*components/services/install/eazel-install-rpm-glue.c
*components/services/install/eazel-install-types.h
*components/services/install/eazel-install-xml-package-list.h
*components/services/install/eazel-install-xml-package-list.c
* components/services/install/genpkg_list.example
* components/services/install/eazel-install.c
* components/services/install/eazel-install-protocols.c
* components/services/install/eazel-install-rpm-glue.c
* components/services/install/eazel-install-types.h
* components/services/install/eazel-install-xml-package-list.h
* components/services/install/eazel-install-xml-package-list.c
Cleaned up invalid variable names to conform to eazel coding standards.
Added the genpkg_list option to create a package-list.xml from a

View file

@ -1 +1 @@
Email: gnomad-hackers@eazel.com
Email: nautilus-list@eazel.com

View file

@ -93,7 +93,7 @@ notes_load_metainfo (Notes *notes)
return;
}
keys = g_list_prepend (NULL, NAUTILUS_METADATA_KEY_ANNOTATION);
nautilus_file_call_when_ready (notes->file, keys, finish_loading_note, notes);
nautilus_file_call_when_ready (notes->file, NULL, keys, finish_loading_note, notes);
g_list_free (keys);
}

View file

@ -93,7 +93,7 @@ notes_load_metainfo (Notes *notes)
return;
}
keys = g_list_prepend (NULL, NAUTILUS_METADATA_KEY_ANNOTATION);
nautilus_file_call_when_ready (notes->file, keys, finish_loading_note, notes);
nautilus_file_call_when_ready (notes->file, NULL, keys, finish_loading_note, notes);
g_list_free (keys);
}

View file

@ -56,6 +56,27 @@ struct MetafileWriteState {
gboolean write_again;
};
typedef struct {
NautilusFile *file; /* Which file to monitor, NULL to monitor all. */
union {
NautilusDirectoryCallback directory;
NautilusFileCallback file;
} callback;
gpointer callback_data;
gboolean wait_for_metafile;
gboolean wait_for_file_list; /* always FALSE if file != NULL */
gboolean wait_for_directory_counts;
} CallWhenReady;
typedef struct {
NautilusFile *file; /* Which file to monitor, NULL to monitor all. */
gconstpointer client;
gboolean monitor_file_list; /* always FALSE if file != NULL */
gboolean monitor_directory_counts;
} Monitor;
#define READ_CHUNK_SIZE (4 * 1024)
static int compare_queued_callbacks (gconstpointer a,
@ -123,11 +144,11 @@ static void
metafile_read_done (NautilusDirectory *directory)
{
GList *p;
QueuedCallback *callback;
CallWhenReady *callback;
/* Tell the callers that were waiting for metadata that it's here.
*/
for (p = directory->details->metafile_callbacks; p != NULL; p = p->next) {
for (p = directory->details->call_when_ready_list; p != NULL; p = p->next) {
callback = p->data;
if (callback->file != NULL) {
@ -137,11 +158,12 @@ metafile_read_done (NautilusDirectory *directory)
nautilus_file_unref (callback->file);
} else {
(* callback->callback.directory) (directory,
NULL,
callback->callback_data);
}
}
nautilus_g_list_free_deep (directory->details->metafile_callbacks);
directory->details->metafile_callbacks = NULL;
nautilus_g_list_free_deep (directory->details->call_when_ready_list);
directory->details->call_when_ready_list = NULL;
}
void
@ -487,11 +509,11 @@ nautilus_directory_request_write_metafile (NautilusDirectory *directory)
}
static int
compare_file_monitor_by_client_and_file (gconstpointer a,
compare_monitor_by_client_and_file (gconstpointer a,
gconstpointer data)
{
const FileMonitor *monitor;
const FileMonitor *compare_monitor;
const Monitor *monitor;
const Monitor *compare_monitor;
monitor = a;
compare_monitor = data;
@ -514,22 +536,22 @@ compare_file_monitor_by_client_and_file (gconstpointer a,
}
static GList *
find_file_monitor (NautilusDirectory *directory,
find_monitor (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client)
{
GList *result;
FileMonitor *file_monitor;
Monitor *monitor;
file_monitor = g_new (FileMonitor, 1);
file_monitor->client = client;
file_monitor->file = file;
monitor = g_new (Monitor, 1);
monitor->client = client;
monitor->file = file;
result = g_list_find_custom (directory->details->file_monitors,
(gpointer) file_monitor,
compare_file_monitor_by_client_and_file);
result = g_list_find_custom (directory->details->monitor_list,
(gpointer) monitor,
compare_monitor_by_client_and_file);
g_free (file_monitor);
g_free (monitor);
return result;
}
@ -538,13 +560,13 @@ static void
cancel_unneeded_file_attribute_requests (NautilusDirectory *directory)
{
GList *p;
FileMonitor *file_monitor;
Monitor *monitor;
/* Cancel the directory-count request if no one cares anymore */
if (directory->details->count_in_progress != NULL) {
for (p = directory->details->file_monitors; p != NULL; p = p->next) {
file_monitor = p->data;
if (file_monitor->monitor_directory_counts) {
for (p = directory->details->monitor_list; p != NULL; p = p->next) {
monitor = p->data;
if (monitor->monitor_directory_counts) {
break;
}
}
@ -555,12 +577,12 @@ cancel_unneeded_file_attribute_requests (NautilusDirectory *directory)
}
}
void
nautilus_directory_remove_file_monitor_link (NautilusDirectory *directory,
GList *link)
static void
remove_monitor_link (NautilusDirectory *directory,
GList *link)
{
directory->details->file_monitors =
g_list_remove_link (directory->details->file_monitors, link);
directory->details->monitor_list =
g_list_remove_link (directory->details->monitor_list, link);
if (link != NULL) {
g_free (link->data);
}
@ -568,23 +590,22 @@ nautilus_directory_remove_file_monitor_link (NautilusDirectory *directory,
}
static void
remove_file_monitor (NautilusDirectory *directory,
remove_monitor (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client)
{
nautilus_directory_remove_file_monitor_link
(directory, find_file_monitor (directory, file, client));
remove_monitor_link (directory, find_monitor (directory, file, client));
}
gboolean
nautilus_directory_is_file_list_monitored (NautilusDirectory *directory)
{
FileMonitor *file_monitor;
Monitor *monitor;
GList *p;
for (p = directory->details->file_monitors; p != NULL; p = p->next) {
file_monitor = p->data;
if (file_monitor->file == NULL) {
for (p = directory->details->monitor_list; p != NULL; p = p->next) {
monitor = p->data;
if (monitor->file == NULL) {
return TRUE;
}
}
@ -593,18 +614,19 @@ nautilus_directory_is_file_list_monitored (NautilusDirectory *directory)
}
void
nautilus_directory_file_monitor_add_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client,
GList *attributes,
GList *metadata_keys,
NautilusFileListCallback callback,
gpointer callback_data)
nautilus_directory_monitor_add_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client,
GList *directory_metadata_keys,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
gboolean was_monitoring_file_list;
gboolean will_be_monitoring_file_list;
gboolean rely_on_directory_load;
FileMonitor *file_monitor;
Monitor *monitor;
g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
@ -619,18 +641,18 @@ nautilus_directory_file_monitor_add_internal (NautilusDirectory *directory,
rely_on_directory_load = will_be_monitoring_file_list && !directory->details->directory_loaded;
/* Replace any current monitor for this client/file pair. */
remove_file_monitor (directory, file, client);
remove_monitor (directory, file, client);
file_monitor = g_new (FileMonitor, 1);
file_monitor->client = client;
file_monitor->file = file;
file_monitor->monitor_directory_counts = g_list_find_custom
(attributes,
monitor = g_new (Monitor, 1);
monitor->client = client;
monitor->file = file;
monitor->monitor_directory_counts = g_list_find_custom
(file_attributes,
NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT,
(GCompareFunc) nautilus_strcmp) != NULL;
directory->details->file_monitors =
g_list_prepend (directory->details->file_monitors, file_monitor);
directory->details->monitor_list =
g_list_prepend (directory->details->monitor_list, monitor);
/* Clean up stale requests only after (optionally) removing old
* monitor and adding new one.
@ -695,27 +717,6 @@ nautilus_directory_file_monitor_add_internal (NautilusDirectory *directory,
directory);
}
void
nautilus_directory_file_monitor_add (NautilusDirectory *directory,
gconstpointer client,
GList *attributes,
GList *metadata_keys,
NautilusFileListCallback callback,
gpointer callback_data)
{
g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
g_return_if_fail (client != NULL);
g_return_if_fail (callback != NULL);
nautilus_directory_file_monitor_add_internal (directory,
NULL,
client,
attributes,
metadata_keys,
callback,
callback_data);
}
int
nautilus_compare_file_with_name (gconstpointer a, gconstpointer b)
{
@ -902,9 +903,9 @@ nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory)
}
void
nautilus_directory_file_monitor_remove_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client)
nautilus_directory_monitor_remove_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client)
{
gboolean was_monitoring_file_list;
@ -912,7 +913,7 @@ nautilus_directory_file_monitor_remove_internal (NautilusDirectory *directory,
was_monitoring_file_list = nautilus_directory_is_file_list_monitored (directory);
remove_file_monitor (directory, file, client);
remove_monitor (directory, file, client);
cancel_unneeded_file_attribute_requests (directory);
if (was_monitoring_file_list && !nautilus_directory_is_file_list_monitored (directory)) {
@ -920,17 +921,10 @@ nautilus_directory_file_monitor_remove_internal (NautilusDirectory *directory,
}
}
void
nautilus_directory_file_monitor_remove (NautilusDirectory *directory,
gconstpointer client)
{
nautilus_directory_file_monitor_remove_internal (directory, NULL, client);
}
static int
compare_queued_callbacks (gconstpointer a, gconstpointer b)
{
const QueuedCallback *callback_a, *callback_b;
const CallWhenReady *callback_a, *callback_b;
callback_a = a;
callback_b = b;
@ -966,103 +960,88 @@ compare_queued_callbacks (gconstpointer a, gconstpointer b)
void
nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
const QueuedCallback *callback)
NautilusFile *file,
GList *directory_metadata_keys,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback directory_callback,
NautilusFileCallback file_callback,
gpointer callback_data)
{
CallWhenReady callback;
g_assert (directory == NULL || NAUTILUS_IS_DIRECTORY (directory));
g_assert (callback != NULL);
g_assert (callback->file == NULL || callback->file->details->directory == directory);
/* Call back right away if it's already ready. */
if (directory == NULL || directory->details->metafile_read) {
if (callback->file != NULL) {
(* callback->callback.file) (callback->file,
callback->callback_data);
if (file != NULL) {
(* file_callback) (file,
callback_data);
} else {
(* callback->callback.directory) (directory,
callback->callback_data);
(* directory_callback) (directory,
NULL,
callback_data);
}
return;
}
/* Construct a callback object. */
callback.file = file;
if (file == NULL) {
callback.callback.directory = directory_callback;
} else {
callback.callback.file = file_callback;
}
callback.callback_data = callback_data;
/* MORE HERE */
/* Add the new callback to the list unless it's already in there. */
if (g_list_find_custom (directory->details->metafile_callbacks,
(QueuedCallback *) callback,
/* REPLACE THE OLD ONE INSTEAD DARIN */
if (g_list_find_custom (directory->details->call_when_ready_list,
&callback,
compare_queued_callbacks) == NULL) {
nautilus_file_ref (callback->file);
directory->details->metafile_callbacks = g_list_prepend
(directory->details->metafile_callbacks,
g_memdup (callback,
sizeof (*callback)));
nautilus_file_ref (file);
directory->details->call_when_ready_list = g_list_prepend
(directory->details->call_when_ready_list,
g_memdup (&callback,
sizeof (callback)));
}
/* Start reading the metafile. */
nautilus_directory_request_read_metafile (directory);
}
void
nautilus_directory_call_when_ready (NautilusDirectory *directory,
GList *directory_metadata_keys,
GList *file_metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
QueuedCallback new_callback;
g_return_if_fail (directory == NULL || NAUTILUS_IS_DIRECTORY (directory));
g_return_if_fail (directory_metadata_keys != NULL || file_metadata_keys != NULL);
g_return_if_fail (callback != NULL);
new_callback.file = NULL;
new_callback.callback.directory = callback;
new_callback.callback_data = callback_data;
nautilus_directory_call_when_ready_internal (directory, &new_callback);
}
void
nautilus_directory_cancel_callback_internal (NautilusDirectory *directory,
const QueuedCallback *callback)
NautilusFile *file,
NautilusDirectoryCallback directory_callback,
NautilusFileCallback file_callback,
gpointer callback_data)
{
CallWhenReady callback;
GList *p;
g_assert (NAUTILUS_IS_DIRECTORY (directory));
g_assert (callback != NULL);
/* Construct a callback object. */
callback.file = file;
if (file == NULL) {
callback.callback.directory = directory_callback;
} else {
callback.callback.file = file_callback;
}
callback.callback_data = callback_data;
/* Remove queued callback from the list. */
p = g_list_find_custom (directory->details->metafile_callbacks,
(QueuedCallback *) callback,
p = g_list_find_custom (directory->details->call_when_ready_list,
&callback,
compare_queued_callbacks);
if (p != NULL) {
nautilus_file_unref (callback->file);
nautilus_file_unref (file);
g_free (p->data);
directory->details->metafile_callbacks = g_list_remove_link
(directory->details->metafile_callbacks, p);
directory->details->call_when_ready_list = g_list_remove_link
(directory->details->call_when_ready_list, p);
}
}
void
nautilus_directory_cancel_callback (NautilusDirectory *directory,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
QueuedCallback old_callback;
g_return_if_fail (callback != NULL);
if (directory == NULL) {
return;
}
/* NULL is OK here for non-vfs protocols */
g_return_if_fail (!directory || NAUTILUS_IS_DIRECTORY (directory));
old_callback.file = NULL;
old_callback.callback.directory = callback;
old_callback.callback_data = callback_data;
nautilus_directory_cancel_callback_internal (directory, &old_callback);
}
static void
directory_count_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
@ -1104,7 +1083,7 @@ static void
process_pending_file_attribute_requests (NautilusDirectory *directory)
{
GList *p, *p2;
FileMonitor *monitor;
Monitor *monitor;
NautilusFile *file;
char *uri;
@ -1113,7 +1092,7 @@ process_pending_file_attribute_requests (NautilusDirectory *directory)
}
/* Quick out if no one wants directory counts monitored. */
for (p = directory->details->file_monitors; p != NULL; p = p->next) {
for (p = directory->details->monitor_list; p != NULL; p = p->next) {
monitor = p->data;
if (monitor->monitor_directory_counts) {
break;
@ -1130,7 +1109,7 @@ process_pending_file_attribute_requests (NautilusDirectory *directory)
&& !file->details->got_directory_count
&& !file->details->directory_count_failed) {
/* Make sure that someone cares about this particular directory's count. */
for (p2 = directory->details->file_monitors; p2 != NULL; p2 = p2->next) {
for (p2 = directory->details->monitor_list; p2 != NULL; p2 = p2->next) {
monitor = p2->data;
if (monitor->monitor_directory_counts
&& (monitor->file == NULL || monitor->file == file)) {
@ -1211,3 +1190,24 @@ nautilus_directory_get_info_for_new_files (NautilusDirectory *directory,
= g_list_prepend (directory->details->get_file_infos_in_progress,
handle);
}
void
nautilus_async_destroying_file (NautilusFile *file)
{
GList *p, *next;
Monitor *monitor;
/* Remove any monitors or callbacks. */
/* Make sure all monitors have been cleaned up first. */
for (p = file->details->directory->details->monitor_list; p != NULL; p = next) {
next = p->next;
monitor = p->data;
if (monitor->file == file) {
/* Client should have removed monitor earlier. */
g_warning ("destroyed file still being monitored");
remove_monitor_link (file->details->directory, p);
}
}
}

View file

@ -58,9 +58,8 @@ struct NautilusDirectoryDetails
/* These lists are going to be pretty short. If we think they
* are going to get big, we can use hash tables instead.
*/
GList *metafile_callbacks;
GList *monitors;
GList *file_monitors;
GList *call_when_ready_list;
GList *monitor_list;
gboolean directory_loaded;
GnomeVFSAsyncHandle *directory_load_in_progress;
@ -75,82 +74,78 @@ struct NautilusDirectoryDetails
NautilusFile *count_file;
};
typedef struct {
NautilusFile *file; /* Which file to monitor, NULL to monitor all. */
union {
NautilusDirectoryCallback directory;
NautilusFileCallback file;
} callback;
gpointer callback_data;
} QueuedCallback;
typedef struct {
NautilusFile *file; /* Which file to monitor, NULL to monitor all. */
gconstpointer client;
gboolean monitor_directory_counts;
} FileMonitor;
typedef struct {
char *from_uri;
char *to_uri;
} URIPair;
/* Almost-public change notification calls */
void nautilus_directory_notify_files_added (GList *uris);
void nautilus_directory_notify_files_moved (GList *uri_pairs);
void nautilus_directory_notify_files_removed (GList *uris);
void nautilus_directory_notify_files_added (GList *uris);
void nautilus_directory_notify_files_moved (GList *uri_pairs);
void nautilus_directory_notify_files_removed (GList *uris);
/* async. interface */
void nautilus_directory_cancel_callback_internal (NautilusDirectory *directory,
const QueuedCallback *callback);
void nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
const QueuedCallback *callback);
void nautilus_directory_file_monitor_add_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client,
GList *attributes,
GList *metadata_keys,
NautilusFileListCallback callback,
gpointer callback_data);
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);
void nautilus_directory_request_read_metafile (NautilusDirectory *directory);
void nautilus_directory_request_write_metafile (NautilusDirectory *directory);
void nautilus_directory_schedule_dequeue_pending (NautilusDirectory *directory);
void nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory);
void nautilus_metafile_read_cancel (NautilusDirectory *directory);
void nautilus_metafile_write_start (NautilusDirectory *directory);
void nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
NautilusFile *file,
GList *directory_metadata_keys,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback directory_callback,
NautilusFileCallback file_callback,
gpointer callback_data);
void nautilus_directory_cancel_callback_internal (NautilusDirectory *directory,
NautilusFile *file,
NautilusDirectoryCallback directory_callback,
NautilusFileCallback file_callback,
gpointer callback_data);
void nautilus_directory_monitor_add_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client,
GList *directory_metadata_keys,
GList *attributes,
GList *metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data);
void nautilus_directory_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);
void nautilus_directory_request_read_metafile (NautilusDirectory *directory);
void nautilus_directory_request_write_metafile (NautilusDirectory *directory);
void nautilus_directory_schedule_dequeue_pending (NautilusDirectory *directory);
void nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory);
void nautilus_metafile_read_cancel (NautilusDirectory *directory);
void nautilus_metafile_write_start (NautilusDirectory *directory);
void nautilus_async_destroying_file (NautilusFile *file);
/* Calls shared between directory, file, and async. code. */
NautilusFile *nautilus_directory_find_file (NautilusDirectory *directory,
const char *file_name);
char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
const char *file_name,
const char *key,
const char *default_metadata);
gboolean nautilus_directory_set_file_metadata (NautilusDirectory *directory,
const char *file_name,
const char *key,
const char *default_metadata,
const char *metadata);
xmlNode * nautilus_directory_get_file_metadata_node (NautilusDirectory *directory,
const char *file_name,
gboolean create);
void nautilus_directory_emit_metadata_changed (NautilusDirectory *directory);
void nautilus_directory_emit_files_added (NautilusDirectory *directory,
GList *added_files);
void nautilus_directory_emit_files_changed (NautilusDirectory *directory,
GList *changed_files);
NautilusFile *nautilus_directory_find_file (NautilusDirectory *directory,
const char *file_name);
char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
const char *file_name,
const char *key,
const char *default_metadata);
gboolean nautilus_directory_set_file_metadata (NautilusDirectory *directory,
const char *file_name,
const char *key,
const char *default_metadata,
const char *metadata);
xmlNode * nautilus_directory_get_file_metadata_node (NautilusDirectory *directory,
const char *file_name,
gboolean create);
void nautilus_directory_emit_metadata_changed (NautilusDirectory *directory);
void nautilus_directory_emit_files_added (NautilusDirectory *directory,
GList *added_files);
void nautilus_directory_emit_files_changed (NautilusDirectory *directory,
GList *changed_files);
/* debugging functions */
int nautilus_directory_number_outstanding (void);
int nautilus_directory_number_outstanding (void);
/* Shared functions not directly related to NautilusDirectory/File. */
int nautilus_compare_file_with_name (gconstpointer a,
gconstpointer b);
int nautilus_compare_file_with_name (gconstpointer a,
gconstpointer b);

View file

@ -160,9 +160,9 @@ nautilus_directory_destroy (GtkObject *object)
nautilus_directory_stop_monitoring_file_list (directory);
}
if (directory->details->file_monitors != NULL) {
if (directory->details->monitor_list != NULL) {
g_warning ("destroying a NautilusDirectory while it's being monitored");
nautilus_g_list_free_deep (directory->details->file_monitors);
nautilus_g_list_free_deep (directory->details->monitor_list);
}
g_hash_table_remove (directory_objects, directory->details->uri_text);
@ -1114,6 +1114,80 @@ nautilus_directory_contains_file (NautilusDirectory *directory,
return file->details->directory == directory;
}
void
nautilus_directory_call_when_ready (NautilusDirectory *directory,
GList *directory_metadata_keys,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
g_return_if_fail (directory == NULL || NAUTILUS_IS_DIRECTORY (directory));
g_return_if_fail (directory_metadata_keys != NULL || file_metadata_keys != NULL);
g_return_if_fail (callback != NULL);
nautilus_directory_call_when_ready_internal
(directory,
NULL,
directory_metadata_keys,
file_attributes,
file_metadata_keys,
callback,
NULL,
callback_data);
}
void
nautilus_directory_cancel_callback (NautilusDirectory *directory,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
g_return_if_fail (callback != NULL);
if (directory == NULL) {
return;
}
/* NULL is OK here for non-vfs protocols */
g_return_if_fail (!directory || NAUTILUS_IS_DIRECTORY (directory));
nautilus_directory_cancel_callback_internal
(directory,
NULL,
callback,
NULL,
callback_data);
}
void
nautilus_directory_file_monitor_add (NautilusDirectory *directory,
gconstpointer client,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
g_return_if_fail (client != NULL);
g_return_if_fail (callback != NULL);
nautilus_directory_monitor_add_internal (directory,
NULL,
client,
NULL,
file_attributes,
file_metadata_keys,
callback,
callback_data);
}
void
nautilus_directory_file_monitor_remove (NautilusDirectory *directory,
gconstpointer client)
{
nautilus_directory_monitor_remove_internal (directory, NULL, client);
}
#if !defined (NAUTILUS_OMIT_SELF_CHECK)
static int data_dummy;
@ -1131,9 +1205,10 @@ get_files_callback (NautilusDirectory *directory, GList *files, gpointer callbac
}
static void
got_metadata_callback (NautilusDirectory *directory, gpointer callback_data)
got_metadata_callback (NautilusDirectory *directory, GList *files, gpointer callback_data)
{
g_assert (NAUTILUS_IS_DIRECTORY (directory));
g_assert (files == NULL);
g_assert (callback_data == &data_dummy);
got_metadata_flag = TRUE;
@ -1164,7 +1239,7 @@ nautilus_self_check_directory (void)
get_files_callback, &data_dummy);
got_metadata_flag = FALSE;
nautilus_directory_call_when_ready (directory, list, NULL,
nautilus_directory_call_when_ready (directory, list, NULL, NULL,
got_metadata_callback, &data_dummy);
while (!got_metadata_flag) {
@ -1211,7 +1286,7 @@ nautilus_self_check_directory (void)
directory = nautilus_directory_get ("file:///etc");
got_metadata_flag = FALSE;
nautilus_directory_call_when_ready (directory, list, NULL,
nautilus_directory_call_when_ready (directory, list, NULL, NULL,
got_metadata_callback, &data_dummy);
while (!got_metadata_flag) {

View file

@ -63,8 +63,6 @@ typedef struct NautilusFile NautilusFile;
#endif
typedef void (*NautilusDirectoryCallback) (NautilusDirectory *directory,
gpointer callback_data);
typedef void (*NautilusFileListCallback) (NautilusDirectory *directory,
GList *files,
gpointer callback_data);
@ -90,17 +88,20 @@ gboolean nautilus_directory_contains_file (NautilusDirectory
NautilusFile *file);
/* Waiting for data that's read asynchronously.
* This interface currently works only for metadata, but could be expanded
* to other attributes as well.
* The file attribute and metadata keys are for files in the directory.
* If any file attributes or metadata keys are passed, it won't call
* until all the files are seen.
*/
void nautilus_directory_call_when_ready (NautilusDirectory *directory,
GList *directory_metadata_keys,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data);
void nautilus_directory_cancel_callback (NautilusDirectory *directory,
NautilusDirectoryCallback callback,
gpointer callback_data);
/* Getting and setting metadata. */
char * nautilus_directory_get_metadata (NautilusDirectory *directory,
const char *key,
@ -131,7 +132,7 @@ void nautilus_directory_file_monitor_add (NautilusDirectory
gconstpointer client,
GList *attributes,
GList *metadata_keys,
NautilusFileListCallback initial_files_callback,
NautilusDirectoryCallback initial_files_callback,
gpointer callback_data);
void nautilus_directory_file_monitor_remove (NautilusDirectory *directory,
gconstpointer client);

View file

@ -29,6 +29,7 @@
* in changes to the attributes.
*/
#define NAUTILUS_FILE_ATTRIBUTE_FAST_MIME_TYPE "MIME type"
#define NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT "directory item count"
#endif /* NAUTILUS_FILE_ATTRIBUTES_H */

View file

@ -208,23 +208,10 @@ static void
destroy (GtkObject *object)
{
NautilusFile *file;
GList *p, *next;
FileMonitor *file_monitor;
file = NAUTILUS_FILE (object);
/* Make sure all monitors have been cleaned up first. */
p = file->details->directory->details->file_monitors;
while (p != NULL) {
next = p->next;
file_monitor = p->data;
if (file_monitor->file == file) {
/* Client should have removed monitor earlier. */
g_warning ("destroyed file still being monitored");
nautilus_directory_remove_file_monitor_link (file->details->directory, p);
}
p = next;
}
nautilus_async_destroying_file (file);
if (file->details->is_gone) {
g_assert (g_list_find (file->details->directory->details->files, file) == NULL);
@ -899,23 +886,28 @@ nautilus_file_monitor_add (NautilusFile *file,
g_return_if_fail (client != NULL);
g_return_if_fail (attributes != NULL || metadata_keys != NULL);
nautilus_directory_file_monitor_add_internal (file->details->directory,
file,
client,
attributes,
metadata_keys,
NULL,
NULL);
}
nautilus_directory_monitor_add_internal
(file->details->directory,
file,
client,
NULL,
attributes,
metadata_keys,
NULL,
NULL);
}
void
void
nautilus_file_monitor_remove (NautilusFile *file,
gconstpointer client)
{
g_return_if_fail (NAUTILUS_IS_FILE (file));
g_return_if_fail (client != NULL);
nautilus_directory_file_monitor_remove_internal (file->details->directory, file, client);
nautilus_directory_monitor_remove_internal
(file->details->directory,
file,
client);
}
@ -1745,22 +1737,24 @@ nautilus_file_is_gone (NautilusFile *file)
void
nautilus_file_call_when_ready (NautilusFile *file,
GList *file_attributes,
GList *file_metadata_keys,
NautilusFileCallback callback,
gpointer callback_data)
{
QueuedCallback new_callback;
g_return_if_fail (NAUTILUS_IS_FILE (file));
g_return_if_fail (file_metadata_keys != NULL);
g_return_if_fail (callback != NULL);
new_callback.file = file;
new_callback.callback.file = callback;
new_callback.callback_data = callback_data;
nautilus_directory_call_when_ready_internal (file->details->directory,
&new_callback);
nautilus_directory_call_when_ready_internal
(file->details->directory,
file,
NULL,
file_attributes,
file_metadata_keys,
NULL,
callback,
callback_data);
}
void
@ -1768,8 +1762,6 @@ nautilus_file_cancel_callback (NautilusFile *file,
NautilusFileCallback callback,
gpointer callback_data)
{
QueuedCallback old_callback;
g_return_if_fail (callback != NULL);
if (file == NULL) {
@ -1778,12 +1770,12 @@ nautilus_file_cancel_callback (NautilusFile *file,
g_return_if_fail (NAUTILUS_IS_FILE (file));
old_callback.file = file;
old_callback.callback.file = callback;
old_callback.callback_data = callback_data;
nautilus_directory_cancel_callback_internal (file->details->directory,
&old_callback);
nautilus_directory_cancel_callback_internal
(file->details->directory,
file,
NULL,
callback,
callback_data);
}
/**

View file

@ -87,6 +87,7 @@ void nautilus_file_monitor_remove (NautilusFile
* to other attributes as well.
*/
void nautilus_file_call_when_ready (NautilusFile *file,
GList *attributes,
GList *metadata_keys,
NautilusFileCallback callback,
gpointer callback_data);

View file

@ -56,6 +56,27 @@ struct MetafileWriteState {
gboolean write_again;
};
typedef struct {
NautilusFile *file; /* Which file to monitor, NULL to monitor all. */
union {
NautilusDirectoryCallback directory;
NautilusFileCallback file;
} callback;
gpointer callback_data;
gboolean wait_for_metafile;
gboolean wait_for_file_list; /* always FALSE if file != NULL */
gboolean wait_for_directory_counts;
} CallWhenReady;
typedef struct {
NautilusFile *file; /* Which file to monitor, NULL to monitor all. */
gconstpointer client;
gboolean monitor_file_list; /* always FALSE if file != NULL */
gboolean monitor_directory_counts;
} Monitor;
#define READ_CHUNK_SIZE (4 * 1024)
static int compare_queued_callbacks (gconstpointer a,
@ -123,11 +144,11 @@ static void
metafile_read_done (NautilusDirectory *directory)
{
GList *p;
QueuedCallback *callback;
CallWhenReady *callback;
/* Tell the callers that were waiting for metadata that it's here.
*/
for (p = directory->details->metafile_callbacks; p != NULL; p = p->next) {
for (p = directory->details->call_when_ready_list; p != NULL; p = p->next) {
callback = p->data;
if (callback->file != NULL) {
@ -137,11 +158,12 @@ metafile_read_done (NautilusDirectory *directory)
nautilus_file_unref (callback->file);
} else {
(* callback->callback.directory) (directory,
NULL,
callback->callback_data);
}
}
nautilus_g_list_free_deep (directory->details->metafile_callbacks);
directory->details->metafile_callbacks = NULL;
nautilus_g_list_free_deep (directory->details->call_when_ready_list);
directory->details->call_when_ready_list = NULL;
}
void
@ -487,11 +509,11 @@ nautilus_directory_request_write_metafile (NautilusDirectory *directory)
}
static int
compare_file_monitor_by_client_and_file (gconstpointer a,
compare_monitor_by_client_and_file (gconstpointer a,
gconstpointer data)
{
const FileMonitor *monitor;
const FileMonitor *compare_monitor;
const Monitor *monitor;
const Monitor *compare_monitor;
monitor = a;
compare_monitor = data;
@ -514,22 +536,22 @@ compare_file_monitor_by_client_and_file (gconstpointer a,
}
static GList *
find_file_monitor (NautilusDirectory *directory,
find_monitor (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client)
{
GList *result;
FileMonitor *file_monitor;
Monitor *monitor;
file_monitor = g_new (FileMonitor, 1);
file_monitor->client = client;
file_monitor->file = file;
monitor = g_new (Monitor, 1);
monitor->client = client;
monitor->file = file;
result = g_list_find_custom (directory->details->file_monitors,
(gpointer) file_monitor,
compare_file_monitor_by_client_and_file);
result = g_list_find_custom (directory->details->monitor_list,
(gpointer) monitor,
compare_monitor_by_client_and_file);
g_free (file_monitor);
g_free (monitor);
return result;
}
@ -538,13 +560,13 @@ static void
cancel_unneeded_file_attribute_requests (NautilusDirectory *directory)
{
GList *p;
FileMonitor *file_monitor;
Monitor *monitor;
/* Cancel the directory-count request if no one cares anymore */
if (directory->details->count_in_progress != NULL) {
for (p = directory->details->file_monitors; p != NULL; p = p->next) {
file_monitor = p->data;
if (file_monitor->monitor_directory_counts) {
for (p = directory->details->monitor_list; p != NULL; p = p->next) {
monitor = p->data;
if (monitor->monitor_directory_counts) {
break;
}
}
@ -555,12 +577,12 @@ cancel_unneeded_file_attribute_requests (NautilusDirectory *directory)
}
}
void
nautilus_directory_remove_file_monitor_link (NautilusDirectory *directory,
GList *link)
static void
remove_monitor_link (NautilusDirectory *directory,
GList *link)
{
directory->details->file_monitors =
g_list_remove_link (directory->details->file_monitors, link);
directory->details->monitor_list =
g_list_remove_link (directory->details->monitor_list, link);
if (link != NULL) {
g_free (link->data);
}
@ -568,23 +590,22 @@ nautilus_directory_remove_file_monitor_link (NautilusDirectory *directory,
}
static void
remove_file_monitor (NautilusDirectory *directory,
remove_monitor (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client)
{
nautilus_directory_remove_file_monitor_link
(directory, find_file_monitor (directory, file, client));
remove_monitor_link (directory, find_monitor (directory, file, client));
}
gboolean
nautilus_directory_is_file_list_monitored (NautilusDirectory *directory)
{
FileMonitor *file_monitor;
Monitor *monitor;
GList *p;
for (p = directory->details->file_monitors; p != NULL; p = p->next) {
file_monitor = p->data;
if (file_monitor->file == NULL) {
for (p = directory->details->monitor_list; p != NULL; p = p->next) {
monitor = p->data;
if (monitor->file == NULL) {
return TRUE;
}
}
@ -593,18 +614,19 @@ nautilus_directory_is_file_list_monitored (NautilusDirectory *directory)
}
void
nautilus_directory_file_monitor_add_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client,
GList *attributes,
GList *metadata_keys,
NautilusFileListCallback callback,
gpointer callback_data)
nautilus_directory_monitor_add_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client,
GList *directory_metadata_keys,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
gboolean was_monitoring_file_list;
gboolean will_be_monitoring_file_list;
gboolean rely_on_directory_load;
FileMonitor *file_monitor;
Monitor *monitor;
g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
@ -619,18 +641,18 @@ nautilus_directory_file_monitor_add_internal (NautilusDirectory *directory,
rely_on_directory_load = will_be_monitoring_file_list && !directory->details->directory_loaded;
/* Replace any current monitor for this client/file pair. */
remove_file_monitor (directory, file, client);
remove_monitor (directory, file, client);
file_monitor = g_new (FileMonitor, 1);
file_monitor->client = client;
file_monitor->file = file;
file_monitor->monitor_directory_counts = g_list_find_custom
(attributes,
monitor = g_new (Monitor, 1);
monitor->client = client;
monitor->file = file;
monitor->monitor_directory_counts = g_list_find_custom
(file_attributes,
NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT,
(GCompareFunc) nautilus_strcmp) != NULL;
directory->details->file_monitors =
g_list_prepend (directory->details->file_monitors, file_monitor);
directory->details->monitor_list =
g_list_prepend (directory->details->monitor_list, monitor);
/* Clean up stale requests only after (optionally) removing old
* monitor and adding new one.
@ -695,27 +717,6 @@ nautilus_directory_file_monitor_add_internal (NautilusDirectory *directory,
directory);
}
void
nautilus_directory_file_monitor_add (NautilusDirectory *directory,
gconstpointer client,
GList *attributes,
GList *metadata_keys,
NautilusFileListCallback callback,
gpointer callback_data)
{
g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
g_return_if_fail (client != NULL);
g_return_if_fail (callback != NULL);
nautilus_directory_file_monitor_add_internal (directory,
NULL,
client,
attributes,
metadata_keys,
callback,
callback_data);
}
int
nautilus_compare_file_with_name (gconstpointer a, gconstpointer b)
{
@ -902,9 +903,9 @@ nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory)
}
void
nautilus_directory_file_monitor_remove_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client)
nautilus_directory_monitor_remove_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client)
{
gboolean was_monitoring_file_list;
@ -912,7 +913,7 @@ nautilus_directory_file_monitor_remove_internal (NautilusDirectory *directory,
was_monitoring_file_list = nautilus_directory_is_file_list_monitored (directory);
remove_file_monitor (directory, file, client);
remove_monitor (directory, file, client);
cancel_unneeded_file_attribute_requests (directory);
if (was_monitoring_file_list && !nautilus_directory_is_file_list_monitored (directory)) {
@ -920,17 +921,10 @@ nautilus_directory_file_monitor_remove_internal (NautilusDirectory *directory,
}
}
void
nautilus_directory_file_monitor_remove (NautilusDirectory *directory,
gconstpointer client)
{
nautilus_directory_file_monitor_remove_internal (directory, NULL, client);
}
static int
compare_queued_callbacks (gconstpointer a, gconstpointer b)
{
const QueuedCallback *callback_a, *callback_b;
const CallWhenReady *callback_a, *callback_b;
callback_a = a;
callback_b = b;
@ -966,103 +960,88 @@ compare_queued_callbacks (gconstpointer a, gconstpointer b)
void
nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
const QueuedCallback *callback)
NautilusFile *file,
GList *directory_metadata_keys,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback directory_callback,
NautilusFileCallback file_callback,
gpointer callback_data)
{
CallWhenReady callback;
g_assert (directory == NULL || NAUTILUS_IS_DIRECTORY (directory));
g_assert (callback != NULL);
g_assert (callback->file == NULL || callback->file->details->directory == directory);
/* Call back right away if it's already ready. */
if (directory == NULL || directory->details->metafile_read) {
if (callback->file != NULL) {
(* callback->callback.file) (callback->file,
callback->callback_data);
if (file != NULL) {
(* file_callback) (file,
callback_data);
} else {
(* callback->callback.directory) (directory,
callback->callback_data);
(* directory_callback) (directory,
NULL,
callback_data);
}
return;
}
/* Construct a callback object. */
callback.file = file;
if (file == NULL) {
callback.callback.directory = directory_callback;
} else {
callback.callback.file = file_callback;
}
callback.callback_data = callback_data;
/* MORE HERE */
/* Add the new callback to the list unless it's already in there. */
if (g_list_find_custom (directory->details->metafile_callbacks,
(QueuedCallback *) callback,
/* REPLACE THE OLD ONE INSTEAD DARIN */
if (g_list_find_custom (directory->details->call_when_ready_list,
&callback,
compare_queued_callbacks) == NULL) {
nautilus_file_ref (callback->file);
directory->details->metafile_callbacks = g_list_prepend
(directory->details->metafile_callbacks,
g_memdup (callback,
sizeof (*callback)));
nautilus_file_ref (file);
directory->details->call_when_ready_list = g_list_prepend
(directory->details->call_when_ready_list,
g_memdup (&callback,
sizeof (callback)));
}
/* Start reading the metafile. */
nautilus_directory_request_read_metafile (directory);
}
void
nautilus_directory_call_when_ready (NautilusDirectory *directory,
GList *directory_metadata_keys,
GList *file_metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
QueuedCallback new_callback;
g_return_if_fail (directory == NULL || NAUTILUS_IS_DIRECTORY (directory));
g_return_if_fail (directory_metadata_keys != NULL || file_metadata_keys != NULL);
g_return_if_fail (callback != NULL);
new_callback.file = NULL;
new_callback.callback.directory = callback;
new_callback.callback_data = callback_data;
nautilus_directory_call_when_ready_internal (directory, &new_callback);
}
void
nautilus_directory_cancel_callback_internal (NautilusDirectory *directory,
const QueuedCallback *callback)
NautilusFile *file,
NautilusDirectoryCallback directory_callback,
NautilusFileCallback file_callback,
gpointer callback_data)
{
CallWhenReady callback;
GList *p;
g_assert (NAUTILUS_IS_DIRECTORY (directory));
g_assert (callback != NULL);
/* Construct a callback object. */
callback.file = file;
if (file == NULL) {
callback.callback.directory = directory_callback;
} else {
callback.callback.file = file_callback;
}
callback.callback_data = callback_data;
/* Remove queued callback from the list. */
p = g_list_find_custom (directory->details->metafile_callbacks,
(QueuedCallback *) callback,
p = g_list_find_custom (directory->details->call_when_ready_list,
&callback,
compare_queued_callbacks);
if (p != NULL) {
nautilus_file_unref (callback->file);
nautilus_file_unref (file);
g_free (p->data);
directory->details->metafile_callbacks = g_list_remove_link
(directory->details->metafile_callbacks, p);
directory->details->call_when_ready_list = g_list_remove_link
(directory->details->call_when_ready_list, p);
}
}
void
nautilus_directory_cancel_callback (NautilusDirectory *directory,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
QueuedCallback old_callback;
g_return_if_fail (callback != NULL);
if (directory == NULL) {
return;
}
/* NULL is OK here for non-vfs protocols */
g_return_if_fail (!directory || NAUTILUS_IS_DIRECTORY (directory));
old_callback.file = NULL;
old_callback.callback.directory = callback;
old_callback.callback_data = callback_data;
nautilus_directory_cancel_callback_internal (directory, &old_callback);
}
static void
directory_count_callback (GnomeVFSAsyncHandle *handle,
GnomeVFSResult result,
@ -1104,7 +1083,7 @@ static void
process_pending_file_attribute_requests (NautilusDirectory *directory)
{
GList *p, *p2;
FileMonitor *monitor;
Monitor *monitor;
NautilusFile *file;
char *uri;
@ -1113,7 +1092,7 @@ process_pending_file_attribute_requests (NautilusDirectory *directory)
}
/* Quick out if no one wants directory counts monitored. */
for (p = directory->details->file_monitors; p != NULL; p = p->next) {
for (p = directory->details->monitor_list; p != NULL; p = p->next) {
monitor = p->data;
if (monitor->monitor_directory_counts) {
break;
@ -1130,7 +1109,7 @@ process_pending_file_attribute_requests (NautilusDirectory *directory)
&& !file->details->got_directory_count
&& !file->details->directory_count_failed) {
/* Make sure that someone cares about this particular directory's count. */
for (p2 = directory->details->file_monitors; p2 != NULL; p2 = p2->next) {
for (p2 = directory->details->monitor_list; p2 != NULL; p2 = p2->next) {
monitor = p2->data;
if (monitor->monitor_directory_counts
&& (monitor->file == NULL || monitor->file == file)) {
@ -1211,3 +1190,24 @@ nautilus_directory_get_info_for_new_files (NautilusDirectory *directory,
= g_list_prepend (directory->details->get_file_infos_in_progress,
handle);
}
void
nautilus_async_destroying_file (NautilusFile *file)
{
GList *p, *next;
Monitor *monitor;
/* Remove any monitors or callbacks. */
/* Make sure all monitors have been cleaned up first. */
for (p = file->details->directory->details->monitor_list; p != NULL; p = next) {
next = p->next;
monitor = p->data;
if (monitor->file == file) {
/* Client should have removed monitor earlier. */
g_warning ("destroyed file still being monitored");
remove_monitor_link (file->details->directory, p);
}
}
}

View file

@ -58,9 +58,8 @@ struct NautilusDirectoryDetails
/* These lists are going to be pretty short. If we think they
* are going to get big, we can use hash tables instead.
*/
GList *metafile_callbacks;
GList *monitors;
GList *file_monitors;
GList *call_when_ready_list;
GList *monitor_list;
gboolean directory_loaded;
GnomeVFSAsyncHandle *directory_load_in_progress;
@ -75,82 +74,78 @@ struct NautilusDirectoryDetails
NautilusFile *count_file;
};
typedef struct {
NautilusFile *file; /* Which file to monitor, NULL to monitor all. */
union {
NautilusDirectoryCallback directory;
NautilusFileCallback file;
} callback;
gpointer callback_data;
} QueuedCallback;
typedef struct {
NautilusFile *file; /* Which file to monitor, NULL to monitor all. */
gconstpointer client;
gboolean monitor_directory_counts;
} FileMonitor;
typedef struct {
char *from_uri;
char *to_uri;
} URIPair;
/* Almost-public change notification calls */
void nautilus_directory_notify_files_added (GList *uris);
void nautilus_directory_notify_files_moved (GList *uri_pairs);
void nautilus_directory_notify_files_removed (GList *uris);
void nautilus_directory_notify_files_added (GList *uris);
void nautilus_directory_notify_files_moved (GList *uri_pairs);
void nautilus_directory_notify_files_removed (GList *uris);
/* async. interface */
void nautilus_directory_cancel_callback_internal (NautilusDirectory *directory,
const QueuedCallback *callback);
void nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
const QueuedCallback *callback);
void nautilus_directory_file_monitor_add_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client,
GList *attributes,
GList *metadata_keys,
NautilusFileListCallback callback,
gpointer callback_data);
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);
void nautilus_directory_request_read_metafile (NautilusDirectory *directory);
void nautilus_directory_request_write_metafile (NautilusDirectory *directory);
void nautilus_directory_schedule_dequeue_pending (NautilusDirectory *directory);
void nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory);
void nautilus_metafile_read_cancel (NautilusDirectory *directory);
void nautilus_metafile_write_start (NautilusDirectory *directory);
void nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
NautilusFile *file,
GList *directory_metadata_keys,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback directory_callback,
NautilusFileCallback file_callback,
gpointer callback_data);
void nautilus_directory_cancel_callback_internal (NautilusDirectory *directory,
NautilusFile *file,
NautilusDirectoryCallback directory_callback,
NautilusFileCallback file_callback,
gpointer callback_data);
void nautilus_directory_monitor_add_internal (NautilusDirectory *directory,
NautilusFile *file,
gconstpointer client,
GList *directory_metadata_keys,
GList *attributes,
GList *metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data);
void nautilus_directory_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);
void nautilus_directory_request_read_metafile (NautilusDirectory *directory);
void nautilus_directory_request_write_metafile (NautilusDirectory *directory);
void nautilus_directory_schedule_dequeue_pending (NautilusDirectory *directory);
void nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory);
void nautilus_metafile_read_cancel (NautilusDirectory *directory);
void nautilus_metafile_write_start (NautilusDirectory *directory);
void nautilus_async_destroying_file (NautilusFile *file);
/* Calls shared between directory, file, and async. code. */
NautilusFile *nautilus_directory_find_file (NautilusDirectory *directory,
const char *file_name);
char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
const char *file_name,
const char *key,
const char *default_metadata);
gboolean nautilus_directory_set_file_metadata (NautilusDirectory *directory,
const char *file_name,
const char *key,
const char *default_metadata,
const char *metadata);
xmlNode * nautilus_directory_get_file_metadata_node (NautilusDirectory *directory,
const char *file_name,
gboolean create);
void nautilus_directory_emit_metadata_changed (NautilusDirectory *directory);
void nautilus_directory_emit_files_added (NautilusDirectory *directory,
GList *added_files);
void nautilus_directory_emit_files_changed (NautilusDirectory *directory,
GList *changed_files);
NautilusFile *nautilus_directory_find_file (NautilusDirectory *directory,
const char *file_name);
char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
const char *file_name,
const char *key,
const char *default_metadata);
gboolean nautilus_directory_set_file_metadata (NautilusDirectory *directory,
const char *file_name,
const char *key,
const char *default_metadata,
const char *metadata);
xmlNode * nautilus_directory_get_file_metadata_node (NautilusDirectory *directory,
const char *file_name,
gboolean create);
void nautilus_directory_emit_metadata_changed (NautilusDirectory *directory);
void nautilus_directory_emit_files_added (NautilusDirectory *directory,
GList *added_files);
void nautilus_directory_emit_files_changed (NautilusDirectory *directory,
GList *changed_files);
/* debugging functions */
int nautilus_directory_number_outstanding (void);
int nautilus_directory_number_outstanding (void);
/* Shared functions not directly related to NautilusDirectory/File. */
int nautilus_compare_file_with_name (gconstpointer a,
gconstpointer b);
int nautilus_compare_file_with_name (gconstpointer a,
gconstpointer b);

View file

@ -160,9 +160,9 @@ nautilus_directory_destroy (GtkObject *object)
nautilus_directory_stop_monitoring_file_list (directory);
}
if (directory->details->file_monitors != NULL) {
if (directory->details->monitor_list != NULL) {
g_warning ("destroying a NautilusDirectory while it's being monitored");
nautilus_g_list_free_deep (directory->details->file_monitors);
nautilus_g_list_free_deep (directory->details->monitor_list);
}
g_hash_table_remove (directory_objects, directory->details->uri_text);
@ -1114,6 +1114,80 @@ nautilus_directory_contains_file (NautilusDirectory *directory,
return file->details->directory == directory;
}
void
nautilus_directory_call_when_ready (NautilusDirectory *directory,
GList *directory_metadata_keys,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
g_return_if_fail (directory == NULL || NAUTILUS_IS_DIRECTORY (directory));
g_return_if_fail (directory_metadata_keys != NULL || file_metadata_keys != NULL);
g_return_if_fail (callback != NULL);
nautilus_directory_call_when_ready_internal
(directory,
NULL,
directory_metadata_keys,
file_attributes,
file_metadata_keys,
callback,
NULL,
callback_data);
}
void
nautilus_directory_cancel_callback (NautilusDirectory *directory,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
g_return_if_fail (callback != NULL);
if (directory == NULL) {
return;
}
/* NULL is OK here for non-vfs protocols */
g_return_if_fail (!directory || NAUTILUS_IS_DIRECTORY (directory));
nautilus_directory_cancel_callback_internal
(directory,
NULL,
callback,
NULL,
callback_data);
}
void
nautilus_directory_file_monitor_add (NautilusDirectory *directory,
gconstpointer client,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data)
{
g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
g_return_if_fail (client != NULL);
g_return_if_fail (callback != NULL);
nautilus_directory_monitor_add_internal (directory,
NULL,
client,
NULL,
file_attributes,
file_metadata_keys,
callback,
callback_data);
}
void
nautilus_directory_file_monitor_remove (NautilusDirectory *directory,
gconstpointer client)
{
nautilus_directory_monitor_remove_internal (directory, NULL, client);
}
#if !defined (NAUTILUS_OMIT_SELF_CHECK)
static int data_dummy;
@ -1131,9 +1205,10 @@ get_files_callback (NautilusDirectory *directory, GList *files, gpointer callbac
}
static void
got_metadata_callback (NautilusDirectory *directory, gpointer callback_data)
got_metadata_callback (NautilusDirectory *directory, GList *files, gpointer callback_data)
{
g_assert (NAUTILUS_IS_DIRECTORY (directory));
g_assert (files == NULL);
g_assert (callback_data == &data_dummy);
got_metadata_flag = TRUE;
@ -1164,7 +1239,7 @@ nautilus_self_check_directory (void)
get_files_callback, &data_dummy);
got_metadata_flag = FALSE;
nautilus_directory_call_when_ready (directory, list, NULL,
nautilus_directory_call_when_ready (directory, list, NULL, NULL,
got_metadata_callback, &data_dummy);
while (!got_metadata_flag) {
@ -1211,7 +1286,7 @@ nautilus_self_check_directory (void)
directory = nautilus_directory_get ("file:///etc");
got_metadata_flag = FALSE;
nautilus_directory_call_when_ready (directory, list, NULL,
nautilus_directory_call_when_ready (directory, list, NULL, NULL,
got_metadata_callback, &data_dummy);
while (!got_metadata_flag) {

View file

@ -63,8 +63,6 @@ typedef struct NautilusFile NautilusFile;
#endif
typedef void (*NautilusDirectoryCallback) (NautilusDirectory *directory,
gpointer callback_data);
typedef void (*NautilusFileListCallback) (NautilusDirectory *directory,
GList *files,
gpointer callback_data);
@ -90,17 +88,20 @@ gboolean nautilus_directory_contains_file (NautilusDirectory
NautilusFile *file);
/* Waiting for data that's read asynchronously.
* This interface currently works only for metadata, but could be expanded
* to other attributes as well.
* The file attribute and metadata keys are for files in the directory.
* If any file attributes or metadata keys are passed, it won't call
* until all the files are seen.
*/
void nautilus_directory_call_when_ready (NautilusDirectory *directory,
GList *directory_metadata_keys,
GList *file_attributes,
GList *file_metadata_keys,
NautilusDirectoryCallback callback,
gpointer callback_data);
void nautilus_directory_cancel_callback (NautilusDirectory *directory,
NautilusDirectoryCallback callback,
gpointer callback_data);
/* Getting and setting metadata. */
char * nautilus_directory_get_metadata (NautilusDirectory *directory,
const char *key,
@ -131,7 +132,7 @@ void nautilus_directory_file_monitor_add (NautilusDirectory
gconstpointer client,
GList *attributes,
GList *metadata_keys,
NautilusFileListCallback initial_files_callback,
NautilusDirectoryCallback initial_files_callback,
gpointer callback_data);
void nautilus_directory_file_monitor_remove (NautilusDirectory *directory,
gconstpointer client);

View file

@ -29,6 +29,7 @@
* in changes to the attributes.
*/
#define NAUTILUS_FILE_ATTRIBUTE_FAST_MIME_TYPE "MIME type"
#define NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT "directory item count"
#endif /* NAUTILUS_FILE_ATTRIBUTES_H */

View file

@ -208,23 +208,10 @@ static void
destroy (GtkObject *object)
{
NautilusFile *file;
GList *p, *next;
FileMonitor *file_monitor;
file = NAUTILUS_FILE (object);
/* Make sure all monitors have been cleaned up first. */
p = file->details->directory->details->file_monitors;
while (p != NULL) {
next = p->next;
file_monitor = p->data;
if (file_monitor->file == file) {
/* Client should have removed monitor earlier. */
g_warning ("destroyed file still being monitored");
nautilus_directory_remove_file_monitor_link (file->details->directory, p);
}
p = next;
}
nautilus_async_destroying_file (file);
if (file->details->is_gone) {
g_assert (g_list_find (file->details->directory->details->files, file) == NULL);
@ -899,23 +886,28 @@ nautilus_file_monitor_add (NautilusFile *file,
g_return_if_fail (client != NULL);
g_return_if_fail (attributes != NULL || metadata_keys != NULL);
nautilus_directory_file_monitor_add_internal (file->details->directory,
file,
client,
attributes,
metadata_keys,
NULL,
NULL);
}
nautilus_directory_monitor_add_internal
(file->details->directory,
file,
client,
NULL,
attributes,
metadata_keys,
NULL,
NULL);
}
void
void
nautilus_file_monitor_remove (NautilusFile *file,
gconstpointer client)
{
g_return_if_fail (NAUTILUS_IS_FILE (file));
g_return_if_fail (client != NULL);
nautilus_directory_file_monitor_remove_internal (file->details->directory, file, client);
nautilus_directory_monitor_remove_internal
(file->details->directory,
file,
client);
}
@ -1745,22 +1737,24 @@ nautilus_file_is_gone (NautilusFile *file)
void
nautilus_file_call_when_ready (NautilusFile *file,
GList *file_attributes,
GList *file_metadata_keys,
NautilusFileCallback callback,
gpointer callback_data)
{
QueuedCallback new_callback;
g_return_if_fail (NAUTILUS_IS_FILE (file));
g_return_if_fail (file_metadata_keys != NULL);
g_return_if_fail (callback != NULL);
new_callback.file = file;
new_callback.callback.file = callback;
new_callback.callback_data = callback_data;
nautilus_directory_call_when_ready_internal (file->details->directory,
&new_callback);
nautilus_directory_call_when_ready_internal
(file->details->directory,
file,
NULL,
file_attributes,
file_metadata_keys,
NULL,
callback,
callback_data);
}
void
@ -1768,8 +1762,6 @@ nautilus_file_cancel_callback (NautilusFile *file,
NautilusFileCallback callback,
gpointer callback_data)
{
QueuedCallback old_callback;
g_return_if_fail (callback != NULL);
if (file == NULL) {
@ -1778,12 +1770,12 @@ nautilus_file_cancel_callback (NautilusFile *file,
g_return_if_fail (NAUTILUS_IS_FILE (file));
old_callback.file = file;
old_callback.callback.file = callback;
old_callback.callback_data = callback_data;
nautilus_directory_cancel_callback_internal (file->details->directory,
&old_callback);
nautilus_directory_cancel_callback_internal
(file->details->directory,
file,
NULL,
callback,
callback_data);
}
/**

View file

@ -87,6 +87,7 @@ void nautilus_file_monitor_remove (NautilusFile
* to other attributes as well.
*/
void nautilus_file_call_when_ready (NautilusFile *file,
GList *attributes,
GList *metadata_keys,
NautilusFileCallback callback,
gpointer callback_data);

View file

@ -179,6 +179,7 @@ static void get_required_metadata_keys
GList **directory_keys_result,
GList **file_keys_result);
static void metadata_ready_callback (NautilusDirectory *directory,
GList *files,
gpointer callback_data);
NAUTILUS_DEFINE_CLASS_BOILERPLATE (FMDirectoryView, fm_directory_view, GTK_TYPE_SCROLLED_WINDOW)
@ -1993,6 +1994,7 @@ fm_directory_view_load_uri (FMDirectoryView *view,
nautilus_directory_call_when_ready (view->details->model,
directory_keys,
NULL,
file_keys,
metadata_ready_callback,
view);
@ -2047,6 +2049,7 @@ finish_loading_uri (FMDirectoryView *view)
static void
metadata_ready_callback (NautilusDirectory *directory,
GList *files,
gpointer callback_data)
{
FMDirectoryView *view;
@ -2054,6 +2057,7 @@ metadata_ready_callback (NautilusDirectory *directory,
view = callback_data;
g_assert (FM_IS_DIRECTORY_VIEW (view));
g_assert (files == NULL);
g_assert (view->details->model == directory);
finish_loading_uri (view);

View file

@ -479,6 +479,7 @@ add_meta_view_iids_from_preferences (NautilusNavigationInfo *navinfo)
static void
got_metadata_callback (NautilusDirectory *directory,
GList *files,
gpointer callback_data)
{
NautilusNavigationInfo *info;
@ -554,6 +555,7 @@ nautilus_navigation_info_new (Nautilus_NavigationRequestInfo *nri,
nautilus_directory_call_when_ready (navinfo->directory,
keys,
NULL,
NULL,
got_metadata_callback,
navinfo);
g_list_free (keys);

View file

@ -479,6 +479,7 @@ add_meta_view_iids_from_preferences (NautilusNavigationInfo *navinfo)
static void
got_metadata_callback (NautilusDirectory *directory,
GList *files,
gpointer callback_data)
{
NautilusNavigationInfo *info;
@ -554,6 +555,7 @@ nautilus_navigation_info_new (Nautilus_NavigationRequestInfo *nri,
nautilus_directory_call_when_ready (navinfo->directory,
keys,
NULL,
NULL,
got_metadata_callback,
navinfo);
g_list_free (keys);