summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarin Adler <darin@src.gnome.org>2000-11-09 01:36:13 +0000
committerDarin Adler <darin@src.gnome.org>2000-11-09 01:36:13 +0000
commita03bb1a3166bc03f33bbd2d4f61cfb44c3a4692b (patch)
treefbb19fd6789c3d267167ff7f2a23a1f413e2fb1b
parent40eb73da3962485ccd9aadf85639088e26d64c5a (diff)
downloadnautilus-a03bb1a3166bc03f33bbd2d4f61cfb44c3a4692b.tar.gz
buddy: Gene Ragan <gzr@eazel.com>
* libnautilus-extensions/nautilus-file.c: (rename_callback): Since metadata for the directory itself is now stored under a fixed name, no need to rename the metadata for self-owned files any more. (get_item_count), (get_size), (compare_directories_by_count), (compare_files_by_size), (compare_by_size): Reimplement compares by size so they don't use gnome_vfs_file_info_compare -- this makes them work better for info == NULL cases. (get_date), (compare_by_modification_date): Reimplement compares by modification date so they don't use gnome_vfs_file_info_compare -- this makes them work better for info == NULL cases. (compare_by_name): Sort files that start with "." or "#" last. (compare_by_name_and_directory_name): Helper function so that we always sort by directory name when names are equal. (nautilus_file_compare_for_sort): Use the new functions above so we never have to use the gnome_vfs_file_info_compare function. Because of that, we won't have to keep file names around any more. This also simplified the logic -- I was able to remove all the special cases for info == NULL. (get_metadata_name): Function that returns "." for self-owned files so the metadata for the directory itself is stored somewhere that's not affected by renaming. (nautilus_file_get_metadata), (nautilus_file_get_metadata_list), (nautilus_file_set_metadata), (nautilus_file_set_metadata_list), (nautilus_file_get_boolean_metadata), (nautilus_file_get_integer_metadata), (nautilus_file_set_boolean_metadata), (nautilus_file_set_integer_metadata): Use the new get_metadata_name function. * src/file-manager/nautilus-directory-view-ui.xml: Changed an old <menuitem/> to <separator/>. * po/.cvsignore: Ignore the tmp directory, but no need to ignore the .headerlock file which is now obsolete. * README: Minor tweaks. * libnautilus-extensions/Makefile.am: Resorted lists.
-rw-r--r--ChangeLog43
-rw-r--r--README11
-rw-r--r--libnautilus-extensions/Makefile.am16
-rw-r--r--libnautilus-extensions/nautilus-file.c417
-rw-r--r--libnautilus-private/Makefile.am16
-rw-r--r--libnautilus-private/nautilus-file.c417
-rw-r--r--po/.cvsignore4
-rw-r--r--src/file-manager/nautilus-directory-view-ui.xml2
8 files changed, 639 insertions, 287 deletions
diff --git a/ChangeLog b/ChangeLog
index ecb81767b..3a8249a1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,46 @@
+2000-11-08 Darin Adler <darin@eazel.com>
+
+ buddy: Gene Ragan <gzr@eazel.com>
+
+ * libnautilus-extensions/nautilus-file.c: (rename_callback): Since
+ metadata for the directory itself is now stored under a fixed
+ name, no need to rename the metadata for self-owned files any
+ more.
+ (get_item_count), (get_size), (compare_directories_by_count),
+ (compare_files_by_size), (compare_by_size): Reimplement compares
+ by size so they don't use gnome_vfs_file_info_compare -- this
+ makes them work better for info == NULL cases.
+ (get_date), (compare_by_modification_date): Reimplement compares
+ by modification date so they don't use gnome_vfs_file_info_compare
+ -- this makes them work better for info == NULL cases.
+ (compare_by_name): Sort files that start with "." or "#" last.
+ (compare_by_name_and_directory_name): Helper function so that we
+ always sort by directory name when names are equal.
+ (nautilus_file_compare_for_sort): Use the new functions above so
+ we never have to use the gnome_vfs_file_info_compare function.
+ Because of that, we won't have to keep file names around any more.
+ This also simplified the logic -- I was able to remove all the
+ special cases for info == NULL.
+ (get_metadata_name): Function that returns "." for self-owned
+ files so the metadata for the directory itself is stored somewhere
+ that's not affected by renaming.
+ (nautilus_file_get_metadata), (nautilus_file_get_metadata_list),
+ (nautilus_file_set_metadata), (nautilus_file_set_metadata_list),
+ (nautilus_file_get_boolean_metadata),
+ (nautilus_file_get_integer_metadata),
+ (nautilus_file_set_boolean_metadata),
+ (nautilus_file_set_integer_metadata): Use the new
+ get_metadata_name function.
+
+ * src/file-manager/nautilus-directory-view-ui.xml: Changed an old
+ <menuitem/> to <separator/>.
+
+ * po/.cvsignore: Ignore the tmp directory, but no need to ignore
+ the .headerlock file which is now obsolete.
+
+ * README: Minor tweaks.
+ * libnautilus-extensions/Makefile.am: Resorted lists.
+
2000-11-08 John Sullivan <sullivan@eazel.com>
buddy: Darin Adler <darin@eazel.com>
diff --git a/README b/README
index d7fc12869..56bfdc186 100644
--- a/README
+++ b/README
@@ -114,7 +114,7 @@ The following lists the packages and the versions they should report.
glib: 1.2.8 HC1.2
gtk+: 1.2.8 HC1.2
imlib: 1.9.8.1 HC1.2
- gnome-xml: 1.8.10 HC1.2
+ gnome-xml: 1.8.10 HC1.2
ORBit: 0.5.4 HC1.2
gnome-libs: 1.2.7 --enable-prefer-db1 HC1.2
gnome-http: 1.0.7 HC1.2
@@ -167,12 +167,12 @@ The following lists the packages and the versions that are required.
module branch configure options dist.
------ ------ ----------------- -----
popt: <1.5, but not from GNOME CVS, see below> RH6.2
- glib: glib-1-2 HC1.2
- gtk+: gtk-1-2 HC1.2
- imlib: HEAD HC1.2
+ glib: glib-1-2
+ gtk+: gtk-1-2
+ imlib: HEAD
gnome-xml: LIB_XML_1_BRANCH
ORBit: orbit-stable-0-5
- gnome-libs: gnome-libs-1-0 --enable-prefer-db1 HC1.2
+ gnome-libs: gnome-libs-1-0 --enable-prefer-db1
gnome-http: HEAD
oaf: HEAD
gconf: HEAD
@@ -187,7 +187,6 @@ The following lists the packages and the versions that are required.
nautilus: HEAD
RH6.2 == Version from Red Hat 6.2 OK
-HC1.2 == Version from Helix Code Gnome 1.2 OK
One difference between tarball and cvs compilation is that when you
get stuff from cvs, you don't get a configure script. This script has
diff --git a/libnautilus-extensions/Makefile.am b/libnautilus-extensions/Makefile.am
index 6bc7bb0bb..80a434818 100644
--- a/libnautilus-extensions/Makefile.am
+++ b/libnautilus-extensions/Makefile.am
@@ -44,8 +44,6 @@ libnautilus_extensions_la_LDFLAGS = \
$(NULL)
libnautilus_extensions_la_SOURCES = \
- nautilus-file-operations-progress.c \
- nautilus-file-operations.c \
nautilus-background-canvas-group.c \
nautilus-background.c \
nautilus-bonobo-extensions.c \
@@ -63,10 +61,12 @@ libnautilus_extensions_la_SOURCES = \
nautilus-directory-metafile.c \
nautilus-directory.c \
nautilus-drag.c \
- nautilus-druid.c \
nautilus-druid-page-eazel.c \
+ nautilus-druid.c \
nautilus-entry.c \
nautilus-file-changes-queue.c \
+ nautilus-file-operations-progress.c \
+ nautilus-file-operations.c \
nautilus-file-utilities.c \
nautilus-file.c \
nautilus-font-factory.c \
@@ -132,8 +132,6 @@ libnautilus_extensions_la_SOURCES = \
# Everything is private for now
noinst_HEADERS = \
- nautilus-file-operations.h \
- nautilus-file-operations-progress.h \
nautilus-background-canvas-group.h \
nautilus-background.h \
nautilus-bonobo-extensions.h \
@@ -153,11 +151,13 @@ noinst_HEADERS = \
nautilus-directory-private.h \
nautilus-directory.h \
nautilus-drag.h \
- nautilus-druid.h \
nautilus-druid-page-eazel.h \
+ nautilus-druid.h \
nautilus-entry.h \
nautilus-file-attributes.h \
nautilus-file-changes-queue.h \
+ nautilus-file-operations-progress.h \
+ nautilus-file-operations.h \
nautilus-file-private.h \
nautilus-file-utilities.h \
nautilus-file.h \
@@ -176,8 +176,8 @@ noinst_HEADERS = \
nautilus-icon-canvas-item.h \
nautilus-icon-container.h \
nautilus-icon-dnd.h \
- nautilus-icon-factory.h \
nautilus-icon-factory-private.h \
+ nautilus-icon-factory.h \
nautilus-icon-private.h \
nautilus-icon-text-item.h \
nautilus-image.h \
@@ -199,8 +199,8 @@ noinst_HEADERS = \
nautilus-preferences-group.h \
nautilus-preferences-item.h \
nautilus-preferences-pane.h \
- nautilus-preferences.h \
nautilus-preferences-private.h \
+ nautilus-preferences.h \
nautilus-program-chooser.h \
nautilus-program-choosing.h \
nautilus-radio-button-group.h \
diff --git a/libnautilus-extensions/nautilus-file.c b/libnautilus-extensions/nautilus-file.c
index 68bc24aa1..8e581b52f 100644
--- a/libnautilus-extensions/nautilus-file.c
+++ b/libnautilus-extensions/nautilus-file.c
@@ -58,6 +58,12 @@ extern void eazel_dump_stack_trace (const char *print_prefix,
/* from libleakcheck.so */
#endif
+/* Files that start with these characters sort after files that don't. */
+#define SORT_LAST_CHARACTERS ".#"
+
+/* Name to use to tag metadata for the directory itself. */
+#define FILE_NAME_FOR_DIRECTORY_METADATA "."
+
typedef enum {
NAUTILUS_DATE_TYPE_MODIFIED,
NAUTILUS_DATE_TYPE_CHANGED,
@@ -65,6 +71,24 @@ typedef enum {
NAUTILUS_DATE_TYPE_PERMISSIONS_CHANGED
} NautilusDateType;
+typedef struct {
+ NautilusFile *file;
+ GnomeVFSAsyncHandle *handle;
+ NautilusFileOperationCallback callback;
+ gpointer callback_data;
+} Operation;
+
+/* These are in sort order. Known things come first, then things
+ * where we can't know, finally things where we don't yet know.
+ */
+typedef enum {
+ KNOWN,
+ UNKNOWABLE,
+ UNKNOWN
+} Knowledge;
+
+typedef GList * (* ModifyListFunction) (GList *list, NautilusFile *file);
+
enum {
CHANGED,
LAST_SIGNAL
@@ -111,7 +135,6 @@ nautilus_file_initialize (NautilusFile *file)
file->details = g_new0 (NautilusFileDetails, 1);
}
-
static NautilusFile *
nautilus_file_new_from_relative_uri (NautilusDirectory *directory,
const char *relative_uri)
@@ -155,8 +178,6 @@ info_missing (NautilusFile *file, GnomeVFSFileInfoFields needed_mask)
return (info->valid_fields & needed_mask) != needed_mask;
}
-typedef GList * (* ModifyListFunction) (GList *list, NautilusFile *file);
-
static void
modify_link_hash_table (NautilusFile *file,
ModifyListFunction modify_function)
@@ -443,7 +464,7 @@ nautilus_file_unref (NautilusFile *file)
}
static gboolean
-nautilus_file_is_self_owned (NautilusFile *file)
+is_self_owned (NautilusFile *file)
{
return file->details->directory->details->as_file == file;
}
@@ -491,7 +512,7 @@ nautilus_file_get_parent_uri (NautilusFile *file)
{
g_assert (NAUTILUS_IS_FILE (file));
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
/* Callers expect an empty string, not a NULL. */
return g_strdup ("");
}
@@ -507,7 +528,7 @@ get_file_for_parent_directory (NautilusFile *file)
g_assert (NAUTILUS_IS_FILE (file));
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
return NULL;
}
@@ -689,7 +710,7 @@ nautilus_file_can_rename (NautilusFile *file)
}
/* Self-owned files can't be renamed */
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
return FALSE;
}
@@ -725,7 +746,7 @@ nautilus_file_get_gnome_vfs_uri (NautilusFile *file)
return NULL;
}
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
gnome_vfs_uri_ref (vfs_uri);
return vfs_uri;
}
@@ -734,13 +755,6 @@ nautilus_file_get_gnome_vfs_uri (NautilusFile *file)
(vfs_uri, file->details->relative_uri);
}
-typedef struct {
- NautilusFile *file;
- GnomeVFSAsyncHandle *handle;
- NautilusFileOperationCallback callback;
- gpointer callback_data;
-} Operation;
-
static Operation *
operation_new (NautilusFile *file,
NautilusFileOperationCallback callback,
@@ -839,8 +853,15 @@ rename_callback (GnomeVFSAsyncHandle *handle,
old_uri = nautilus_file_get_uri (op->file);
old_relative_uri = g_strdup (op->file->details->relative_uri);
update_info_and_name (op->file, new_info);
- nautilus_directory_rename_file_metadata
- (directory, old_relative_uri, op->file->details->relative_uri);
+
+ /* Self-owned files store their metadata under the
+ * hard-code name "." so there's no need to rename
+ * their metadata when they are renamed.
+ */
+ if (!is_self_owned (op->file)) {
+ nautilus_directory_rename_file_metadata
+ (directory, old_relative_uri, op->file->details->relative_uri);
+ }
renamed_directory = nautilus_directory_get_existing (old_uri);
if (renamed_directory != NULL) {
@@ -912,7 +933,7 @@ nautilus_file_rename (NautilusFile *file,
/* Self-owned files can't be renamed. Test the name-not-actually-changing
* case before this case.
*/
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
/* Claim that something changed even if the rename
* failed. This makes it easier for some clients who
* see the "reverting" to the old name as "changing
@@ -1160,84 +1181,204 @@ nautilus_file_update_name (NautilusFile *file, const char *name)
return TRUE;
}
+static Knowledge
+get_item_count (NautilusFile *file,
+ guint *count)
+{
+ gboolean known, unreadable;
+
+ known = nautilus_file_get_directory_item_count
+ (file, count, &unreadable);
+ if (!known) {
+ return UNKNOWN;
+ }
+ if (unreadable) {
+ return UNKNOWABLE;
+ }
+ return KNOWN;
+}
+
+static Knowledge
+get_size (NautilusFile *file,
+ GnomeVFSFileSize *size)
+{
+ /* If we tried and failed, then treat it like there is no size
+ * to know.
+ */
+ if (file->details->get_info_failed) {
+ return UNKNOWABLE;
+ }
+
+ /* If the info is NULL that means we haven't even tried yet,
+ * so it's just unknown, not unknowable.
+ */
+ if (file->details->info == NULL) {
+ return UNKNOWN;
+ }
+
+ /* If we got info with no size in it, it means there is no
+ * such thing as a size as far as gnome-vfs is concerned,
+ * so "unknowable".
+ */
+ if ((file->details->info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) == 0) {
+ return UNKNOWABLE;
+ }
+
+ /* We have a size! */
+ *size = file->details->info->size;
+ return KNOWN;
+}
+
+static Knowledge
+get_modification_time (NautilusFile *file,
+ time_t *modification_time)
+{
+ /* If we tried and failed, then treat it like there is no size
+ * to know.
+ */
+ if (file->details->get_info_failed) {
+ return UNKNOWABLE;
+ }
+
+ /* If the info is NULL that means we haven't even tried yet,
+ * so it's just unknown, not unknowable.
+ */
+ if (file->details->info == NULL) {
+ return UNKNOWN;
+ }
+
+ /* If we got info with no modification time in it, it means
+ * there is no such thing as a modification time as far as
+ * gnome-vfs is concerned, so "unknowable".
+ */
+ if ((file->details->info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MTIME) == 0) {
+ return UNKNOWABLE;
+ }
+
+ /* We have a modification time. */
+ *modification_time = file->details->info->mtime;
+ return KNOWN;
+}
+
static int
-nautilus_file_compare_directories_by_size (NautilusFile *file_1, NautilusFile *file_2)
+compare_directories_by_count (NautilusFile *file_1, NautilusFile *file_2)
{
/* Sort order:
* Directories with n items
* Directories with 0 items
+ * Directories with "unknowable" # of items
* Directories with unknown # of items
- * All files.
- * The files are sorted by size in a separate pass.
*/
- gboolean is_directory_1, is_directory_2;
- gboolean count_known_1, count_known_2;
- gboolean count_unreadable_1, count_unreadable_2;
- guint item_count_1, item_count_2;
- is_directory_1 = nautilus_file_is_directory (file_1);
- is_directory_2 = nautilus_file_is_directory (file_2);
+ Knowledge count_known_1, count_known_2;
+ guint count_1, count_2;
- if (is_directory_1 && !is_directory_2) {
+ count_known_1 = get_item_count (file_1, &count_1);
+ count_known_2 = get_item_count (file_2, &count_2);
+
+ if (count_known_1 < count_known_2) {
return -1;
}
- if (is_directory_2 && !is_directory_1) {
+ if (count_known_1 > count_known_2) {
return +1;
}
- if (!is_directory_1 && !is_directory_2) {
- return 0;
+ if (count_1 > count_2) {
+ return -1;
+ }
+ if (count_1 < count_2) {
+ return +1;
}
- /* Both are directories, compare by item count. */
+ return 0;
+}
- count_known_1 = nautilus_file_get_directory_item_count (file_1,
- &item_count_1,
- &count_unreadable_1);
- count_known_2 = nautilus_file_get_directory_item_count (file_2,
- &item_count_2,
- &count_unreadable_2);
+static int
+compare_files_by_size (NautilusFile *file_1, NautilusFile *file_2)
+{
+ /* Sort order:
+ * Files with large sizes.
+ * Files with smaller sizes.
+ * Files with "unknowable" size.
+ * Files with unknown size.
+ */
+
+ Knowledge size_known_1, size_known_2;
+ GnomeVFSFileSize size_1, size_2;
+
+ size_known_1 = get_size (file_1, &size_1);
+ size_known_2 = get_size (file_2, &size_2);
- if (!count_known_1 && count_known_2) {
+ if (size_known_1 < size_known_2) {
+ return -1;
+ }
+ if (size_known_1 > size_known_2) {
return +1;
}
- if (count_known_1 && !count_known_2) {
+
+ if (size_1 > size_2) {
return -1;
}
+ if (size_1 < size_2) {
+ return +1;
+ }
- if (!count_known_1 && !count_known_2) {
- /* Put unknowable after simply unknown. */
- if (count_unreadable_1 && !count_unreadable_2) {
- return +1;
- }
+ return 0;
+}
- if (!count_unreadable_1 && count_unreadable_2) {
- return -1;
- }
+static int
+compare_by_size (NautilusFile *file_1, NautilusFile *file_2)
+{
+ /* Sort order:
+ * Directories with n items
+ * Directories with 0 items
+ * Directories with "unknowable" # of items
+ * Directories with unknown # of items
+ * Files with large sizes.
+ * Files with smaller sizes.
+ * Files with "unknowable" size.
+ * Files with unknown size.
+ */
- return 0;
- }
+ gboolean is_directory_1, is_directory_2;
- if (item_count_1 > item_count_2) {
+ is_directory_1 = nautilus_file_is_directory (file_1);
+ is_directory_2 = nautilus_file_is_directory (file_2);
+
+ if (is_directory_1 && !is_directory_2) {
return -1;
}
- if (item_count_2 > item_count_1) {
+ if (is_directory_2 && !is_directory_1) {
return +1;
}
- return 0;
+ if (is_directory_1) {
+ return compare_directories_by_count (file_1, file_2);
+ } else {
+ return compare_files_by_size (file_1, file_2);
+ }
}
static int
-nautilus_file_compare_by_name (NautilusFile *file_1, NautilusFile *file_2)
+compare_by_name (NautilusFile *file_1, NautilusFile *file_2)
{
char *name_1, *name_2;
+ gboolean sort_last_1, sort_last_2;
int compare;
name_1 = nautilus_file_get_name (file_1);
name_2 = nautilus_file_get_name (file_2);
- compare = nautilus_strcmp_case_breaks_ties (name_1, name_2);
+ sort_last_1 = strchr (SORT_LAST_CHARACTERS, name_1[0]) != NULL;
+ sort_last_2 = strchr (SORT_LAST_CHARACTERS, name_2[0]) != NULL;
+
+ if (sort_last_1 && !sort_last_2) {
+ compare = +1;
+ } else if (!sort_last_1 && sort_last_2) {
+ compare = -1;
+ } else {
+ compare = nautilus_strcmp_case_breaks_ties (name_1, name_2);
+ }
g_free (name_1);
g_free (name_2);
@@ -1246,11 +1387,15 @@ nautilus_file_compare_by_name (NautilusFile *file_1, NautilusFile *file_2)
}
static int
-nautilus_file_compare_by_directory_name (NautilusFile *file_1, NautilusFile *file_2)
+compare_by_directory_name (NautilusFile *file_1, NautilusFile *file_2)
{
char *directory_1, *directory_2;
int compare;
+ if (file_1->details->directory == file_2->details->directory) {
+ return 0;
+ }
+
directory_1 = nautilus_file_get_parent_uri_for_display (file_1);
directory_2 = nautilus_file_get_parent_uri_for_display (file_2);
@@ -1307,7 +1452,7 @@ prepend_automatic_emblem_names (NautilusFile *file,
}
static int
-nautilus_file_compare_by_emblems (NautilusFile *file_1, NautilusFile *file_2)
+compare_by_emblems (NautilusFile *file_1, NautilusFile *file_2)
{
int auto_1, auto_2;
GList *keywords_1, *keywords_2;
@@ -1353,7 +1498,7 @@ nautilus_file_compare_by_emblems (NautilusFile *file_1, NautilusFile *file_2)
}
static int
-nautilus_file_compare_by_type (NautilusFile *file_1, NautilusFile *file_2)
+compare_by_type (NautilusFile *file_1, NautilusFile *file_2)
{
gboolean is_directory_1;
gboolean is_directory_2;
@@ -1399,6 +1544,51 @@ nautilus_file_compare_by_type (NautilusFile *file_1, NautilusFile *file_2)
return result;
}
+static int
+compare_by_modification_time (NautilusFile *file_1, NautilusFile *file_2)
+{
+ /* Sort order:
+ * Files with newer times.
+ * Files with older times.
+ * Files with "unknowable" times.
+ * Files with unknown times.
+ */
+
+ Knowledge time_known_1, time_known_2;
+ time_t time_1, time_2;
+
+ time_known_1 = get_modification_time (file_1, &time_1);
+ time_known_2 = get_modification_time (file_2, &time_2);
+
+ if (time_known_1 < time_known_2) {
+ return -1;
+ }
+ if (time_known_1 > time_known_2) {
+ return +1;
+ }
+
+ if (time_1 > time_2) {
+ return -1;
+ }
+ if (time_1 < time_2) {
+ return +1;
+ }
+
+ return 0;
+}
+
+static int
+compare_by_full_path (NautilusFile *file_1, NautilusFile *file_2)
+{
+ int compare;
+
+ compare = compare_by_directory_name (file_1, file_2);
+ if (compare != 0) {
+ return compare;
+ }
+ return compare_by_name (file_1, file_2);
+}
+
/**
* nautilus_file_compare_for_sort:
* @file_1: A file object
@@ -1416,20 +1606,11 @@ nautilus_file_compare_for_sort (NautilusFile *file_1,
NautilusFile *file_2,
NautilusFileSortType sort_type)
{
- GnomeVFSDirectorySortRule rules[3];
int compare;
- char *name_1, *name_2;
g_return_val_if_fail (NAUTILUS_IS_FILE (file_1), 0);
g_return_val_if_fail (NAUTILUS_IS_FILE (file_2), 0);
- /* FIXME: If we didn't use
- * GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE, we could free
- * the names in the file info (in update_info_and_name) and
- * save some storage per-file. We might need to stop using it
- * anyway to make international sorting work right.
- */
-
switch (sort_type) {
case NAUTILUS_FILE_SORT_BY_NAME:
/* Note: This used to put directories first. I
@@ -1437,89 +1618,50 @@ nautilus_file_compare_for_sort (NautilusFile *file_1,
* but I can imagine discussing this further.
* John Sullivan <sullivan@eazel.com>
*/
- compare = nautilus_file_compare_by_name (file_1, file_2);
+ compare = compare_by_name (file_1, file_2);
if (compare != 0) {
return compare;
}
- return nautilus_file_compare_by_directory_name (file_1, file_2);
+ return compare_by_directory_name (file_1, file_2);
case NAUTILUS_FILE_SORT_BY_DIRECTORY:
- compare = nautilus_file_compare_by_directory_name (file_1, file_2);
- if (compare != 0) {
- return compare;
- }
- return nautilus_file_compare_by_name (file_1, file_2);
+ return compare_by_full_path (file_1, file_2);
case NAUTILUS_FILE_SORT_BY_SIZE:
/* Compare directory sizes ourselves, then if necessary
* use GnomeVFS to compare file sizes.
*/
- compare = nautilus_file_compare_directories_by_size (file_1, file_2);
+ compare = compare_by_size (file_1, file_2);
if (compare != 0) {
return compare;
}
- rules[0] = GNOME_VFS_DIRECTORY_SORT_BYSIZE;
- rules[1] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE;
- rules[2] = GNOME_VFS_DIRECTORY_SORT_NONE;
- break;
+ return compare_by_full_path (file_1, file_2);
case NAUTILUS_FILE_SORT_BY_TYPE:
/* GnomeVFS doesn't know about our special text for certain
* mime types, so we handle the mime-type sorting ourselves.
*/
- compare = nautilus_file_compare_by_type (file_1, file_2);
+ compare = compare_by_type (file_1, file_2);
if (compare != 0) {
return compare;
}
- rules[0] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE;
- rules[1] = GNOME_VFS_DIRECTORY_SORT_NONE;
- break;
+ return compare_by_full_path (file_1, file_2);
case NAUTILUS_FILE_SORT_BY_MTIME:
- rules[0] = GNOME_VFS_DIRECTORY_SORT_BYMTIME;
- rules[1] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE;
- rules[2] = GNOME_VFS_DIRECTORY_SORT_NONE;
- break;
+ compare = compare_by_modification_time (file_1, file_2);
+ if (compare != 0) {
+ return compare;
+ }
+ return compare_by_full_path (file_1, file_2);
case NAUTILUS_FILE_SORT_BY_EMBLEMS:
/* GnomeVFS doesn't know squat about our emblems, so
* we handle comparing them here, before falling back
* to tie-breakers.
*/
- compare = nautilus_file_compare_by_emblems (file_1, file_2);
+ compare = compare_by_emblems (file_1, file_2);
if (compare != 0) {
return compare;
}
- rules[0] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE;
- rules[1] = GNOME_VFS_DIRECTORY_SORT_NONE;
- break;
+ return compare_by_full_path (file_1, file_2);
default:
g_return_val_if_fail (FALSE, 0);
}
-
- if (file_1->details->info == NULL) {
- if (file_2->details->info == NULL) {
- name_1 = nautilus_file_get_name (file_1);
- name_2 = nautilus_file_get_name (file_2);
- compare = nautilus_strcmp_case_breaks_ties (name_1, name_2);
- g_free (name_1);
- g_free (name_2);
- } else {
- /* FIXME bugzilla.eazel.com 2426:
- * We do have a name for file 2 to
- * compare with, so we can probably do better
- * than this for all cases.
- */
- compare = -1;
- }
- } else if (file_2->details->info == NULL) {
- /* FIXME bugzilla.eazel.com 2426:
- * We do have a name for file 1 to compare
- * with, so we can probably do better than this for
- * all cases.
- */
- compare = +1;
- } else {
- compare = gnome_vfs_file_info_compare_for_sort
- (file_1->details->info, file_2->details->info, rules);
- }
-
- return compare;
}
/**
@@ -1566,6 +1708,19 @@ nautilus_file_compare_name (NautilusFile *file,
return result;
}
+/* We use the file's URI for the metadata for files in a directory,
+ * but we use a hard-coded string for the metadata for the directory
+ * itself.
+ */
+static const char *
+get_metadata_name (NautilusFile *file)
+{
+ if (is_self_owned (file)) {
+ return FILE_NAME_FOR_DIRECTORY_METADATA;
+ }
+ return file->details->relative_uri;
+}
+
char *
nautilus_file_get_metadata (NautilusFile *file,
const char *key,
@@ -1580,7 +1735,7 @@ nautilus_file_get_metadata (NautilusFile *file,
return nautilus_directory_get_file_metadata
(file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata);
}
@@ -1601,7 +1756,7 @@ nautilus_file_get_metadata_list (NautilusFile *file,
return nautilus_directory_get_file_metadata_list
(file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
list_key,
list_subkey);
}
@@ -1617,7 +1772,7 @@ nautilus_file_set_metadata (NautilusFile *file,
g_return_if_fail (key[0] != '\0');
if (nautilus_directory_set_file_metadata (file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata,
metadata)) {
@@ -1638,7 +1793,7 @@ nautilus_file_set_metadata_list (NautilusFile *file,
g_return_if_fail (list_subkey[0] != '\0');
if (nautilus_directory_set_file_metadata_list (file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
list_key,
list_subkey,
list)) {
@@ -1661,7 +1816,7 @@ nautilus_file_get_boolean_metadata (NautilusFile *file,
return nautilus_directory_get_boolean_file_metadata
(file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata);
}
@@ -1680,7 +1835,7 @@ nautilus_file_get_integer_metadata (NautilusFile *file,
return nautilus_directory_get_integer_file_metadata
(file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata);
}
@@ -1697,7 +1852,7 @@ nautilus_file_set_boolean_metadata (NautilusFile *file,
g_return_if_fail (key[0] != '\0');
if (nautilus_directory_set_boolean_file_metadata (file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata,
metadata)) {
@@ -1716,7 +1871,7 @@ nautilus_file_set_integer_metadata (NautilusFile *file,
g_return_if_fail (key[0] != '\0');
if (nautilus_directory_set_integer_file_metadata (file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata,
metadata)) {
@@ -1800,7 +1955,7 @@ nautilus_file_get_uri (NautilusFile *file)
g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
return g_strdup (file->details->directory->details->uri);
}
@@ -3826,7 +3981,7 @@ nautilus_file_mark_gone (NautilusFile *file)
/* Let the directory know it's gone. */
directory = file->details->directory;
- if (directory->details->as_file != file) {
+ if (!is_self_owned (file)) {
nautilus_directory_remove_file (directory, file);
}
@@ -3857,7 +4012,7 @@ nautilus_file_changed (NautilusFile *file)
g_return_if_fail (NAUTILUS_IS_FILE (file));
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
nautilus_file_emit_changed (file);
} else {
fake_list.data = file;
diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am
index 6bc7bb0bb..80a434818 100644
--- a/libnautilus-private/Makefile.am
+++ b/libnautilus-private/Makefile.am
@@ -44,8 +44,6 @@ libnautilus_extensions_la_LDFLAGS = \
$(NULL)
libnautilus_extensions_la_SOURCES = \
- nautilus-file-operations-progress.c \
- nautilus-file-operations.c \
nautilus-background-canvas-group.c \
nautilus-background.c \
nautilus-bonobo-extensions.c \
@@ -63,10 +61,12 @@ libnautilus_extensions_la_SOURCES = \
nautilus-directory-metafile.c \
nautilus-directory.c \
nautilus-drag.c \
- nautilus-druid.c \
nautilus-druid-page-eazel.c \
+ nautilus-druid.c \
nautilus-entry.c \
nautilus-file-changes-queue.c \
+ nautilus-file-operations-progress.c \
+ nautilus-file-operations.c \
nautilus-file-utilities.c \
nautilus-file.c \
nautilus-font-factory.c \
@@ -132,8 +132,6 @@ libnautilus_extensions_la_SOURCES = \
# Everything is private for now
noinst_HEADERS = \
- nautilus-file-operations.h \
- nautilus-file-operations-progress.h \
nautilus-background-canvas-group.h \
nautilus-background.h \
nautilus-bonobo-extensions.h \
@@ -153,11 +151,13 @@ noinst_HEADERS = \
nautilus-directory-private.h \
nautilus-directory.h \
nautilus-drag.h \
- nautilus-druid.h \
nautilus-druid-page-eazel.h \
+ nautilus-druid.h \
nautilus-entry.h \
nautilus-file-attributes.h \
nautilus-file-changes-queue.h \
+ nautilus-file-operations-progress.h \
+ nautilus-file-operations.h \
nautilus-file-private.h \
nautilus-file-utilities.h \
nautilus-file.h \
@@ -176,8 +176,8 @@ noinst_HEADERS = \
nautilus-icon-canvas-item.h \
nautilus-icon-container.h \
nautilus-icon-dnd.h \
- nautilus-icon-factory.h \
nautilus-icon-factory-private.h \
+ nautilus-icon-factory.h \
nautilus-icon-private.h \
nautilus-icon-text-item.h \
nautilus-image.h \
@@ -199,8 +199,8 @@ noinst_HEADERS = \
nautilus-preferences-group.h \
nautilus-preferences-item.h \
nautilus-preferences-pane.h \
- nautilus-preferences.h \
nautilus-preferences-private.h \
+ nautilus-preferences.h \
nautilus-program-chooser.h \
nautilus-program-choosing.h \
nautilus-radio-button-group.h \
diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c
index 68bc24aa1..8e581b52f 100644
--- a/libnautilus-private/nautilus-file.c
+++ b/libnautilus-private/nautilus-file.c
@@ -58,6 +58,12 @@ extern void eazel_dump_stack_trace (const char *print_prefix,
/* from libleakcheck.so */
#endif
+/* Files that start with these characters sort after files that don't. */
+#define SORT_LAST_CHARACTERS ".#"
+
+/* Name to use to tag metadata for the directory itself. */
+#define FILE_NAME_FOR_DIRECTORY_METADATA "."
+
typedef enum {
NAUTILUS_DATE_TYPE_MODIFIED,
NAUTILUS_DATE_TYPE_CHANGED,
@@ -65,6 +71,24 @@ typedef enum {
NAUTILUS_DATE_TYPE_PERMISSIONS_CHANGED
} NautilusDateType;
+typedef struct {
+ NautilusFile *file;
+ GnomeVFSAsyncHandle *handle;
+ NautilusFileOperationCallback callback;
+ gpointer callback_data;
+} Operation;
+
+/* These are in sort order. Known things come first, then things
+ * where we can't know, finally things where we don't yet know.
+ */
+typedef enum {
+ KNOWN,
+ UNKNOWABLE,
+ UNKNOWN
+} Knowledge;
+
+typedef GList * (* ModifyListFunction) (GList *list, NautilusFile *file);
+
enum {
CHANGED,
LAST_SIGNAL
@@ -111,7 +135,6 @@ nautilus_file_initialize (NautilusFile *file)
file->details = g_new0 (NautilusFileDetails, 1);
}
-
static NautilusFile *
nautilus_file_new_from_relative_uri (NautilusDirectory *directory,
const char *relative_uri)
@@ -155,8 +178,6 @@ info_missing (NautilusFile *file, GnomeVFSFileInfoFields needed_mask)
return (info->valid_fields & needed_mask) != needed_mask;
}
-typedef GList * (* ModifyListFunction) (GList *list, NautilusFile *file);
-
static void
modify_link_hash_table (NautilusFile *file,
ModifyListFunction modify_function)
@@ -443,7 +464,7 @@ nautilus_file_unref (NautilusFile *file)
}
static gboolean
-nautilus_file_is_self_owned (NautilusFile *file)
+is_self_owned (NautilusFile *file)
{
return file->details->directory->details->as_file == file;
}
@@ -491,7 +512,7 @@ nautilus_file_get_parent_uri (NautilusFile *file)
{
g_assert (NAUTILUS_IS_FILE (file));
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
/* Callers expect an empty string, not a NULL. */
return g_strdup ("");
}
@@ -507,7 +528,7 @@ get_file_for_parent_directory (NautilusFile *file)
g_assert (NAUTILUS_IS_FILE (file));
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
return NULL;
}
@@ -689,7 +710,7 @@ nautilus_file_can_rename (NautilusFile *file)
}
/* Self-owned files can't be renamed */
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
return FALSE;
}
@@ -725,7 +746,7 @@ nautilus_file_get_gnome_vfs_uri (NautilusFile *file)
return NULL;
}
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
gnome_vfs_uri_ref (vfs_uri);
return vfs_uri;
}
@@ -734,13 +755,6 @@ nautilus_file_get_gnome_vfs_uri (NautilusFile *file)
(vfs_uri, file->details->relative_uri);
}
-typedef struct {
- NautilusFile *file;
- GnomeVFSAsyncHandle *handle;
- NautilusFileOperationCallback callback;
- gpointer callback_data;
-} Operation;
-
static Operation *
operation_new (NautilusFile *file,
NautilusFileOperationCallback callback,
@@ -839,8 +853,15 @@ rename_callback (GnomeVFSAsyncHandle *handle,
old_uri = nautilus_file_get_uri (op->file);
old_relative_uri = g_strdup (op->file->details->relative_uri);
update_info_and_name (op->file, new_info);
- nautilus_directory_rename_file_metadata
- (directory, old_relative_uri, op->file->details->relative_uri);
+
+ /* Self-owned files store their metadata under the
+ * hard-code name "." so there's no need to rename
+ * their metadata when they are renamed.
+ */
+ if (!is_self_owned (op->file)) {
+ nautilus_directory_rename_file_metadata
+ (directory, old_relative_uri, op->file->details->relative_uri);
+ }
renamed_directory = nautilus_directory_get_existing (old_uri);
if (renamed_directory != NULL) {
@@ -912,7 +933,7 @@ nautilus_file_rename (NautilusFile *file,
/* Self-owned files can't be renamed. Test the name-not-actually-changing
* case before this case.
*/
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
/* Claim that something changed even if the rename
* failed. This makes it easier for some clients who
* see the "reverting" to the old name as "changing
@@ -1160,84 +1181,204 @@ nautilus_file_update_name (NautilusFile *file, const char *name)
return TRUE;
}
+static Knowledge
+get_item_count (NautilusFile *file,
+ guint *count)
+{
+ gboolean known, unreadable;
+
+ known = nautilus_file_get_directory_item_count
+ (file, count, &unreadable);
+ if (!known) {
+ return UNKNOWN;
+ }
+ if (unreadable) {
+ return UNKNOWABLE;
+ }
+ return KNOWN;
+}
+
+static Knowledge
+get_size (NautilusFile *file,
+ GnomeVFSFileSize *size)
+{
+ /* If we tried and failed, then treat it like there is no size
+ * to know.
+ */
+ if (file->details->get_info_failed) {
+ return UNKNOWABLE;
+ }
+
+ /* If the info is NULL that means we haven't even tried yet,
+ * so it's just unknown, not unknowable.
+ */
+ if (file->details->info == NULL) {
+ return UNKNOWN;
+ }
+
+ /* If we got info with no size in it, it means there is no
+ * such thing as a size as far as gnome-vfs is concerned,
+ * so "unknowable".
+ */
+ if ((file->details->info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) == 0) {
+ return UNKNOWABLE;
+ }
+
+ /* We have a size! */
+ *size = file->details->info->size;
+ return KNOWN;
+}
+
+static Knowledge
+get_modification_time (NautilusFile *file,
+ time_t *modification_time)
+{
+ /* If we tried and failed, then treat it like there is no size
+ * to know.
+ */
+ if (file->details->get_info_failed) {
+ return UNKNOWABLE;
+ }
+
+ /* If the info is NULL that means we haven't even tried yet,
+ * so it's just unknown, not unknowable.
+ */
+ if (file->details->info == NULL) {
+ return UNKNOWN;
+ }
+
+ /* If we got info with no modification time in it, it means
+ * there is no such thing as a modification time as far as
+ * gnome-vfs is concerned, so "unknowable".
+ */
+ if ((file->details->info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MTIME) == 0) {
+ return UNKNOWABLE;
+ }
+
+ /* We have a modification time. */
+ *modification_time = file->details->info->mtime;
+ return KNOWN;
+}
+
static int
-nautilus_file_compare_directories_by_size (NautilusFile *file_1, NautilusFile *file_2)
+compare_directories_by_count (NautilusFile *file_1, NautilusFile *file_2)
{
/* Sort order:
* Directories with n items
* Directories with 0 items
+ * Directories with "unknowable" # of items
* Directories with unknown # of items
- * All files.
- * The files are sorted by size in a separate pass.
*/
- gboolean is_directory_1, is_directory_2;
- gboolean count_known_1, count_known_2;
- gboolean count_unreadable_1, count_unreadable_2;
- guint item_count_1, item_count_2;
- is_directory_1 = nautilus_file_is_directory (file_1);
- is_directory_2 = nautilus_file_is_directory (file_2);
+ Knowledge count_known_1, count_known_2;
+ guint count_1, count_2;
- if (is_directory_1 && !is_directory_2) {
+ count_known_1 = get_item_count (file_1, &count_1);
+ count_known_2 = get_item_count (file_2, &count_2);
+
+ if (count_known_1 < count_known_2) {
return -1;
}
- if (is_directory_2 && !is_directory_1) {
+ if (count_known_1 > count_known_2) {
return +1;
}
- if (!is_directory_1 && !is_directory_2) {
- return 0;
+ if (count_1 > count_2) {
+ return -1;
+ }
+ if (count_1 < count_2) {
+ return +1;
}
- /* Both are directories, compare by item count. */
+ return 0;
+}
- count_known_1 = nautilus_file_get_directory_item_count (file_1,
- &item_count_1,
- &count_unreadable_1);
- count_known_2 = nautilus_file_get_directory_item_count (file_2,
- &item_count_2,
- &count_unreadable_2);
+static int
+compare_files_by_size (NautilusFile *file_1, NautilusFile *file_2)
+{
+ /* Sort order:
+ * Files with large sizes.
+ * Files with smaller sizes.
+ * Files with "unknowable" size.
+ * Files with unknown size.
+ */
+
+ Knowledge size_known_1, size_known_2;
+ GnomeVFSFileSize size_1, size_2;
+
+ size_known_1 = get_size (file_1, &size_1);
+ size_known_2 = get_size (file_2, &size_2);
- if (!count_known_1 && count_known_2) {
+ if (size_known_1 < size_known_2) {
+ return -1;
+ }
+ if (size_known_1 > size_known_2) {
return +1;
}
- if (count_known_1 && !count_known_2) {
+
+ if (size_1 > size_2) {
return -1;
}
+ if (size_1 < size_2) {
+ return +1;
+ }
- if (!count_known_1 && !count_known_2) {
- /* Put unknowable after simply unknown. */
- if (count_unreadable_1 && !count_unreadable_2) {
- return +1;
- }
+ return 0;
+}
- if (!count_unreadable_1 && count_unreadable_2) {
- return -1;
- }
+static int
+compare_by_size (NautilusFile *file_1, NautilusFile *file_2)
+{
+ /* Sort order:
+ * Directories with n items
+ * Directories with 0 items
+ * Directories with "unknowable" # of items
+ * Directories with unknown # of items
+ * Files with large sizes.
+ * Files with smaller sizes.
+ * Files with "unknowable" size.
+ * Files with unknown size.
+ */
- return 0;
- }
+ gboolean is_directory_1, is_directory_2;
- if (item_count_1 > item_count_2) {
+ is_directory_1 = nautilus_file_is_directory (file_1);
+ is_directory_2 = nautilus_file_is_directory (file_2);
+
+ if (is_directory_1 && !is_directory_2) {
return -1;
}
- if (item_count_2 > item_count_1) {
+ if (is_directory_2 && !is_directory_1) {
return +1;
}
- return 0;
+ if (is_directory_1) {
+ return compare_directories_by_count (file_1, file_2);
+ } else {
+ return compare_files_by_size (file_1, file_2);
+ }
}
static int
-nautilus_file_compare_by_name (NautilusFile *file_1, NautilusFile *file_2)
+compare_by_name (NautilusFile *file_1, NautilusFile *file_2)
{
char *name_1, *name_2;
+ gboolean sort_last_1, sort_last_2;
int compare;
name_1 = nautilus_file_get_name (file_1);
name_2 = nautilus_file_get_name (file_2);
- compare = nautilus_strcmp_case_breaks_ties (name_1, name_2);
+ sort_last_1 = strchr (SORT_LAST_CHARACTERS, name_1[0]) != NULL;
+ sort_last_2 = strchr (SORT_LAST_CHARACTERS, name_2[0]) != NULL;
+
+ if (sort_last_1 && !sort_last_2) {
+ compare = +1;
+ } else if (!sort_last_1 && sort_last_2) {
+ compare = -1;
+ } else {
+ compare = nautilus_strcmp_case_breaks_ties (name_1, name_2);
+ }
g_free (name_1);
g_free (name_2);
@@ -1246,11 +1387,15 @@ nautilus_file_compare_by_name (NautilusFile *file_1, NautilusFile *file_2)
}
static int
-nautilus_file_compare_by_directory_name (NautilusFile *file_1, NautilusFile *file_2)
+compare_by_directory_name (NautilusFile *file_1, NautilusFile *file_2)
{
char *directory_1, *directory_2;
int compare;
+ if (file_1->details->directory == file_2->details->directory) {
+ return 0;
+ }
+
directory_1 = nautilus_file_get_parent_uri_for_display (file_1);
directory_2 = nautilus_file_get_parent_uri_for_display (file_2);
@@ -1307,7 +1452,7 @@ prepend_automatic_emblem_names (NautilusFile *file,
}
static int
-nautilus_file_compare_by_emblems (NautilusFile *file_1, NautilusFile *file_2)
+compare_by_emblems (NautilusFile *file_1, NautilusFile *file_2)
{
int auto_1, auto_2;
GList *keywords_1, *keywords_2;
@@ -1353,7 +1498,7 @@ nautilus_file_compare_by_emblems (NautilusFile *file_1, NautilusFile *file_2)
}
static int
-nautilus_file_compare_by_type (NautilusFile *file_1, NautilusFile *file_2)
+compare_by_type (NautilusFile *file_1, NautilusFile *file_2)
{
gboolean is_directory_1;
gboolean is_directory_2;
@@ -1399,6 +1544,51 @@ nautilus_file_compare_by_type (NautilusFile *file_1, NautilusFile *file_2)
return result;
}
+static int
+compare_by_modification_time (NautilusFile *file_1, NautilusFile *file_2)
+{
+ /* Sort order:
+ * Files with newer times.
+ * Files with older times.
+ * Files with "unknowable" times.
+ * Files with unknown times.
+ */
+
+ Knowledge time_known_1, time_known_2;
+ time_t time_1, time_2;
+
+ time_known_1 = get_modification_time (file_1, &time_1);
+ time_known_2 = get_modification_time (file_2, &time_2);
+
+ if (time_known_1 < time_known_2) {
+ return -1;
+ }
+ if (time_known_1 > time_known_2) {
+ return +1;
+ }
+
+ if (time_1 > time_2) {
+ return -1;
+ }
+ if (time_1 < time_2) {
+ return +1;
+ }
+
+ return 0;
+}
+
+static int
+compare_by_full_path (NautilusFile *file_1, NautilusFile *file_2)
+{
+ int compare;
+
+ compare = compare_by_directory_name (file_1, file_2);
+ if (compare != 0) {
+ return compare;
+ }
+ return compare_by_name (file_1, file_2);
+}
+
/**
* nautilus_file_compare_for_sort:
* @file_1: A file object
@@ -1416,20 +1606,11 @@ nautilus_file_compare_for_sort (NautilusFile *file_1,
NautilusFile *file_2,
NautilusFileSortType sort_type)
{
- GnomeVFSDirectorySortRule rules[3];
int compare;
- char *name_1, *name_2;
g_return_val_if_fail (NAUTILUS_IS_FILE (file_1), 0);
g_return_val_if_fail (NAUTILUS_IS_FILE (file_2), 0);
- /* FIXME: If we didn't use
- * GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE, we could free
- * the names in the file info (in update_info_and_name) and
- * save some storage per-file. We might need to stop using it
- * anyway to make international sorting work right.
- */
-
switch (sort_type) {
case NAUTILUS_FILE_SORT_BY_NAME:
/* Note: This used to put directories first. I
@@ -1437,89 +1618,50 @@ nautilus_file_compare_for_sort (NautilusFile *file_1,
* but I can imagine discussing this further.
* John Sullivan <sullivan@eazel.com>
*/
- compare = nautilus_file_compare_by_name (file_1, file_2);
+ compare = compare_by_name (file_1, file_2);
if (compare != 0) {
return compare;
}
- return nautilus_file_compare_by_directory_name (file_1, file_2);
+ return compare_by_directory_name (file_1, file_2);
case NAUTILUS_FILE_SORT_BY_DIRECTORY:
- compare = nautilus_file_compare_by_directory_name (file_1, file_2);
- if (compare != 0) {
- return compare;
- }
- return nautilus_file_compare_by_name (file_1, file_2);
+ return compare_by_full_path (file_1, file_2);
case NAUTILUS_FILE_SORT_BY_SIZE:
/* Compare directory sizes ourselves, then if necessary
* use GnomeVFS to compare file sizes.
*/
- compare = nautilus_file_compare_directories_by_size (file_1, file_2);
+ compare = compare_by_size (file_1, file_2);
if (compare != 0) {
return compare;
}
- rules[0] = GNOME_VFS_DIRECTORY_SORT_BYSIZE;
- rules[1] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE;
- rules[2] = GNOME_VFS_DIRECTORY_SORT_NONE;
- break;
+ return compare_by_full_path (file_1, file_2);
case NAUTILUS_FILE_SORT_BY_TYPE:
/* GnomeVFS doesn't know about our special text for certain
* mime types, so we handle the mime-type sorting ourselves.
*/
- compare = nautilus_file_compare_by_type (file_1, file_2);
+ compare = compare_by_type (file_1, file_2);
if (compare != 0) {
return compare;
}
- rules[0] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE;
- rules[1] = GNOME_VFS_DIRECTORY_SORT_NONE;
- break;
+ return compare_by_full_path (file_1, file_2);
case NAUTILUS_FILE_SORT_BY_MTIME:
- rules[0] = GNOME_VFS_DIRECTORY_SORT_BYMTIME;
- rules[1] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE;
- rules[2] = GNOME_VFS_DIRECTORY_SORT_NONE;
- break;
+ compare = compare_by_modification_time (file_1, file_2);
+ if (compare != 0) {
+ return compare;
+ }
+ return compare_by_full_path (file_1, file_2);
case NAUTILUS_FILE_SORT_BY_EMBLEMS:
/* GnomeVFS doesn't know squat about our emblems, so
* we handle comparing them here, before falling back
* to tie-breakers.
*/
- compare = nautilus_file_compare_by_emblems (file_1, file_2);
+ compare = compare_by_emblems (file_1, file_2);
if (compare != 0) {
return compare;
}
- rules[0] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE;
- rules[1] = GNOME_VFS_DIRECTORY_SORT_NONE;
- break;
+ return compare_by_full_path (file_1, file_2);
default:
g_return_val_if_fail (FALSE, 0);
}
-
- if (file_1->details->info == NULL) {
- if (file_2->details->info == NULL) {
- name_1 = nautilus_file_get_name (file_1);
- name_2 = nautilus_file_get_name (file_2);
- compare = nautilus_strcmp_case_breaks_ties (name_1, name_2);
- g_free (name_1);
- g_free (name_2);
- } else {
- /* FIXME bugzilla.eazel.com 2426:
- * We do have a name for file 2 to
- * compare with, so we can probably do better
- * than this for all cases.
- */
- compare = -1;
- }
- } else if (file_2->details->info == NULL) {
- /* FIXME bugzilla.eazel.com 2426:
- * We do have a name for file 1 to compare
- * with, so we can probably do better than this for
- * all cases.
- */
- compare = +1;
- } else {
- compare = gnome_vfs_file_info_compare_for_sort
- (file_1->details->info, file_2->details->info, rules);
- }
-
- return compare;
}
/**
@@ -1566,6 +1708,19 @@ nautilus_file_compare_name (NautilusFile *file,
return result;
}
+/* We use the file's URI for the metadata for files in a directory,
+ * but we use a hard-coded string for the metadata for the directory
+ * itself.
+ */
+static const char *
+get_metadata_name (NautilusFile *file)
+{
+ if (is_self_owned (file)) {
+ return FILE_NAME_FOR_DIRECTORY_METADATA;
+ }
+ return file->details->relative_uri;
+}
+
char *
nautilus_file_get_metadata (NautilusFile *file,
const char *key,
@@ -1580,7 +1735,7 @@ nautilus_file_get_metadata (NautilusFile *file,
return nautilus_directory_get_file_metadata
(file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata);
}
@@ -1601,7 +1756,7 @@ nautilus_file_get_metadata_list (NautilusFile *file,
return nautilus_directory_get_file_metadata_list
(file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
list_key,
list_subkey);
}
@@ -1617,7 +1772,7 @@ nautilus_file_set_metadata (NautilusFile *file,
g_return_if_fail (key[0] != '\0');
if (nautilus_directory_set_file_metadata (file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata,
metadata)) {
@@ -1638,7 +1793,7 @@ nautilus_file_set_metadata_list (NautilusFile *file,
g_return_if_fail (list_subkey[0] != '\0');
if (nautilus_directory_set_file_metadata_list (file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
list_key,
list_subkey,
list)) {
@@ -1661,7 +1816,7 @@ nautilus_file_get_boolean_metadata (NautilusFile *file,
return nautilus_directory_get_boolean_file_metadata
(file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata);
}
@@ -1680,7 +1835,7 @@ nautilus_file_get_integer_metadata (NautilusFile *file,
return nautilus_directory_get_integer_file_metadata
(file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata);
}
@@ -1697,7 +1852,7 @@ nautilus_file_set_boolean_metadata (NautilusFile *file,
g_return_if_fail (key[0] != '\0');
if (nautilus_directory_set_boolean_file_metadata (file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata,
metadata)) {
@@ -1716,7 +1871,7 @@ nautilus_file_set_integer_metadata (NautilusFile *file,
g_return_if_fail (key[0] != '\0');
if (nautilus_directory_set_integer_file_metadata (file->details->directory,
- file->details->relative_uri,
+ get_metadata_name (file),
key,
default_metadata,
metadata)) {
@@ -1800,7 +1955,7 @@ nautilus_file_get_uri (NautilusFile *file)
g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
return g_strdup (file->details->directory->details->uri);
}
@@ -3826,7 +3981,7 @@ nautilus_file_mark_gone (NautilusFile *file)
/* Let the directory know it's gone. */
directory = file->details->directory;
- if (directory->details->as_file != file) {
+ if (!is_self_owned (file)) {
nautilus_directory_remove_file (directory, file);
}
@@ -3857,7 +4012,7 @@ nautilus_file_changed (NautilusFile *file)
g_return_if_fail (NAUTILUS_IS_FILE (file));
- if (nautilus_file_is_self_owned (file)) {
+ if (is_self_owned (file)) {
nautilus_file_emit_changed (file);
} else {
fake_list.data = file;
diff --git a/po/.cvsignore b/po/.cvsignore
index 8f4907dec..27c09646a 100644
--- a/po/.cvsignore
+++ b/po/.cvsignore
@@ -5,7 +5,7 @@ Makefile.in
Makefile.in.in
POTFILES
cat-id-tbl.c
+messages
nautilus.pot
stamp-cat-id
-messages
-.headerlock \ No newline at end of file
+tmp
diff --git a/src/file-manager/nautilus-directory-view-ui.xml b/src/file-manager/nautilus-directory-view-ui.xml
index c85f5db1d..40d54d9f1 100644
--- a/src/file-manager/nautilus-directory-view-ui.xml
+++ b/src/file-manager/nautilus-directory-view-ui.xml
@@ -27,7 +27,7 @@
_label="Other _Application..."
_tip="Choose another application with which to open the selected item"
verb="OtherApplication"/>
- <menuitem/>
+ <separator/>
<placeholder name="Viewers Placeholder"/>
<menuitem name="OtherViewer"
_label="Other _Viewer..."