mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-27 15:56:18 -04:00
Fix FS#8949 - Alphabetical directory listing reversed after "Error Accessing Directory", patch by pondlife, some long line police by me, also kill a few error splashes in functions that could be called by threads other than UI
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18742 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
88c60e6b07
commit
48b52aec46
5 changed files with 80 additions and 49 deletions
|
|
@ -55,6 +55,8 @@
|
||||||
|
|
||||||
#include "backdrop.h"
|
#include "backdrop.h"
|
||||||
|
|
||||||
|
static int compare_sort_dir; /* qsort key for sorting directories */
|
||||||
|
|
||||||
int ft_build_playlist(struct tree_context* c, int start_index)
|
int ft_build_playlist(struct tree_context* c, int start_index)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -189,13 +191,13 @@ static int compare(const void* p1, const void* p2)
|
||||||
|
|
||||||
if (e1->attr & ATTR_DIRECTORY && e2->attr & ATTR_DIRECTORY)
|
if (e1->attr & ATTR_DIRECTORY && e2->attr & ATTR_DIRECTORY)
|
||||||
{ /* two directories */
|
{ /* two directories */
|
||||||
criteria = global_settings.sort_dir;
|
criteria = compare_sort_dir;
|
||||||
|
|
||||||
#ifdef HAVE_MULTIVOLUME
|
#ifdef HAVE_MULTIVOLUME
|
||||||
if (e1->attr & ATTR_VOLUME || e2->attr & ATTR_VOLUME)
|
if (e1->attr & ATTR_VOLUME || e2->attr & ATTR_VOLUME)
|
||||||
{ /* a volume identifier is involved */
|
{ /* a volume identifier is involved */
|
||||||
if (e1->attr & ATTR_VOLUME && e2->attr & ATTR_VOLUME)
|
if (e1->attr & ATTR_VOLUME && e2->attr & ATTR_VOLUME)
|
||||||
criteria = 0; /* two volumes: sort alphabetically */
|
criteria = SORT_ALPHA; /* two volumes: sort alphabetically */
|
||||||
else /* only one is a volume: volume first */
|
else /* only one is a volume: volume first */
|
||||||
return (e2->attr & ATTR_VOLUME) - (e1->attr & ATTR_VOLUME);
|
return (e2->attr & ATTR_VOLUME) - (e1->attr & ATTR_VOLUME);
|
||||||
}
|
}
|
||||||
|
|
@ -207,11 +209,12 @@ static int compare(const void* p1, const void* p2)
|
||||||
criteria = global_settings.sort_file;
|
criteria = global_settings.sort_file;
|
||||||
}
|
}
|
||||||
else /* dir and file, dir goes first */
|
else /* dir and file, dir goes first */
|
||||||
return ( e2->attr & ATTR_DIRECTORY ) - ( e1->attr & ATTR_DIRECTORY );
|
return (e2->attr & ATTR_DIRECTORY) - (e1->attr & ATTR_DIRECTORY);
|
||||||
|
|
||||||
switch(criteria)
|
switch(criteria)
|
||||||
{
|
{
|
||||||
case 3: /* sort type */
|
case SORT_TYPE:
|
||||||
|
case SORT_TYPE_REVERSED:
|
||||||
{
|
{
|
||||||
int t1 = e1->attr & FILE_ATTR_MASK;
|
int t1 = e1->attr & FILE_ATTR_MASK;
|
||||||
int t2 = e2->attr & FILE_ATTR_MASK;
|
int t2 = e2->attr & FILE_ATTR_MASK;
|
||||||
|
|
@ -221,27 +224,31 @@ static int compare(const void* p1, const void* p2)
|
||||||
if (!t2) /* unknown type */
|
if (!t2) /* unknown type */
|
||||||
t2 = INT_MAX; /* gets a high number, to sort after known */
|
t2 = INT_MAX; /* gets a high number, to sort after known */
|
||||||
|
|
||||||
if (t1 - t2) /* if different */
|
if (t1 != t2) /* if different */
|
||||||
return t1 - t2;
|
return (t1 - t2) * (criteria == SORT_TYPE_REVERSED ? -1 : 1);
|
||||||
/* else fall through to alphabetical sorting */
|
/* else fall through to alphabetical sorting */
|
||||||
}
|
}
|
||||||
case 0: /* sort alphabetically asc */
|
|
||||||
|
case SORT_DATE:
|
||||||
|
case SORT_DATE_REVERSED:
|
||||||
|
/* Ignore SORT_TYPE */
|
||||||
|
if (criteria == SORT_DATE || criteria == SORT_DATE_REVERSED)
|
||||||
|
{
|
||||||
|
if (e1->time_write != e2->time_write)
|
||||||
|
return (e1->time_write - e2->time_write)
|
||||||
|
* (criteria == SORT_DATE_REVERSED ? -1 : 1);
|
||||||
|
/* else fall through to alphabetical sorting */
|
||||||
|
}
|
||||||
|
|
||||||
|
case SORT_ALPHA:
|
||||||
|
case SORT_ALPHA_REVERSED:
|
||||||
if (global_settings.sort_case)
|
if (global_settings.sort_case)
|
||||||
return strncmp(e1->name, e2->name, MAX_PATH);
|
return strncmp(e1->name, e2->name, MAX_PATH)
|
||||||
|
* (criteria == SORT_ALPHA_REVERSED ? -1 : 1);
|
||||||
else
|
else
|
||||||
return strncasecmp(e1->name, e2->name, MAX_PATH);
|
return strncasecmp(e1->name, e2->name, MAX_PATH)
|
||||||
|
* (criteria == SORT_ALPHA_REVERSED ? -1 : 1);
|
||||||
|
|
||||||
case 4: /* sort alphabetically desc */
|
|
||||||
if (global_settings.sort_case)
|
|
||||||
return strncmp(e2->name, e1->name, MAX_PATH);
|
|
||||||
else
|
|
||||||
return strncasecmp(e2->name, e1->name, MAX_PATH);
|
|
||||||
|
|
||||||
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 */
|
return 0; /* never reached */
|
||||||
}
|
}
|
||||||
|
|
@ -345,6 +352,7 @@ int ft_load(struct tree_context* c, const char* tempdir)
|
||||||
c->dirlength = i;
|
c->dirlength = i;
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
|
compare_sort_dir = c->sort_dir;
|
||||||
qsort(c->dircache,i,sizeof(struct entry),compare);
|
qsort(c->dircache,i,sizeof(struct entry),compare);
|
||||||
|
|
||||||
/* If thumbnail talking is enabled, make an extra run to mark files with
|
/* If thumbnail talking is enabled, make an extra run to mark files with
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
|
||||||
static int get_next_directory(char *dir);
|
static int get_next_directory(char *dir);
|
||||||
static int get_next_dir(char *dir, bool is_forward, bool recursion);
|
static int get_next_dir(char *dir, bool is_forward, bool recursion);
|
||||||
static int get_previous_directory(char *dir);
|
static int get_previous_directory(char *dir);
|
||||||
static int check_subdir_for_music(char *dir, char *subdir, bool recurse);
|
static int check_subdir_for_music(char *dir, const char *subdir, bool recurse);
|
||||||
static int format_track_path(char *dest, char *src, int buf_length, int max,
|
static int format_track_path(char *dest, char *src, int buf_length, int max,
|
||||||
const char *dir);
|
const char *dir);
|
||||||
static void display_playlist_count(int count, const unsigned char *fmt,
|
static void display_playlist_count(int count, const unsigned char *fmt,
|
||||||
|
|
@ -1425,20 +1425,23 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
|
||||||
{
|
{
|
||||||
struct playlist_info* playlist = ¤t_playlist;
|
struct playlist_info* playlist = ¤t_playlist;
|
||||||
int result = -1;
|
int result = -1;
|
||||||
int sort_dir = global_settings.sort_dir;
|
|
||||||
char *start_dir = NULL;
|
char *start_dir = NULL;
|
||||||
bool exit = false;
|
bool exit = false;
|
||||||
|
int i;
|
||||||
struct tree_context* tc = tree_get_context();
|
struct tree_context* tc = tree_get_context();
|
||||||
int dirfilter = *(tc->dirfilter);
|
int saved_dirfilter = *(tc->dirfilter);
|
||||||
|
|
||||||
|
/* process random folder advance */
|
||||||
if (global_settings.next_folder == FOLDER_ADVANCE_RANDOM)
|
if (global_settings.next_folder == FOLDER_ADVANCE_RANDOM)
|
||||||
{
|
{
|
||||||
int fd = open(ROCKBOX_DIR "/folder_advance_list.dat",O_RDONLY);
|
int fd = open(ROCKBOX_DIR "/folder_advance_list.dat", O_RDONLY);
|
||||||
char buffer[MAX_PATH];
|
|
||||||
int folder_count = 0,i;
|
|
||||||
srand(current_tick);
|
|
||||||
*(tc->dirfilter) = SHOW_MUSIC;
|
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
{
|
{
|
||||||
|
char buffer[MAX_PATH];
|
||||||
|
int folder_count = 0;
|
||||||
|
srand(current_tick);
|
||||||
|
*(tc->dirfilter) = SHOW_MUSIC;
|
||||||
|
tc->sort_dir = global_settings.sort_dir;
|
||||||
read(fd,&folder_count,sizeof(int));
|
read(fd,&folder_count,sizeof(int));
|
||||||
if (!folder_count)
|
if (!folder_count)
|
||||||
exit = true;
|
exit = true;
|
||||||
|
|
@ -1453,17 +1456,21 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
|
||||||
if (folder_count)
|
if (folder_count)
|
||||||
strcpy(dir,buffer);
|
strcpy(dir,buffer);
|
||||||
close(fd);
|
close(fd);
|
||||||
*(tc->dirfilter) = dirfilter;
|
*(tc->dirfilter) = saved_dirfilter;
|
||||||
|
tc->sort_dir = global_settings.sort_dir;
|
||||||
reload_directory();
|
reload_directory();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* not random folder advance */
|
|
||||||
if (recursion){
|
/* not random folder advance (or random folder advance unavailable) */
|
||||||
|
if (recursion)
|
||||||
|
{
|
||||||
/* start with root */
|
/* start with root */
|
||||||
dir[0] = '\0';
|
dir[0] = '\0';
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
/* start with current directory */
|
/* start with current directory */
|
||||||
strncpy(dir, playlist->filename, playlist->dirlen-1);
|
strncpy(dir, playlist->filename, playlist->dirlen-1);
|
||||||
dir[playlist->dirlen-1] = '\0';
|
dir[playlist->dirlen-1] = '\0';
|
||||||
|
|
@ -1472,16 +1479,27 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
|
||||||
/* use the tree browser dircache to load files */
|
/* use the tree browser dircache to load files */
|
||||||
*(tc->dirfilter) = SHOW_ALL;
|
*(tc->dirfilter) = SHOW_ALL;
|
||||||
|
|
||||||
/* sort in another direction if previous dir is requested */
|
/* set up sorting/direction */
|
||||||
if(!is_forward){
|
tc->sort_dir = global_settings.sort_dir;
|
||||||
if ((global_settings.sort_dir == 0) || (global_settings.sort_dir == 3))
|
if (!is_forward)
|
||||||
global_settings.sort_dir = 4;
|
{
|
||||||
else if (global_settings.sort_dir == 1)
|
/* Sort options, indices of forward/reverse options differ in bit 0 */
|
||||||
global_settings.sort_dir = 2;
|
const int sortpairs[] =
|
||||||
else if (global_settings.sort_dir == 2)
|
{
|
||||||
global_settings.sort_dir = 1;
|
SORT_ALPHA, SORT_ALPHA_REVERSED,
|
||||||
else if (global_settings.sort_dir == 4)
|
SORT_DATE, SORT_DATE_REVERSED,
|
||||||
global_settings.sort_dir = 0;
|
SORT_TYPE, SORT_TYPE_REVERSED,
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; sortpairs[i] >= 0; i++)
|
||||||
|
{
|
||||||
|
if (sortpairs[i] == global_settings.sort_dir)
|
||||||
|
{
|
||||||
|
tc->sort_dir = sortpairs[i^1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!exit)
|
while (!exit)
|
||||||
|
|
@ -1492,7 +1510,6 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
|
||||||
|
|
||||||
if (ft_load(tc, (dir[0]=='\0')?"/":dir) < 0)
|
if (ft_load(tc, (dir[0]=='\0')?"/":dir) < 0)
|
||||||
{
|
{
|
||||||
splash(HZ*2, ID2P(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR));
|
|
||||||
exit = true;
|
exit = true;
|
||||||
result = -1;
|
result = -1;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1542,13 +1559,13 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* restore dirfilter & sort_dir */
|
/* restore dirfilter */
|
||||||
*(tc->dirfilter) = dirfilter;
|
*(tc->dirfilter) = saved_dirfilter;
|
||||||
global_settings.sort_dir = sort_dir;
|
tc->sort_dir = global_settings.sort_dir;
|
||||||
|
|
||||||
/* special case if nothing found: try start searching again from root */
|
/* special case if nothing found: try start searching again from root */
|
||||||
if (result == -1 && !recursion){
|
if (result == -1 && !recursion){
|
||||||
result = get_next_dir(dir,is_forward, true);
|
result = get_next_dir(dir, is_forward, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -1558,7 +1575,7 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
|
||||||
* Checks if there are any music files in the dir or any of its
|
* Checks if there are any music files in the dir or any of its
|
||||||
* subdirectories. May be called recursively.
|
* subdirectories. May be called recursively.
|
||||||
*/
|
*/
|
||||||
static int check_subdir_for_music(char *dir, char *subdir, bool recurse)
|
static int check_subdir_for_music(char *dir, const char *subdir, bool recurse)
|
||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
int dirlen = strlen(dir);
|
int dirlen = strlen(dir);
|
||||||
|
|
@ -1573,7 +1590,6 @@ static int check_subdir_for_music(char *dir, char *subdir, bool recurse)
|
||||||
|
|
||||||
if (ft_load(tc, dir) < 0)
|
if (ft_load(tc, dir) < 0)
|
||||||
{
|
{
|
||||||
splash(HZ*2, ID2P(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR));
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,10 @@ enum { SHOW_ALL, SHOW_SUPPORTED, SHOW_MUSIC, SHOW_PLAYLIST, SHOW_ID3DB,
|
||||||
NUM_FILTER_MODES,
|
NUM_FILTER_MODES,
|
||||||
SHOW_WPS, SHOW_RWPS, SHOW_FMR, SHOW_CFG, SHOW_LNG, SHOW_MOD, SHOW_FONT, SHOW_PLUGINS};
|
SHOW_WPS, SHOW_RWPS, SHOW_FMR, SHOW_CFG, SHOW_LNG, SHOW_MOD, SHOW_FONT, SHOW_PLUGINS};
|
||||||
|
|
||||||
|
/* file and dir sort options */
|
||||||
|
enum { SORT_ALPHA, SORT_DATE, SORT_DATE_REVERSED, SORT_TYPE, /* available as settings */
|
||||||
|
SORT_ALPHA_REVERSED, SORT_TYPE_REVERSED }; /* internal use only */
|
||||||
|
|
||||||
/* recursive dir insert options */
|
/* recursive dir insert options */
|
||||||
enum { RECURSE_OFF, RECURSE_ON, RECURSE_ASK };
|
enum { RECURSE_OFF, RECURSE_ON, RECURSE_ASK };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -900,6 +900,7 @@ int rockbox_browse(const char *root, int dirfilter)
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
int *last_filter = tc.dirfilter;
|
int *last_filter = tc.dirfilter;
|
||||||
tc.dirfilter = &dirfilter;
|
tc.dirfilter = &dirfilter;
|
||||||
|
tc.sort_dir = global_settings.sort_dir;
|
||||||
|
|
||||||
reload_dir = true;
|
reload_dir = true;
|
||||||
if (dirfilter >= NUM_FILTER_MODES)
|
if (dirfilter >= NUM_FILTER_MODES)
|
||||||
|
|
@ -940,6 +941,7 @@ void tree_mem_init(void)
|
||||||
/* initialize tree context struct */
|
/* initialize tree context struct */
|
||||||
memset(&tc, 0, sizeof(tc));
|
memset(&tc, 0, sizeof(tc));
|
||||||
tc.dirfilter = &global_settings.dirfilter;
|
tc.dirfilter = &global_settings.dirfilter;
|
||||||
|
tc.sort_dir = global_settings.sort_dir;
|
||||||
|
|
||||||
tc.name_buffer_size = AVERAGE_FILENAME_LENGTH * max_files;
|
tc.name_buffer_size = AVERAGE_FILENAME_LENGTH * max_files;
|
||||||
tc.name_buffer = buffer_alloc(tc.name_buffer_size);
|
tc.name_buffer = buffer_alloc(tc.name_buffer_size);
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ struct tree_context {
|
||||||
int name_buffer_size;
|
int name_buffer_size;
|
||||||
int dentry_size;
|
int dentry_size;
|
||||||
bool dirfull;
|
bool dirfull;
|
||||||
|
int sort_dir; /* directory sort order */
|
||||||
};
|
};
|
||||||
|
|
||||||
void tree_mem_init(void);
|
void tree_mem_init(void);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue