summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog33
-rw-r--r--libnautilus-extensions/Makefile.am1
-rw-r--r--libnautilus-extensions/nautilus-directory-notify.h35
-rw-r--r--libnautilus-extensions/nautilus-directory-private.h113
-rw-r--r--libnautilus-extensions/nautilus-directory.c60
-rw-r--r--libnautilus-extensions/nautilus-file-changes-queue.c2
-rw-r--r--libnautilus-extensions/nautilus-file.c51
-rw-r--r--libnautilus-extensions/nautilus-link.c3
-rw-r--r--libnautilus-extensions/nautilus-volume-monitor.c2
-rw-r--r--libnautilus-private/Makefile.am1
-rw-r--r--libnautilus-private/nautilus-directory-notify.h35
-rw-r--r--libnautilus-private/nautilus-directory-private.h113
-rw-r--r--libnautilus-private/nautilus-directory.c60
-rw-r--r--libnautilus-private/nautilus-file-changes-queue.c2
-rw-r--r--libnautilus-private/nautilus-file.c51
-rw-r--r--libnautilus-private/nautilus-link.c3
-rw-r--r--libnautilus-private/nautilus-volume-monitor.c2
17 files changed, 359 insertions, 208 deletions
diff --git a/ChangeLog b/ChangeLog
index d34e90276..5fe7b2552 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2000-08-10 Darin Adler <darin@eazel.com>
+
+ * libnautilus-extensions/Makefile.am:
+ * libnautilus-extensions/nautilus-directory-notify.h:
+ * libnautilus-extensions/nautilus-directory-private.h:
+ * libnautilus-extensions/nautilus-file-changes-queue.c:
+ * libnautilus-extensions/nautilus-link.c:
+ * libnautilus-extensions/nautilus-volume-monitor.c:
+ Moved the notify calls to a separate header, since people were
+ using them as an excuse to peek at NautilusDirectory's privates.
+
+ * libnautilus-extensions/nautilus-directory.c:
+ (nautilus_directory_get_internal), (nautilus_directory_get),
+ (nautilus_directory_get_existing): Cleaned up API so that
+ internal code can get a directory without creating one.
+ (get_parent_directory_if_exists): Used new API to cut down
+ code a bit.
+ (nautilus_directory_notify_files_removed),
+ (nautilus_directory_notify_files_moved): Always create a
+ NautilusFile object. This results in a bit more work, but is
+ more compatible with the 1/2 done symbolic link change notify
+ work.
+
+ * libnautilus-extensions/nautilus-file.c:
+ (nautilus_file_get_internal): Don't create a new directory if
+ being called in the mode where we don't create a new file.
+ (update_link), (get_link_files),
+ (update_links_if_target), (nautilus_file_update_info),
+ (nautilus_file_mark_gone), (nautilus_file_emit_changed):
+ More work on notifying links about changes to the target file.
+ This isn't quite working and isn't required so I'll get back to it
+ later. At the moment it is not doing any harm.
+
2000-08-10 Maciej Stachowiak <mjs@eazel.com>
* docs/state-machines.txt: a start on some design work for sane
diff --git a/libnautilus-extensions/Makefile.am b/libnautilus-extensions/Makefile.am
index 8dee9c45a..753910af6 100644
--- a/libnautilus-extensions/Makefile.am
+++ b/libnautilus-extensions/Makefile.am
@@ -121,6 +121,7 @@ noinst_HEADERS = \
nautilus-default-file-icon.h \
nautilus-directory-background.h \
nautilus-directory-metafile.h \
+ nautilus-directory-notify.h \
nautilus-directory-private.h \
nautilus-directory.h \
nautilus-drag.h \
diff --git a/libnautilus-extensions/nautilus-directory-notify.h b/libnautilus-extensions/nautilus-directory-notify.h
new file mode 100644
index 000000000..ac15a1b8b
--- /dev/null
+++ b/libnautilus-extensions/nautilus-directory-notify.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-directory-notify.h: Nautilus directory notify calls.
+
+ Copyright (C) 2000 Eazel, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with this program; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Darin Adler <darin@eazel.com>
+*/
+
+#include <glib.h>
+
+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);
diff --git a/libnautilus-extensions/nautilus-directory-private.h b/libnautilus-extensions/nautilus-directory-private.h
index b4fd888e1..8f1f5d679 100644
--- a/libnautilus-extensions/nautilus-directory-private.h
+++ b/libnautilus-extensions/nautilus-directory-private.h
@@ -95,71 +95,62 @@ struct NautilusDirectoryDetails
GList *file_operations_in_progress; /* list of FileOperation * */
};
-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);
-
/* async. interface */
-void nautilus_directory_async_state_changed (NautilusDirectory *directory);
-void nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
- NautilusFile *file,
- GList *file_attributes,
- gboolean monitor_metadata,
- NautilusDirectoryCallback directory_callback,
- NautilusFileCallback file_callback,
- gpointer callback_data);
-gboolean nautilus_directory_check_if_ready_internal (NautilusDirectory *directory,
- NautilusFile *file,
- GList *file_attributes);
-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 *attributes,
- gboolean monitor_metadata,
- 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_directory_cancel (NautilusDirectory *directory);
-void nautilus_metafile_write_start (NautilusDirectory *directory);
-void nautilus_async_destroying_file (NautilusFile *file);
-void nautilus_directory_force_reload (NautilusDirectory *directory);
+void nautilus_directory_async_state_changed (NautilusDirectory *directory);
+void nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
+ NautilusFile *file,
+ GList *file_attributes,
+ gboolean monitor_metadata,
+ NautilusDirectoryCallback directory_callback,
+ NautilusFileCallback file_callback,
+ gpointer callback_data);
+gboolean nautilus_directory_check_if_ready_internal (NautilusDirectory *directory,
+ NautilusFile *file,
+ GList *file_attributes);
+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 *attributes,
+ gboolean monitor_metadata,
+ 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_directory_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,
- const char *file_name);
-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);
-void nautilus_directory_emit_done_loading (NautilusDirectory *directory);
-
+NautilusFile * nautilus_directory_find_file (NautilusDirectory *directory,
+ const char *file_name);
+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);
+void nautilus_directory_emit_done_loading (NautilusDirectory *directory);
+NautilusDirectory *nautilus_directory_get_internal (const char *uri,
+ gboolean create);
/* 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);
diff --git a/libnautilus-extensions/nautilus-directory.c b/libnautilus-extensions/nautilus-directory.c
index 5e2b5213e..d600be4b0 100644
--- a/libnautilus-extensions/nautilus-directory.c
+++ b/libnautilus-extensions/nautilus-directory.c
@@ -26,6 +26,7 @@
#include "nautilus-directory-private.h"
#include "nautilus-directory-metafile.h"
+#include "nautilus-directory-notify.h"
#include "nautilus-file-private.h"
#include "nautilus-file-utilities.h"
#include "nautilus-glib-extensions.h"
@@ -285,7 +286,7 @@ is_canonical_uri (const char *uri)
* If two windows are viewing the same uri, the directory object is shared.
*/
NautilusDirectory *
-nautilus_directory_get (const char *uri)
+nautilus_directory_get_internal (const char *uri, gboolean create)
{
char *canonical_uri;
NautilusDirectory *directory;
@@ -309,7 +310,7 @@ nautilus_directory_get (const char *uri)
canonical_uri);
if (directory != NULL) {
nautilus_directory_ref (directory);
- } else {
+ } else if (create) {
/* Create a new directory object instead. */
directory = nautilus_directory_new (canonical_uri);
if (directory == NULL) {
@@ -329,6 +330,18 @@ nautilus_directory_get (const char *uri)
return directory;
}
+NautilusDirectory *
+nautilus_directory_get (const char *uri)
+{
+ return nautilus_directory_get_internal (uri, TRUE);
+}
+
+static NautilusDirectory *
+nautilus_directory_get_existing (const char *uri)
+{
+ return nautilus_directory_get_internal (uri, FALSE);
+}
+
char *
nautilus_directory_get_uri (NautilusDirectory *directory)
{
@@ -631,47 +644,16 @@ get_parent_directory (const char *uri)
static NautilusDirectory *
get_parent_directory_if_exists (const char *uri)
{
- char *directory_uri, *canonical_uri;
+ char *directory_uri;
NautilusDirectory *directory;
/* Make text version of directory URI. */
directory_uri = uri_get_directory_part (uri);
- canonical_uri = make_uri_canonical (directory_uri);
+ directory = nautilus_directory_get_existing (directory_uri);
g_free (directory_uri);
-
- /* Get directory from hash table. */
- if (directories == NULL) {
- directory = NULL;
- } else {
- g_assert (is_canonical_uri (canonical_uri));
- directory = g_hash_table_lookup (directories,
- canonical_uri);
- }
- g_free (canonical_uri);
return directory;
}
-static NautilusFile *
-get_file_if_exists (const char *uri)
-{
- NautilusDirectory *directory;
- char *name;
- NautilusFile *file;
-
- /* Get parent directory. */
- directory = get_parent_directory_if_exists (uri);
- if (directory == NULL) {
- return NULL;
- }
-
- /* Find the file. */
- name = uri_get_basename (uri);
- file = nautilus_directory_find_file (directory, name);
- g_free (name);
-
- return file;
-}
-
static void
hash_table_list_prepend (GHashTable *table, gconstpointer key, gpointer data)
{
@@ -785,13 +767,12 @@ nautilus_directory_notify_files_removed (GList *uris)
uri = (const char *) p->data;
/* Find the file. */
- file = get_file_if_exists (uri);
+ file = nautilus_file_get (uri);
if (file == NULL) {
continue;
}
/* 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,
@@ -825,7 +806,7 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
pair = p->data;
/* Move an existing file. */
- file = get_file_if_exists (pair->from_uri);
+ file = nautilus_file_get (pair->from_uri);
if (file == NULL) {
/* Handle this as it it was a new file. */
new_files_list = g_list_prepend (new_files_list,
@@ -883,6 +864,9 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
/* Done with the old directory. */
nautilus_directory_unref (old_directory);
+
+ /* Unref each file once to balance out nautilus_file_get. */
+ unref_list = g_list_prepend (unref_list, file);
}
}
diff --git a/libnautilus-extensions/nautilus-file-changes-queue.c b/libnautilus-extensions/nautilus-file-changes-queue.c
index 37bcd97d2..19c7df72e 100644
--- a/libnautilus-extensions/nautilus-file-changes-queue.c
+++ b/libnautilus-extensions/nautilus-file-changes-queue.c
@@ -25,7 +25,7 @@
#include "nautilus-file-changes-queue.h"
#include "nautilus-glib-extensions.h"
-#include "nautilus-directory-private.h"
+#include "nautilus-directory-notify.h"
#ifdef G_THREADS_ENABLED
#define MUTEX_LOCK(a) if ((a) != NULL) g_mutex_lock (a)
diff --git a/libnautilus-extensions/nautilus-file.c b/libnautilus-extensions/nautilus-file.c
index 0261a1942..0794a5073 100644
--- a/libnautilus-extensions/nautilus-file.c
+++ b/libnautilus-extensions/nautilus-file.c
@@ -290,7 +290,7 @@ nautilus_file_get_internal (const char *uri, gboolean create)
}
/* Get object that represents the directory. */
- directory = nautilus_directory_get (directory_uri);
+ directory = nautilus_directory_get_internal (directory_uri, create);
g_free (directory_uri);
if (directory == NULL) {
gnome_vfs_uri_unref (vfs_uri);
@@ -1013,6 +1013,42 @@ nautilus_file_should_get_top_left_text (NautilusFile *file)
return nautilus_file_is_local (file);
}
+static void
+update_link (NautilusFile *link_file, NautilusFile *target_file)
+{
+ g_assert (NAUTILUS_IS_FILE (link_file));
+ g_assert (NAUTILUS_IS_FILE (target_file));
+ g_assert (!info_missing (link_file, GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME));
+}
+
+static GList *
+get_link_files (NautilusFile *target_file)
+{
+ char *uri;
+ GList *link_files;
+
+ if (symbolic_links == NULL) {
+ link_files = NULL;
+ } else {
+ uri = nautilus_file_get_uri (target_file);
+ link_files = g_hash_table_lookup (symbolic_links, uri);
+ g_free (uri);
+ }
+ return nautilus_file_list_copy (link_files);
+}
+
+static void
+update_links_if_target (NautilusFile *target_file)
+{
+ GList *link_files, *p;
+
+ link_files = get_link_files (target_file);
+ for (p = link_files; p != NULL; p = p->next) {
+ update_link (NAUTILUS_FILE (p->data), target_file);
+ }
+ nautilus_file_list_free (link_files);
+}
+
gboolean
nautilus_file_update_info (NautilusFile *file, GnomeVFSFileInfo *info)
{
@@ -1043,6 +1079,8 @@ nautilus_file_update_info (NautilusFile *file, GnomeVFSFileInfo *info)
add_to_link_hash_table (file);
+ update_links_if_target (file);
+
return TRUE;
}
@@ -3593,6 +3631,8 @@ nautilus_file_mark_gone (NautilusFile *file)
GList **files;
file->details->is_gone = TRUE;
+
+ update_links_if_target (file);
/* Drop away all the old file information, but keep the name. */
/* FIXME: Maybe we can get rid of the name too eventually, but
@@ -3657,10 +3697,19 @@ nautilus_file_changed (NautilusFile *file)
void
nautilus_file_emit_changed (NautilusFile *file)
{
+ GList *link_files, *p;
+
g_assert (NAUTILUS_IS_FILE (file));
/* Send out a signal. */
gtk_signal_emit (GTK_OBJECT (file), signals[CHANGED], file);
+
+ /* Tell link files pointing to this object about the change. */
+ link_files = get_link_files (file);
+ for (p = link_files; p != NULL; p = p->next) {
+ nautilus_file_changed (NAUTILUS_FILE (p->data));
+ }
+ nautilus_file_list_free (link_files);
}
/**
diff --git a/libnautilus-extensions/nautilus-link.c b/libnautilus-extensions/nautilus-link.c
index 69ade4c64..a596cf28f 100644
--- a/libnautilus-extensions/nautilus-link.c
+++ b/libnautilus-extensions/nautilus-link.c
@@ -25,8 +25,7 @@
#include <config.h>
#include "nautilus-link.h"
-/* FIXME: Bad to include the private file here, but necessary for now. */
-#include "nautilus-directory-private.h"
+#include "nautilus-directory-notify.h"
#include "nautilus-file-utilities.h"
#include "nautilus-file.h"
#include "nautilus-global-preferences.h"
diff --git a/libnautilus-extensions/nautilus-volume-monitor.c b/libnautilus-extensions/nautilus-volume-monitor.c
index 52c53194d..2b7361884 100644
--- a/libnautilus-extensions/nautilus-volume-monitor.c
+++ b/libnautilus-extensions/nautilus-volume-monitor.c
@@ -33,7 +33,7 @@
#include <libgnomevfs/gnome-vfs.h>
#include <mntent.h>
#include <libnautilus-extensions/nautilus-cdrom-extensions.h>
-#include <libnautilus-extensions/nautilus-directory-private.h>
+#include <libnautilus-extensions/nautilus-directory-notify.h>
#include <libnautilus-extensions/nautilus-file-utilities.h>
#include <libnautilus-extensions/nautilus-gtk-extensions.h>
#include <libnautilus-extensions/nautilus-gtk-macros.h>
diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am
index 8dee9c45a..753910af6 100644
--- a/libnautilus-private/Makefile.am
+++ b/libnautilus-private/Makefile.am
@@ -121,6 +121,7 @@ noinst_HEADERS = \
nautilus-default-file-icon.h \
nautilus-directory-background.h \
nautilus-directory-metafile.h \
+ nautilus-directory-notify.h \
nautilus-directory-private.h \
nautilus-directory.h \
nautilus-drag.h \
diff --git a/libnautilus-private/nautilus-directory-notify.h b/libnautilus-private/nautilus-directory-notify.h
new file mode 100644
index 000000000..ac15a1b8b
--- /dev/null
+++ b/libnautilus-private/nautilus-directory-notify.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-directory-notify.h: Nautilus directory notify calls.
+
+ Copyright (C) 2000 Eazel, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with this program; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Darin Adler <darin@eazel.com>
+*/
+
+#include <glib.h>
+
+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);
diff --git a/libnautilus-private/nautilus-directory-private.h b/libnautilus-private/nautilus-directory-private.h
index b4fd888e1..8f1f5d679 100644
--- a/libnautilus-private/nautilus-directory-private.h
+++ b/libnautilus-private/nautilus-directory-private.h
@@ -95,71 +95,62 @@ struct NautilusDirectoryDetails
GList *file_operations_in_progress; /* list of FileOperation * */
};
-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);
-
/* async. interface */
-void nautilus_directory_async_state_changed (NautilusDirectory *directory);
-void nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
- NautilusFile *file,
- GList *file_attributes,
- gboolean monitor_metadata,
- NautilusDirectoryCallback directory_callback,
- NautilusFileCallback file_callback,
- gpointer callback_data);
-gboolean nautilus_directory_check_if_ready_internal (NautilusDirectory *directory,
- NautilusFile *file,
- GList *file_attributes);
-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 *attributes,
- gboolean monitor_metadata,
- 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_directory_cancel (NautilusDirectory *directory);
-void nautilus_metafile_write_start (NautilusDirectory *directory);
-void nautilus_async_destroying_file (NautilusFile *file);
-void nautilus_directory_force_reload (NautilusDirectory *directory);
+void nautilus_directory_async_state_changed (NautilusDirectory *directory);
+void nautilus_directory_call_when_ready_internal (NautilusDirectory *directory,
+ NautilusFile *file,
+ GList *file_attributes,
+ gboolean monitor_metadata,
+ NautilusDirectoryCallback directory_callback,
+ NautilusFileCallback file_callback,
+ gpointer callback_data);
+gboolean nautilus_directory_check_if_ready_internal (NautilusDirectory *directory,
+ NautilusFile *file,
+ GList *file_attributes);
+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 *attributes,
+ gboolean monitor_metadata,
+ 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_directory_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,
- const char *file_name);
-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);
-void nautilus_directory_emit_done_loading (NautilusDirectory *directory);
-
+NautilusFile * nautilus_directory_find_file (NautilusDirectory *directory,
+ const char *file_name);
+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);
+void nautilus_directory_emit_done_loading (NautilusDirectory *directory);
+NautilusDirectory *nautilus_directory_get_internal (const char *uri,
+ gboolean create);
/* 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);
diff --git a/libnautilus-private/nautilus-directory.c b/libnautilus-private/nautilus-directory.c
index 5e2b5213e..d600be4b0 100644
--- a/libnautilus-private/nautilus-directory.c
+++ b/libnautilus-private/nautilus-directory.c
@@ -26,6 +26,7 @@
#include "nautilus-directory-private.h"
#include "nautilus-directory-metafile.h"
+#include "nautilus-directory-notify.h"
#include "nautilus-file-private.h"
#include "nautilus-file-utilities.h"
#include "nautilus-glib-extensions.h"
@@ -285,7 +286,7 @@ is_canonical_uri (const char *uri)
* If two windows are viewing the same uri, the directory object is shared.
*/
NautilusDirectory *
-nautilus_directory_get (const char *uri)
+nautilus_directory_get_internal (const char *uri, gboolean create)
{
char *canonical_uri;
NautilusDirectory *directory;
@@ -309,7 +310,7 @@ nautilus_directory_get (const char *uri)
canonical_uri);
if (directory != NULL) {
nautilus_directory_ref (directory);
- } else {
+ } else if (create) {
/* Create a new directory object instead. */
directory = nautilus_directory_new (canonical_uri);
if (directory == NULL) {
@@ -329,6 +330,18 @@ nautilus_directory_get (const char *uri)
return directory;
}
+NautilusDirectory *
+nautilus_directory_get (const char *uri)
+{
+ return nautilus_directory_get_internal (uri, TRUE);
+}
+
+static NautilusDirectory *
+nautilus_directory_get_existing (const char *uri)
+{
+ return nautilus_directory_get_internal (uri, FALSE);
+}
+
char *
nautilus_directory_get_uri (NautilusDirectory *directory)
{
@@ -631,47 +644,16 @@ get_parent_directory (const char *uri)
static NautilusDirectory *
get_parent_directory_if_exists (const char *uri)
{
- char *directory_uri, *canonical_uri;
+ char *directory_uri;
NautilusDirectory *directory;
/* Make text version of directory URI. */
directory_uri = uri_get_directory_part (uri);
- canonical_uri = make_uri_canonical (directory_uri);
+ directory = nautilus_directory_get_existing (directory_uri);
g_free (directory_uri);
-
- /* Get directory from hash table. */
- if (directories == NULL) {
- directory = NULL;
- } else {
- g_assert (is_canonical_uri (canonical_uri));
- directory = g_hash_table_lookup (directories,
- canonical_uri);
- }
- g_free (canonical_uri);
return directory;
}
-static NautilusFile *
-get_file_if_exists (const char *uri)
-{
- NautilusDirectory *directory;
- char *name;
- NautilusFile *file;
-
- /* Get parent directory. */
- directory = get_parent_directory_if_exists (uri);
- if (directory == NULL) {
- return NULL;
- }
-
- /* Find the file. */
- name = uri_get_basename (uri);
- file = nautilus_directory_find_file (directory, name);
- g_free (name);
-
- return file;
-}
-
static void
hash_table_list_prepend (GHashTable *table, gconstpointer key, gpointer data)
{
@@ -785,13 +767,12 @@ nautilus_directory_notify_files_removed (GList *uris)
uri = (const char *) p->data;
/* Find the file. */
- file = get_file_if_exists (uri);
+ file = nautilus_file_get (uri);
if (file == NULL) {
continue;
}
/* 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,
@@ -825,7 +806,7 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
pair = p->data;
/* Move an existing file. */
- file = get_file_if_exists (pair->from_uri);
+ file = nautilus_file_get (pair->from_uri);
if (file == NULL) {
/* Handle this as it it was a new file. */
new_files_list = g_list_prepend (new_files_list,
@@ -883,6 +864,9 @@ nautilus_directory_notify_files_moved (GList *uri_pairs)
/* Done with the old directory. */
nautilus_directory_unref (old_directory);
+
+ /* Unref each file once to balance out nautilus_file_get. */
+ unref_list = g_list_prepend (unref_list, file);
}
}
diff --git a/libnautilus-private/nautilus-file-changes-queue.c b/libnautilus-private/nautilus-file-changes-queue.c
index 37bcd97d2..19c7df72e 100644
--- a/libnautilus-private/nautilus-file-changes-queue.c
+++ b/libnautilus-private/nautilus-file-changes-queue.c
@@ -25,7 +25,7 @@
#include "nautilus-file-changes-queue.h"
#include "nautilus-glib-extensions.h"
-#include "nautilus-directory-private.h"
+#include "nautilus-directory-notify.h"
#ifdef G_THREADS_ENABLED
#define MUTEX_LOCK(a) if ((a) != NULL) g_mutex_lock (a)
diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c
index 0261a1942..0794a5073 100644
--- a/libnautilus-private/nautilus-file.c
+++ b/libnautilus-private/nautilus-file.c
@@ -290,7 +290,7 @@ nautilus_file_get_internal (const char *uri, gboolean create)
}
/* Get object that represents the directory. */
- directory = nautilus_directory_get (directory_uri);
+ directory = nautilus_directory_get_internal (directory_uri, create);
g_free (directory_uri);
if (directory == NULL) {
gnome_vfs_uri_unref (vfs_uri);
@@ -1013,6 +1013,42 @@ nautilus_file_should_get_top_left_text (NautilusFile *file)
return nautilus_file_is_local (file);
}
+static void
+update_link (NautilusFile *link_file, NautilusFile *target_file)
+{
+ g_assert (NAUTILUS_IS_FILE (link_file));
+ g_assert (NAUTILUS_IS_FILE (target_file));
+ g_assert (!info_missing (link_file, GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME));
+}
+
+static GList *
+get_link_files (NautilusFile *target_file)
+{
+ char *uri;
+ GList *link_files;
+
+ if (symbolic_links == NULL) {
+ link_files = NULL;
+ } else {
+ uri = nautilus_file_get_uri (target_file);
+ link_files = g_hash_table_lookup (symbolic_links, uri);
+ g_free (uri);
+ }
+ return nautilus_file_list_copy (link_files);
+}
+
+static void
+update_links_if_target (NautilusFile *target_file)
+{
+ GList *link_files, *p;
+
+ link_files = get_link_files (target_file);
+ for (p = link_files; p != NULL; p = p->next) {
+ update_link (NAUTILUS_FILE (p->data), target_file);
+ }
+ nautilus_file_list_free (link_files);
+}
+
gboolean
nautilus_file_update_info (NautilusFile *file, GnomeVFSFileInfo *info)
{
@@ -1043,6 +1079,8 @@ nautilus_file_update_info (NautilusFile *file, GnomeVFSFileInfo *info)
add_to_link_hash_table (file);
+ update_links_if_target (file);
+
return TRUE;
}
@@ -3593,6 +3631,8 @@ nautilus_file_mark_gone (NautilusFile *file)
GList **files;
file->details->is_gone = TRUE;
+
+ update_links_if_target (file);
/* Drop away all the old file information, but keep the name. */
/* FIXME: Maybe we can get rid of the name too eventually, but
@@ -3657,10 +3697,19 @@ nautilus_file_changed (NautilusFile *file)
void
nautilus_file_emit_changed (NautilusFile *file)
{
+ GList *link_files, *p;
+
g_assert (NAUTILUS_IS_FILE (file));
/* Send out a signal. */
gtk_signal_emit (GTK_OBJECT (file), signals[CHANGED], file);
+
+ /* Tell link files pointing to this object about the change. */
+ link_files = get_link_files (file);
+ for (p = link_files; p != NULL; p = p->next) {
+ nautilus_file_changed (NAUTILUS_FILE (p->data));
+ }
+ nautilus_file_list_free (link_files);
}
/**
diff --git a/libnautilus-private/nautilus-link.c b/libnautilus-private/nautilus-link.c
index 69ade4c64..a596cf28f 100644
--- a/libnautilus-private/nautilus-link.c
+++ b/libnautilus-private/nautilus-link.c
@@ -25,8 +25,7 @@
#include <config.h>
#include "nautilus-link.h"
-/* FIXME: Bad to include the private file here, but necessary for now. */
-#include "nautilus-directory-private.h"
+#include "nautilus-directory-notify.h"
#include "nautilus-file-utilities.h"
#include "nautilus-file.h"
#include "nautilus-global-preferences.h"
diff --git a/libnautilus-private/nautilus-volume-monitor.c b/libnautilus-private/nautilus-volume-monitor.c
index 52c53194d..2b7361884 100644
--- a/libnautilus-private/nautilus-volume-monitor.c
+++ b/libnautilus-private/nautilus-volume-monitor.c
@@ -33,7 +33,7 @@
#include <libgnomevfs/gnome-vfs.h>
#include <mntent.h>
#include <libnautilus-extensions/nautilus-cdrom-extensions.h>
-#include <libnautilus-extensions/nautilus-directory-private.h>
+#include <libnautilus-extensions/nautilus-directory-notify.h>
#include <libnautilus-extensions/nautilus-file-utilities.h>
#include <libnautilus-extensions/nautilus-gtk-extensions.h>
#include <libnautilus-extensions/nautilus-gtk-macros.h>