Commit 503b5255 authored by Darin Adler's avatar Darin Adler

Implemented Reload for directory views.

	* libnautilus-extensions/nautilus-directory-private.h:
	* libnautilus-extensions/nautilus-directory-async.c:
	(nautilus_directory_monitor_add_internal),
	(dequeue_pending_idle_callback), (cancel_directory_load),
	(directory_load_done),
	(nautilus_directory_monitor_remove_internal),
	(nautilus_directory_call_when_ready_internal),
	(mark_all_files_unconfirmed), (start_monitoring_file_list),
	(nautilus_directory_stop_monitoring_file_list),
	(nautilus_directory_force_reload):
	* libnautilus-extensions/nautilus-directory.c:
	(call_files_changed_unref_free_list),
	(nautilus_directory_notify_files_removed),
	(nautilus_directory_notify_files_moved),
	(nautilus_directory_file_monitor_add):
	* libnautilus-extensions/nautilus-file-private.h:
	* libnautilus-extensions/nautilus-file.c: (nautilus_file_get),
	(destroy), (nautilus_file_monitor_remove), (nautilus_file_delete),
	(nautilus_file_mark_gone), (nautilus_file_changed),
	(nautilus_file_emit_changed):
	Added the necessary tweaks to the async. I/O so we can handle
	a reload, not just the initial load.

	* libnautilus-extensions/nautilus-icon-container.h:
	* libnautilus-extensions/nautilus-icon-container.c:
	(nautilus_icon_container_add): Changed API so it will detect if
	you try to add the same item twice and indicate it with a return
	value; needed so we can handle reload.

	* libnautilus-extensions/nautilus-list.c: (set_single_click_mode),
	(update_single_click_mode_from_preferences),
	(nautilus_list_initialize), (click_policy_changed_callback):
	Fixed bug where a change in single click mode would chang the
	appearance of the names in the list, but not cause a redraw when
	the setting was changed.

	* libnautilus/nautilus-undoable.c:
	(undo_atom_destroy_callback_data), (undo_atom_destroy),
	(undo_atom_destroy_callback_data_g_func_cover),
	(nautilus_undo_register_full):
	Fixed a bug where it would try to destroy the undo atom even when
	it didn't own it.

	* libnautilus/nautilus-undoable.h:
	Got rid of some cruft I left in here by accident.

	* src/file-manager/fm-icon-view.c: (fm_icon_view_add_file):
	* src/file-manager/fm-list-view.c: (fm_list_view_add_file):
	Only add the files if they are not already in the list. This is
	needed for reload.

	* src/ntl-main.c: (main): Tweaked this function to be easier to
	understand and better organized. Also added a "desktop" option
	as a start for my next task.
parent 31652a34
2000-05-22 Darin Adler <darin@eazel.com>
Implemented Reload for directory views.
* libnautilus-extensions/nautilus-directory-private.h:
* libnautilus-extensions/nautilus-directory-async.c:
(nautilus_directory_monitor_add_internal),
(dequeue_pending_idle_callback), (cancel_directory_load),
(directory_load_done),
(nautilus_directory_monitor_remove_internal),
(nautilus_directory_call_when_ready_internal),
(mark_all_files_unconfirmed), (start_monitoring_file_list),
(nautilus_directory_stop_monitoring_file_list),
(nautilus_directory_force_reload):
* libnautilus-extensions/nautilus-directory.c:
(call_files_changed_unref_free_list),
(nautilus_directory_notify_files_removed),
(nautilus_directory_notify_files_moved),
(nautilus_directory_file_monitor_add):
* libnautilus-extensions/nautilus-file-private.h:
* libnautilus-extensions/nautilus-file.c: (nautilus_file_get),
(destroy), (nautilus_file_monitor_remove), (nautilus_file_delete),
(nautilus_file_mark_gone), (nautilus_file_changed),
(nautilus_file_emit_changed):
Added the necessary tweaks to the async. I/O so we can handle
a reload, not just the initial load.
* libnautilus-extensions/nautilus-icon-container.h:
* libnautilus-extensions/nautilus-icon-container.c:
(nautilus_icon_container_add): Changed API so it will detect if
you try to add the same item twice and indicate it with a return
value; needed so we can handle reload.
* libnautilus-extensions/nautilus-list.c: (set_single_click_mode),
(update_single_click_mode_from_preferences),
(nautilus_list_initialize), (click_policy_changed_callback):
Fixed bug where a change in single click mode would chang the
appearance of the names in the list, but not cause a redraw when
the setting was changed.
* libnautilus/nautilus-undoable.c:
(undo_atom_destroy_callback_data), (undo_atom_destroy),
(undo_atom_destroy_callback_data_g_func_cover),
(nautilus_undo_register_full):
Fixed a bug where it would try to destroy the undo atom even when
it didn't own it.
* libnautilus/nautilus-undoable.h:
Got rid of some cruft I left in here by accident.
* src/file-manager/fm-icon-view.c: (fm_icon_view_add_file):
* src/file-manager/fm-list-view.c: (fm_list_view_add_file):
Only add the files if they are not already in the list. This is
needed for reload.
* src/ntl-main.c: (main): Tweaked this function to be easier to
understand and better organized. Also added a "desktop" option
as a start for my next task.
2000-05-22 Eskil Heyn Olsen <eskil@eazel.om>
* components/services/trilobite/src/trilobite-service-private.h:
......
.deps
.libs
Makefile
Makefile.in
trilobite-eazel-time-service
trilobite-eazel-time-service-common.c
trilobite-eazel-time-service-skels.c
trilobite-eazel-time-service-stubs.c
trilobite-eazel-time-service.h
......@@ -547,12 +547,6 @@ nautilus_directory_monitor_add_internal (NautilusDirectory *directory,
g_assert (NAUTILUS_IS_DIRECTORY (directory));
/* If monitoring everything (file == NULL) then there must be
* a callback. If not, there must not be.
*/
g_assert (file != NULL || callback != NULL);
g_assert (file == NULL || callback == NULL);
/* Replace any current monitor for this client/file pair. */
remove_monitor (directory, file, client);
......@@ -569,7 +563,8 @@ nautilus_directory_monitor_add_internal (NautilusDirectory *directory,
/* Tell the new monitor-er about the current set of
* files, which may or may not be all of them.
*/
if (directory->details->files != NULL && file == NULL) {
if (directory->details->files != NULL && callback != NULL) {
g_assert (file == NULL);
(* callback) (directory,
directory->details->files,
callback_data);
......@@ -611,10 +606,10 @@ dequeue_pending_idle_callback (gpointer callback_data)
{
NautilusDirectory *directory;
GList *pending_file_info;
GList *p;
GList *p, *next;
NautilusFile *file;
GList *pending_files;
GList *changed_files;
GList *pending_files, *changed_files, *saw_again_files;
GnomeVFSFileInfo *file_info;
directory = NAUTILUS_DIRECTORY (callback_data);
......@@ -636,33 +631,64 @@ dequeue_pending_idle_callback (gpointer callback_data)
pending_files = NULL;
changed_files = NULL;
saw_again_files = NULL;
/* Build a list of NautilusFile objects. */
for (p = pending_file_info; p != NULL; p = p->next) {
file_info = p->data;
/* check if the file already exists */
file = nautilus_directory_find_file (directory,
((const GnomeVFSFileInfo *)p->data)->name);
file = nautilus_directory_find_file (directory, file_info->name);
if (file != NULL) {
/* file already exists, check if it changed */
if (nautilus_file_update (file, p->data)) {
file->details->unconfirmed = FALSE;
if (nautilus_file_update (file, file_info)) {
/* File changed, notify about the change. */
nautilus_file_ref (file);
changed_files = g_list_prepend (changed_files, file);
}
} else if (!update_file_info_in_list_if_needed (pending_files, p->data)) {
nautilus_file_ref (file);
saw_again_files = g_list_prepend (saw_again_files, file);
} else if (!update_file_info_in_list_if_needed (pending_files, file_info)) {
/* new file, create a nautilus file object and add it to the list */
file = nautilus_file_new (directory, p->data);
file = nautilus_file_new (directory, file_info);
pending_files = g_list_prepend (pending_files, file);
}
}
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);
/* If we are done loading, then we assume that any unconfirmed
* files are gone.
*/
if (directory->details->directory_loaded) {
for (p = directory->details->files; p != NULL; p = next) {
file = p->data;
next = p->next;
if (file->details->unconfirmed) {
file->details->is_gone = TRUE;
directory->details->files = g_list_remove_link
(directory->details->files, p);
g_list_free (p);
if (!nautilus_directory_is_file_list_monitored (directory)) {
nautilus_file_ref (file);
}
changed_files = g_list_prepend (changed_files, file);
}
}
}
/* Tell the objects that are monitoring about changed files. */
/* Tell the objects that are monitoring about changed files.
* Send out added signals too, for the reload case.
*/
nautilus_directory_emit_files_added (directory, saw_again_files);
nautilus_directory_emit_files_changed (directory, changed_files);
nautilus_file_list_free (saw_again_files);
nautilus_file_list_free (changed_files);
/* Remember them for later. */
/* Tell the objects that are monitoring about these new files. */
nautilus_directory_emit_files_added (directory, pending_files);
directory->details->files = g_list_concat
(directory->details->files, pending_files);
......@@ -692,13 +718,19 @@ directory_load_one (NautilusDirectory *directory,
}
static void
directory_load_done (NautilusDirectory *directory,
GnomeVFSResult result)
cancel_directory_load (NautilusDirectory *directory)
{
if (directory->details->directory_load_in_progress != NULL) {
gnome_vfs_async_cancel (directory->details->directory_load_in_progress);
directory->details->directory_load_in_progress = NULL;
}
}
static void
directory_load_done (NautilusDirectory *directory,
GnomeVFSResult result)
{
cancel_directory_load (directory);
directory->details->directory_loaded = TRUE;
/* Call the idle function right away. */
......@@ -768,6 +800,7 @@ nautilus_directory_monitor_remove_internal (NautilusDirectory *directory,
g_assert (client != NULL);
remove_monitor (directory, file, client);
state_changed (directory);
}
......@@ -877,8 +910,7 @@ nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
/* Add the new callback to the list. */
directory->details->call_when_ready_list = g_list_prepend
(directory->details->call_when_ready_list,
g_memdup (&callback,
sizeof (callback)));
g_memdup (&callback, sizeof (callback)));
state_changed (directory);
}
......@@ -1226,20 +1258,35 @@ nautilus_directory_is_file_list_monitored (NautilusDirectory *directory)
return directory->details->file_list_monitored;
}
static void
mark_all_files_unconfirmed (NautilusDirectory *directory)
{
GList *p;
NautilusFile *file;
for (p = directory->details->files; p != NULL; p = p->next) {
file = p->data;
file->details->unconfirmed = TRUE;
}
}
/* Start monitoring the file list if it isn't already. */
static void
start_monitoring_file_list (NautilusDirectory *directory)
{
if (directory->details->file_list_monitored) {
return;
if (!directory->details->file_list_monitored) {
g_assert (directory->details->directory_load_in_progress == NULL);
directory->details->file_list_monitored = TRUE;
nautilus_file_list_ref (directory->details->files);
}
g_assert (directory->details->directory_load_in_progress == NULL);
directory->details->file_list_monitored = TRUE;
nautilus_file_list_ref (directory->details->files);
if (directory->details->directory_loaded
|| directory->details->directory_load_in_progress != NULL) {
return;
}
mark_all_files_unconfirmed (directory);
g_assert (directory->details->uri->text != NULL);
directory->details->directory_load_list_last_handled
= GNOME_VFS_DIRECTORY_LIST_POSITION_NONE;
......@@ -1270,14 +1317,18 @@ nautilus_directory_stop_monitoring_file_list (NautilusDirectory *directory)
return;
}
if (directory->details->directory_load_in_progress != NULL) {
gnome_vfs_async_cancel (directory->details->directory_load_in_progress);
directory->details->directory_load_in_progress = NULL;
}
nautilus_file_list_unref (directory->details->files);
directory->details->file_list_monitored = FALSE;
cancel_directory_load (directory);
nautilus_file_list_unref (directory->details->files);
}
void
nautilus_directory_force_reload (NautilusDirectory *directory)
{
cancel_directory_load (directory);
directory->details->directory_loaded = FALSE;
state_changed (directory);
}
static gboolean
......
......@@ -129,6 +129,7 @@ void nautilus_directory_stop_monitoring_file_list (NautilusDirectory
void nautilus_metafile_read_cancel (NautilusDirectory *directory);
void nautilus_metafile_write_start (NautilusDirectory *directory);
void nautilus_async_destroying_file (NautilusFile *file);
void nautilus_directory_force_reload (NautilusDirectory *directory);
/* Calls shared between directory, file, and async. code. */
NautilusFile *nautilus_directory_find_file (NautilusDirectory *directory,
......
......@@ -616,6 +616,17 @@ call_files_changed_free_list (gpointer key, gpointer value, gpointer user_data)
g_list_free (value);
}
static void
call_files_changed_unref_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);
nautilus_file_list_free (value);
}
static void
call_get_file_info_free_list (gpointer key, gpointer value, gpointer user_data)
{
......@@ -690,6 +701,7 @@ nautilus_directory_notify_files_removed (GList *uris)
}
/* Mark it gone and prepare to send the changed signal. */
nautilus_file_ref (file);
nautilus_file_mark_gone (file);
hash_table_list_prepend (changed_lists,
file->details->directory,
......@@ -697,7 +709,7 @@ nautilus_directory_notify_files_removed (GList *uris)
}
/* Now send out the changed signals. */
g_hash_table_foreach (changed_lists, call_files_changed_free_list, NULL);
g_hash_table_foreach (changed_lists, call_files_changed_unref_free_list, NULL);
g_hash_table_destroy (changed_lists);
}
......@@ -753,6 +765,7 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
*/
if (new_directory != old_directory) {
/* Remove from old directory. */
g_message ("moved: editing files list");
files = &old_directory->details->files;
g_assert (g_list_find (*files, file) != NULL);
*files = g_list_remove (*files, file);
......@@ -866,11 +879,16 @@ nautilus_directory_file_monitor_add (NautilusDirectory *directory,
g_return_if_fail (client != NULL);
g_return_if_fail (callback != NULL);
if (force_reload) {
nautilus_directory_force_reload (directory);
}
nautilus_directory_monitor_add_internal
(directory, NULL,
client,
file_attributes, monitor_metadata,
callback, callback_data);
force_reload ? NULL : callback,
callback_data);
}
void
......
......@@ -28,6 +28,7 @@
struct NautilusFileDetails
{
NautilusDirectory *directory;
gboolean unconfirmed;
gboolean is_gone;
GnomeVFSFileInfo *info;
......
......@@ -198,7 +198,7 @@ nautilus_file_get (const char *uri)
} else {
file = nautilus_file_new (directory, file_info);
directory->details->files =
g_list_append (directory->details->files, file);
g_list_prepend (directory->details->files, file);
}
gnome_vfs_file_info_unref (file_info);
......@@ -211,17 +211,18 @@ static void
destroy (GtkObject *object)
{
NautilusFile *file;
GList **files;
file = NAUTILUS_FILE (object);
nautilus_async_destroying_file (file);
files = &file->details->directory->details->files;
if (file->details->is_gone) {
g_assert (g_list_find (file->details->directory->details->files, file) == NULL);
g_assert (g_list_find (*files, file) == NULL);
} else {
g_assert (g_list_find (file->details->directory->details->files, file) != NULL);
file->details->directory->details->files
= g_list_remove (file->details->directory->details->files, file);
g_assert (g_list_find (*files, file) != NULL);
*files = g_list_remove (*files, file);
}
nautilus_directory_unref (file->details->directory);
......@@ -1115,16 +1116,14 @@ nautilus_file_monitor_add (NautilusFile *file,
}
void
nautilus_file_monitor_remove (NautilusFile *file,
gconstpointer client)
nautilus_file_monitor_remove (NautilusFile *file,
gconstpointer client)
{
g_return_if_fail (NAUTILUS_IS_FILE (file));
g_return_if_fail (client != NULL);
nautilus_directory_monitor_remove_internal
(file->details->directory,
file,
client);
(file->details->directory, file, client);
}
......@@ -2034,22 +2033,29 @@ nautilus_file_delete (NautilusFile *file)
/* Mark the file gone. */
if (result == GNOME_VFS_OK || result == GNOME_VFS_ERROR_NOTFOUND) {
nautilus_file_ref (file);
nautilus_file_mark_gone (file);
nautilus_file_changed (file);
nautilus_file_unref (file);
}
}
void
nautilus_file_mark_gone (NautilusFile *file)
{
NautilusDirectory *directory;
GList **files;
file->details->is_gone = TRUE;
/* Let the directory know it's gone. */
files = &file->details->directory->details->files;
directory = file->details->directory;
files = &directory->details->files;
g_assert (g_list_find (*files, file) != NULL);
*files = g_list_remove (*files, file);
if (nautilus_directory_is_file_list_monitored (directory)) {
nautilus_file_unref (file);
}
}
/**
......@@ -2061,13 +2067,14 @@ nautilus_file_mark_gone (NautilusFile *file)
void
nautilus_file_changed (NautilusFile *file)
{
GList *changed_files;
GList fake_list;
g_return_if_fail (NAUTILUS_IS_FILE (file));
changed_files = g_list_prepend (NULL, file);
nautilus_directory_emit_files_changed (file->details->directory, changed_files);
g_list_free (changed_files);
fake_list.data = file;
fake_list.next = NULL;
fake_list.prev = NULL;
nautilus_directory_emit_files_changed (file->details->directory, &fake_list);
}
/**
......@@ -2085,9 +2092,7 @@ nautilus_file_emit_changed (NautilusFile *file)
g_assert (NAUTILUS_IS_FILE (file));
/* Send out a signal. */
gtk_signal_emit (GTK_OBJECT (file),
signals[CHANGED],
file);
gtk_signal_emit (GTK_OBJECT (file), signals[CHANGED], file);
}
/**
......
......@@ -2815,22 +2815,34 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
* @container: A NautilusIconContainer
* @data: Icon data.
*
* Add @image with caption @text and data @data to @container.
* Add icon to represent @data to container.
* Returns FALSE if there was already such an icon.
**/
void
gboolean
nautilus_icon_container_add (NautilusIconContainer *container,
NautilusIconData *data)
{
NautilusIconContainerDetails *details;
GList *p;
NautilusIcon *icon;
gboolean have_stored_position;
NautilusIconPosition position;
g_return_if_fail (NAUTILUS_IS_ICON_CONTAINER (container));
g_return_if_fail (data != NULL);
g_return_val_if_fail (NAUTILUS_IS_ICON_CONTAINER (container), FALSE);
g_return_val_if_fail (data != NULL, FALSE);
details = container->details;
/* FIXME: I guess we need to use an indexed data structure to
* avoid this loop.
*/
for (p = details->icons; p != NULL; p = p->next) {
icon = p->data;
if (icon->data == data) {
return FALSE;
}
}
have_stored_position = FALSE;
position.scale_x = 1.0;
position.scale_y = 1.0;
......@@ -2876,6 +2888,8 @@ nautilus_icon_container_add (NautilusIconContainer *container,
GTK_SIGNAL_FUNC (bounds_changed_callback), container);
request_idle (container);
return TRUE;
}
/**
......@@ -2895,6 +2909,9 @@ nautilus_icon_container_remove (NautilusIconContainer *container,
g_return_val_if_fail (NAUTILUS_IS_ICON_CONTAINER (container), FALSE);
g_return_val_if_fail (data != NULL, FALSE);
/* FIXME: I guess we need to use an indexed data structure to
* avoid this loop.
*/
for (p = container->details->icons; p != NULL; p = p->next) {
icon = p->data;
if (icon->data == data) {
......
......@@ -125,7 +125,7 @@ GtkWidget *nautilus_icon_container_new (void);
/* adding, removing, and managing icons */
void nautilus_icon_container_clear (NautilusIconContainer *view);
void nautilus_icon_container_add (NautilusIconContainer *view,
gboolean nautilus_icon_container_add (NautilusIconContainer *view,
NautilusIconData *data);
gboolean nautilus_icon_container_remove (NautilusIconContainer *view,
NautilusIconData *data);
......
......@@ -407,6 +407,29 @@ nautilus_list_initialize_class (NautilusListClass *klass)
object_class->destroy = nautilus_list_destroy;
}
static void
set_single_click_mode (NautilusList *list,
gboolean single_click_mode)
{
if (list->details->single_click_mode == single_click_mode) {
return;
}
list->details->single_click_mode = single_click_mode;
gtk_widget_queue_draw (GTK_WIDGET (list));
}
static void
update_single_click_mode_from_preferences (NautilusList *list)
{
int click_policy;
click_policy = nautilus_preferences_get_enum
(NAUTILUS_PREFERENCES_CLICK_POLICY,
NAUTILUS_CLICK_POLICY_SINGLE);
set_single_click_mode (list, click_policy == NAUTILUS_CLICK_POLICY_SINGLE);
}
/* Standard object initialization function */
static void
nautilus_list_initialize (NautilusList *list)
......@@ -440,9 +463,7 @@ nautilus_list_initialize (NautilusList *list)
list->details->last_typeselect_time = 0LL;
/* Initialize the single click mode from preferences */
list->details->single_click_mode =
(nautilus_preferences_get_enum (NAUTILUS_PREFERENCES_CLICK_POLICY,
NAUTILUS_CLICK_POLICY_SINGLE) == NAUTILUS_CLICK_POLICY_SINGLE);
update_single_click_mode_from_preferences (list);
/* Keep track of changes in clicking policy */
nautilus_preferences_add_enum_callback (NAUTILUS_PREFERENCES_CLICK_POLICY,
......@@ -2382,15 +2403,7 @@ nautilus_list_clear (GtkCList *clist)
static void
click_policy_changed_callback (gpointer user_data)
{
NautilusList *list;
g_assert (NAUTILUS_IS_LIST (user_data));
list = NAUTILUS_LIST (user_data);
list->details->single_click_mode =
(nautilus_preferences_get_enum (NAUTILUS_PREFERENCES_CLICK_POLICY,
NAUTILUS_CLICK_POLICY_SINGLE) == NAUTILUS_CLICK_POLICY_SINGLE);
update_single_click_mode_from_preferences (NAUTILUS_LIST (user_data));
}
......