summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarin Adler <darin@src.gnome.org>2000-01-14 19:36:38 +0000
committerDarin Adler <darin@src.gnome.org>2000-01-14 19:36:38 +0000
commit4a8e99789c03a92c14b3b12f2cac1f2bd97e2a1b (patch)
treebb6a35123b46bbc4c08b9a1b25535927b9f67bd4
parent38e733fe7d7ebfc8e182bc6d9d48258567819f73 (diff)
downloadnautilus-4a8e99789c03a92c14b3b12f2cac1f2bd97e2a1b.tar.gz
Added code to load and save metadata.
-rw-r--r--ChangeLog-2000041441
-rw-r--r--libnautilus-extensions/Makefile.am15
-rw-r--r--libnautilus-extensions/nautilus-background.c26
-rw-r--r--libnautilus-extensions/nautilus-directory.c466
-rw-r--r--libnautilus-extensions/nautilus-directory.h166
-rw-r--r--libnautilus-extensions/nautilus-lib-self-check-functions.c3
-rw-r--r--libnautilus-extensions/nautilus-lib-self-check-functions.h15
-rw-r--r--libnautilus-extensions/nautilus-self-checks.h6
-rw-r--r--libnautilus-private/Makefile.am15
-rw-r--r--libnautilus-private/nautilus-background.c26
-rw-r--r--libnautilus-private/nautilus-directory.c466
-rw-r--r--libnautilus-private/nautilus-directory.h166
-rw-r--r--libnautilus-private/nautilus-lib-self-check-functions.c3
-rw-r--r--libnautilus-private/nautilus-lib-self-check-functions.h15
-rw-r--r--libnautilus-private/nautilus-self-checks.h6
-rw-r--r--libnautilus/Makefile.am15
-rw-r--r--libnautilus/nautilus-background.c26
-rw-r--r--libnautilus/nautilus-directory.c466
-rw-r--r--libnautilus/nautilus-directory.h166
-rw-r--r--libnautilus/nautilus-lib-self-check-functions.c3
-rw-r--r--libnautilus/nautilus-lib-self-check-functions.h15
-rw-r--r--libnautilus/nautilus-self-checks.h6
-rw-r--r--src/file-manager/Makefile.am4
-rw-r--r--src/file-manager/fm-directory-protected.h47
-rw-r--r--src/file-manager/fm-directory.c196
-rw-r--r--src/file-manager/fm-directory.h163
-rw-r--r--src/file-manager/fm-vfs-directory.c153
-rw-r--r--src/file-manager/fm-vfs-directory.h64
-rw-r--r--src/nautilus-information-panel.c80
-rw-r--r--src/nautilus-information-panel.h7
-rw-r--r--src/nautilus-self-check-functions.c4
-rw-r--r--src/nautilus-self-check-functions.h11
-rw-r--r--src/nautilus-sidebar.c80
-rw-r--r--src/nautilus-sidebar.h7
-rw-r--r--src/ntl-index-panel.c80
-rw-r--r--src/ntl-index-panel.h7
36 files changed, 2256 insertions, 779 deletions
diff --git a/ChangeLog-20000414 b/ChangeLog-20000414
index faa2a99ba..fb8ae00f8 100644
--- a/ChangeLog-20000414
+++ b/ChangeLog-20000414
@@ -1,3 +1,44 @@
+2000-01-14 Darin Adler <darin@eazel.com>
+
+ First cut at some actual saving of metadata.
+ Neither the interface nor the implementation is great yet.
+ But it's a start.
+
+ * libnautilus/Makefile.am:
+ libnautilus/nautilus-directory.h:
+ libnautilus/nautilus-directory.c:
+ libnautilus/nautilus-lib-self-check-functions.h:
+ libnautilus/nautilus-lib-self-check-functions.c:
+ src/file-manager/Makefile.am:
+ src/file-manager/fm-directory-protected.h:
+ src/file-manager/fm-directory.h:
+ src/file-manager/fm-directory.c:
+ src/file-manager/fm-vfs-directory.h:
+ src/file-manager/fm-vfs-directory.c:
+ Moved the old FMDirectory class into the library and named it
+ NautilusDirectory. Added functions for reading and writing
+ metadata.
+
+ * src/ntl-index-panel.c: Added the code to save the index panel's
+ background color in metadata.
+
+ * libnautilus/Makefile.am: Added gnome-vfs and gnome-xml,
+ since the new code uses them.
+
+ * libnautilus/nautilus-self-checks.h:
+ libnautilus/nautilus-lib-self-check-functions.h:
+ libnautilus/nautilus-lib-self-check-functions.c:
+ src/nautilus-self-check-functions.h:
+ src/nautilus-self-check-functions.c:
+ Added macros to the self-check framework so the list of self check
+ functions appears in exactly one place for each directory/module.
+
+ * src/ntl-index-panel.h: src/ntl-index-panel.c: Moved the fields
+ of the index panel inside a private details structure so they can
+ change without affecting clients.
+
+ * libnautilus/nautilus-background.c: Just some reformatting.
+
2000-01-13 John Sullivan <sullivan@eazel.com>
More work pushing code from FMDirectoryView into subclasses.
diff --git a/libnautilus-extensions/Makefile.am b/libnautilus-extensions/Makefile.am
index 2a7912af8..46d1de41d 100644
--- a/libnautilus-extensions/Makefile.am
+++ b/libnautilus-extensions/Makefile.am
@@ -4,8 +4,17 @@ INCLUDES=-I$(top_srcdir) -I$(top_builddir) \
$(GNOME_CFLAGS) \
$(GNORBA_CFLAGS) \
$(GDK_PIXBUF_CFLAGS) \
+ $(VFS_CFLAGS) \
+ $(XML_CFLAGS) \
$(WERROR)
+libnautilus_la_LDFLAGS=\
+ $(GNOME_LIBS) \
+ $(GNORBA_LIBS) \
+ $(GDK_PIXBUF_LIBS) -lcanvas_pixbuf \
+ $(VFS_LIBS) \
+ $(XML_LIBS)
+
nautilus_idl_sources=nautilus-stubs.c nautilus-skels.c nautilus.h nautilus-common.c
fsextension_idl_sources=fsextension-stubs.c fsextension-skels.c fsextension-common.c fsextension.h
BUILT_SOURCES=$(nautilus_idl_sources)
@@ -23,6 +32,7 @@ libnautilusinclude_HEADERS= \
gtkscrollframe.h \
nautilus.h \
nautilus-background.h \
+ nautilus-directory.h \
nautilus-file-utilities.h \
nautilus-gtk-extensions.h \
nautilus-lib-self-check-functions.h \
@@ -41,6 +51,7 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \
gtkscrollframe.c \
nautilus-background.c \
nautilus-background-canvas-group.c \
+ nautilus-directory.c \
nautilus-file-utilities.c \
nautilus-gtk-extensions.c \
nautilus-lib-self-check-functions.c \
@@ -51,10 +62,6 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \
ntl-view-frame.c \
$(fsextension_idl_sources)
-libnautilus_la_LDFLAGS=$(GNOME_LIBS) \
- $(GNORBA_LIBS) \
- $(GDK_PIXBUF_LIBS) -lcanvas_pixbuf
-
$(nautilus_idl_sources): nautilus_idl_stamp
$(fsextension_idl_sources): fsextension_idl_stamp
diff --git a/libnautilus-extensions/nautilus-background.c b/libnautilus-extensions/nautilus-background.c
index 057f265f6..d8090881f 100644
--- a/libnautilus-extensions/nautilus-background.c
+++ b/libnautilus-extensions/nautilus-background.c
@@ -185,7 +185,8 @@ nautilus_gtk_style_get_default_class (void)
return default_class;
}
-static void nautilus_gdk_window_update_sizes (GdkWindow *window, int *width, int *height)
+static void
+nautilus_gdk_window_update_sizes (GdkWindow *window, int *width, int *height)
{
g_return_if_fail (window != NULL);
g_return_if_fail (width != NULL);
@@ -199,17 +200,18 @@ static void nautilus_gdk_window_update_sizes (GdkWindow *window, int *width, int
gdk_window_get_size (window, NULL, height);
}
-static void nautilus_background_draw_flat_box (GtkStyle *style,
- GdkWindow *window,
- GtkStateType state_type,
- GtkShadowType shadow_type,
- GdkRectangle *area,
- GtkWidget *widget,
- gchar *detail,
- gint x,
- gint y,
- gint width,
- gint height)
+static void
+nautilus_background_draw_flat_box (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char *detail,
+ int x,
+ int y,
+ int width,
+ int height)
{
gboolean call_parent;
NautilusBackground *background;
diff --git a/libnautilus-extensions/nautilus-directory.c b/libnautilus-extensions/nautilus-directory.c
new file mode 100644
index 000000000..86b3c00f9
--- /dev/null
+++ b/libnautilus-extensions/nautilus-directory.c
@@ -0,0 +1,466 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-directory.c: Mautilus directory model.
+
+ Copyright (C) 1999, 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>
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "nautilus-directory.h"
+
+#include <stdlib.h>
+
+#include <gtk/gtkmain.h>
+
+#include <libgnomevfs/gnome-vfs-types.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libgnomevfs/gnome-vfs-async-ops.h>
+
+#include <gnome-xml/parser.h>
+#include <gnome-xml/tree.h>
+#include <gnome-xml/xmlmemory.h>
+
+#include "nautilus-gtk-macros.h"
+#include "nautilus-lib-self-check-functions.h"
+#include "nautilus-string.h"
+
+#define METAFILE_NAME ".nautilus.xml"
+#define METAFILE_XML_VERSION "1.0"
+
+static void nautilus_directory_initialize_class (gpointer klass);
+static void nautilus_directory_initialize (gpointer object, gpointer klass);
+static void nautilus_directory_finalize (GtkObject *object);
+
+static NautilusDirectory *nautilus_directory_new (const char* uri);
+
+static void nautilus_directory_read_metafile (NautilusDirectory *directory);
+static void nautilus_directory_write_metafile (NautilusDirectory *directory);
+static void nautilus_directory_request_write_metafile (NautilusDirectory *directory);
+static void nautilus_directory_remove_write_metafile_idle (NautilusDirectory *directory);
+
+NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusDirectory, nautilus_directory, GTK_TYPE_OBJECT)
+
+static GtkObjectClass *parent_class;
+
+struct _NautilusDirectoryDetails
+{
+ char *uri_text;
+ GnomeVFSURI *uri;
+
+ GnomeVFSURI *metafile_uri;
+ xmlDoc *metafile_tree;
+ int write_metafile_idle_id;
+
+ NautilusFileList *files;
+};
+
+struct _NautilusFile
+{
+};
+
+static GHashTable* directory_objects;
+
+static void
+nautilus_directory_initialize_class (gpointer klass)
+{
+ GtkObjectClass *object_class;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ parent_class = gtk_type_class (GTK_TYPE_OBJECT);
+
+ object_class->finalize = nautilus_directory_finalize;
+}
+
+static void
+nautilus_directory_initialize (gpointer object, gpointer klass)
+{
+ NautilusDirectory *directory;
+
+ directory = NAUTILUS_DIRECTORY(object);
+
+ directory->details = g_new0 (NautilusDirectoryDetails, 1);
+}
+
+static void
+nautilus_directory_finalize (GtkObject *object)
+{
+ NautilusDirectory *directory;
+
+ directory = NAUTILUS_DIRECTORY (object);
+
+ g_hash_table_remove (directory_objects, directory->details->uri_text);
+
+ g_free (directory->details->uri_text);
+ if (directory->details->uri)
+ gnome_vfs_uri_unref (directory->details->uri);
+ if (directory->details->metafile_uri)
+ gnome_vfs_uri_unref (directory->details->metafile_uri);
+ xmlFreeDoc (directory->details->metafile_tree);
+ nautilus_directory_remove_write_metafile_idle (directory);
+
+ g_free (directory->details);
+
+ NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object));
+}
+
+/**
+ * nautilus_directory_get:
+ * @uri: URI of directory to get.
+ *
+ * Get a directory given a uri.
+ * Creates the appropriate subclass given the uri mappings.
+ * Returns a referenced object, not a floating one. Unref when finished.
+ * If two windows are viewing the same uri, the directory object is shared.
+ */
+NautilusDirectory *
+nautilus_directory_get (const char *uri)
+{
+ NautilusDirectory *directory;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ /* FIXME: This currently ignores the issue of two uris that are not identical but point
+ to the same data.
+ */
+
+ /* Create the hash table first time through. */
+ if (!directory_objects)
+ directory_objects = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* If the object is already in the hash table, look it up. */
+ directory = g_hash_table_lookup (directory_objects, uri);
+ if (directory != NULL) {
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
+ gtk_object_ref (GTK_OBJECT (directory));
+ } else {
+ /* Create a new directory object instead. */
+ directory = NAUTILUS_DIRECTORY (nautilus_directory_new (uri));
+ g_assert (strcmp (directory->details->uri_text, uri) == 0);
+
+ /* Put it in the hash table. */
+ gtk_object_ref (GTK_OBJECT (directory));
+ gtk_object_sink (GTK_OBJECT (directory));
+ g_hash_table_insert (directory_objects, directory->details->uri_text, directory);
+ }
+
+ return directory;
+}
+
+/* This reads the metafile synchronously. This must go eventually.
+ To do this asynchronously we'd need a way to read an entire file
+ with async. calls; currently you can only get the file length with
+ a synchronous call.
+*/
+static void
+nautilus_directory_read_metafile (NautilusDirectory *directory)
+{
+ GnomeVFSResult result;
+ GnomeVFSFileInfo metafile_info;
+ GnomeVFSHandle *metafile_handle;
+ char *buffer;
+ GnomeVFSFileSize size, actual_size;
+
+ g_assert (directory->details->metafile_tree == NULL);
+
+ result = gnome_vfs_get_file_info_uri (directory->details->metafile_uri,
+ &metafile_info,
+ GNOME_VFS_FILE_INFO_DEFAULT,
+ NULL);
+ if (result == GNOME_VFS_ERROR_NOTFOUND)
+ return;
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_read_metafile: gnome_vfs_get_file_info_uri failed");
+
+ metafile_handle = NULL;
+ if (result == GNOME_VFS_OK) {
+ result = gnome_vfs_open_uri (&metafile_handle,
+ directory->details->metafile_uri,
+ GNOME_VFS_OPEN_READ);
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_read_metafile: gnome_vfs_open_uri failed");
+ }
+
+ if (result == GNOME_VFS_OK) {
+ size = metafile_info.size;
+ if (size != metafile_info.size) {
+ g_warning ("nautilus_directory_read_metafile: metafile too large");
+ result = GNOME_VFS_ERROR_TOOBIG;
+ }
+ }
+
+ if (result == GNOME_VFS_OK) {
+ buffer = g_malloc (size);
+
+ result = gnome_vfs_read (metafile_handle, buffer, size, &actual_size);
+
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_read_metafile: gnome_vfs_read failed");
+ else if (actual_size != size)
+ g_warning ("nautilus_directory_read_metafile: size changed between get_info and read");
+ }
+
+ if (metafile_handle != NULL)
+ gnome_vfs_close (metafile_handle);
+
+ if (result == GNOME_VFS_OK)
+ directory->details->metafile_tree = xmlParseMemory (buffer, actual_size);
+
+ g_free (buffer);
+}
+
+static void
+nautilus_directory_remove_write_metafile_idle (NautilusDirectory *directory)
+{
+ if (directory->details->write_metafile_idle_id != 0) {
+ gtk_idle_remove (directory->details->write_metafile_idle_id);
+ directory->details->write_metafile_idle_id = 0;
+ }
+}
+
+/* This writes the metafile synchronously. This must go eventually. */
+static void
+nautilus_directory_write_metafile (NautilusDirectory *directory)
+{
+ xmlChar *buffer;
+ int buffer_size;
+ GnomeVFSResult result;
+ GnomeVFSHandle *metafile_handle;
+ GnomeVFSFileSize actual_size;
+
+ g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
+
+ /* We are about the write the metafile, so we can cancel the pending
+ request to do it. */
+ nautilus_directory_remove_write_metafile_idle (directory);
+
+ /* Don't write anything if there's nothing to write.
+ At some point, we might want to change this to actually delete
+ the metafile in this case.
+ */
+ if (directory->details->metafile_tree == NULL)
+ return;
+
+ xmlDocDumpMemory (directory->details->metafile_tree, &buffer, &buffer_size);
+
+ metafile_handle = NULL;
+ result = gnome_vfs_create_uri (&metafile_handle,
+ directory->details->metafile_uri,
+ GNOME_VFS_OPEN_WRITE,
+ FALSE,
+ GNOME_VFS_PERM_USER_ALL | GNOME_VFS_PERM_GROUP_ALL | GNOME_VFS_PERM_OTHER_ALL);
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_write_metafile: gnome_vfs_create_uri failed");
+
+ if (result == GNOME_VFS_OK) {
+ result = gnome_vfs_write (metafile_handle, buffer, buffer_size, &actual_size);
+
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_write_metafile: gnome_vfs_write failed");
+ else if (actual_size != buffer_size)
+ g_warning ("nautilus_directory_read_metafile: unable to write all");
+ }
+
+ if (metafile_handle != NULL)
+ gnome_vfs_close (metafile_handle);
+
+ xmlFree (buffer);
+}
+
+static gboolean
+nautilus_directory_write_metafile_on_idle (gpointer data)
+{
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (data), FALSE);
+ nautilus_directory_write_metafile (data);
+ return FALSE;
+}
+
+static void
+nautilus_directory_request_write_metafile (NautilusDirectory *directory)
+{
+ /* Set up an idle task that will write the metafile. */
+ if (directory->details->write_metafile_idle_id == 0)
+ directory->details->write_metafile_idle_id =
+ gtk_idle_add (nautilus_directory_write_metafile_on_idle,
+ directory);
+}
+
+#if NAUTILUS_DIRECTORY_ASYNC
+
+static void
+nautilus_directory_opened_metafile (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer callback_data)
+{
+}
+
+ result = gnome_vfs_async_open_uri (&metafile_handle, metafile_uri, GNOME_VFS_OPEN_READ,
+ nautilus_directory_opened_metafile, directory);
+#endif
+
+static NautilusDirectory *
+nautilus_directory_new (const char* uri)
+{
+ NautilusDirectory *directory;
+ GnomeVFSURI *vfs_uri;
+ GnomeVFSURI *metafile_uri;
+
+ vfs_uri = gnome_vfs_uri_new (uri);
+ if (vfs_uri == NULL)
+ return NULL;
+
+ metafile_uri = gnome_vfs_uri_append_path (vfs_uri, METAFILE_NAME);
+ if (metafile_uri == NULL)
+ return NULL;
+
+ directory = gtk_type_new (NAUTILUS_TYPE_DIRECTORY);
+
+ directory->details->uri_text = g_strdup (uri);
+ directory->details->uri = vfs_uri;
+ directory->details->metafile_uri = metafile_uri;
+
+ nautilus_directory_read_metafile (directory);
+
+ return directory;
+}
+
+void
+nautilus_directory_get_files (NautilusDirectory *directory,
+ NautilusFileListCallback callback,
+ gpointer callback_data)
+{
+ g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
+ g_return_if_fail (callback != NULL);
+
+ if (directory->details->files != NULL)
+ (* callback) (directory,
+ directory->details->files,
+ callback_data);
+}
+
+char *
+nautilus_directory_get_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata)
+{
+ xmlNode *root;
+ xmlChar *property;
+ char *result;
+
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+ g_return_val_if_fail (tag, NULL);
+ g_return_val_if_fail (tag[0], NULL);
+
+ root = xmlDocGetRootElement (directory->details->metafile_tree);
+ property = xmlGetProp (root, tag);
+ if (property == NULL)
+ result = g_strdup (default_metadata);
+ else
+ result = g_strdup (property);
+ g_free (property);
+
+ return result;
+}
+
+void
+nautilus_directory_set_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata,
+ const char *metadata)
+{
+ char *old_metadata;
+ gboolean old_metadata_matches;
+ xmlNode *root;
+ const char *value;
+ xmlAttr *property_node;
+
+ g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
+ g_return_if_fail (tag);
+ g_return_if_fail (tag[0]);
+
+ /* If the data in the metafile is already correct, do nothing. */
+ old_metadata = nautilus_directory_get_metadata (directory, tag, default_metadata);
+ old_metadata_matches = nautilus_strcmp (old_metadata, metadata) == 0;
+ g_free (old_metadata);
+ if (old_metadata_matches)
+ return;
+
+ /* Data that matches the default is represented in the tree by
+ the lack of an attribute.
+ */
+ if (nautilus_strcmp (default_metadata, metadata) == 0)
+ value = NULL;
+ else
+ value = metadata;
+
+ /* Get at the tree. */
+ if (directory->details->metafile_tree == NULL)
+ directory->details->metafile_tree = xmlNewDoc (METAFILE_XML_VERSION);
+ root = xmlDocGetRootElement (directory->details->metafile_tree);
+ if (root == NULL) {
+ root = xmlNewDocNode (directory->details->metafile_tree, NULL, "DIRECTORY", NULL);
+ xmlDocSetRootElement (directory->details->metafile_tree, root);
+ }
+
+ /* Add or remove an attribute node. */
+ property_node = xmlSetProp (root, tag, value);
+ if (value == NULL)
+ xmlRemoveProp (property_node);
+
+ /* Since we changed the tree, arrange for it to be written. */
+ nautilus_directory_request_write_metafile (directory);
+}
+
+#if !defined (NAUTILUS_OMIT_SELF_CHECK)
+
+static int data_dummy;
+static guint file_count;
+
+static void
+get_files_cb (NautilusDirectory *directory, NautilusFileList *files, gpointer data)
+{
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
+ g_assert (files);
+ g_assert (data == &data_dummy);
+
+ file_count += g_list_length (files);
+}
+
+void
+nautilus_self_check_directory (void)
+{
+ NautilusDirectory *directory;
+
+ directory = nautilus_directory_get ("file:///etc");
+
+ g_assert (g_hash_table_size (directory_objects) == 1);
+
+ file_count = 0;
+ nautilus_directory_get_files (directory, get_files_cb, &data_dummy);
+
+ gtk_object_unref (GTK_OBJECT (directory));
+
+ g_assert (g_hash_table_size (directory_objects) == 0);
+}
+
+#endif /* !NAUTILUS_OMIT_SELF_CHECK */
diff --git a/libnautilus-extensions/nautilus-directory.h b/libnautilus-extensions/nautilus-directory.h
new file mode 100644
index 000000000..eed024e0b
--- /dev/null
+++ b/libnautilus-extensions/nautilus-directory.h
@@ -0,0 +1,166 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-directory.h: Nautilus directory model.
+
+ Copyright (C) 1999 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>
+*/
+
+#ifndef NAUTILUS_DIRECTORY_H
+#define NAUTILUS_DIRECTORY_H
+
+#include <gtk/gtkobject.h>
+
+/* NautilusDirectory is a class that manages the model for a directory,
+ real or virtual, for Nautilus, mainly the file-manager component. The directory is
+ responsible for managing both real data and cached metadata. On top of
+ the file system independence provided by gnome-vfs, the directory
+ object also provides:
+
+ 1) A synchronization framework, which notifies via signals as the
+ set of known files changes.
+ 2) An abstract interface for getting attributes and performing
+ operations on files.
+ 3) An interface that folds together the cached information that's
+ kept in the metafile with "trustworthy" versions of the same
+ information available from other means.
+*/
+
+typedef struct _NautilusDirectory NautilusDirectory;
+typedef struct _NautilusDirectoryClass NautilusDirectoryClass;
+
+#define NAUTILUS_TYPE_DIRECTORY \
+ (nautilus_directory_get_type ())
+#define NAUTILUS_DIRECTORY(obj) \
+ (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_DIRECTORY, NautilusDirectory))
+#define NAUTILUS_DIRECTORY_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DIRECTORY, NautilusDirectoryClass))
+#define NAUTILUS_IS_DIRECTORY(obj) \
+ (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_DIRECTORY))
+#define NAUTILUS_IS_DIRECTORY_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DIRECTORY))
+
+typedef struct _NautilusFile NautilusFile;
+typedef GList NautilusFileList;
+
+typedef void (*NautilusFileListCallback) (NautilusDirectory *directory,
+ NautilusFileList *files,
+ gpointer data);
+
+/* Basic GtkObject requirements. */
+GtkType nautilus_directory_get_type (void);
+
+/* Get a directory given a uri.
+ Creates the appropriate subclass given the uri mappings.
+ Returns a referenced object, not a floating one. Unref when finished.
+ If two windows are viewing the same uri, the directory object is shared.
+*/
+NautilusDirectory *nautilus_directory_get (const char *uri);
+
+/* Simple preliminary interface for getting and setting metadata. */
+char * nautilus_directory_get_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata);
+char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *tag,
+ const char *default_metadata);
+void nautilus_directory_set_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata,
+ const char *metadata);
+void nautilus_directory_set_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *tag,
+ const char *default_metadata,
+ const char *metadata);
+
+/* Get the current files.
+ Instead of returning the list of files, this function uses a callback.
+ The directory guarantees that signals won't be emitted while in the
+ callback function.
+*/
+void nautilus_directory_get_files (NautilusDirectory *directory,
+ NautilusFileListCallback callback,
+ gpointer callback_data);
+
+/* Return true if the directory has enough information for layout.
+ This will be false until the metafile is read to prevent a partial layout
+ from being done.
+*/
+gboolean nautilus_directory_is_ready_for_layout (NautilusDirectory *directory);
+
+/* Basic operations on file objects. */
+void nautilus_file_ref (NautilusFile *file);
+void nautilus_file_unref (NautilusFile *file);
+char * nautilus_file_get_name (NautilusFile *file);
+
+/* Return true if this file has already been deleted.
+ This object will be unref'd after sending the files_removed signal,
+ but it could hang around longer if someone ref'd it.
+*/
+gboolean nautilus_file_is_gone (NautilusFile *file);
+
+typedef struct _NautilusDirectoryDetails NautilusDirectoryDetails;
+
+struct _NautilusDirectory
+{
+ GtkObject object;
+
+ /* Hidden details. */
+ NautilusDirectoryDetails *details;
+};
+
+struct _NautilusDirectoryClass
+{
+ GtkObjectClass parent_class;
+
+ /*** Notification signals for clients to connect to. ***/
+
+ /* The files_added and files_removed signals are emitted as
+ the directory model discovers new files or discovers that
+ old files have been deleted. In the case of files_removed,
+ this is the last chance to forget about these file objects
+ which are about to be unref'd.
+ */
+ void (* files_added) (NautilusDirectory *directory,
+ NautilusFileList *added_files);
+ void (* files_removed) (NautilusDirectory *directory,
+ NautilusFileList *removed_files);
+
+ /* The files_changed signal is emitted as changes occur to
+ existing files that are noticed by the synchronization framework.
+ The client must register which file attributes it is interested
+ in. Changes to other attributes are not reported via the signal.
+ */
+ void (* files_changed) (NautilusDirectory *directory,
+ NautilusFileList *changed_files);
+
+ /* The ready_for_layout signal is emitted when the directory
+ model judges that enough files are available for the layout
+ process to begin. For normal directories this is after the
+ metafile has been read. If there's no way to get the basic
+ layout information before getting the actual files, then
+ this signal need not be emitted as long as is_ready_for_layout
+ is already true.
+ */
+ void (* ready_for_layout) (NautilusDirectory *directory);
+};
+
+#endif /* NAUTILUS_DIRECTORY_H */
diff --git a/libnautilus-extensions/nautilus-lib-self-check-functions.c b/libnautilus-extensions/nautilus-lib-self-check-functions.c
index 8fd904042..76f06a41e 100644
--- a/libnautilus-extensions/nautilus-lib-self-check-functions.c
+++ b/libnautilus-extensions/nautilus-lib-self-check-functions.c
@@ -33,8 +33,7 @@
void nautilus_run_lib_self_checks ()
{
- nautilus_self_check_background ();
- nautilus_self_check_gdk_extensions ();
+ NAUTILUS_LIB_FOR_EACH_SELF_CHECK_FUNCTION (NAUTILUS_CALL_SELF_CHECK_FUNCTION)
}
#endif /* ! NAUTILUS_OMIT_SELF_CHECK */
diff --git a/libnautilus-extensions/nautilus-lib-self-check-functions.h b/libnautilus-extensions/nautilus-lib-self-check-functions.h
index 2b68bd8d6..eff8b1312 100644
--- a/libnautilus-extensions/nautilus-lib-self-check-functions.h
+++ b/libnautilus-extensions/nautilus-lib-self-check-functions.h
@@ -32,8 +32,17 @@ void nautilus_run_lib_self_checks (void);
the self-check framework take way too long (since one file would
have to include everything).
- So we put the prototypes here instead.
+ So we put the list of functions here instead.
+
+ Instead of just putting prototypes here, we put this macro that
+ can be used to do operations on the whole list of functions.
*/
-void nautilus_self_check_gdk_extensions (void);
-void nautilus_self_check_background (void);
+#define NAUTILUS_LIB_FOR_EACH_SELF_CHECK_FUNCTION(macro) \
+ macro(nautilus_self_check_background) \
+ macro(nautilus_self_check_directory) \
+ macro(nautilus_self_check_gdk_extensions) \
+/* Add new self-check functions to the list above this line. */
+
+/* Generate prototypes for all the functions. */
+NAUTILUS_LIB_FOR_EACH_SELF_CHECK_FUNCTION (NAUTILUS_SELF_CHECK_FUNCTION_PROTOTYPE)
diff --git a/libnautilus-extensions/nautilus-self-checks.h b/libnautilus-extensions/nautilus-self-checks.h
index bfbdd40c0..ab4b30ef3 100644
--- a/libnautilus-extensions/nautilus-self-checks.h
+++ b/libnautilus-extensions/nautilus-self-checks.h
@@ -51,4 +51,10 @@ G_STMT_START { \
#define NAUTILUS_CHECK_STRING_RESULT(expression, expected_value) \
NAUTILUS_CHECK_RESULT(string, expression, expected_value)
+#define NAUTILUS_SELF_CHECK_FUNCTION_PROTOTYPE(function) \
+ void function (void);
+
+#define NAUTILUS_CALL_SELF_CHECK_FUNCTION(function) \
+ function ();
+
#endif /* NAUTILUS_SELF_CHECKS_H */
diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am
index 2a7912af8..46d1de41d 100644
--- a/libnautilus-private/Makefile.am
+++ b/libnautilus-private/Makefile.am
@@ -4,8 +4,17 @@ INCLUDES=-I$(top_srcdir) -I$(top_builddir) \
$(GNOME_CFLAGS) \
$(GNORBA_CFLAGS) \
$(GDK_PIXBUF_CFLAGS) \
+ $(VFS_CFLAGS) \
+ $(XML_CFLAGS) \
$(WERROR)
+libnautilus_la_LDFLAGS=\
+ $(GNOME_LIBS) \
+ $(GNORBA_LIBS) \
+ $(GDK_PIXBUF_LIBS) -lcanvas_pixbuf \
+ $(VFS_LIBS) \
+ $(XML_LIBS)
+
nautilus_idl_sources=nautilus-stubs.c nautilus-skels.c nautilus.h nautilus-common.c
fsextension_idl_sources=fsextension-stubs.c fsextension-skels.c fsextension-common.c fsextension.h
BUILT_SOURCES=$(nautilus_idl_sources)
@@ -23,6 +32,7 @@ libnautilusinclude_HEADERS= \
gtkscrollframe.h \
nautilus.h \
nautilus-background.h \
+ nautilus-directory.h \
nautilus-file-utilities.h \
nautilus-gtk-extensions.h \
nautilus-lib-self-check-functions.h \
@@ -41,6 +51,7 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \
gtkscrollframe.c \
nautilus-background.c \
nautilus-background-canvas-group.c \
+ nautilus-directory.c \
nautilus-file-utilities.c \
nautilus-gtk-extensions.c \
nautilus-lib-self-check-functions.c \
@@ -51,10 +62,6 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \
ntl-view-frame.c \
$(fsextension_idl_sources)
-libnautilus_la_LDFLAGS=$(GNOME_LIBS) \
- $(GNORBA_LIBS) \
- $(GDK_PIXBUF_LIBS) -lcanvas_pixbuf
-
$(nautilus_idl_sources): nautilus_idl_stamp
$(fsextension_idl_sources): fsextension_idl_stamp
diff --git a/libnautilus-private/nautilus-background.c b/libnautilus-private/nautilus-background.c
index 057f265f6..d8090881f 100644
--- a/libnautilus-private/nautilus-background.c
+++ b/libnautilus-private/nautilus-background.c
@@ -185,7 +185,8 @@ nautilus_gtk_style_get_default_class (void)
return default_class;
}
-static void nautilus_gdk_window_update_sizes (GdkWindow *window, int *width, int *height)
+static void
+nautilus_gdk_window_update_sizes (GdkWindow *window, int *width, int *height)
{
g_return_if_fail (window != NULL);
g_return_if_fail (width != NULL);
@@ -199,17 +200,18 @@ static void nautilus_gdk_window_update_sizes (GdkWindow *window, int *width, int
gdk_window_get_size (window, NULL, height);
}
-static void nautilus_background_draw_flat_box (GtkStyle *style,
- GdkWindow *window,
- GtkStateType state_type,
- GtkShadowType shadow_type,
- GdkRectangle *area,
- GtkWidget *widget,
- gchar *detail,
- gint x,
- gint y,
- gint width,
- gint height)
+static void
+nautilus_background_draw_flat_box (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char *detail,
+ int x,
+ int y,
+ int width,
+ int height)
{
gboolean call_parent;
NautilusBackground *background;
diff --git a/libnautilus-private/nautilus-directory.c b/libnautilus-private/nautilus-directory.c
new file mode 100644
index 000000000..86b3c00f9
--- /dev/null
+++ b/libnautilus-private/nautilus-directory.c
@@ -0,0 +1,466 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-directory.c: Mautilus directory model.
+
+ Copyright (C) 1999, 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>
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "nautilus-directory.h"
+
+#include <stdlib.h>
+
+#include <gtk/gtkmain.h>
+
+#include <libgnomevfs/gnome-vfs-types.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libgnomevfs/gnome-vfs-async-ops.h>
+
+#include <gnome-xml/parser.h>
+#include <gnome-xml/tree.h>
+#include <gnome-xml/xmlmemory.h>
+
+#include "nautilus-gtk-macros.h"
+#include "nautilus-lib-self-check-functions.h"
+#include "nautilus-string.h"
+
+#define METAFILE_NAME ".nautilus.xml"
+#define METAFILE_XML_VERSION "1.0"
+
+static void nautilus_directory_initialize_class (gpointer klass);
+static void nautilus_directory_initialize (gpointer object, gpointer klass);
+static void nautilus_directory_finalize (GtkObject *object);
+
+static NautilusDirectory *nautilus_directory_new (const char* uri);
+
+static void nautilus_directory_read_metafile (NautilusDirectory *directory);
+static void nautilus_directory_write_metafile (NautilusDirectory *directory);
+static void nautilus_directory_request_write_metafile (NautilusDirectory *directory);
+static void nautilus_directory_remove_write_metafile_idle (NautilusDirectory *directory);
+
+NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusDirectory, nautilus_directory, GTK_TYPE_OBJECT)
+
+static GtkObjectClass *parent_class;
+
+struct _NautilusDirectoryDetails
+{
+ char *uri_text;
+ GnomeVFSURI *uri;
+
+ GnomeVFSURI *metafile_uri;
+ xmlDoc *metafile_tree;
+ int write_metafile_idle_id;
+
+ NautilusFileList *files;
+};
+
+struct _NautilusFile
+{
+};
+
+static GHashTable* directory_objects;
+
+static void
+nautilus_directory_initialize_class (gpointer klass)
+{
+ GtkObjectClass *object_class;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ parent_class = gtk_type_class (GTK_TYPE_OBJECT);
+
+ object_class->finalize = nautilus_directory_finalize;
+}
+
+static void
+nautilus_directory_initialize (gpointer object, gpointer klass)
+{
+ NautilusDirectory *directory;
+
+ directory = NAUTILUS_DIRECTORY(object);
+
+ directory->details = g_new0 (NautilusDirectoryDetails, 1);
+}
+
+static void
+nautilus_directory_finalize (GtkObject *object)
+{
+ NautilusDirectory *directory;
+
+ directory = NAUTILUS_DIRECTORY (object);
+
+ g_hash_table_remove (directory_objects, directory->details->uri_text);
+
+ g_free (directory->details->uri_text);
+ if (directory->details->uri)
+ gnome_vfs_uri_unref (directory->details->uri);
+ if (directory->details->metafile_uri)
+ gnome_vfs_uri_unref (directory->details->metafile_uri);
+ xmlFreeDoc (directory->details->metafile_tree);
+ nautilus_directory_remove_write_metafile_idle (directory);
+
+ g_free (directory->details);
+
+ NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object));
+}
+
+/**
+ * nautilus_directory_get:
+ * @uri: URI of directory to get.
+ *
+ * Get a directory given a uri.
+ * Creates the appropriate subclass given the uri mappings.
+ * Returns a referenced object, not a floating one. Unref when finished.
+ * If two windows are viewing the same uri, the directory object is shared.
+ */
+NautilusDirectory *
+nautilus_directory_get (const char *uri)
+{
+ NautilusDirectory *directory;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ /* FIXME: This currently ignores the issue of two uris that are not identical but point
+ to the same data.
+ */
+
+ /* Create the hash table first time through. */
+ if (!directory_objects)
+ directory_objects = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* If the object is already in the hash table, look it up. */
+ directory = g_hash_table_lookup (directory_objects, uri);
+ if (directory != NULL) {
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
+ gtk_object_ref (GTK_OBJECT (directory));
+ } else {
+ /* Create a new directory object instead. */
+ directory = NAUTILUS_DIRECTORY (nautilus_directory_new (uri));
+ g_assert (strcmp (directory->details->uri_text, uri) == 0);
+
+ /* Put it in the hash table. */
+ gtk_object_ref (GTK_OBJECT (directory));
+ gtk_object_sink (GTK_OBJECT (directory));
+ g_hash_table_insert (directory_objects, directory->details->uri_text, directory);
+ }
+
+ return directory;
+}
+
+/* This reads the metafile synchronously. This must go eventually.
+ To do this asynchronously we'd need a way to read an entire file
+ with async. calls; currently you can only get the file length with
+ a synchronous call.
+*/
+static void
+nautilus_directory_read_metafile (NautilusDirectory *directory)
+{
+ GnomeVFSResult result;
+ GnomeVFSFileInfo metafile_info;
+ GnomeVFSHandle *metafile_handle;
+ char *buffer;
+ GnomeVFSFileSize size, actual_size;
+
+ g_assert (directory->details->metafile_tree == NULL);
+
+ result = gnome_vfs_get_file_info_uri (directory->details->metafile_uri,
+ &metafile_info,
+ GNOME_VFS_FILE_INFO_DEFAULT,
+ NULL);
+ if (result == GNOME_VFS_ERROR_NOTFOUND)
+ return;
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_read_metafile: gnome_vfs_get_file_info_uri failed");
+
+ metafile_handle = NULL;
+ if (result == GNOME_VFS_OK) {
+ result = gnome_vfs_open_uri (&metafile_handle,
+ directory->details->metafile_uri,
+ GNOME_VFS_OPEN_READ);
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_read_metafile: gnome_vfs_open_uri failed");
+ }
+
+ if (result == GNOME_VFS_OK) {
+ size = metafile_info.size;
+ if (size != metafile_info.size) {
+ g_warning ("nautilus_directory_read_metafile: metafile too large");
+ result = GNOME_VFS_ERROR_TOOBIG;
+ }
+ }
+
+ if (result == GNOME_VFS_OK) {
+ buffer = g_malloc (size);
+
+ result = gnome_vfs_read (metafile_handle, buffer, size, &actual_size);
+
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_read_metafile: gnome_vfs_read failed");
+ else if (actual_size != size)
+ g_warning ("nautilus_directory_read_metafile: size changed between get_info and read");
+ }
+
+ if (metafile_handle != NULL)
+ gnome_vfs_close (metafile_handle);
+
+ if (result == GNOME_VFS_OK)
+ directory->details->metafile_tree = xmlParseMemory (buffer, actual_size);
+
+ g_free (buffer);
+}
+
+static void
+nautilus_directory_remove_write_metafile_idle (NautilusDirectory *directory)
+{
+ if (directory->details->write_metafile_idle_id != 0) {
+ gtk_idle_remove (directory->details->write_metafile_idle_id);
+ directory->details->write_metafile_idle_id = 0;
+ }
+}
+
+/* This writes the metafile synchronously. This must go eventually. */
+static void
+nautilus_directory_write_metafile (NautilusDirectory *directory)
+{
+ xmlChar *buffer;
+ int buffer_size;
+ GnomeVFSResult result;
+ GnomeVFSHandle *metafile_handle;
+ GnomeVFSFileSize actual_size;
+
+ g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
+
+ /* We are about the write the metafile, so we can cancel the pending
+ request to do it. */
+ nautilus_directory_remove_write_metafile_idle (directory);
+
+ /* Don't write anything if there's nothing to write.
+ At some point, we might want to change this to actually delete
+ the metafile in this case.
+ */
+ if (directory->details->metafile_tree == NULL)
+ return;
+
+ xmlDocDumpMemory (directory->details->metafile_tree, &buffer, &buffer_size);
+
+ metafile_handle = NULL;
+ result = gnome_vfs_create_uri (&metafile_handle,
+ directory->details->metafile_uri,
+ GNOME_VFS_OPEN_WRITE,
+ FALSE,
+ GNOME_VFS_PERM_USER_ALL | GNOME_VFS_PERM_GROUP_ALL | GNOME_VFS_PERM_OTHER_ALL);
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_write_metafile: gnome_vfs_create_uri failed");
+
+ if (result == GNOME_VFS_OK) {
+ result = gnome_vfs_write (metafile_handle, buffer, buffer_size, &actual_size);
+
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_write_metafile: gnome_vfs_write failed");
+ else if (actual_size != buffer_size)
+ g_warning ("nautilus_directory_read_metafile: unable to write all");
+ }
+
+ if (metafile_handle != NULL)
+ gnome_vfs_close (metafile_handle);
+
+ xmlFree (buffer);
+}
+
+static gboolean
+nautilus_directory_write_metafile_on_idle (gpointer data)
+{
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (data), FALSE);
+ nautilus_directory_write_metafile (data);
+ return FALSE;
+}
+
+static void
+nautilus_directory_request_write_metafile (NautilusDirectory *directory)
+{
+ /* Set up an idle task that will write the metafile. */
+ if (directory->details->write_metafile_idle_id == 0)
+ directory->details->write_metafile_idle_id =
+ gtk_idle_add (nautilus_directory_write_metafile_on_idle,
+ directory);
+}
+
+#if NAUTILUS_DIRECTORY_ASYNC
+
+static void
+nautilus_directory_opened_metafile (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer callback_data)
+{
+}
+
+ result = gnome_vfs_async_open_uri (&metafile_handle, metafile_uri, GNOME_VFS_OPEN_READ,
+ nautilus_directory_opened_metafile, directory);
+#endif
+
+static NautilusDirectory *
+nautilus_directory_new (const char* uri)
+{
+ NautilusDirectory *directory;
+ GnomeVFSURI *vfs_uri;
+ GnomeVFSURI *metafile_uri;
+
+ vfs_uri = gnome_vfs_uri_new (uri);
+ if (vfs_uri == NULL)
+ return NULL;
+
+ metafile_uri = gnome_vfs_uri_append_path (vfs_uri, METAFILE_NAME);
+ if (metafile_uri == NULL)
+ return NULL;
+
+ directory = gtk_type_new (NAUTILUS_TYPE_DIRECTORY);
+
+ directory->details->uri_text = g_strdup (uri);
+ directory->details->uri = vfs_uri;
+ directory->details->metafile_uri = metafile_uri;
+
+ nautilus_directory_read_metafile (directory);
+
+ return directory;
+}
+
+void
+nautilus_directory_get_files (NautilusDirectory *directory,
+ NautilusFileListCallback callback,
+ gpointer callback_data)
+{
+ g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
+ g_return_if_fail (callback != NULL);
+
+ if (directory->details->files != NULL)
+ (* callback) (directory,
+ directory->details->files,
+ callback_data);
+}
+
+char *
+nautilus_directory_get_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata)
+{
+ xmlNode *root;
+ xmlChar *property;
+ char *result;
+
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+ g_return_val_if_fail (tag, NULL);
+ g_return_val_if_fail (tag[0], NULL);
+
+ root = xmlDocGetRootElement (directory->details->metafile_tree);
+ property = xmlGetProp (root, tag);
+ if (property == NULL)
+ result = g_strdup (default_metadata);
+ else
+ result = g_strdup (property);
+ g_free (property);
+
+ return result;
+}
+
+void
+nautilus_directory_set_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata,
+ const char *metadata)
+{
+ char *old_metadata;
+ gboolean old_metadata_matches;
+ xmlNode *root;
+ const char *value;
+ xmlAttr *property_node;
+
+ g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
+ g_return_if_fail (tag);
+ g_return_if_fail (tag[0]);
+
+ /* If the data in the metafile is already correct, do nothing. */
+ old_metadata = nautilus_directory_get_metadata (directory, tag, default_metadata);
+ old_metadata_matches = nautilus_strcmp (old_metadata, metadata) == 0;
+ g_free (old_metadata);
+ if (old_metadata_matches)
+ return;
+
+ /* Data that matches the default is represented in the tree by
+ the lack of an attribute.
+ */
+ if (nautilus_strcmp (default_metadata, metadata) == 0)
+ value = NULL;
+ else
+ value = metadata;
+
+ /* Get at the tree. */
+ if (directory->details->metafile_tree == NULL)
+ directory->details->metafile_tree = xmlNewDoc (METAFILE_XML_VERSION);
+ root = xmlDocGetRootElement (directory->details->metafile_tree);
+ if (root == NULL) {
+ root = xmlNewDocNode (directory->details->metafile_tree, NULL, "DIRECTORY", NULL);
+ xmlDocSetRootElement (directory->details->metafile_tree, root);
+ }
+
+ /* Add or remove an attribute node. */
+ property_node = xmlSetProp (root, tag, value);
+ if (value == NULL)
+ xmlRemoveProp (property_node);
+
+ /* Since we changed the tree, arrange for it to be written. */
+ nautilus_directory_request_write_metafile (directory);
+}
+
+#if !defined (NAUTILUS_OMIT_SELF_CHECK)
+
+static int data_dummy;
+static guint file_count;
+
+static void
+get_files_cb (NautilusDirectory *directory, NautilusFileList *files, gpointer data)
+{
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
+ g_assert (files);
+ g_assert (data == &data_dummy);
+
+ file_count += g_list_length (files);
+}
+
+void
+nautilus_self_check_directory (void)
+{
+ NautilusDirectory *directory;
+
+ directory = nautilus_directory_get ("file:///etc");
+
+ g_assert (g_hash_table_size (directory_objects) == 1);
+
+ file_count = 0;
+ nautilus_directory_get_files (directory, get_files_cb, &data_dummy);
+
+ gtk_object_unref (GTK_OBJECT (directory));
+
+ g_assert (g_hash_table_size (directory_objects) == 0);
+}
+
+#endif /* !NAUTILUS_OMIT_SELF_CHECK */
diff --git a/libnautilus-private/nautilus-directory.h b/libnautilus-private/nautilus-directory.h
new file mode 100644
index 000000000..eed024e0b
--- /dev/null
+++ b/libnautilus-private/nautilus-directory.h
@@ -0,0 +1,166 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-directory.h: Nautilus directory model.
+
+ Copyright (C) 1999 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>
+*/
+
+#ifndef NAUTILUS_DIRECTORY_H
+#define NAUTILUS_DIRECTORY_H
+
+#include <gtk/gtkobject.h>
+
+/* NautilusDirectory is a class that manages the model for a directory,
+ real or virtual, for Nautilus, mainly the file-manager component. The directory is
+ responsible for managing both real data and cached metadata. On top of
+ the file system independence provided by gnome-vfs, the directory
+ object also provides:
+
+ 1) A synchronization framework, which notifies via signals as the
+ set of known files changes.
+ 2) An abstract interface for getting attributes and performing
+ operations on files.
+ 3) An interface that folds together the cached information that's
+ kept in the metafile with "trustworthy" versions of the same
+ information available from other means.
+*/
+
+typedef struct _NautilusDirectory NautilusDirectory;
+typedef struct _NautilusDirectoryClass NautilusDirectoryClass;
+
+#define NAUTILUS_TYPE_DIRECTORY \
+ (nautilus_directory_get_type ())
+#define NAUTILUS_DIRECTORY(obj) \
+ (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_DIRECTORY, NautilusDirectory))
+#define NAUTILUS_DIRECTORY_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DIRECTORY, NautilusDirectoryClass))
+#define NAUTILUS_IS_DIRECTORY(obj) \
+ (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_DIRECTORY))
+#define NAUTILUS_IS_DIRECTORY_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DIRECTORY))
+
+typedef struct _NautilusFile NautilusFile;
+typedef GList NautilusFileList;
+
+typedef void (*NautilusFileListCallback) (NautilusDirectory *directory,
+ NautilusFileList *files,
+ gpointer data);
+
+/* Basic GtkObject requirements. */
+GtkType nautilus_directory_get_type (void);
+
+/* Get a directory given a uri.
+ Creates the appropriate subclass given the uri mappings.
+ Returns a referenced object, not a floating one. Unref when finished.
+ If two windows are viewing the same uri, the directory object is shared.
+*/
+NautilusDirectory *nautilus_directory_get (const char *uri);
+
+/* Simple preliminary interface for getting and setting metadata. */
+char * nautilus_directory_get_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata);
+char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *tag,
+ const char *default_metadata);
+void nautilus_directory_set_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata,
+ const char *metadata);
+void nautilus_directory_set_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *tag,
+ const char *default_metadata,
+ const char *metadata);
+
+/* Get the current files.
+ Instead of returning the list of files, this function uses a callback.
+ The directory guarantees that signals won't be emitted while in the
+ callback function.
+*/
+void nautilus_directory_get_files (NautilusDirectory *directory,
+ NautilusFileListCallback callback,
+ gpointer callback_data);
+
+/* Return true if the directory has enough information for layout.
+ This will be false until the metafile is read to prevent a partial layout
+ from being done.
+*/
+gboolean nautilus_directory_is_ready_for_layout (NautilusDirectory *directory);
+
+/* Basic operations on file objects. */
+void nautilus_file_ref (NautilusFile *file);
+void nautilus_file_unref (NautilusFile *file);
+char * nautilus_file_get_name (NautilusFile *file);
+
+/* Return true if this file has already been deleted.
+ This object will be unref'd after sending the files_removed signal,
+ but it could hang around longer if someone ref'd it.
+*/
+gboolean nautilus_file_is_gone (NautilusFile *file);
+
+typedef struct _NautilusDirectoryDetails NautilusDirectoryDetails;
+
+struct _NautilusDirectory
+{
+ GtkObject object;
+
+ /* Hidden details. */
+ NautilusDirectoryDetails *details;
+};
+
+struct _NautilusDirectoryClass
+{
+ GtkObjectClass parent_class;
+
+ /*** Notification signals for clients to connect to. ***/
+
+ /* The files_added and files_removed signals are emitted as
+ the directory model discovers new files or discovers that
+ old files have been deleted. In the case of files_removed,
+ this is the last chance to forget about these file objects
+ which are about to be unref'd.
+ */
+ void (* files_added) (NautilusDirectory *directory,
+ NautilusFileList *added_files);
+ void (* files_removed) (NautilusDirectory *directory,
+ NautilusFileList *removed_files);
+
+ /* The files_changed signal is emitted as changes occur to
+ existing files that are noticed by the synchronization framework.
+ The client must register which file attributes it is interested
+ in. Changes to other attributes are not reported via the signal.
+ */
+ void (* files_changed) (NautilusDirectory *directory,
+ NautilusFileList *changed_files);
+
+ /* The ready_for_layout signal is emitted when the directory
+ model judges that enough files are available for the layout
+ process to begin. For normal directories this is after the
+ metafile has been read. If there's no way to get the basic
+ layout information before getting the actual files, then
+ this signal need not be emitted as long as is_ready_for_layout
+ is already true.
+ */
+ void (* ready_for_layout) (NautilusDirectory *directory);
+};
+
+#endif /* NAUTILUS_DIRECTORY_H */
diff --git a/libnautilus-private/nautilus-lib-self-check-functions.c b/libnautilus-private/nautilus-lib-self-check-functions.c
index 8fd904042..76f06a41e 100644
--- a/libnautilus-private/nautilus-lib-self-check-functions.c
+++ b/libnautilus-private/nautilus-lib-self-check-functions.c
@@ -33,8 +33,7 @@
void nautilus_run_lib_self_checks ()
{
- nautilus_self_check_background ();
- nautilus_self_check_gdk_extensions ();
+ NAUTILUS_LIB_FOR_EACH_SELF_CHECK_FUNCTION (NAUTILUS_CALL_SELF_CHECK_FUNCTION)
}
#endif /* ! NAUTILUS_OMIT_SELF_CHECK */
diff --git a/libnautilus-private/nautilus-lib-self-check-functions.h b/libnautilus-private/nautilus-lib-self-check-functions.h
index 2b68bd8d6..eff8b1312 100644
--- a/libnautilus-private/nautilus-lib-self-check-functions.h
+++ b/libnautilus-private/nautilus-lib-self-check-functions.h
@@ -32,8 +32,17 @@ void nautilus_run_lib_self_checks (void);
the self-check framework take way too long (since one file would
have to include everything).
- So we put the prototypes here instead.
+ So we put the list of functions here instead.
+
+ Instead of just putting prototypes here, we put this macro that
+ can be used to do operations on the whole list of functions.
*/
-void nautilus_self_check_gdk_extensions (void);
-void nautilus_self_check_background (void);
+#define NAUTILUS_LIB_FOR_EACH_SELF_CHECK_FUNCTION(macro) \
+ macro(nautilus_self_check_background) \
+ macro(nautilus_self_check_directory) \
+ macro(nautilus_self_check_gdk_extensions) \
+/* Add new self-check functions to the list above this line. */
+
+/* Generate prototypes for all the functions. */
+NAUTILUS_LIB_FOR_EACH_SELF_CHECK_FUNCTION (NAUTILUS_SELF_CHECK_FUNCTION_PROTOTYPE)
diff --git a/libnautilus-private/nautilus-self-checks.h b/libnautilus-private/nautilus-self-checks.h
index bfbdd40c0..ab4b30ef3 100644
--- a/libnautilus-private/nautilus-self-checks.h
+++ b/libnautilus-private/nautilus-self-checks.h
@@ -51,4 +51,10 @@ G_STMT_START { \
#define NAUTILUS_CHECK_STRING_RESULT(expression, expected_value) \
NAUTILUS_CHECK_RESULT(string, expression, expected_value)
+#define NAUTILUS_SELF_CHECK_FUNCTION_PROTOTYPE(function) \
+ void function (void);
+
+#define NAUTILUS_CALL_SELF_CHECK_FUNCTION(function) \
+ function ();
+
#endif /* NAUTILUS_SELF_CHECKS_H */
diff --git a/libnautilus/Makefile.am b/libnautilus/Makefile.am
index 2a7912af8..46d1de41d 100644
--- a/libnautilus/Makefile.am
+++ b/libnautilus/Makefile.am
@@ -4,8 +4,17 @@ INCLUDES=-I$(top_srcdir) -I$(top_builddir) \
$(GNOME_CFLAGS) \
$(GNORBA_CFLAGS) \
$(GDK_PIXBUF_CFLAGS) \
+ $(VFS_CFLAGS) \
+ $(XML_CFLAGS) \
$(WERROR)
+libnautilus_la_LDFLAGS=\
+ $(GNOME_LIBS) \
+ $(GNORBA_LIBS) \
+ $(GDK_PIXBUF_LIBS) -lcanvas_pixbuf \
+ $(VFS_LIBS) \
+ $(XML_LIBS)
+
nautilus_idl_sources=nautilus-stubs.c nautilus-skels.c nautilus.h nautilus-common.c
fsextension_idl_sources=fsextension-stubs.c fsextension-skels.c fsextension-common.c fsextension.h
BUILT_SOURCES=$(nautilus_idl_sources)
@@ -23,6 +32,7 @@ libnautilusinclude_HEADERS= \
gtkscrollframe.h \
nautilus.h \
nautilus-background.h \
+ nautilus-directory.h \
nautilus-file-utilities.h \
nautilus-gtk-extensions.h \
nautilus-lib-self-check-functions.h \
@@ -41,6 +51,7 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \
gtkscrollframe.c \
nautilus-background.c \
nautilus-background-canvas-group.c \
+ nautilus-directory.c \
nautilus-file-utilities.c \
nautilus-gtk-extensions.c \
nautilus-lib-self-check-functions.c \
@@ -51,10 +62,6 @@ libnautilus_la_SOURCES=$(nautilus_idl_sources) \
ntl-view-frame.c \
$(fsextension_idl_sources)
-libnautilus_la_LDFLAGS=$(GNOME_LIBS) \
- $(GNORBA_LIBS) \
- $(GDK_PIXBUF_LIBS) -lcanvas_pixbuf
-
$(nautilus_idl_sources): nautilus_idl_stamp
$(fsextension_idl_sources): fsextension_idl_stamp
diff --git a/libnautilus/nautilus-background.c b/libnautilus/nautilus-background.c
index 057f265f6..d8090881f 100644
--- a/libnautilus/nautilus-background.c
+++ b/libnautilus/nautilus-background.c
@@ -185,7 +185,8 @@ nautilus_gtk_style_get_default_class (void)
return default_class;
}
-static void nautilus_gdk_window_update_sizes (GdkWindow *window, int *width, int *height)
+static void
+nautilus_gdk_window_update_sizes (GdkWindow *window, int *width, int *height)
{
g_return_if_fail (window != NULL);
g_return_if_fail (width != NULL);
@@ -199,17 +200,18 @@ static void nautilus_gdk_window_update_sizes (GdkWindow *window, int *width, int
gdk_window_get_size (window, NULL, height);
}
-static void nautilus_background_draw_flat_box (GtkStyle *style,
- GdkWindow *window,
- GtkStateType state_type,
- GtkShadowType shadow_type,
- GdkRectangle *area,
- GtkWidget *widget,
- gchar *detail,
- gint x,
- gint y,
- gint width,
- gint height)
+static void
+nautilus_background_draw_flat_box (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GtkShadowType shadow_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ char *detail,
+ int x,
+ int y,
+ int width,
+ int height)
{
gboolean call_parent;
NautilusBackground *background;
diff --git a/libnautilus/nautilus-directory.c b/libnautilus/nautilus-directory.c
new file mode 100644
index 000000000..86b3c00f9
--- /dev/null
+++ b/libnautilus/nautilus-directory.c
@@ -0,0 +1,466 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-directory.c: Mautilus directory model.
+
+ Copyright (C) 1999, 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>
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "nautilus-directory.h"
+
+#include <stdlib.h>
+
+#include <gtk/gtkmain.h>
+
+#include <libgnomevfs/gnome-vfs-types.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libgnomevfs/gnome-vfs-async-ops.h>
+
+#include <gnome-xml/parser.h>
+#include <gnome-xml/tree.h>
+#include <gnome-xml/xmlmemory.h>
+
+#include "nautilus-gtk-macros.h"
+#include "nautilus-lib-self-check-functions.h"
+#include "nautilus-string.h"
+
+#define METAFILE_NAME ".nautilus.xml"
+#define METAFILE_XML_VERSION "1.0"
+
+static void nautilus_directory_initialize_class (gpointer klass);
+static void nautilus_directory_initialize (gpointer object, gpointer klass);
+static void nautilus_directory_finalize (GtkObject *object);
+
+static NautilusDirectory *nautilus_directory_new (const char* uri);
+
+static void nautilus_directory_read_metafile (NautilusDirectory *directory);
+static void nautilus_directory_write_metafile (NautilusDirectory *directory);
+static void nautilus_directory_request_write_metafile (NautilusDirectory *directory);
+static void nautilus_directory_remove_write_metafile_idle (NautilusDirectory *directory);
+
+NAUTILUS_DEFINE_GET_TYPE_FUNCTION (NautilusDirectory, nautilus_directory, GTK_TYPE_OBJECT)
+
+static GtkObjectClass *parent_class;
+
+struct _NautilusDirectoryDetails
+{
+ char *uri_text;
+ GnomeVFSURI *uri;
+
+ GnomeVFSURI *metafile_uri;
+ xmlDoc *metafile_tree;
+ int write_metafile_idle_id;
+
+ NautilusFileList *files;
+};
+
+struct _NautilusFile
+{
+};
+
+static GHashTable* directory_objects;
+
+static void
+nautilus_directory_initialize_class (gpointer klass)
+{
+ GtkObjectClass *object_class;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ parent_class = gtk_type_class (GTK_TYPE_OBJECT);
+
+ object_class->finalize = nautilus_directory_finalize;
+}
+
+static void
+nautilus_directory_initialize (gpointer object, gpointer klass)
+{
+ NautilusDirectory *directory;
+
+ directory = NAUTILUS_DIRECTORY(object);
+
+ directory->details = g_new0 (NautilusDirectoryDetails, 1);
+}
+
+static void
+nautilus_directory_finalize (GtkObject *object)
+{
+ NautilusDirectory *directory;
+
+ directory = NAUTILUS_DIRECTORY (object);
+
+ g_hash_table_remove (directory_objects, directory->details->uri_text);
+
+ g_free (directory->details->uri_text);
+ if (directory->details->uri)
+ gnome_vfs_uri_unref (directory->details->uri);
+ if (directory->details->metafile_uri)
+ gnome_vfs_uri_unref (directory->details->metafile_uri);
+ xmlFreeDoc (directory->details->metafile_tree);
+ nautilus_directory_remove_write_metafile_idle (directory);
+
+ g_free (directory->details);
+
+ NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object));
+}
+
+/**
+ * nautilus_directory_get:
+ * @uri: URI of directory to get.
+ *
+ * Get a directory given a uri.
+ * Creates the appropriate subclass given the uri mappings.
+ * Returns a referenced object, not a floating one. Unref when finished.
+ * If two windows are viewing the same uri, the directory object is shared.
+ */
+NautilusDirectory *
+nautilus_directory_get (const char *uri)
+{
+ NautilusDirectory *directory;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ /* FIXME: This currently ignores the issue of two uris that are not identical but point
+ to the same data.
+ */
+
+ /* Create the hash table first time through. */
+ if (!directory_objects)
+ directory_objects = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* If the object is already in the hash table, look it up. */
+ directory = g_hash_table_lookup (directory_objects, uri);
+ if (directory != NULL) {
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
+ gtk_object_ref (GTK_OBJECT (directory));
+ } else {
+ /* Create a new directory object instead. */
+ directory = NAUTILUS_DIRECTORY (nautilus_directory_new (uri));
+ g_assert (strcmp (directory->details->uri_text, uri) == 0);
+
+ /* Put it in the hash table. */
+ gtk_object_ref (GTK_OBJECT (directory));
+ gtk_object_sink (GTK_OBJECT (directory));
+ g_hash_table_insert (directory_objects, directory->details->uri_text, directory);
+ }
+
+ return directory;
+}
+
+/* This reads the metafile synchronously. This must go eventually.
+ To do this asynchronously we'd need a way to read an entire file
+ with async. calls; currently you can only get the file length with
+ a synchronous call.
+*/
+static void
+nautilus_directory_read_metafile (NautilusDirectory *directory)
+{
+ GnomeVFSResult result;
+ GnomeVFSFileInfo metafile_info;
+ GnomeVFSHandle *metafile_handle;
+ char *buffer;
+ GnomeVFSFileSize size, actual_size;
+
+ g_assert (directory->details->metafile_tree == NULL);
+
+ result = gnome_vfs_get_file_info_uri (directory->details->metafile_uri,
+ &metafile_info,
+ GNOME_VFS_FILE_INFO_DEFAULT,
+ NULL);
+ if (result == GNOME_VFS_ERROR_NOTFOUND)
+ return;
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_read_metafile: gnome_vfs_get_file_info_uri failed");
+
+ metafile_handle = NULL;
+ if (result == GNOME_VFS_OK) {
+ result = gnome_vfs_open_uri (&metafile_handle,
+ directory->details->metafile_uri,
+ GNOME_VFS_OPEN_READ);
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_read_metafile: gnome_vfs_open_uri failed");
+ }
+
+ if (result == GNOME_VFS_OK) {
+ size = metafile_info.size;
+ if (size != metafile_info.size) {
+ g_warning ("nautilus_directory_read_metafile: metafile too large");
+ result = GNOME_VFS_ERROR_TOOBIG;
+ }
+ }
+
+ if (result == GNOME_VFS_OK) {
+ buffer = g_malloc (size);
+
+ result = gnome_vfs_read (metafile_handle, buffer, size, &actual_size);
+
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_read_metafile: gnome_vfs_read failed");
+ else if (actual_size != size)
+ g_warning ("nautilus_directory_read_metafile: size changed between get_info and read");
+ }
+
+ if (metafile_handle != NULL)
+ gnome_vfs_close (metafile_handle);
+
+ if (result == GNOME_VFS_OK)
+ directory->details->metafile_tree = xmlParseMemory (buffer, actual_size);
+
+ g_free (buffer);
+}
+
+static void
+nautilus_directory_remove_write_metafile_idle (NautilusDirectory *directory)
+{
+ if (directory->details->write_metafile_idle_id != 0) {
+ gtk_idle_remove (directory->details->write_metafile_idle_id);
+ directory->details->write_metafile_idle_id = 0;
+ }
+}
+
+/* This writes the metafile synchronously. This must go eventually. */
+static void
+nautilus_directory_write_metafile (NautilusDirectory *directory)
+{
+ xmlChar *buffer;
+ int buffer_size;
+ GnomeVFSResult result;
+ GnomeVFSHandle *metafile_handle;
+ GnomeVFSFileSize actual_size;
+
+ g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
+
+ /* We are about the write the metafile, so we can cancel the pending
+ request to do it. */
+ nautilus_directory_remove_write_metafile_idle (directory);
+
+ /* Don't write anything if there's nothing to write.
+ At some point, we might want to change this to actually delete
+ the metafile in this case.
+ */
+ if (directory->details->metafile_tree == NULL)
+ return;
+
+ xmlDocDumpMemory (directory->details->metafile_tree, &buffer, &buffer_size);
+
+ metafile_handle = NULL;
+ result = gnome_vfs_create_uri (&metafile_handle,
+ directory->details->metafile_uri,
+ GNOME_VFS_OPEN_WRITE,
+ FALSE,
+ GNOME_VFS_PERM_USER_ALL | GNOME_VFS_PERM_GROUP_ALL | GNOME_VFS_PERM_OTHER_ALL);
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_write_metafile: gnome_vfs_create_uri failed");
+
+ if (result == GNOME_VFS_OK) {
+ result = gnome_vfs_write (metafile_handle, buffer, buffer_size, &actual_size);
+
+ if (result != GNOME_VFS_OK)
+ g_warning ("nautilus_directory_write_metafile: gnome_vfs_write failed");
+ else if (actual_size != buffer_size)
+ g_warning ("nautilus_directory_read_metafile: unable to write all");
+ }
+
+ if (metafile_handle != NULL)
+ gnome_vfs_close (metafile_handle);
+
+ xmlFree (buffer);
+}
+
+static gboolean
+nautilus_directory_write_metafile_on_idle (gpointer data)
+{
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (data), FALSE);
+ nautilus_directory_write_metafile (data);
+ return FALSE;
+}
+
+static void
+nautilus_directory_request_write_metafile (NautilusDirectory *directory)
+{
+ /* Set up an idle task that will write the metafile. */
+ if (directory->details->write_metafile_idle_id == 0)
+ directory->details->write_metafile_idle_id =
+ gtk_idle_add (nautilus_directory_write_metafile_on_idle,
+ directory);
+}
+
+#if NAUTILUS_DIRECTORY_ASYNC
+
+static void
+nautilus_directory_opened_metafile (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer callback_data)
+{
+}
+
+ result = gnome_vfs_async_open_uri (&metafile_handle, metafile_uri, GNOME_VFS_OPEN_READ,
+ nautilus_directory_opened_metafile, directory);
+#endif
+
+static NautilusDirectory *
+nautilus_directory_new (const char* uri)
+{
+ NautilusDirectory *directory;
+ GnomeVFSURI *vfs_uri;
+ GnomeVFSURI *metafile_uri;
+
+ vfs_uri = gnome_vfs_uri_new (uri);
+ if (vfs_uri == NULL)
+ return NULL;
+
+ metafile_uri = gnome_vfs_uri_append_path (vfs_uri, METAFILE_NAME);
+ if (metafile_uri == NULL)
+ return NULL;
+
+ directory = gtk_type_new (NAUTILUS_TYPE_DIRECTORY);
+
+ directory->details->uri_text = g_strdup (uri);
+ directory->details->uri = vfs_uri;
+ directory->details->metafile_uri = metafile_uri;
+
+ nautilus_directory_read_metafile (directory);
+
+ return directory;
+}
+
+void
+nautilus_directory_get_files (NautilusDirectory *directory,
+ NautilusFileListCallback callback,
+ gpointer callback_data)
+{
+ g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
+ g_return_if_fail (callback != NULL);
+
+ if (directory->details->files != NULL)
+ (* callback) (directory,
+ directory->details->files,
+ callback_data);
+}
+
+char *
+nautilus_directory_get_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata)
+{
+ xmlNode *root;
+ xmlChar *property;
+ char *result;
+
+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), NULL);
+ g_return_val_if_fail (tag, NULL);
+ g_return_val_if_fail (tag[0], NULL);
+
+ root = xmlDocGetRootElement (directory->details->metafile_tree);
+ property = xmlGetProp (root, tag);
+ if (property == NULL)
+ result = g_strdup (default_metadata);
+ else
+ result = g_strdup (property);
+ g_free (property);
+
+ return result;
+}
+
+void
+nautilus_directory_set_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata,
+ const char *metadata)
+{
+ char *old_metadata;
+ gboolean old_metadata_matches;
+ xmlNode *root;
+ const char *value;
+ xmlAttr *property_node;
+
+ g_return_if_fail (NAUTILUS_IS_DIRECTORY (directory));
+ g_return_if_fail (tag);
+ g_return_if_fail (tag[0]);
+
+ /* If the data in the metafile is already correct, do nothing. */
+ old_metadata = nautilus_directory_get_metadata (directory, tag, default_metadata);
+ old_metadata_matches = nautilus_strcmp (old_metadata, metadata) == 0;
+ g_free (old_metadata);
+ if (old_metadata_matches)
+ return;
+
+ /* Data that matches the default is represented in the tree by
+ the lack of an attribute.
+ */
+ if (nautilus_strcmp (default_metadata, metadata) == 0)
+ value = NULL;
+ else
+ value = metadata;
+
+ /* Get at the tree. */
+ if (directory->details->metafile_tree == NULL)
+ directory->details->metafile_tree = xmlNewDoc (METAFILE_XML_VERSION);
+ root = xmlDocGetRootElement (directory->details->metafile_tree);
+ if (root == NULL) {
+ root = xmlNewDocNode (directory->details->metafile_tree, NULL, "DIRECTORY", NULL);
+ xmlDocSetRootElement (directory->details->metafile_tree, root);
+ }
+
+ /* Add or remove an attribute node. */
+ property_node = xmlSetProp (root, tag, value);
+ if (value == NULL)
+ xmlRemoveProp (property_node);
+
+ /* Since we changed the tree, arrange for it to be written. */
+ nautilus_directory_request_write_metafile (directory);
+}
+
+#if !defined (NAUTILUS_OMIT_SELF_CHECK)
+
+static int data_dummy;
+static guint file_count;
+
+static void
+get_files_cb (NautilusDirectory *directory, NautilusFileList *files, gpointer data)
+{
+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
+ g_assert (files);
+ g_assert (data == &data_dummy);
+
+ file_count += g_list_length (files);
+}
+
+void
+nautilus_self_check_directory (void)
+{
+ NautilusDirectory *directory;
+
+ directory = nautilus_directory_get ("file:///etc");
+
+ g_assert (g_hash_table_size (directory_objects) == 1);
+
+ file_count = 0;
+ nautilus_directory_get_files (directory, get_files_cb, &data_dummy);
+
+ gtk_object_unref (GTK_OBJECT (directory));
+
+ g_assert (g_hash_table_size (directory_objects) == 0);
+}
+
+#endif /* !NAUTILUS_OMIT_SELF_CHECK */
diff --git a/libnautilus/nautilus-directory.h b/libnautilus/nautilus-directory.h
new file mode 100644
index 000000000..eed024e0b
--- /dev/null
+++ b/libnautilus/nautilus-directory.h
@@ -0,0 +1,166 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+
+ nautilus-directory.h: Nautilus directory model.
+
+ Copyright (C) 1999 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>
+*/
+
+#ifndef NAUTILUS_DIRECTORY_H
+#define NAUTILUS_DIRECTORY_H
+
+#include <gtk/gtkobject.h>
+
+/* NautilusDirectory is a class that manages the model for a directory,
+ real or virtual, for Nautilus, mainly the file-manager component. The directory is
+ responsible for managing both real data and cached metadata. On top of
+ the file system independence provided by gnome-vfs, the directory
+ object also provides:
+
+ 1) A synchronization framework, which notifies via signals as the
+ set of known files changes.
+ 2) An abstract interface for getting attributes and performing
+ operations on files.
+ 3) An interface that folds together the cached information that's
+ kept in the metafile with "trustworthy" versions of the same
+ information available from other means.
+*/
+
+typedef struct _NautilusDirectory NautilusDirectory;
+typedef struct _NautilusDirectoryClass NautilusDirectoryClass;
+
+#define NAUTILUS_TYPE_DIRECTORY \
+ (nautilus_directory_get_type ())
+#define NAUTILUS_DIRECTORY(obj) \
+ (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_DIRECTORY, NautilusDirectory))
+#define NAUTILUS_DIRECTORY_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_DIRECTORY, NautilusDirectoryClass))
+#define NAUTILUS_IS_DIRECTORY(obj) \
+ (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_DIRECTORY))
+#define NAUTILUS_IS_DIRECTORY_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_DIRECTORY))
+
+typedef struct _NautilusFile NautilusFile;
+typedef GList NautilusFileList;
+
+typedef void (*NautilusFileListCallback) (NautilusDirectory *directory,
+ NautilusFileList *files,
+ gpointer data);
+
+/* Basic GtkObject requirements. */
+GtkType nautilus_directory_get_type (void);
+
+/* Get a directory given a uri.
+ Creates the appropriate subclass given the uri mappings.
+ Returns a referenced object, not a floating one. Unref when finished.
+ If two windows are viewing the same uri, the directory object is shared.
+*/
+NautilusDirectory *nautilus_directory_get (const char *uri);
+
+/* Simple preliminary interface for getting and setting metadata. */
+char * nautilus_directory_get_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata);
+char * nautilus_directory_get_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *tag,
+ const char *default_metadata);
+void nautilus_directory_set_metadata (NautilusDirectory *directory,
+ const char *tag,
+ const char *default_metadata,
+ const char *metadata);
+void nautilus_directory_set_file_metadata (NautilusDirectory *directory,
+ const char *file_name,
+ const char *tag,
+ const char *default_metadata,
+ const char *metadata);
+
+/* Get the current files.
+ Instead of returning the list of files, this function uses a callback.
+ The directory guarantees that signals won't be emitted while in the
+ callback function.
+*/
+void nautilus_directory_get_files (NautilusDirectory *directory,
+ NautilusFileListCallback callback,
+ gpointer callback_data);
+
+/* Return true if the directory has enough information for layout.
+ This will be false until the metafile is read to prevent a partial layout
+ from being done.
+*/
+gboolean nautilus_directory_is_ready_for_layout (NautilusDirectory *directory);
+
+/* Basic operations on file objects. */
+void nautilus_file_ref (NautilusFile *file);
+void nautilus_file_unref (NautilusFile *file);
+char * nautilus_file_get_name (NautilusFile *file);
+
+/* Return true if this file has already been deleted.
+ This object will be unref'd after sending the files_removed signal,
+ but it could hang around longer if someone ref'd it.
+*/
+gboolean nautilus_file_is_gone (NautilusFile *file);
+
+typedef struct _NautilusDirectoryDetails NautilusDirectoryDetails;
+
+struct _NautilusDirectory
+{
+ GtkObject object;
+
+ /* Hidden details. */
+ NautilusDirectoryDetails *details;
+};
+
+struct _NautilusDirectoryClass
+{
+ GtkObjectClass parent_class;
+
+ /*** Notification signals for clients to connect to. ***/
+
+ /* The files_added and files_removed signals are emitted as
+ the directory model discovers new files or discovers that
+ old files have been deleted. In the case of files_removed,
+ this is the last chance to forget about these file objects
+ which are about to be unref'd.
+ */
+ void (* files_added) (NautilusDirectory *directory,
+ NautilusFileList *added_files);
+ void (* files_removed) (NautilusDirectory *directory,
+ NautilusFileList *removed_files);
+
+ /* The files_changed signal is emitted as changes occur to
+ existing files that are noticed by the synchronization framework.
+ The client must register which file attributes it is interested
+ in. Changes to other attributes are not reported via the signal.
+ */
+ void (* files_changed) (NautilusDirectory *directory,
+ NautilusFileList *changed_files);
+
+ /* The ready_for_layout signal is emitted when the directory
+ model judges that enough files are available for the layout
+ process to begin. For normal directories this is after the
+ metafile has been read. If there's no way to get the basic
+ layout information before getting the actual files, then
+ this signal need not be emitted as long as is_ready_for_layout
+ is already true.
+ */
+ void (* ready_for_layout) (NautilusDirectory *directory);
+};
+
+#endif /* NAUTILUS_DIRECTORY_H */
diff --git a/libnautilus/nautilus-lib-self-check-functions.c b/libnautilus/nautilus-lib-self-check-functions.c
index 8fd904042..76f06a41e 100644
--- a/libnautilus/nautilus-lib-self-check-functions.c
+++ b/libnautilus/nautilus-lib-self-check-functions.c
@@ -33,8 +33,7 @@
void nautilus_run_lib_self_checks ()
{
- nautilus_self_check_background ();
- nautilus_self_check_gdk_extensions ();
+ NAUTILUS_LIB_FOR_EACH_SELF_CHECK_FUNCTION (NAUTILUS_CALL_SELF_CHECK_FUNCTION)
}
#endif /* ! NAUTILUS_OMIT_SELF_CHECK */
diff --git a/libnautilus/nautilus-lib-self-check-functions.h b/libnautilus/nautilus-lib-self-check-functions.h
index 2b68bd8d6..eff8b1312 100644
--- a/libnautilus/nautilus-lib-self-check-functions.h
+++ b/libnautilus/nautilus-lib-self-check-functions.h
@@ -32,8 +32,17 @@ void nautilus_run_lib_self_checks (void);
the self-check framework take way too long (since one file would
have to include everything).
- So we put the prototypes here instead.
+ So we put the list of functions here instead.
+
+ Instead of just putting prototypes here, we put this macro that
+ can be used to do operations on the whole list of functions.
*/
-void nautilus_self_check_gdk_extensions (void);
-void nautilus_self_check_background (void);
+#define NAUTILUS_LIB_FOR_EACH_SELF_CHECK_FUNCTION(macro) \
+ macro(nautilus_self_check_background) \
+ macro(nautilus_self_check_directory) \
+ macro(nautilus_self_check_gdk_extensions) \
+/* Add new self-check functions to the list above this line. */
+
+/* Generate prototypes for all the functions. */
+NAUTILUS_LIB_FOR_EACH_SELF_CHECK_FUNCTION (NAUTILUS_SELF_CHECK_FUNCTION_PROTOTYPE)
diff --git a/libnautilus/nautilus-self-checks.h b/libnautilus/nautilus-self-checks.h
index bfbdd40c0..ab4b30ef3 100644
--- a/libnautilus/nautilus-self-checks.h
+++ b/libnautilus/nautilus-self-checks.h
@@ -51,4 +51,10 @@ G_STMT_START { \
#define NAUTILUS_CHECK_STRING_RESULT(expression, expected_value) \
NAUTILUS_CHECK_RESULT(string, expression, expected_value)
+#define NAUTILUS_SELF_CHECK_FUNCTION_PROTOTYPE(function) \
+ void function (void);
+
+#define NAUTILUS_CALL_SELF_CHECK_FUNCTION(function) \
+ function ();
+
#endif /* NAUTILUS_SELF_CHECKS_H */
diff --git a/src/file-manager/Makefile.am b/src/file-manager/Makefile.am
index e99b3e10a..8be362170 100644
--- a/src/file-manager/Makefile.am
+++ b/src/file-manager/Makefile.am
@@ -44,10 +44,6 @@ ntl_file_manager_SOURCES= \
fm-directory-view-icons.c \
fm-directory-view-list.h \
fm-directory-view-list.c \
- fm-directory.h \
- fm-directory.c \
- fm-vfs-directory.h \
- fm-vfs-directory.c \
fm-main.c
# noinst_PROGRAMS=gnome-desktop
diff --git a/src/file-manager/fm-directory-protected.h b/src/file-manager/fm-directory-protected.h
deleted file mode 100644
index adea65f16..000000000
--- a/src/file-manager/fm-directory-protected.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
-
- fm-directory-protected.h: GNOME file manager directory model,
- details for child classes only.
-
- Copyright (C) 1999 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>
-*/
-
-#ifndef FM_DIRECTORY_PROTECTED_H
-#define FM_DIRECTORY_PROTECTED_H
-
-#include "fm-directory.h"
-
-/* The word "protected" in the name of this file means that these are details of the
- FMDirectory class that need to be known to concrete child classes of FMDirectory,
- but not to clients of FMDirectory.
-
- The terminology is stolen from C++.
-*/
-
-struct _FMDirectoryDetails
-{
- char *hash_table_key; /* Could change this "URI" if we want to use it that way. */
-};
-
-struct _FMFile
-{
-};
-
-#endif /* FM_DIRECTORY_PROTECTED_H */
diff --git a/src/file-manager/fm-directory.c b/src/file-manager/fm-directory.c
deleted file mode 100644
index db359585a..000000000
--- a/src/file-manager/fm-directory.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
-
- fm-directory.c: GNOME file manager directory model.
-
- Copyright (C) 1999, 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>
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "fm-directory.h"
-
-#include "fm-directory-protected.h"
-#include "fm-vfs-directory.h"
-#include <gtk/gtksignal.h>
-#include <libnautilus/nautilus-gtk-macros.h>
-#include "../nautilus-self-check-functions.h"
-
-static void fm_directory_destroy (GtkObject *object);
-static void fm_directory_finalize (GtkObject *object);
-
-enum {
- GET_FILES,
- LAST_SIGNAL
-};
-
-static GtkObjectClass *parent_class;
-static guint signals[LAST_SIGNAL];
-
-static GHashTable* directory_objects;
-
-static void
-fm_directory_initialize_class (gpointer klass)
-{
- GtkObjectClass *object_class;
-
- object_class = GTK_OBJECT_CLASS (klass);
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
-
- signals[GET_FILES] =
- gtk_signal_new ("get_files",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (FMDirectoryClass, get_files),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE,
- 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
-
- gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
-
- object_class->destroy = fm_directory_destroy;
- object_class->finalize = fm_directory_finalize;
-}
-
-static void
-fm_directory_initialize (gpointer object, gpointer klass)
-{
- FMDirectory *directory;
-
- directory = FM_DIRECTORY(object);
-
- directory->details = g_new0 (FMDirectoryDetails, 1);
-}
-
-static void
-fm_directory_destroy (GtkObject *object)
-{
- FMDirectory *directory;
-
- directory = FM_DIRECTORY (object);
- g_hash_table_remove (directory_objects, directory->details->hash_table_key);
-
- NAUTILUS_CALL_PARENT_CLASS(GTK_OBJECT_CLASS, destroy, (object));
-}
-
-static void
-fm_directory_finalize (GtkObject *object)
-{
- FMDirectory *directory;
-
- directory = FM_DIRECTORY (object);
- g_free (directory->details->hash_table_key);
- g_free (directory->details);
-
- NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object));
-}
-
-NAUTILUS_DEFINE_GET_TYPE_FUNCTION (FMDirectory, fm_directory, GTK_TYPE_OBJECT)
-
-/**
- * fm_directory_get:
- * @uri: URI of directory to get.
- *
- * Get a directory given a uri.
- * Creates the appropriate subclass given the uri mappings.
- * Returns a referenced object, not a floating one. Unref when finished.
- * If two windows are viewing the same uri, the directory object is shared.
- */
-FMDirectory *
-fm_directory_get (const char *uri)
-{
- FMDirectory *directory;
-
- g_return_val_if_fail (uri != NULL, NULL);
-
- /* FIXME: This currently ignores the issue of two uris that are not identical but point
- to the same data.
- */
-
- /* Create the hash table first time through. */
- if (!directory_objects)
- directory_objects = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* If the object is already in the hash table, look it up. */
- directory = g_hash_table_lookup (directory_objects, uri);
- if (directory != NULL) {
- g_assert (FM_IS_DIRECTORY (directory));
- gtk_object_ref (GTK_OBJECT (directory));
- } else {
- /* Create a new directory object instead. */
- directory = FM_DIRECTORY (fm_vfs_directory_new (uri));
- g_assert (strcmp (directory->details->hash_table_key, uri) == 0);
-
- /* Put it in the hash table. */
- gtk_object_ref (GTK_OBJECT (directory));
- gtk_object_sink (GTK_OBJECT (directory));
- g_hash_table_insert (directory_objects, directory->details->hash_table_key, directory);
- }
-
- return directory;
-}
-
-void
-fm_directory_get_files (FMDirectory *directory,
- FMFileListCallback callback,
- gpointer callback_data)
-{
- g_return_if_fail (FM_IS_DIRECTORY (directory));
- g_return_if_fail (callback);
-
- gtk_signal_emit (GTK_OBJECT (directory), signals[GET_FILES], callback, callback_data);
-}
-
-/* self check code */
-
-#if !defined (NAUTILUS_OMIT_SELF_CHECK)
-
-static int data_dummy;
-static guint file_count;
-
-static void
-get_files_cb (FMDirectory *directory, FMFileList *files, gpointer data)
-{
- g_assert (FM_IS_DIRECTORY (directory));
- g_assert (files);
- g_assert (data == &data_dummy);
-
- file_count += g_list_length (files);
-}
-
-void
-nautilus_self_check_fm_directory (void)
-{
- FMDirectory *directory;
-
- directory = fm_directory_get ("file:///etc");
-
- g_assert (g_hash_table_size (directory_objects) == 1);
-
- file_count = 0;
- fm_directory_get_files (directory, get_files_cb, &data_dummy);
-
- gtk_object_unref (GTK_OBJECT (directory));
-
- g_assert (g_hash_table_size (directory_objects) == 0);
-}
-
-#endif /* !NAUTILUS_OMIT_SELF_CHECK */
diff --git a/src/file-manager/fm-directory.h b/src/file-manager/fm-directory.h
deleted file mode 100644
index d9fbd225e..000000000
--- a/src/file-manager/fm-directory.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
-
- fm-directory.h: GNOME file manager directory model
-
- Copyright (C) 1999 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>
-*/
-
-#ifndef FM_DIRECTORY_H
-#define FM_DIRECTORY_H
-
-#include <gtk/gtkobject.h>
-
-/* FMDirectory is an abstract class that manages the model for a directory,
- real or virtual, for the GNOME file manager. The directory is
- responsible for managing both real data and cached metadata. On top of
- the file system independence provided by GNOME VFS, the directory
- object also provides:
-
- 1) A synchronization framework, which notifies via signals as the
- set of known files changes.
- 2) An abstract interface for getting attributes and performing
- operations on files.
- 3) An interface that folds together the cached information that's
- kept in the metafile with "trustworthy" versions of the same
- information available from other means.
-
- In addition, none of the GnomeVFS interface is exposed directly, to
- help ensure that subclasses that are not based on GnomeVFS are possible.
-*/
-
-typedef struct _FMDirectory FMDirectory;
-typedef struct _FMDirectoryClass FMDirectoryClass;
-
-#define FM_TYPE_DIRECTORY \
- (fm_directory_get_type ())
-#define FM_DIRECTORY(obj) \
- (GTK_CHECK_CAST ((obj), FM_TYPE_DIRECTORY, FMDirectory))
-#define FM_DIRECTORY_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), FM_TYPE_DIRECTORY, FMDirectoryClass))
-#define FM_IS_DIRECTORY(obj) \
- (GTK_CHECK_TYPE ((obj), FM_TYPE_DIRECTORY))
-#define FM_IS_DIRECTORY_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), FM_TYPE_DIRECTORY))
-
-typedef struct _FMFile FMFile;
-typedef GList FMFileList;
-
-typedef void (*FMFileListCallback) (FMDirectory *directory,
- FMFileList *files,
- gpointer data);
-
-/* Basic GtkObject requirements. */
-GtkType fm_directory_get_type (void);
-
-/* Get a directory given a uri.
- Creates the appropriate subclass given the uri mappings.
- Returns a referenced object, not a floating one. Unref when finished.
- If two windows are viewing the same uri, the directory object is shared.
-*/
-FMDirectory *fm_directory_get (const char *uri);
-
-/* Get the current files.
- Instead of returning the list of files, this function uses a callback.
- The directory guarantees that signals won't be emitted while in the
- callback function.
-*/
-void fm_directory_get_files (FMDirectory *directory,
- FMFileListCallback callback,
- gpointer callback_data);
-
-/* Return true if the directory has enough information for layout.
- This will be false until the metafile is read to prevent a partial layout
- from being done.
-*/
-gboolean fm_directory_is_ready_for_layout (FMDirectory *directory);
-
-/* Basic operations on file objects. */
-void fm_file_ref (FMFile *file);
-void fm_file_unref (FMFile *file);
-char * fm_file_get_name (FMFile *file);
-
-/* Return true if this file has already been deleted.
- This object will be unref'd after sending the files_removed signal,
- but it could hang around longer if someone ref'd it.
-*/
-gboolean fm_file_is_gone (FMFile *file);
-
-typedef struct _FMDirectoryDetails FMDirectoryDetails;
-
-struct _FMDirectory
-{
- GtkObject object;
-
- /* Hidden details. */
- FMDirectoryDetails *details;
-};
-
-struct _FMDirectoryClass
-{
- GtkObjectClass parent_class;
-
- /*** Notification signals for clients to connect to. ***/
-
- /* The files_added and files_removed signals are emitted as
- the directory model discovers new files or discovers that
- old files have been deleted. In the case of files_removed,
- this is the last chance to forget about these file objects
- which are about to be unref'd.
- */
- void (* files_added) (FMDirectory *directory,
- FMFileList *added_files);
- void (* files_removed) (FMDirectory *directory,
- FMFileList *removed_files);
-
- /* The files_changed signal is emitted as changes occur to
- existing files that are noticed by the synchronization framework.
- The client must register which file attributes it is interested
- in. Changes to other attributes are not reported via the signal.
- */
- void (* files_changed) (FMDirectory *directory,
- FMFileList *changed_files);
-
- /* The ready_for_layout signal is emitted when the directory
- model judges that enough files are available for the layout
- process to begin. For normal directories this is after the
- metafile has been read. If there's no way to get the basic
- layout information before getting the actual files, then
- this signal need not be emitted as long as is_ready_for_layout
- is already true.
- */
- void (* ready_for_layout) (FMDirectory *directory);
-
- /*** Interface for FMDirectory subclasses to implement. ***/
-
- /* Implementation of fm_get_files. */
- void (* get_files) (FMDirectory *directory,
- FMFileListCallback callback,
- gpointer data);
-
- /* Implementation of destruction for an FMFile for an item
- in this directory.
- */
- void (* finalize_file) (FMFile *file);
-};
-
-#endif /* FM_DIRECTORY_H */
diff --git a/src/file-manager/fm-vfs-directory.c b/src/file-manager/fm-vfs-directory.c
deleted file mode 100644
index 8cfe3812b..000000000
--- a/src/file-manager/fm-vfs-directory.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
-
- fm-vfs-directory.c: GNOME file manager directory model, VFS implementation.
-
- Copyright (C) 1999, 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>
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "fm-vfs-directory.h"
-
-#include "fm-directory-protected.h"
-#include <libnautilus/nautilus-gtk-macros.h>
-#include <libgnomevfs/gnome-vfs.h>
-
-struct _FMVFSDirectoryDetails {
- GnomeVFSURI *uri;
-
- FMFileList *files;
-};
-
-static void fm_vfs_directory_destroy (GtkObject *object);
-static void fm_vfs_directory_finalize (GtkObject *object);
-static void fm_vfs_directory_get_files (FMDirectory *directory,
- FMFileListCallback callback,
- gpointer callback_data);
-
-static GtkObjectClass *parent_class;
-
-#define METAFILE_NAME ".gnomad.xml"
-
-/* The process of reading a directory:
-
- 1) Read and parse the metafile.
- 2) Read the directory to notice changes.
-*/
-
-static void
-fm_vfs_directory_initialize_class (gpointer klass)
-{
- GtkObjectClass *object_class;
- FMDirectoryClass *abstract_directory_class;
-
- object_class = GTK_OBJECT_CLASS (klass);
- abstract_directory_class = FM_DIRECTORY_CLASS (klass);
- parent_class = gtk_type_class (FM_TYPE_DIRECTORY);
-
- object_class->destroy = fm_vfs_directory_destroy;
- object_class->finalize = fm_vfs_directory_finalize;
-
- abstract_directory_class->get_files = fm_vfs_directory_get_files;
-}
-
-static void
-fm_vfs_directory_initialize (gpointer object, gpointer klass)
-{
- FMVFSDirectory *directory;
-
- directory = FM_VFS_DIRECTORY (object);
-
- directory->details = g_new0 (FMVFSDirectoryDetails, 1);
-}
-
-static void
-fm_vfs_directory_destroy (GtkObject *object)
-{
- NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
-}
-
-static void
-fm_vfs_directory_finalize (GtkObject *object)
-{
- FMVFSDirectory *directory;
-
- directory = FM_VFS_DIRECTORY (object);
- g_free (directory->details);
-
- NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object));
-}
-
-NAUTILUS_DEFINE_GET_TYPE_FUNCTION(FMVFSDirectory, fm_vfs_directory, FM_TYPE_DIRECTORY)
-
-static void
-fm_vfs_opened_metafile (GnomeVFSAsyncHandle *handle,
- GnomeVFSResult result,
- gpointer callback_data)
-{
-}
-
-FMVFSDirectory *
-fm_vfs_directory_new (const char* uri)
-{
- FMVFSDirectory *directory;
- GnomeVFSURI *vfs_uri;
- GnomeVFSURI *metafile_uri;
- GnomeVFSAsyncHandle *metafile_handle;
- GnomeVFSResult result;
-
- vfs_uri = gnome_vfs_uri_new (uri);
- if (vfs_uri == NULL)
- return NULL;
-
- metafile_uri = gnome_vfs_uri_append_path (vfs_uri, METAFILE_NAME);
- if (metafile_uri == NULL)
- return NULL;
-
- directory = gtk_type_new (FM_TYPE_VFS_DIRECTORY);
-
- FM_DIRECTORY (directory)->details->hash_table_key = g_strdup (uri);
-
- directory->details->uri = vfs_uri;
-
- result = gnome_vfs_async_open_uri (&metafile_handle, metafile_uri, GNOME_VFS_OPEN_READ,
- fm_vfs_opened_metafile, directory);
-
- return directory;
-}
-
-static void
-fm_vfs_directory_get_files (FMDirectory *abstract_directory,
- FMFileListCallback callback,
- gpointer callback_data)
-{
- FMVFSDirectory *directory;
-
- g_return_if_fail (FM_IS_VFS_DIRECTORY (abstract_directory));
- g_return_if_fail (callback != NULL);
-
- directory = FM_VFS_DIRECTORY (abstract_directory);
- if (directory->details->files != NULL)
- (* callback) (abstract_directory,
- directory->details->files,
- callback_data);
-}
diff --git a/src/file-manager/fm-vfs-directory.h b/src/file-manager/fm-vfs-directory.h
deleted file mode 100644
index a9627c0c1..000000000
--- a/src/file-manager/fm-vfs-directory.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
-
- fm-vfs-directory.c: GNOME file manager directory model, VFS implementation.
-
- Copyright (C) 1999 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>
- */
-
-#ifndef FM_VFS_DIRECTORY_H
-#define FM_VFS_DIRECTORY_H
-
-#include "fm-directory.h"
-
-/* FMVFSDirectory is the concrete VFS implementation of FMDirectory. */
-
-typedef struct _FMVFSDirectory FMVFSDirectory;
-typedef struct _FMVFSDirectoryClass FMVFSDirectoryClass;
-
-#define FM_TYPE_VFS_DIRECTORY \
- (fm_vfs_directory_get_type ())
-#define FM_VFS_DIRECTORY(obj) \
- (GTK_CHECK_CAST ((obj), FM_TYPE_VFS_DIRECTORY, FMVFSDirectory))
-#define FM_VFS_DIRECTORY_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), FM_TYPE_VFS_DIRECTORY, FMVFSDirectoryClass))
-#define FM_IS_VFS_DIRECTORY(obj) \
- (GTK_CHECK_TYPE ((obj), FM_TYPE_VFS_DIRECTORY))
-#define FM_IS_VFS_DIRECTORY_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), FM_TYPE_VFS_DIRECTORY))
-
-typedef struct _FMVFSDirectoryDetails FMVFSDirectoryDetails;
-
-struct _FMVFSDirectory
-{
- FMDirectory abstract_directory;
-
- FMVFSDirectoryDetails *details;
-};
-
-struct _FMVFSDirectoryClass
-{
- FMDirectoryClass parent_class;
-};
-
-/* Basic GtkObject requirements. */
-GtkType fm_vfs_directory_get_type (void);
-FMVFSDirectory *fm_vfs_directory_new (const char *uri);
-
-#endif /* FM_VFS_DIRECTORY_H */
diff --git a/src/nautilus-information-panel.c b/src/nautilus-information-panel.c
index f580100a3..2a68ecdbe 100644
--- a/src/nautilus-information-panel.c
+++ b/src/nautilus-information-panel.c
@@ -29,12 +29,21 @@
#include "ntl-meta-view.h"
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libnautilus/nautilus-background.h>
+#include <libnautilus/nautilus-directory.h>
#include <libnautilus/nautilus-gtk-macros.h>
#include <libnautilus/nautilus-string.h>
#define ARRAY_LENGTH(array) \
(sizeof (array) / sizeof ((array)[0]))
+struct _NautilusIndexPanelDetails {
+ GtkWidget *index_container;
+ GtkWidget *per_uri_container;
+ GtkWidget *meta_tabs;
+ gchar *uri;
+ NautilusDirectory *directory;
+};
+
static void nautilus_index_panel_initialize_class (gpointer klass);
static void nautilus_index_panel_initialize (gpointer object, gpointer klass);
static void nautilus_index_panel_destroy (GtkObject *object);
@@ -53,6 +62,8 @@ static GdkFont *select_font(const gchar *text_to_format, gint width, const gchar
static GtkObjectClass *parent_class;
+#define DEFAULT_BACKGROUND_COLOR "rgb:DDDD/DDDD/FFFF"
+
/* drag and drop definitions */
enum dnd_targets_enum
@@ -87,10 +98,11 @@ nautilus_index_panel_initialize_class (gpointer klass)
static void make_per_uri_container(NautilusIndexPanel *index_panel)
{
- index_panel->per_uri_container = gtk_vbox_new (FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (index_panel->per_uri_container), 0);
- gtk_widget_show (index_panel->per_uri_container);
- gtk_box_pack_start (GTK_BOX (index_panel->index_container), index_panel->per_uri_container, FALSE, FALSE, 0);
+ index_panel->details->per_uri_container = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (index_panel->details->per_uri_container), 0);
+ gtk_widget_show (index_panel->details->per_uri_container);
+ gtk_box_pack_start (GTK_BOX (index_panel->details->index_container),
+ index_panel->details->per_uri_container, FALSE, FALSE, 0);
}
/* initialize the instance's fields, create the necessary subviews, etc. */
@@ -103,25 +115,27 @@ nautilus_index_panel_initialize (gpointer object, gpointer klass)
index_panel = NAUTILUS_INDEX_PANEL (object);
widget = GTK_WIDGET (object);
+
+ index_panel->details = g_new0 (NautilusIndexPanelDetails, 1);
/* set the size of the index panel */
gtk_widget_set_usize (widget, 136, 400);
/* create the container box */
- index_panel->index_container = gtk_vbox_new (FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (index_panel->index_container), 0);
- gtk_widget_show (index_panel->index_container);
- gtk_container_add (GTK_CONTAINER (index_panel), index_panel->index_container);
+ index_panel->details->index_container = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (index_panel->details->index_container), 0);
+ gtk_widget_show (index_panel->details->index_container);
+ gtk_container_add (GTK_CONTAINER (index_panel), index_panel->details->index_container);
/* allocate and install the vbox to hold the per-uri information */
make_per_uri_container (index_panel);
/* allocate and install the meta-tabs (for now it's a notebook) */
- index_panel->meta_tabs = gtk_notebook_new ();
- gtk_widget_set_usize (index_panel->meta_tabs, 136, 200);
- gtk_widget_show (index_panel->meta_tabs);
- gtk_box_pack_end (GTK_BOX (index_panel->index_container), index_panel->meta_tabs, FALSE, FALSE, 0);
+ index_panel->details->meta_tabs = gtk_notebook_new ();
+ gtk_widget_set_usize (index_panel->details->meta_tabs, 136, 200);
+ gtk_widget_show (index_panel->details->meta_tabs);
+ gtk_box_pack_end (GTK_BOX (index_panel->details->index_container), index_panel->details->meta_tabs, FALSE, FALSE, 0);
/* prepare ourselves to receive dropped objects */
gtk_drag_dest_set (GTK_WIDGET (index_panel),
@@ -146,7 +160,8 @@ nautilus_index_panel_finalize (GtkObject *object)
index_panel = NAUTILUS_INDEX_PANEL (object);
- g_free (index_panel->uri);
+ g_free (index_panel->details->uri);
+ g_free (index_panel->details);
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object));
}
@@ -190,8 +205,14 @@ nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *cont
case TARGET_COLOR:
data = (guint16 *)selection_data->data;
color_spec = g_strdup_printf ("rgb:%04hX/%04hX/%04hX", data[0], data[1], data[2]);
+
+ nautilus_directory_set_metadata (NAUTILUS_INDEX_PANEL (widget)->details->directory,
+ "index_panel_background_color",
+ DEFAULT_BACKGROUND_COLOR,
+ color_spec);
background = nautilus_get_widget_background (widget);
nautilus_background_set_color (background, color_spec);
+
g_free (color_spec);
break;
@@ -224,7 +245,7 @@ void nautilus_index_panel_add_meta_view (NautilusIndexPanel *index_panel, Nautil
GTK_SIGNAL_FUNC(nautilus_window_send_show_properties), meta_view);
*/
- gtk_notebook_prepend_page (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view), label);
+ gtk_notebook_prepend_page (GTK_NOTEBOOK (index_panel->details->meta_tabs), GTK_WIDGET (meta_view), label);
gtk_widget_show (GTK_WIDGET (meta_view));
}
@@ -233,9 +254,9 @@ void nautilus_index_panel_remove_meta_view (NautilusIndexPanel *index_panel, Nau
{
gint page_num;
- page_num = gtk_notebook_page_num (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view));
+ page_num = gtk_notebook_page_num (GTK_NOTEBOOK (index_panel->details->meta_tabs), GTK_WIDGET (meta_view));
g_return_if_fail (page_num >= 0);
- gtk_notebook_remove_page (GTK_NOTEBOOK (index_panel->meta_tabs), page_num);
+ gtk_notebook_remove_page (GTK_NOTEBOOK (index_panel->details->meta_tabs), page_num);
}
/* set up the logo image */
@@ -247,7 +268,7 @@ void nautilus_index_panel_set_up_logo (NautilusIndexPanel *index_panel, const gc
file_name = gnome_pixmap_file (logo_path);
pix_widget = GTK_WIDGET (gnome_pixmap_new_from_file (file_name));
gtk_widget_show (pix_widget);
- gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), pix_widget, 0, 0, 0);
+ gtk_box_pack_start (GTK_BOX (index_panel->details->per_uri_container), pix_widget, 0, 0, 0);
g_free (file_name);
}
@@ -326,7 +347,7 @@ nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar
return;
label_widget = gtk_label_new (file_name);
- gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), label_widget, 0, 0, 0);
+ gtk_box_pack_start (GTK_BOX (index_panel->details->per_uri_container), label_widget, 0, 0, 0);
label_font = select_font(file_name, GTK_WIDGET (index_panel)->allocation.width - 4,
"-bitstream-courier-medium-r-normal-*-%d-*-*-*-*-*-*-*");
@@ -348,11 +369,22 @@ nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar
void nautilus_index_panel_set_up_info (NautilusIndexPanel *index_panel, const gchar* new_uri)
{
+ NautilusDirectory *directory;
NautilusBackground *background;
+ char *background_color;
+
+ directory = nautilus_directory_get (new_uri);
+ if (index_panel->details->directory != NULL)
+ gtk_object_unref (GTK_OBJECT (index_panel->details->directory));
+ index_panel->details->directory = directory;
- /* set up the background from the metadata. At first, just use hardwired backgrounds */
+ /* Set up the background from the metadata. */
background = nautilus_get_widget_background (GTK_WIDGET (index_panel));
- nautilus_background_set_color (background, "rgb:DDDD/DDDD/FFFF");
+ background_color = nautilus_directory_get_metadata (directory,
+ "index_panel_background_color",
+ DEFAULT_BACKGROUND_COLOR);
+ nautilus_background_set_color (background, background_color);
+ g_free (background_color);
/* next, install the logo image. */
/* For now, just use a fixed folder image */
@@ -375,14 +407,14 @@ void nautilus_index_panel_set_uri (NautilusIndexPanel *index_panel, const gchar*
{
/* there's nothing to do if the uri is the same as the current one */
- if (nautilus_strcmp (index_panel->uri, new_uri) == 0)
+ if (nautilus_strcmp (index_panel->details->uri, new_uri) == 0)
return;
- g_free (index_panel->uri);
- index_panel->uri = g_strdup (new_uri);
+ g_free (index_panel->details->uri);
+ index_panel->details->uri = g_strdup (new_uri);
/* get rid of the old widgets in the per_uri container */
- gtk_widget_destroy (index_panel->per_uri_container);
+ gtk_widget_destroy (index_panel->details->per_uri_container);
make_per_uri_container (index_panel);
/* populate the per-uri box with the info */
diff --git a/src/nautilus-information-panel.h b/src/nautilus-information-panel.h
index f2fb10325..24c2a4373 100644
--- a/src/nautilus-information-panel.h
+++ b/src/nautilus-information-panel.h
@@ -43,13 +43,12 @@ typedef struct _NautilusIndexPanelClass NautilusIndexPanelClass;
#define NAUTILUS_IS_INDEX_PANEL_CLASS(klass) \
(GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_INDEX_PANEL))
+typedef struct _NautilusIndexPanelDetails NautilusIndexPanelDetails;
+
struct _NautilusIndexPanel
{
GtkEventBox event_box;
- GtkWidget *index_container;
- GtkWidget *per_uri_container;
- GtkWidget *meta_tabs;
- gchar *uri;
+ NautilusIndexPanelDetails *details;
};
struct _NautilusIndexPanelClass
diff --git a/src/nautilus-self-check-functions.c b/src/nautilus-self-check-functions.c
index 14d8dffe1..11248bc9b 100644
--- a/src/nautilus-self-check-functions.c
+++ b/src/nautilus-self-check-functions.c
@@ -33,9 +33,7 @@
void nautilus_run_self_checks()
{
-#if 0
- nautilus_self_check_fm_directory();
-#endif
+ NAUTILUS_FOR_EACH_SELF_CHECK_FUNCTION (NAUTILUS_CALL_SELF_CHECK_FUNCTION)
}
#endif /* ! NAUTILUS_OMIT_SELF_CHECK */
diff --git a/src/nautilus-self-check-functions.h b/src/nautilus-self-check-functions.h
index 6c11cf9bc..7c0479212 100644
--- a/src/nautilus-self-check-functions.h
+++ b/src/nautilus-self-check-functions.h
@@ -30,7 +30,14 @@ void nautilus_run_self_checks (void);
the self-check framework take way too long (since one file would
have to include everything).
- So we put the prototypes here instead.
+ So we put the list of functions here instead.
+
+ Instead of just putting prototypes here, we put this macro that
+ can be used to do operations on the whole list of functions.
*/
-void nautilus_self_check_fm_directory (void);
+#define NAUTILUS_FOR_EACH_SELF_CHECK_FUNCTION(macro) \
+/* Add new self-check functions to the list above this line. */
+
+/* Generate prototypes for all the functions. */
+NAUTILUS_FOR_EACH_SELF_CHECK_FUNCTION (NAUTILUS_SELF_CHECK_FUNCTION_PROTOTYPE)
diff --git a/src/nautilus-sidebar.c b/src/nautilus-sidebar.c
index f580100a3..2a68ecdbe 100644
--- a/src/nautilus-sidebar.c
+++ b/src/nautilus-sidebar.c
@@ -29,12 +29,21 @@
#include "ntl-meta-view.h"
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libnautilus/nautilus-background.h>
+#include <libnautilus/nautilus-directory.h>
#include <libnautilus/nautilus-gtk-macros.h>
#include <libnautilus/nautilus-string.h>
#define ARRAY_LENGTH(array) \
(sizeof (array) / sizeof ((array)[0]))
+struct _NautilusIndexPanelDetails {
+ GtkWidget *index_container;
+ GtkWidget *per_uri_container;
+ GtkWidget *meta_tabs;
+ gchar *uri;
+ NautilusDirectory *directory;
+};
+
static void nautilus_index_panel_initialize_class (gpointer klass);
static void nautilus_index_panel_initialize (gpointer object, gpointer klass);
static void nautilus_index_panel_destroy (GtkObject *object);
@@ -53,6 +62,8 @@ static GdkFont *select_font(const gchar *text_to_format, gint width, const gchar
static GtkObjectClass *parent_class;
+#define DEFAULT_BACKGROUND_COLOR "rgb:DDDD/DDDD/FFFF"
+
/* drag and drop definitions */
enum dnd_targets_enum
@@ -87,10 +98,11 @@ nautilus_index_panel_initialize_class (gpointer klass)
static void make_per_uri_container(NautilusIndexPanel *index_panel)
{
- index_panel->per_uri_container = gtk_vbox_new (FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (index_panel->per_uri_container), 0);
- gtk_widget_show (index_panel->per_uri_container);
- gtk_box_pack_start (GTK_BOX (index_panel->index_container), index_panel->per_uri_container, FALSE, FALSE, 0);
+ index_panel->details->per_uri_container = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (index_panel->details->per_uri_container), 0);
+ gtk_widget_show (index_panel->details->per_uri_container);
+ gtk_box_pack_start (GTK_BOX (index_panel->details->index_container),
+ index_panel->details->per_uri_container, FALSE, FALSE, 0);
}
/* initialize the instance's fields, create the necessary subviews, etc. */
@@ -103,25 +115,27 @@ nautilus_index_panel_initialize (gpointer object, gpointer klass)
index_panel = NAUTILUS_INDEX_PANEL (object);
widget = GTK_WIDGET (object);
+
+ index_panel->details = g_new0 (NautilusIndexPanelDetails, 1);
/* set the size of the index panel */
gtk_widget_set_usize (widget, 136, 400);
/* create the container box */
- index_panel->index_container = gtk_vbox_new (FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (index_panel->index_container), 0);
- gtk_widget_show (index_panel->index_container);
- gtk_container_add (GTK_CONTAINER (index_panel), index_panel->index_container);
+ index_panel->details->index_container = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (index_panel->details->index_container), 0);
+ gtk_widget_show (index_panel->details->index_container);
+ gtk_container_add (GTK_CONTAINER (index_panel), index_panel->details->index_container);
/* allocate and install the vbox to hold the per-uri information */
make_per_uri_container (index_panel);
/* allocate and install the meta-tabs (for now it's a notebook) */
- index_panel->meta_tabs = gtk_notebook_new ();
- gtk_widget_set_usize (index_panel->meta_tabs, 136, 200);
- gtk_widget_show (index_panel->meta_tabs);
- gtk_box_pack_end (GTK_BOX (index_panel->index_container), index_panel->meta_tabs, FALSE, FALSE, 0);
+ index_panel->details->meta_tabs = gtk_notebook_new ();
+ gtk_widget_set_usize (index_panel->details->meta_tabs, 136, 200);
+ gtk_widget_show (index_panel->details->meta_tabs);
+ gtk_box_pack_end (GTK_BOX (index_panel->details->index_container), index_panel->details->meta_tabs, FALSE, FALSE, 0);
/* prepare ourselves to receive dropped objects */
gtk_drag_dest_set (GTK_WIDGET (index_panel),
@@ -146,7 +160,8 @@ nautilus_index_panel_finalize (GtkObject *object)
index_panel = NAUTILUS_INDEX_PANEL (object);
- g_free (index_panel->uri);
+ g_free (index_panel->details->uri);
+ g_free (index_panel->details);
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object));
}
@@ -190,8 +205,14 @@ nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *cont
case TARGET_COLOR:
data = (guint16 *)selection_data->data;
color_spec = g_strdup_printf ("rgb:%04hX/%04hX/%04hX", data[0], data[1], data[2]);
+
+ nautilus_directory_set_metadata (NAUTILUS_INDEX_PANEL (widget)->details->directory,
+ "index_panel_background_color",
+ DEFAULT_BACKGROUND_COLOR,
+ color_spec);
background = nautilus_get_widget_background (widget);
nautilus_background_set_color (background, color_spec);
+
g_free (color_spec);
break;
@@ -224,7 +245,7 @@ void nautilus_index_panel_add_meta_view (NautilusIndexPanel *index_panel, Nautil
GTK_SIGNAL_FUNC(nautilus_window_send_show_properties), meta_view);
*/
- gtk_notebook_prepend_page (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view), label);
+ gtk_notebook_prepend_page (GTK_NOTEBOOK (index_panel->details->meta_tabs), GTK_WIDGET (meta_view), label);
gtk_widget_show (GTK_WIDGET (meta_view));
}
@@ -233,9 +254,9 @@ void nautilus_index_panel_remove_meta_view (NautilusIndexPanel *index_panel, Nau
{
gint page_num;
- page_num = gtk_notebook_page_num (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view));
+ page_num = gtk_notebook_page_num (GTK_NOTEBOOK (index_panel->details->meta_tabs), GTK_WIDGET (meta_view));
g_return_if_fail (page_num >= 0);
- gtk_notebook_remove_page (GTK_NOTEBOOK (index_panel->meta_tabs), page_num);
+ gtk_notebook_remove_page (GTK_NOTEBOOK (index_panel->details->meta_tabs), page_num);
}
/* set up the logo image */
@@ -247,7 +268,7 @@ void nautilus_index_panel_set_up_logo (NautilusIndexPanel *index_panel, const gc
file_name = gnome_pixmap_file (logo_path);
pix_widget = GTK_WIDGET (gnome_pixmap_new_from_file (file_name));
gtk_widget_show (pix_widget);
- gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), pix_widget, 0, 0, 0);
+ gtk_box_pack_start (GTK_BOX (index_panel->details->per_uri_container), pix_widget, 0, 0, 0);
g_free (file_name);
}
@@ -326,7 +347,7 @@ nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar
return;
label_widget = gtk_label_new (file_name);
- gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), label_widget, 0, 0, 0);
+ gtk_box_pack_start (GTK_BOX (index_panel->details->per_uri_container), label_widget, 0, 0, 0);
label_font = select_font(file_name, GTK_WIDGET (index_panel)->allocation.width - 4,
"-bitstream-courier-medium-r-normal-*-%d-*-*-*-*-*-*-*");
@@ -348,11 +369,22 @@ nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar
void nautilus_index_panel_set_up_info (NautilusIndexPanel *index_panel, const gchar* new_uri)
{
+ NautilusDirectory *directory;
NautilusBackground *background;
+ char *background_color;
+
+ directory = nautilus_directory_get (new_uri);
+ if (index_panel->details->directory != NULL)
+ gtk_object_unref (GTK_OBJECT (index_panel->details->directory));
+ index_panel->details->directory = directory;
- /* set up the background from the metadata. At first, just use hardwired backgrounds */
+ /* Set up the background from the metadata. */
background = nautilus_get_widget_background (GTK_WIDGET (index_panel));
- nautilus_background_set_color (background, "rgb:DDDD/DDDD/FFFF");
+ background_color = nautilus_directory_get_metadata (directory,
+ "index_panel_background_color",
+ DEFAULT_BACKGROUND_COLOR);
+ nautilus_background_set_color (background, background_color);
+ g_free (background_color);
/* next, install the logo image. */
/* For now, just use a fixed folder image */
@@ -375,14 +407,14 @@ void nautilus_index_panel_set_uri (NautilusIndexPanel *index_panel, const gchar*
{
/* there's nothing to do if the uri is the same as the current one */
- if (nautilus_strcmp (index_panel->uri, new_uri) == 0)
+ if (nautilus_strcmp (index_panel->details->uri, new_uri) == 0)
return;
- g_free (index_panel->uri);
- index_panel->uri = g_strdup (new_uri);
+ g_free (index_panel->details->uri);
+ index_panel->details->uri = g_strdup (new_uri);
/* get rid of the old widgets in the per_uri container */
- gtk_widget_destroy (index_panel->per_uri_container);
+ gtk_widget_destroy (index_panel->details->per_uri_container);
make_per_uri_container (index_panel);
/* populate the per-uri box with the info */
diff --git a/src/nautilus-sidebar.h b/src/nautilus-sidebar.h
index f2fb10325..24c2a4373 100644
--- a/src/nautilus-sidebar.h
+++ b/src/nautilus-sidebar.h
@@ -43,13 +43,12 @@ typedef struct _NautilusIndexPanelClass NautilusIndexPanelClass;
#define NAUTILUS_IS_INDEX_PANEL_CLASS(klass) \
(GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_INDEX_PANEL))
+typedef struct _NautilusIndexPanelDetails NautilusIndexPanelDetails;
+
struct _NautilusIndexPanel
{
GtkEventBox event_box;
- GtkWidget *index_container;
- GtkWidget *per_uri_container;
- GtkWidget *meta_tabs;
- gchar *uri;
+ NautilusIndexPanelDetails *details;
};
struct _NautilusIndexPanelClass
diff --git a/src/ntl-index-panel.c b/src/ntl-index-panel.c
index f580100a3..2a68ecdbe 100644
--- a/src/ntl-index-panel.c
+++ b/src/ntl-index-panel.c
@@ -29,12 +29,21 @@
#include "ntl-meta-view.h"
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libnautilus/nautilus-background.h>
+#include <libnautilus/nautilus-directory.h>
#include <libnautilus/nautilus-gtk-macros.h>
#include <libnautilus/nautilus-string.h>
#define ARRAY_LENGTH(array) \
(sizeof (array) / sizeof ((array)[0]))
+struct _NautilusIndexPanelDetails {
+ GtkWidget *index_container;
+ GtkWidget *per_uri_container;
+ GtkWidget *meta_tabs;
+ gchar *uri;
+ NautilusDirectory *directory;
+};
+
static void nautilus_index_panel_initialize_class (gpointer klass);
static void nautilus_index_panel_initialize (gpointer object, gpointer klass);
static void nautilus_index_panel_destroy (GtkObject *object);
@@ -53,6 +62,8 @@ static GdkFont *select_font(const gchar *text_to_format, gint width, const gchar
static GtkObjectClass *parent_class;
+#define DEFAULT_BACKGROUND_COLOR "rgb:DDDD/DDDD/FFFF"
+
/* drag and drop definitions */
enum dnd_targets_enum
@@ -87,10 +98,11 @@ nautilus_index_panel_initialize_class (gpointer klass)
static void make_per_uri_container(NautilusIndexPanel *index_panel)
{
- index_panel->per_uri_container = gtk_vbox_new (FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (index_panel->per_uri_container), 0);
- gtk_widget_show (index_panel->per_uri_container);
- gtk_box_pack_start (GTK_BOX (index_panel->index_container), index_panel->per_uri_container, FALSE, FALSE, 0);
+ index_panel->details->per_uri_container = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (index_panel->details->per_uri_container), 0);
+ gtk_widget_show (index_panel->details->per_uri_container);
+ gtk_box_pack_start (GTK_BOX (index_panel->details->index_container),
+ index_panel->details->per_uri_container, FALSE, FALSE, 0);
}
/* initialize the instance's fields, create the necessary subviews, etc. */
@@ -103,25 +115,27 @@ nautilus_index_panel_initialize (gpointer object, gpointer klass)
index_panel = NAUTILUS_INDEX_PANEL (object);
widget = GTK_WIDGET (object);
+
+ index_panel->details = g_new0 (NautilusIndexPanelDetails, 1);
/* set the size of the index panel */
gtk_widget_set_usize (widget, 136, 400);
/* create the container box */
- index_panel->index_container = gtk_vbox_new (FALSE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (index_panel->index_container), 0);
- gtk_widget_show (index_panel->index_container);
- gtk_container_add (GTK_CONTAINER (index_panel), index_panel->index_container);
+ index_panel->details->index_container = gtk_vbox_new (FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (index_panel->details->index_container), 0);
+ gtk_widget_show (index_panel->details->index_container);
+ gtk_container_add (GTK_CONTAINER (index_panel), index_panel->details->index_container);
/* allocate and install the vbox to hold the per-uri information */
make_per_uri_container (index_panel);
/* allocate and install the meta-tabs (for now it's a notebook) */
- index_panel->meta_tabs = gtk_notebook_new ();
- gtk_widget_set_usize (index_panel->meta_tabs, 136, 200);
- gtk_widget_show (index_panel->meta_tabs);
- gtk_box_pack_end (GTK_BOX (index_panel->index_container), index_panel->meta_tabs, FALSE, FALSE, 0);
+ index_panel->details->meta_tabs = gtk_notebook_new ();
+ gtk_widget_set_usize (index_panel->details->meta_tabs, 136, 200);
+ gtk_widget_show (index_panel->details->meta_tabs);
+ gtk_box_pack_end (GTK_BOX (index_panel->details->index_container), index_panel->details->meta_tabs, FALSE, FALSE, 0);
/* prepare ourselves to receive dropped objects */
gtk_drag_dest_set (GTK_WIDGET (index_panel),
@@ -146,7 +160,8 @@ nautilus_index_panel_finalize (GtkObject *object)
index_panel = NAUTILUS_INDEX_PANEL (object);
- g_free (index_panel->uri);
+ g_free (index_panel->details->uri);
+ g_free (index_panel->details);
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, finalize, (object));
}
@@ -190,8 +205,14 @@ nautilus_index_panel_drag_data_received (GtkWidget *widget, GdkDragContext *cont
case TARGET_COLOR:
data = (guint16 *)selection_data->data;
color_spec = g_strdup_printf ("rgb:%04hX/%04hX/%04hX", data[0], data[1], data[2]);
+
+ nautilus_directory_set_metadata (NAUTILUS_INDEX_PANEL (widget)->details->directory,
+ "index_panel_background_color",
+ DEFAULT_BACKGROUND_COLOR,
+ color_spec);
background = nautilus_get_widget_background (widget);
nautilus_background_set_color (background, color_spec);
+
g_free (color_spec);
break;
@@ -224,7 +245,7 @@ void nautilus_index_panel_add_meta_view (NautilusIndexPanel *index_panel, Nautil
GTK_SIGNAL_FUNC(nautilus_window_send_show_properties), meta_view);
*/
- gtk_notebook_prepend_page (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view), label);
+ gtk_notebook_prepend_page (GTK_NOTEBOOK (index_panel->details->meta_tabs), GTK_WIDGET (meta_view), label);
gtk_widget_show (GTK_WIDGET (meta_view));
}
@@ -233,9 +254,9 @@ void nautilus_index_panel_remove_meta_view (NautilusIndexPanel *index_panel, Nau
{
gint page_num;
- page_num = gtk_notebook_page_num (GTK_NOTEBOOK (index_panel->meta_tabs), GTK_WIDGET (meta_view));
+ page_num = gtk_notebook_page_num (GTK_NOTEBOOK (index_panel->details->meta_tabs), GTK_WIDGET (meta_view));
g_return_if_fail (page_num >= 0);
- gtk_notebook_remove_page (GTK_NOTEBOOK (index_panel->meta_tabs), page_num);
+ gtk_notebook_remove_page (GTK_NOTEBOOK (index_panel->details->meta_tabs), page_num);
}
/* set up the logo image */
@@ -247,7 +268,7 @@ void nautilus_index_panel_set_up_logo (NautilusIndexPanel *index_panel, const gc
file_name = gnome_pixmap_file (logo_path);
pix_widget = GTK_WIDGET (gnome_pixmap_new_from_file (file_name));
gtk_widget_show (pix_widget);
- gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), pix_widget, 0, 0, 0);
+ gtk_box_pack_start (GTK_BOX (index_panel->details->per_uri_container), pix_widget, 0, 0, 0);
g_free (file_name);
}
@@ -326,7 +347,7 @@ nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar
return;
label_widget = gtk_label_new (file_name);
- gtk_box_pack_start (GTK_BOX (index_panel->per_uri_container), label_widget, 0, 0, 0);
+ gtk_box_pack_start (GTK_BOX (index_panel->details->per_uri_container), label_widget, 0, 0, 0);
label_font = select_font(file_name, GTK_WIDGET (index_panel)->allocation.width - 4,
"-bitstream-courier-medium-r-normal-*-%d-*-*-*-*-*-*-*");
@@ -348,11 +369,22 @@ nautilus_index_panel_set_up_label (NautilusIndexPanel *index_panel, const gchar
void nautilus_index_panel_set_up_info (NautilusIndexPanel *index_panel, const gchar* new_uri)
{
+ NautilusDirectory *directory;
NautilusBackground *background;
+ char *background_color;
+
+ directory = nautilus_directory_get (new_uri);
+ if (index_panel->details->directory != NULL)
+ gtk_object_unref (GTK_OBJECT (index_panel->details->directory));
+ index_panel->details->directory = directory;
- /* set up the background from the metadata. At first, just use hardwired backgrounds */
+ /* Set up the background from the metadata. */
background = nautilus_get_widget_background (GTK_WIDGET (index_panel));
- nautilus_background_set_color (background, "rgb:DDDD/DDDD/FFFF");
+ background_color = nautilus_directory_get_metadata (directory,
+ "index_panel_background_color",
+ DEFAULT_BACKGROUND_COLOR);
+ nautilus_background_set_color (background, background_color);
+ g_free (background_color);
/* next, install the logo image. */
/* For now, just use a fixed folder image */
@@ -375,14 +407,14 @@ void nautilus_index_panel_set_uri (NautilusIndexPanel *index_panel, const gchar*
{
/* there's nothing to do if the uri is the same as the current one */
- if (nautilus_strcmp (index_panel->uri, new_uri) == 0)
+ if (nautilus_strcmp (index_panel->details->uri, new_uri) == 0)
return;
- g_free (index_panel->uri);
- index_panel->uri = g_strdup (new_uri);
+ g_free (index_panel->details->uri);
+ index_panel->details->uri = g_strdup (new_uri);
/* get rid of the old widgets in the per_uri container */
- gtk_widget_destroy (index_panel->per_uri_container);
+ gtk_widget_destroy (index_panel->details->per_uri_container);
make_per_uri_container (index_panel);
/* populate the per-uri box with the info */
diff --git a/src/ntl-index-panel.h b/src/ntl-index-panel.h
index f2fb10325..24c2a4373 100644
--- a/src/ntl-index-panel.h
+++ b/src/ntl-index-panel.h
@@ -43,13 +43,12 @@ typedef struct _NautilusIndexPanelClass NautilusIndexPanelClass;
#define NAUTILUS_IS_INDEX_PANEL_CLASS(klass) \
(GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_INDEX_PANEL))
+typedef struct _NautilusIndexPanelDetails NautilusIndexPanelDetails;
+
struct _NautilusIndexPanel
{
GtkEventBox event_box;
- GtkWidget *index_container;
- GtkWidget *per_uri_container;
- GtkWidget *meta_tabs;
- gchar *uri;
+ NautilusIndexPanelDetails *details;
};
struct _NautilusIndexPanelClass