# HG changeset patch # User zas_ # Date 1212655262 0 # Node ID 548b193c084c248f8f97dde2a5ce776c2a614638 # Parent 16b3a5c8aedc5b0161c9c2b32ad1a914e94e6c25 Use uft8_collate_key() to sort utf8 strings. Modify file_data_set_path() to sync collate keys and file_data_pool on path change. Partially fix bug 1959854. diff -r 16b3a5c8aedc -r 548b193c084c src/collect.c --- a/src/collect.c Wed Jun 04 21:12:47 2008 +0000 +++ b/src/collect.c Thu Jun 05 08:41:02 2008 +0000 @@ -132,6 +132,8 @@ switch(collection_list_sort_method) { + case SORT_NAME: + break; case SORT_NONE: return 0; break; @@ -146,20 +148,21 @@ return 0; break; case SORT_PATH: - return CASE_SORT(cia->fd->path, cib->fd->path); + return CASE_SORT(cia->fd->path, cib->fd->path); /* FIXME: utf8_collate */ break; #ifdef HAVE_STRVERSCMP case SORT_NUMBER: return strverscmp(cia->fd->name, cib->fd->name); break; #endif - case SORT_NAME: default: - return CASE_SORT(cia->fd->name, cib->fd->name); break; } - return 0; + if (options->file_sort.case_sensitive) + return strcmp(cia->fd->collate_key_name, cib->fd->collate_key_name); + else + return strcmp(cia->fd->collate_key_name_nocase, cib->fd->collate_key_name_nocase); } GList *collection_list_sort(GList *list, SortType method) diff -r 16b3a5c8aedc -r 548b193c084c src/dupe.c --- a/src/dupe.c Wed Jun 04 21:12:47 2008 +0000 +++ b/src/dupe.c Thu Jun 05 08:41:02 2008 +0000 @@ -1132,11 +1132,11 @@ } if (mask & DUPE_MATCH_NAME) { - if (strcmp(a->fd->name, b->fd->name) != 0) return FALSE; + if (strcmp(a->fd->collate_key_name, b->fd->collate_key_name) != 0) return FALSE; } if (mask & DUPE_MATCH_NAME_CI) { - if (strcasecmp(a->fd->name, b->fd->name) != 0) return FALSE; + if (strcmp(a->fd->collate_key_name_nocase, b->fd->collate_key_name_nocase) != 0) return FALSE; } if (mask & DUPE_MATCH_SIZE) { diff -r 16b3a5c8aedc -r 548b193c084c src/filedata.c --- a/src/filedata.c Wed Jun 04 21:12:47 2008 +0000 +++ b/src/filedata.c Thu Jun 05 08:41:02 2008 +0000 @@ -22,6 +22,8 @@ #include "ui_fileops.h" +static GHashTable *file_data_pool = NULL; + static gint sidecar_file_priority(const gchar *path); @@ -144,15 +146,48 @@ file_data_send_notification(fd); /* FIXME there are probably situations when we don't want to call this */ } +static void file_data_set_collate_keys(FileData *fd) +{ + gchar *caseless_name; + + g_assert(g_utf8_validate(fd->name, -1, NULL)); + + caseless_name = g_utf8_casefold(fd->name, -1); + + g_free(fd->collate_key_name); + g_free(fd->collate_key_name_nocase); + +#if GLIB_CHECK_VERSION(2, 8, 0) + fd->collate_key_name = g_utf8_collate_key_for_filename(fd->name, -1); + fd->collate_key_name_nocase = g_utf8_collate_key_for_filename(caseless_name, -1); +#else + fd->collate_key_name = g_utf8_collate_key(fd->name, -1); + fd->collate_key_name_nocase = g_utf8_collate_key(caseless_name, -1); +#endif + g_free(caseless_name); +} static void file_data_set_path(FileData *fd, const gchar *path) { + g_assert(path && *path); + g_assert(file_data_pool); + + g_free(fd->path); + + if (fd->original_path) + { + g_hash_table_remove(file_data_pool, fd->original_path); + g_free(fd->original_path); + } + fd->original_path = g_strdup(path); + g_hash_table_insert(file_data_pool, fd->original_path, fd); if (strcmp(path, G_DIR_SEPARATOR_S) == 0) { fd->path = g_strdup(path); fd->name = fd->path; fd->extension = fd->name + 1; + file_data_set_collate_keys(fd); return; } @@ -167,6 +202,7 @@ g_free(dir); fd->name = ".."; fd->extension = fd->name + 2; + file_data_set_collate_keys(fd); return; } else if (strcmp(fd->name, ".") == 0) @@ -175,12 +211,15 @@ fd->path = remove_level_from_path(path); fd->name = "."; fd->extension = fd->name + 1; + file_data_set_collate_keys(fd); return; } fd->extension = extension_from_path(fd->path); if (fd->extension == NULL) fd->extension = fd->name + strlen(fd->name); + + file_data_set_collate_keys(fd); } static void file_data_check_changed_files(FileData *fd, struct stat *st) @@ -212,8 +251,6 @@ } } -static GHashTable *file_data_pool = NULL; - static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean check_sidecars) { FileData *fd; @@ -232,10 +269,13 @@ } fd = g_new0(FileData, 1); + + fd->path = NULL; + fd->name = NULL; + fd->collate_key_name = NULL; + fd->collate_key_name_nocase = NULL; + fd->original_path = NULL; - file_data_set_path(fd, path_utf8); - - fd->original_path = g_strdup(path_utf8); fd->size = st->st_size; fd->date = st->st_mtime; fd->pixbuf = NULL; @@ -243,10 +283,11 @@ fd->ref = 1; fd->magick = 0x12345678; - g_hash_table_insert(file_data_pool, fd->original_path, fd); + file_data_set_path(fd, path_utf8); /* set path, name, collate_key_*, original_path */ if (check_sidecars && sidecar_file_priority(fd->extension)) file_data_check_sidecars(fd); + return fd; } @@ -366,6 +407,8 @@ g_free(fd->path); g_free(fd->original_path); + g_free(fd->collate_key_name); + g_free(fd->collate_key_name_nocase); if (fd->pixbuf) g_object_unref(fd->pixbuf); @@ -446,7 +489,7 @@ if (len1 < len2) return -1; if (len1 > len2) return 1; - return strncmp(fd1->name, fd2->name, len1); + return strncmp(fd1->name, fd2->name, len1); /* FIXME: utf8 */ } gboolean file_data_add_change_info(FileData *fd, FileDataChangeType type, const gchar *src, const gchar *dest) @@ -541,26 +584,31 @@ switch (filelist_sort_method) { + case SORT_NAME: + break; case SORT_SIZE: if (fa->size < fb->size) return -1; if (fa->size > fb->size) return 1; - return CASE_SORT(fa->name, fb->name); /* fall back to name */ + /* fall back to name */ break; case SORT_TIME: if (fa->date < fb->date) return -1; if (fa->date > fb->date) return 1; - return CASE_SORT(fa->name, fb->name); /* fall back to name */ + /* fall back to name */ break; #ifdef HAVE_STRVERSCMP case SORT_NUMBER: return strverscmp(fa->name, fb->name); break; #endif - case SORT_NAME: default: - return CASE_SORT(fa->name, fb->name); break; } + + if (options->file_sort.case_sensitive) + return strcmp(fa->collate_key_name, fb->collate_key_name); + else + return strcmp(fa->collate_key_name_nocase, fb->collate_key_name_nocase); } gint filelist_sort_compare_filedata_full(FileData *fa, FileData *fb, SortType method, gint ascend) @@ -1356,12 +1404,7 @@ /* FIXME delete ?*/ if (type == FILEDATA_CHANGE_MOVE || type == FILEDATA_CHANGE_RENAME) { - g_free(fd->path); - g_hash_table_remove(file_data_pool, fd->original_path); - g_free(fd->original_path); file_data_set_path(fd, fd->change->dest); - fd->original_path = g_strdup(fd->change->dest); - g_hash_table_insert(file_data_pool, fd->original_path, fd); } file_data_increment_version(fd); } diff -r 16b3a5c8aedc -r 548b193c084c src/search.c --- a/src/search.c Wed Jun 04 21:12:47 2008 +0000 +++ b/src/search.c Thu Jun 05 08:41:02 2008 +0000 @@ -2234,7 +2234,10 @@ return 0; break; case SEARCH_COLUMN_NAME: - return CASE_SORT(fda->fd->name, fdb->fd->name); + if (options->file_sort.case_sensitive) + return strcmp(fda->fd->collate_key_name, fdb->fd->collate_key_name); + else + return strcmp(fda->fd->collate_key_name_nocase, fdb->fd->collate_key_name_nocase); break; case SEARCH_COLUMN_SIZE: if (fda->fd->size > fdb->fd->size) return 1; @@ -2250,7 +2253,7 @@ return sort_matchdata_dimensions(fda, fdb); break; case SEARCH_COLUMN_PATH: - return CASE_SORT(fda->fd->path, fdb->fd->path); + return CASE_SORT(fda->fd->path, fdb->fd->path); /* FIXME: utf8_collate */ break; default: break; diff -r 16b3a5c8aedc -r 548b193c084c src/typedefs.h --- a/src/typedefs.h Wed Jun 04 21:12:47 2008 +0000 +++ b/src/typedefs.h Thu Jun 05 08:41:02 2008 +0000 @@ -425,6 +425,8 @@ gchar *path; const gchar *name; const gchar *extension; + gchar *collate_key_name; + gchar *collate_key_name_nocase; gint64 size; time_t date; gboolean marks[FILEDATA_MARKS_SIZE]; diff -r 16b3a5c8aedc -r 548b193c084c src/view_dir_tree.c --- a/src/view_dir_tree.c Wed Jun 04 21:12:47 2008 +0000 +++ b/src/view_dir_tree.c Thu Jun 05 08:41:02 2008 +0000 @@ -883,7 +883,10 @@ gtk_tree_model_get(store, a, DIR_COLUMN_POINTER, &nda, -1); gtk_tree_model_get(store, b, DIR_COLUMN_POINTER, &ndb, -1); - return CASE_SORT(nda->fd->name, ndb->fd->name); + if (options->file_sort.case_sensitive) + return strcmp(nda->fd->collate_key_name, nda->fd->collate_key_name); + else + return strcmp(nda->fd->collate_key_name_nocase, nda->fd->collate_key_name_nocase); } /*