diff options
Diffstat (limited to 'libnautilus/nautilus-directory.c')
-rw-r--r-- | libnautilus/nautilus-directory.c | 1093 |
1 files changed, 30 insertions, 1063 deletions
diff --git a/libnautilus/nautilus-directory.c b/libnautilus/nautilus-directory.c index 643c290db..eaa37ac68 100644 --- a/libnautilus/nautilus-directory.c +++ b/libnautilus/nautilus-directory.c @@ -1,6 +1,6 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- - nautilus-directory.c: Mautilus directory model. + nautilus-directory.c: Nautilus directory model. Copyright (C) 1999, 2000 Eazel, Inc. @@ -23,33 +23,20 @@ */ #include <config.h> -#include "nautilus-directory.h" +#include "nautilus-directory-private.h" -#include <grp.h> -#include <pwd.h> #include <stdlib.h> #include <gtk/gtksignal.h> #include <gtk/gtkmain.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> - -#include <libgnomevfs/gnome-vfs-types.h> -#include <libgnomevfs/gnome-vfs-uri.h> -#include <libgnomevfs/gnome-vfs-file-info.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-alloc.h" -#include "nautilus-glib-extensions.h" #include "nautilus-gtk-macros.h" -#include "nautilus-lib-self-check-functions.h" #include "nautilus-string.h" +#include "nautilus-lib-self-check-functions.h" +#include "nautilus-file-private.h" #define METAFILE_NAME ".nautilus-metafile.xml" #define METAFILE_PERMISSIONS (GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_USER_WRITE \ @@ -67,12 +54,6 @@ #define DIRECTORY_LOAD_ITEMS_PER_CB 1 -typedef enum { - NAUTILUS_DATE_TYPE_MODIFIED, - NAUTILUS_DATE_TYPE_CHANGED, - NAUTILUS_DATE_TYPE_ACCESSED -} NautilusDateType; - enum { FILES_ADDED, @@ -80,79 +61,25 @@ enum LAST_SIGNAL }; -/* FIXME: This hack needs to die eventually. See comments with function */ -static int get_directory_item_count_hack (NautilusFile *file, gboolean ignore_invisible_items); - - static guint nautilus_directory_signals[LAST_SIGNAL]; -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); - -static void nautilus_file_free (NautilusFile *file); -static int nautilus_file_compare_by_type (NautilusFile *file_1, NautilusFile *file_2); -static int nautilus_file_compare_for_sort_internal (NautilusFile *file_1, - NautilusFile *file_2, - NautilusFileSortType sort_type, - gboolean reversed); - -static char * nautilus_file_get_date_as_string (NautilusFile *file, - NautilusDateType date_type); -static char *nautilus_file_get_owner_as_string (NautilusFile *file); -static char *nautilus_file_get_group_as_string (NautilusFile *file); -static char *nautilus_file_get_permissions_as_string (NautilusFile *file); -static char * nautilus_file_get_size_as_string (NautilusFile *file); -static char * nautilus_file_get_type_as_string (NautilusFile *file); -static void nautilus_directory_load_cb (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - GnomeVFSDirectoryList *list, - guint entries_read, - gpointer callback_data); -static NautilusFile *nautilus_directory_new_file (NautilusDirectory *directory, - GnomeVFSFileInfo *info); +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); +static void nautilus_directory_load_cb (GnomeVFSAsyncHandle *handle, + GnomeVFSResult result, + GnomeVFSDirectoryList *list, + guint entries_read, + gpointer callback_data); NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusDirectory, nautilus_directory, GTK_TYPE_OBJECT) -struct NautilusDirectoryDetails -{ - char *uri_text; - GnomeVFSURI *uri; - - GnomeVFSURI *metafile_uri; - GnomeVFSURI *alternate_metafile_uri; - gboolean use_alternate_metafile; - - xmlDoc *metafile_tree; - guint write_metafile_idle_id; - - GnomeVFSAsyncHandle *directory_load_in_progress; - GnomeVFSDirectoryListPosition directory_load_list_last_handled; - - GList *pending_file_info; - guint dequeue_pending_idle_id; - - gboolean directory_loaded; - - GList *files; -}; - -struct NautilusFile -{ - guint ref_count; - - NautilusDirectory *directory; - GnomeVFSFileInfo *info; - gboolean is_gone; -}; - static GHashTable* directory_objects; static void @@ -1005,9 +932,9 @@ nautilus_directory_set_integer_metadata (NautilusDirectory *directory, g_free (default_as_string); } -static xmlNode * -get_file_metadata_node (NautilusDirectory *directory, - const char *file_name) +xmlNode * +nautilus_directory_get_file_metadata_node (NautilusDirectory *directory, + const char *file_name) { xmlNode *root, *child; xmlChar *property; @@ -1038,18 +965,18 @@ get_file_metadata_node (NautilusDirectory *directory, return NULL; } -static char * +char * nautilus_directory_get_file_metadata (NautilusDirectory *directory, const char *file_name, const char *tag, const char *default_metadata) { return nautilus_directory_get_metadata_from_node - (get_file_metadata_node (directory, file_name), + (nautilus_directory_get_file_metadata_node (directory, file_name), tag, default_metadata); } -static void +void nautilus_directory_set_file_metadata (NautilusDirectory *directory, const char *file_name, const char *tag, @@ -1118,7 +1045,7 @@ nautilus_directory_set_file_metadata (NautilusDirectory *directory, nautilus_directory_request_write_metafile (directory); } -static NautilusFile * +NautilusFile * nautilus_directory_new_file (NautilusDirectory *directory, GnomeVFSFileInfo *info) { NautilusFile *file; @@ -1135,973 +1062,13 @@ nautilus_directory_new_file (NautilusDirectory *directory, GnomeVFSFileInfo *inf return file; } -/** - * nautilus_file_get: - * @uri: URI of file to get. - * - * Get a file given a uri. - * Returns a referenced object. Unref when finished. - * If two windows are viewing the same uri, the file object is shared. - */ -NautilusFile * -nautilus_file_get (const char *uri) -{ - GnomeVFSResult result; - GnomeVFSFileInfo *file_info; - GnomeVFSURI *vfs_uri, *directory_vfs_uri; - char *directory_uri; - NautilusDirectory *directory; - NautilusFile *file; - - /* Get info on the file. */ - file_info = gnome_vfs_file_info_new (); - result = gnome_vfs_get_file_info (uri, file_info, - GNOME_VFS_FILE_INFO_GETMIMETYPE - | GNOME_VFS_FILE_INFO_FASTMIMETYPE - | GNOME_VFS_FILE_INFO_FOLLOWLINKS, NULL); - if (result != GNOME_VFS_OK) - return NULL; - - /* Make VFS version of URI. */ - vfs_uri = gnome_vfs_uri_new (uri); - if (vfs_uri == NULL) - return NULL; - - /* Make VFS version of directory URI. */ - directory_vfs_uri = gnome_vfs_uri_get_parent (vfs_uri); - gnome_vfs_uri_unref (vfs_uri); - if (directory_vfs_uri == NULL) - return NULL; - - /* Make text version of directory URI. */ - directory_uri = gnome_vfs_uri_to_string (directory_vfs_uri, - GNOME_VFS_URI_HIDE_NONE); - gnome_vfs_uri_unref (directory_vfs_uri); - - /* Get object that represents the directory. */ - directory = nautilus_directory_get (directory_uri); - g_free (directory_uri); - if (directory == NULL) - return NULL; - - file = nautilus_directory_new_file (directory, file_info); - - gnome_vfs_file_info_unref (file_info); - nautilus_file_ref (file); - gtk_object_unref (GTK_OBJECT (directory)); - - return file; -} - -void -nautilus_file_ref (NautilusFile *file) -{ - g_return_if_fail (file != NULL); - - g_assert (file->ref_count < G_MAXINT); - g_assert (file->directory != NULL); - - /* Increment the ref count. */ - if (file->ref_count++ != 0) { - return; - } - - /* As soon as someone other than the directory holds a ref, - * we need to hold the directory too. */ - gtk_object_ref (GTK_OBJECT (file->directory)); -} - -void -nautilus_file_unref (NautilusFile *file) -{ - g_return_if_fail (file != NULL); - - g_assert (file->ref_count != 0); - g_assert (file->directory != NULL); - - /* Decrement the ref count. */ - if (--file->ref_count != 0) { - return; - } - - /* No references left, so it's time to release our hold on the directory. */ - gtk_object_unref (GTK_OBJECT (file->directory)); - if (file->is_gone) { - nautilus_file_free (file); - } -} - -static void -nautilus_file_free (NautilusFile *file) -{ - g_assert (file->ref_count == 0); - - /* Destroy the file object. */ - gnome_vfs_file_info_unref (file->info); - g_free (file); -} - -static int -nautilus_file_compare_by_size_with_directories (NautilusFile *file_1, NautilusFile *file_2) -{ - gboolean is_directory_1; - gboolean is_directory_2; - int item_count_1; - int 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 (is_directory_2 && !is_directory_1) - return +1; - - if (!is_directory_1 && !is_directory_2) - return 0; - - /* Both are directories, compare by item count. */ - /* FIXME: get_directory_item_count_hack is slow, and calling - * it for every pairwise comparison here is nasty. Need to - * change this to (not-yet-existent) architecture where the - * item count can be calculated once in a deferred way, and - * then stored or cached. - */ - item_count_1 = get_directory_item_count_hack (file_1, FALSE); - item_count_2 = get_directory_item_count_hack (file_2, FALSE); - - if (item_count_1 < item_count_2) - return -1; - - if (item_count_2 < item_count_1) - return +1; - - return 0; -} - -static int -nautilus_file_compare_by_type (NautilusFile *file_1, NautilusFile *file_2) -{ - gboolean is_directory_1; - gboolean is_directory_2; - char * type_string_1; - char * type_string_2; - int result; - - /* Directories go first. Then, if mime types are identical, - * don't bother getting strings (for speed). This assumes - * that the string is dependent entirely on the mime type, - * which is true now but might not be later. - */ - 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 0; - - if (is_directory_1) - return -1; - - if (is_directory_2) - return +1; - - if (nautilus_strcmp (file_1->info->mime_type, file_2->info->mime_type) == 0) - return 0; - - type_string_1 = nautilus_file_get_type_as_string (file_1); - type_string_2 = nautilus_file_get_type_as_string (file_2); - - result = nautilus_strcmp (type_string_1, type_string_2); - - g_free (type_string_1); - g_free (type_string_2); - - return result; -} - -static int -nautilus_file_compare_for_sort_internal (NautilusFile *file_1, - NautilusFile *file_2, - NautilusFileSortType sort_type, - gboolean reversed) -{ - GnomeVFSDirectorySortRule *rules; - - g_return_val_if_fail (file_1 != NULL, 0); - g_return_val_if_fail (file_2 != NULL, 0); - g_return_val_if_fail (sort_type != NAUTILUS_FILE_SORT_NONE, 0); - -#define ALLOC_RULES(n) alloca ((n) * sizeof (GnomeVFSDirectorySortRule)) - - switch (sort_type) { - case NAUTILUS_FILE_SORT_BY_NAME: - rules = ALLOC_RULES (2); - /* Note: This used to put directories first. I - * thought that was counterintuitive and removed it, - * but I can imagine discussing this further. - * John Sullivan <sullivan@eazel.com> - */ - rules[0] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE; - rules[1] = GNOME_VFS_DIRECTORY_SORT_NONE; - break; - case NAUTILUS_FILE_SORT_BY_SIZE: - /* Compare directory sizes ourselves, then if necessary - * use GnomeVFS to compare file sizes. - */ - { - int size_compare; - - size_compare = nautilus_file_compare_by_size_with_directories (file_1, file_2); - if (size_compare != 0) - return size_compare; - } - rules = ALLOC_RULES (3); - rules[0] = GNOME_VFS_DIRECTORY_SORT_BYSIZE; - rules[1] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE; - rules[2] = GNOME_VFS_DIRECTORY_SORT_NONE; - break; - 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. - */ - { - int type_compare; - - type_compare = nautilus_file_compare_by_type (file_1, file_2); - if (type_compare != 0) - return type_compare; - } - rules = ALLOC_RULES (2); - rules[0] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE; - rules[1] = GNOME_VFS_DIRECTORY_SORT_NONE; - break; - case NAUTILUS_FILE_SORT_BY_MTIME: - rules = ALLOC_RULES (3); - rules[0] = GNOME_VFS_DIRECTORY_SORT_BYMTIME; - rules[1] = GNOME_VFS_DIRECTORY_SORT_BYNAME_IGNORECASE; - rules[2] = GNOME_VFS_DIRECTORY_SORT_NONE; - break; - default: - g_assert_not_reached (); - return 0; - } - - if (reversed) - return gnome_vfs_file_info_compare_for_sort_reversed (file_1->info, - file_2->info, - rules); - else - return gnome_vfs_file_info_compare_for_sort (file_1->info, - file_2->info, - rules); - -#undef ALLOC_RULES -} - -/** - * nautilus_file_compare_for_sort: - * @file_1: A file object - * @file_2: Another file object - * @sort_type: Sort criterion - * - * Return value: int < 0 if @file_1 should come before file_2 in a smallest-to-largest - * sorted list; int > 0 if @file_2 should come before file_1 in a smallest-to-largest - * sorted list; 0 if @file_1 and @file_2 are equal for this sort criterion. Note - * that each named sort type may actually break ties several ways, with the name - * of the sort criterion being the primary but not only differentiator. - **/ -int -nautilus_file_compare_for_sort (NautilusFile *file_1, - NautilusFile *file_2, - NautilusFileSortType sort_type) -{ - return nautilus_file_compare_for_sort_internal (file_1, file_2, sort_type, FALSE); -} - -/** - * nautilus_file_compare_for_sort_reversed: - * @file_1: A file object - * @file_2: Another file object - * @sort_type: Sort criterion - * - * Return value: The opposite of nautilus_file_compare_for_sort: int > 0 if @file_1 - * should come before file_2 in a smallest-to-largest sorted list; int < 0 if @file_2 - * should come before file_1 in a smallest-to-largest sorted list; 0 if @file_1 - * and @file_2 are equal for this sort criterion. Note that each named sort type - * may actually break ties several ways, with the name of the sort criterion - * being the primary but not only differentiator. - **/ -int -nautilus_file_compare_for_sort_reversed (NautilusFile *file_1, - NautilusFile *file_2, - NautilusFileSortType sort_type) -{ - return nautilus_file_compare_for_sort_internal (file_1, file_2, sort_type, TRUE); -} - -char * -nautilus_file_get_metadata (NautilusFile *file, - const char *tag, - const char *default_metadata) -{ - g_return_val_if_fail (file != NULL, NULL); - - return nautilus_directory_get_file_metadata (file->directory, - file->info->name, - tag, - default_metadata); -} - void -nautilus_file_set_metadata (NautilusFile *file, - const char *tag, - const char *default_metadata, - const char *metadata) +nautilus_directory_files_removed (NautilusDirectory *directory, + GList *removed_files) { - g_return_if_fail (file != NULL); - - nautilus_directory_set_file_metadata (file->directory, - file->info->name, - tag, - default_metadata, - metadata); -} - -char * -nautilus_file_get_name (NautilusFile *file) -{ - g_return_val_if_fail (file != NULL, NULL); - - g_assert (file->directory == NULL || NAUTILUS_IS_DIRECTORY (file->directory)); - g_assert (file->info->name != NULL); - g_assert (file->info->name[0] != '\0'); - - return g_strdup (file->info->name); -} - -char * -nautilus_file_get_uri (NautilusFile *file) -{ - GnomeVFSURI *uri; - char *uri_text; - - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (file->directory != NULL, NULL); - - uri = gnome_vfs_uri_append_path (file->directory->details->uri, file->info->name); - uri_text = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); - gnome_vfs_uri_unref (uri); - return uri_text; -} - -/** - * nautilus_file_get_date_as_string: - * - * Get a user-displayable string representing a file modification date. - * The caller is responsible for g_free-ing this string. - * @file: NautilusFile representing the file in question. - * - * Returns: Newly allocated string ready to display to the user. - * - **/ -static char * -nautilus_file_get_date_as_string (NautilusFile *file, NautilusDateType date_type) -{ - struct tm *file_time; - const char *format; - GDate *today; - GDate *file_date; - guint32 file_date_age; - - g_return_val_if_fail (file != NULL, NULL); - - switch (date_type) - { - case NAUTILUS_DATE_TYPE_CHANGED: - file_time = localtime(&file->info->ctime); - break; - case NAUTILUS_DATE_TYPE_ACCESSED: - file_time = localtime(&file->info->atime); - break; - case NAUTILUS_DATE_TYPE_MODIFIED: - file_time = localtime(&file->info->mtime); - break; - default: - g_assert_not_reached (); - } - file_date = nautilus_g_date_new_tm (file_time); - - today = g_date_new (); - g_date_set_time (today, time (NULL)); - - /* Overflow results in a large number; fine for our purposes. */ - file_date_age = g_date_julian (today) - g_date_julian (file_date); - - g_date_free (file_date); - g_date_free (today); - - /* Format varies depending on how old the date is. This minimizes - * the length (and thus clutter & complication) of typical dates - * while providing sufficient detail for recent dates to make - * them maximally understandable at a glance. Keep all format - * strings separate rather than combining bits & pieces for - * internationalization's sake. - */ - - if (file_date_age == 0) - { - /* today, use special word */ - format = _("today %-I:%M %p"); - } - else if (file_date_age == 1) - { - /* yesterday, use special word */ - format = _("yesterday %-I:%M %p"); - } - else if (file_date_age < 7) - { - /* current week, include day of week */ - format = _("%A %-m/%-d/%y %-I:%M %p"); - } - else - { - format = _("%-m/%-d/%y %-I:%M %p"); - } - - return nautilus_strdup_strftime (format, file_time); -} - -/** - * nautilus_file_get_directory_item_count - * - * Get the number of items in a directory. - * @file: NautilusFile representing a directory. It is an error to - * call this function on a file that is not a directory. - * @ignore_invisible_items: TRUE if invisible items should not be - * included in count. - * - * Returns: item count for this directory. - * - **/ -guint -nautilus_file_get_directory_item_count (NautilusFile *file, - gboolean ignore_invisible_items) -{ - g_return_val_if_fail (nautilus_file_is_directory (file), 0); - - return get_directory_item_count_hack (file, ignore_invisible_items); -} - -/** - * nautilus_file_get_size - * - * Get the file size. - * @file: NautilusFile representing the file in question. - * - * Returns: Size in bytes. - * - **/ -GnomeVFSFileSize -nautilus_file_get_size (NautilusFile *file) -{ - g_return_val_if_fail (file != NULL, 0); - - return file->info->size; -} - -/** - * nautilus_file_get_permissions_as_string: - * - * Get a user-displayable string representing a file's permissions. The caller - * is responsible for g_free-ing this string. - * @file: NautilusFile representing the file in question. - * - * Returns: Newly allocated string ready to display to the user. - * - **/ -static char * -nautilus_file_get_permissions_as_string (NautilusFile *file) -{ - GnomeVFSFilePermissions permissions; - gboolean is_directory; - gboolean is_link; - - permissions = file->info->permissions; - is_directory = nautilus_file_is_directory (file); - is_link = GNOME_VFS_FILE_INFO_SYMLINK(file->info); - - return g_strdup_printf ("%c%c%c%c%c%c%c%c%c%c", - is_link ? 'l' : is_directory ? 'd' : '-', - permissions & GNOME_VFS_PERM_USER_READ ? 'r' : '-', - permissions & GNOME_VFS_PERM_USER_WRITE ? 'w' : '-', - permissions & GNOME_VFS_PERM_USER_EXEC ? 'x' : '-', - permissions & GNOME_VFS_PERM_GROUP_READ ? 'r' : '-', - permissions & GNOME_VFS_PERM_GROUP_WRITE ? 'w' : '-', - permissions & GNOME_VFS_PERM_GROUP_EXEC ? 'x' : '-', - permissions & GNOME_VFS_PERM_OTHER_READ ? 'r' : '-', - permissions & GNOME_VFS_PERM_OTHER_WRITE ? 'w' : '-', - permissions & GNOME_VFS_PERM_OTHER_EXEC ? 'x' : '-'); -} - -/** - * nautilus_file_get_owner_as_string: - * - * Get a user-displayable string representing a file's owner. The caller - * is responsible for g_free-ing this string. - * @file: NautilusFile representing the file in question. - * - * Returns: Newly allocated string ready to display to the user. - * - **/ -static char * -nautilus_file_get_owner_as_string (NautilusFile *file) -{ - struct passwd *password_info; - - /* FIXME: Can we trust the uid in the file info? Might - * there be garbage there? What will it do for non-local files? - */ - /* No need to free result of getpwuid */ - password_info = getpwuid (file->info->uid); - - g_print ("pointer to password info is %p\n", password_info); - - if (password_info == NULL) - { - return g_strdup (_("unknown owner")); - } - - return g_strdup (password_info->pw_name); -} - -/** - * nautilus_file_get_group_as_string: - * - * Get a user-displayable string representing a file's group. The caller - * is responsible for g_free-ing this string. - * @file: NautilusFile representing the file in question. - * - * Returns: Newly allocated string ready to display to the user. - * - **/ -static char * -nautilus_file_get_group_as_string (NautilusFile *file) -{ - struct group *group_info; - - /* FIXME: Can we trust the gid in the file info? Might - * there be garbage there? What will it do for non-local files? - */ - /* No need to free result of getgrgid */ - group_info = getgrgid (file->info->gid); - - if (group_info == NULL) - { - return g_strdup (_("unknown group")); - } - - return g_strdup (group_info->gr_name); -} - - -/* This #include is part of the following hack, and should be removed with it */ -#include <dirent.h> - -static int -get_directory_item_count_hack (NautilusFile *file, gboolean ignore_invisible_items) -{ - /* Code borrowed from Gnomad and hacked into here for now */ - - char * uri; - char * path; - DIR* directory; - int count; - struct dirent * entry; - - g_assert (nautilus_file_is_directory (file)); - - uri = nautilus_file_get_uri (file); - if (nautilus_has_prefix (uri, "file://")) - path = uri + 7; - else - path = uri; - - directory = opendir (path); - - g_free (uri); - - if (!directory) - return 0; - - count = 0; - - while ((entry = readdir(directory)) != NULL) - // Only count invisible items if requested. - if (!ignore_invisible_items || entry->d_name[0] != '.') - count += 1; - - closedir(directory); - - /* This way of getting the count includes . and .., so we subtract those out */ - if (!ignore_invisible_items) { - count -= 2; - } - - return count; -} - -/** - * nautilus_file_get_size_as_string: - * - * Get a user-displayable string representing a file size. The caller - * is responsible for g_free-ing this string. The string is an item - * count for directories. - * @file: NautilusFile representing the file in question. - * - * Returns: Newly allocated string ready to display to the user. - * - **/ -static char * -nautilus_file_get_size_as_string (NautilusFile *file) -{ - g_return_val_if_fail (file != NULL, NULL); - - if (nautilus_file_is_directory (file)) - { - /* FIXME: Since computing the item count is slow, we - * want to do it in a deferred way. However, that - * architecture doesn't exist yet, so we're hacking - * it in for now. - */ - int item_count; - - item_count = get_directory_item_count_hack (file, FALSE); - if (item_count == 0) { - return g_strdup (_("0 items")); - } else if (item_count == 1) { - return g_strdup (_("1 item")); - } else { - return g_strdup_printf (_("%d items"), item_count); - } - } - - return gnome_vfs_file_size_to_string (file->info->size); -} - -/** - * nautilus_file_get_string_attribute: - * - * Get a user-displayable string from a named attribute. Use g_free to - * free this string. - * - * @file: NautilusFile representing the file in question. - * @attribute_name: The name of the desired attribute. The currently supported - * set includes "name", "type", "size", "date_modified", "date_changed", - * "date_accessed", "owner", "group", "permissions". - * - * Returns: Newly allocated string ready to display to the user, or NULL - * if @attribute_name is not supported. - * - **/ -char * -nautilus_file_get_string_attribute (NautilusFile *file, const char *attribute_name) -{ - /* FIXME: Use hash table and switch statement or function pointers for speed? */ - - if (strcmp (attribute_name, "name") == 0) { - return nautilus_file_get_name (file); - } - - if (strcmp (attribute_name, "type") == 0) { - return nautilus_file_get_type_as_string (file); - } - - if (strcmp (attribute_name, "size") == 0) { - return nautilus_file_get_size_as_string (file); - } - - if (strcmp (attribute_name, "date_modified") == 0) { - return nautilus_file_get_date_as_string (file, - NAUTILUS_DATE_TYPE_MODIFIED); - } - - if (strcmp (attribute_name, "date_changed") == 0) { - return nautilus_file_get_date_as_string (file, - NAUTILUS_DATE_TYPE_CHANGED); - } - - if (strcmp (attribute_name, "date_accessed") == 0) { - return nautilus_file_get_date_as_string (file, - NAUTILUS_DATE_TYPE_ACCESSED); - } - - if (strcmp (attribute_name, "permissions") == 0) { - return nautilus_file_get_permissions_as_string (file); - } - - if (strcmp (attribute_name, "owner") == 0) { - return nautilus_file_get_owner_as_string (file); - } - - if (strcmp (attribute_name, "group") == 0) { - return nautilus_file_get_group_as_string (file); - } - - return NULL; -} - -/** - * nautilus_file_get_type_as_string: - * - * Get a user-displayable string representing a file type. The caller - * is responsible for g_free-ing this string. - * @file: NautilusFile representing the file in question. - * - * Returns: Newly allocated string ready to display to the user. - * - **/ -static char * -nautilus_file_get_type_as_string (NautilusFile *file) -{ - g_return_val_if_fail (file != NULL, NULL); - - if (nautilus_file_is_directory (file)) { - /* Special-case this so it isn't "special/directory". - * FIXME: Should this be "folder" instead? - */ - return g_strdup (_("directory")); - } - - if (nautilus_strlen (file->info->mime_type) == 0) { - return g_strdup (_("unknown type")); - } - - return g_strdup (file->info->mime_type); -} - -/** - * nautilus_file_get_type - * - * Return this file's type. - * @file: NautilusFile representing the file in question. - * - * Returns: The type. - * - **/ -GnomeVFSFileType -nautilus_file_get_type (NautilusFile *file) -{ - g_return_val_if_fail (file != NULL, FALSE); - - return file->info->type; -} - -/** - * nautilus_file_get_mime_type - * - * Return this file's mime type. - * @file: NautilusFile representing the file in question. - * - * Returns: The mime type. - * - **/ -const char * -nautilus_file_get_mime_type (NautilusFile *file) -{ - g_return_val_if_fail (file != NULL, FALSE); - - return file->info->mime_type; -} - -/** - * nautilus_file_get_keywords - * - * Return this file's keywords. - * @file: NautilusFile representing the file in question. - * - * Returns: A list of keywords. - * - **/ -GList * -nautilus_file_get_keywords (NautilusFile *file) -{ - GList *keywords; - xmlNode *file_node, *child; - xmlChar *property; - - g_return_val_if_fail (file != NULL, NULL); - - keywords = NULL; - - /* Put all the keywords into a list. */ - file_node = get_file_metadata_node (file->directory, file->info->name); - if (file_node != NULL) { - for (child = file_node->childs; child != NULL; child = child->next) { - if (strcmp (child->name, "KEYWORD") == 0) { - property = xmlGetProp (child, "NAME"); - if (property != NULL) { - keywords = g_list_prepend (keywords, - g_strdup (property)); - } - } - } - } - - return g_list_reverse (keywords); -} - -/** - * nautilus_file_is_symbolic_link - * - * Check if this file is a symbolic link. - * @file: NautilusFile representing the file in question. - * - * Returns: True if the file is a symbolic link. - * - **/ -gboolean -nautilus_file_is_symbolic_link (NautilusFile *file) -{ - g_return_val_if_fail (file != NULL, FALSE); - - return GNOME_VFS_FILE_INFO_SYMLINK (file->info); -} - -/** - * nautilus_file_is_directory - * - * Check if this file is a directory. - * @file: NautilusFile representing the file in question. - * - * Returns: TRUE if @file is a directory. - * - **/ -gboolean -nautilus_file_is_directory (NautilusFile *file) -{ - g_return_val_if_fail (file != NULL, FALSE); - - return nautilus_file_get_type (file) == GNOME_VFS_FILE_TYPE_DIRECTORY; -} - -/** - * nautilus_file_is_executable - * - * Check if this file is executable at all. - * @file: NautilusFile representing the file in question. - * - * Returns: True if any of the execute bits are set. - * - **/ -gboolean -nautilus_file_is_executable (NautilusFile *file) -{ - g_return_val_if_fail (file != NULL, FALSE); - - return (file->info->flags & (GNOME_VFS_PERM_USER_EXEC - | GNOME_VFS_PERM_GROUP_EXEC - | GNOME_VFS_PERM_OTHER_EXEC)) != 0; -} - -/** - * nautilus_file_delete - * - * Delete this file. - * @file: NautilusFile representing the file in question. - **/ -void -nautilus_file_delete (NautilusFile *file) -{ - char *text_uri; - GnomeVFSResult result; - GList *removed_files; - - g_return_if_fail (file != NULL); - - /* Deleting a file that's already gone is easy. */ - if (file->is_gone) { - return; - } - - /* Do the actual deletion. */ - text_uri = nautilus_file_get_uri (file); - if (nautilus_file_is_directory (file)) { - result = gnome_vfs_remove_directory (text_uri); - } else { - result = gnome_vfs_unlink (text_uri); - } - g_free (text_uri); - - /* Mark the file gone. */ - if (result == GNOME_VFS_OK || result == GNOME_VFS_ERROR_NOTFOUND) { - file->is_gone = TRUE; - - /* Let the directory know it's gone. */ - if (file->directory != NULL) { - g_list_remove (file->directory->details->files, file); - - /* Send out a message. */ - removed_files = g_list_prepend (NULL, file); - gtk_signal_emit (GTK_OBJECT (file->directory), - nautilus_directory_signals[FILES_REMOVED], - removed_files); - g_list_free (removed_files); - } - } -} - -/** - * nautilus_file_is_gone - * - * Check if a file has already been deleted. - * @file: NautilusFile representing the file in question. - * - * Returns: TRUE if the file is already gone. - **/ -gboolean -nautilus_file_is_gone (NautilusFile *file) -{ - g_return_val_if_fail (file != NULL, FALSE); - - return file->is_gone; -} - -/** - * nautilus_file_list_ref - * - * Ref all the files in a list. - * @file_list: GList of files. - **/ -void -nautilus_file_list_ref (GList *file_list) -{ - g_list_foreach (file_list, (GFunc) nautilus_file_ref, NULL); -} - -/** - * nautilus_file_list_unref - * - * Unref all the files in a list. - * @file_list: GList of files. - **/ -void -nautilus_file_list_unref (GList *file_list) -{ - g_list_foreach (file_list, (GFunc) nautilus_file_ref, NULL); -} - -/** - * nautilus_file_list_free - * - * Free a list of files after unrefing them. - * @file_list: GList of files. - **/ -void -nautilus_file_list_free (GList *file_list) -{ - nautilus_file_list_unref (file_list); - g_list_free (file_list); + gtk_signal_emit (GTK_OBJECT (directory), + nautilus_directory_signals[FILES_REMOVED], + removed_files); } #if !defined (NAUTILUS_OMIT_SELF_CHECK) |