diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 4722d743a9..2c1f72ffb2 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -154,7 +154,7 @@ new: id: LANG_SORT_CASE desc: in settings_menu eng: "Sort Case Sensitive" -voice: "" +voice: "Sort Case Sensitive" new: id: LANG_RESUME @@ -254,9 +254,9 @@ voice: "" new: id: LANG_CASE_MENU -desc: in fileview_settings_menu() -eng: "Sort Mode" -voice: "Sort Mode" +desc: DEPRECATED +eng: "" +voice: "" new: id: LANG_SCROLL_MENU @@ -2685,3 +2685,39 @@ desc: Onplay open with eng: "Open with" voice: "open with" new: + +id: LANG_SORT_DIR +desc: browser sorting setting +eng: "Sort Directories" +voice: "sort directories" +new: + +id: LANG_SORT_FILE +desc: browser sorting setting +eng: "Sort Files" +voice: "sort files" +new: + +id: LANG_SORT_ALPHA +desc: browser sorting setting +eng: "Alphabetical" +voice: "Alphabetical" +new: + +id: LANG_SORT_DATE +desc: browser sorting setting +eng: "by date" +voice: "by date" +new: + +id: LANG_SORT_DATE_REVERSE +desc: browser sorting setting +eng: "by newest date" +voice: "by newest date" +new: + +id: LANG_SORT_TYPE +desc: browser sorting setting +eng: "by type" +voice: "by type" +new: diff --git a/apps/settings.c b/apps/settings.c index 56f61eb9b7..36fcff3814 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -318,8 +318,11 @@ static struct bit_entry hd_bits[] = {2, S_O(talk_file), 0, "talk file", "off,number,spell" }, {1, S_O(talk_menu), true, "talk menu", off_on }, - /* new stuff to be added here */ + /* new stuff to be added at the end */ /* If values are just added to the end, no need to bump the version. */ + {2, S_O(sort_file), 0, "sort files", "alpha,oldest,newest,type" }, + {2, S_O(sort_dir), 0, "sort dirs", "alpha,oldest,newest" }, + /* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */ }; diff --git a/apps/settings.h b/apps/settings.h index 315824cd9e..ddc3aca599 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -208,6 +208,10 @@ struct user_settings bool talk_menu; /* enable voice UI */ int talk_dir; /* talkbox mode: 0=off 1=number 2=clip@enter 3=clip@hover */ int talk_file; /* voice filename mode: 0=off, 1=number, other t.b.d. */ + + /* file browser sorting */ + int sort_file; /* 0=alpha, 1=date, 2=date (new first), 3=type */ + int sort_dir; /* 0=alpha, 1=date (old first), 2=date (new first) */ }; enum optiontype { INT, BOOL }; diff --git a/apps/settings_menu.c b/apps/settings_menu.c index 34f7a99c2a..d20aa3bda0 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -476,6 +476,29 @@ static bool sort_case(void) return set_bool( str(LANG_SORT_CASE), &global_settings.sort_case ); } +static bool sort_file(void) +{ + struct opt_items names[] = { + { STR(LANG_SORT_ALPHA) }, + { STR(LANG_SORT_DATE) }, + { STR(LANG_SORT_DATE_REVERSE) }, + { STR(LANG_SORT_TYPE) } + }; + return set_option( str(LANG_SORT_FILE), &global_settings.sort_file, INT, + names, 4, NULL ); +} + +static bool sort_dir(void) +{ + struct opt_items names[] = { + { STR(LANG_SORT_ALPHA) }, + { STR(LANG_SORT_DATE) }, + { STR(LANG_SORT_DATE_REVERSE) } + }; + return set_option( str(LANG_SORT_DIR), &global_settings.sort_dir, INT, + names, 3, NULL ); +} + static bool resume(void) { struct opt_items names[] = { @@ -1056,7 +1079,9 @@ static bool fileview_settings_menu(void) bool result; struct menu_item items[] = { - { STR(LANG_CASE_MENU), sort_case }, + { STR(LANG_SORT_CASE), sort_case }, + { STR(LANG_SORT_DIR), sort_dir }, + { STR(LANG_SORT_FILE), sort_file }, { STR(LANG_FILTER), dir_filter }, { STR(LANG_FOLLOW), browse_current }, { STR(LANG_SHOW_ICONS), show_icons }, diff --git a/apps/tree.c b/apps/tree.c index 09391b31b6..c68927be60 100644 --- a/apps/tree.c +++ b/apps/tree.c @@ -255,14 +255,46 @@ static int compare(const void* p1, const void* p2) { struct entry* e1 = (struct entry*)p1; struct entry* e2 = (struct entry*)p2; + int criteria; - if (( e1->attr & ATTR_DIRECTORY ) == ( e2->attr & ATTR_DIRECTORY )) + if (e1->attr & ATTR_DIRECTORY && e2->attr & ATTR_DIRECTORY) + { /* two directories */ + criteria = global_settings.sort_dir; + } + else if (!(e1->attr & ATTR_DIRECTORY) && !(e2->attr & ATTR_DIRECTORY)) + { /* two files */ + criteria = global_settings.sort_file; + } + else /* dir and file, dir goes first */ + return ( e2->attr & ATTR_DIRECTORY ) - ( e1->attr & ATTR_DIRECTORY ); + + switch(criteria) + { + case 3: /* sort type */ + { + int t1 = e1->attr & TREE_ATTR_MASK; + int t2 = e2->attr & TREE_ATTR_MASK; + + if (!t1) /* unknown type */ + t1 = 0x7FFFFFFF; /* gets a high number, to sort after known */ + if (!t2) /* unknown type */ + t2 = 0x7FFFFFFF; /* gets a high number, to sort after known */ + + if (t1 - t2) /* if different */ + return t1 - t2; + /* else fall through to alphabetical sorting */ + } + case 0: /* sort alphabetically */ if (global_settings.sort_case) return strncmp(e1->name, e2->name, MAX_PATH); else return strncasecmp(e1->name, e2->name, MAX_PATH); - else - return ( e2->attr & ATTR_DIRECTORY ) - ( e1->attr & ATTR_DIRECTORY ); + case 1: /* sort date */ + return e1->time_write - e2->time_write; + case 2: /* sort date, newest first */ + return e2->time_write - e1->time_write; + } + return 0; /* never reached */ } static void showfileline(int line, int direntry, bool scroll, int *dirfilter) diff --git a/apps/tree.h b/apps/tree.h index a0015b6e76..01f3669477 100644 --- a/apps/tree.h +++ b/apps/tree.h @@ -36,15 +36,16 @@ struct filetype { /* using attribute not used by FAT */ -#define TREE_ATTR_MPA 0x0100 /* mpeg audio file */ +/* (this also reflects the sort order if by type) */ +#define TREE_ATTR_BMARK 0x0100 /* book mark file */ #define TREE_ATTR_M3U 0x0200 /* playlist */ -#define TREE_ATTR_WPS 0x0300 /* wps config file */ -#define TREE_ATTR_MOD 0x0400 /* firmware file */ -#define TREE_ATTR_CFG 0x0500 /* config file */ +#define TREE_ATTR_MPA 0x0300 /* mpeg audio file */ +#define TREE_ATTR_CFG 0x0400 /* config file */ +#define TREE_ATTR_WPS 0x0500 /* wps config file */ #define TREE_ATTR_FONT 0x0600 /* font file */ #define TREE_ATTR_LNG 0x0700 /* binary lang file */ #define TREE_ATTR_ROCK 0x0800 /* binary rockbox plugin */ -#define TREE_ATTR_BMARK 0x0900 /* book mark file */ +#define TREE_ATTR_MOD 0x0900 /* firmware file */ #define TREE_ATTR_MASK 0xFFC0 /* which bits tree.c uses (above) */ void tree_get_filetypes(struct filetype**, int*);