diff options
author | Nils Wallménius <nils@rockbox.org> | 2008-10-08 16:32:01 +0000 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2008-10-08 16:32:01 +0000 |
commit | 48b52aec468309ef00fc4bfee3b3fff969969661 (patch) | |
tree | 1c74a2cb6c17840b080e0e09fdcad0bae05fbb8c /apps | |
parent | 88c60e6b07b00e737e75d157a2a9b72908d627e8 (diff) | |
download | rockbox-48b52aec468309ef00fc4bfee3b3fff969969661.tar.gz rockbox-48b52aec468309ef00fc4bfee3b3fff969969661.zip |
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
Diffstat (limited to 'apps')
-rw-r--r-- | apps/filetree.c | 46 | ||||
-rw-r--r-- | apps/playlist.c | 74 | ||||
-rw-r--r-- | apps/settings.h | 4 | ||||
-rw-r--r-- | apps/tree.c | 2 | ||||
-rw-r--r-- | apps/tree.h | 1 |
5 files changed, 79 insertions, 48 deletions
diff --git a/apps/filetree.c b/apps/filetree.c index 7ab0e6d0cf..fc5e4d3934 100644 --- a/apps/filetree.c +++ b/apps/filetree.c | |||
@@ -55,6 +55,8 @@ | |||
55 | 55 | ||
56 | #include "backdrop.h" | 56 | #include "backdrop.h" |
57 | 57 | ||
58 | static int compare_sort_dir; /* qsort key for sorting directories */ | ||
59 | |||
58 | int ft_build_playlist(struct tree_context* c, int start_index) | 60 | int ft_build_playlist(struct tree_context* c, int start_index) |
59 | { | 61 | { |
60 | int i; | 62 | int i; |
@@ -189,13 +191,13 @@ static int compare(const void* p1, const void* p2) | |||
189 | 191 | ||
190 | if (e1->attr & ATTR_DIRECTORY && e2->attr & ATTR_DIRECTORY) | 192 | if (e1->attr & ATTR_DIRECTORY && e2->attr & ATTR_DIRECTORY) |
191 | { /* two directories */ | 193 | { /* two directories */ |
192 | criteria = global_settings.sort_dir; | 194 | criteria = compare_sort_dir; |
193 | 195 | ||
194 | #ifdef HAVE_MULTIVOLUME | 196 | #ifdef HAVE_MULTIVOLUME |
195 | if (e1->attr & ATTR_VOLUME || e2->attr & ATTR_VOLUME) | 197 | if (e1->attr & ATTR_VOLUME || e2->attr & ATTR_VOLUME) |
196 | { /* a volume identifier is involved */ | 198 | { /* a volume identifier is involved */ |
197 | if (e1->attr & ATTR_VOLUME && e2->attr & ATTR_VOLUME) | 199 | if (e1->attr & ATTR_VOLUME && e2->attr & ATTR_VOLUME) |
198 | criteria = 0; /* two volumes: sort alphabetically */ | 200 | criteria = SORT_ALPHA; /* two volumes: sort alphabetically */ |
199 | else /* only one is a volume: volume first */ | 201 | else /* only one is a volume: volume first */ |
200 | return (e2->attr & ATTR_VOLUME) - (e1->attr & ATTR_VOLUME); | 202 | return (e2->attr & ATTR_VOLUME) - (e1->attr & ATTR_VOLUME); |
201 | } | 203 | } |
@@ -207,11 +209,12 @@ static int compare(const void* p1, const void* p2) | |||
207 | criteria = global_settings.sort_file; | 209 | criteria = global_settings.sort_file; |
208 | } | 210 | } |
209 | else /* dir and file, dir goes first */ | 211 | else /* dir and file, dir goes first */ |
210 | return ( e2->attr & ATTR_DIRECTORY ) - ( e1->attr & ATTR_DIRECTORY ); | 212 | return (e2->attr & ATTR_DIRECTORY) - (e1->attr & ATTR_DIRECTORY); |
211 | 213 | ||
212 | switch(criteria) | 214 | switch(criteria) |
213 | { | 215 | { |
214 | case 3: /* sort type */ | 216 | case SORT_TYPE: |
217 | case SORT_TYPE_REVERSED: | ||
215 | { | 218 | { |
216 | int t1 = e1->attr & FILE_ATTR_MASK; | 219 | int t1 = e1->attr & FILE_ATTR_MASK; |
217 | int t2 = e2->attr & FILE_ATTR_MASK; | 220 | int t2 = e2->attr & FILE_ATTR_MASK; |
@@ -221,27 +224,31 @@ static int compare(const void* p1, const void* p2) | |||
221 | if (!t2) /* unknown type */ | 224 | if (!t2) /* unknown type */ |
222 | t2 = INT_MAX; /* gets a high number, to sort after known */ | 225 | t2 = INT_MAX; /* gets a high number, to sort after known */ |
223 | 226 | ||
224 | if (t1 - t2) /* if different */ | 227 | if (t1 != t2) /* if different */ |
225 | return t1 - t2; | 228 | return (t1 - t2) * (criteria == SORT_TYPE_REVERSED ? -1 : 1); |
226 | /* else fall through to alphabetical sorting */ | 229 | /* else fall through to alphabetical sorting */ |
227 | } | 230 | } |
228 | case 0: /* sort alphabetically asc */ | ||
229 | if (global_settings.sort_case) | ||
230 | return strncmp(e1->name, e2->name, MAX_PATH); | ||
231 | else | ||
232 | return strncasecmp(e1->name, e2->name, MAX_PATH); | ||
233 | 231 | ||
234 | case 4: /* sort alphabetically desc */ | 232 | case SORT_DATE: |
233 | case SORT_DATE_REVERSED: | ||
234 | /* Ignore SORT_TYPE */ | ||
235 | if (criteria == SORT_DATE || criteria == SORT_DATE_REVERSED) | ||
236 | { | ||
237 | if (e1->time_write != e2->time_write) | ||
238 | return (e1->time_write - e2->time_write) | ||
239 | * (criteria == SORT_DATE_REVERSED ? -1 : 1); | ||
240 | /* else fall through to alphabetical sorting */ | ||
241 | } | ||
242 | |||
243 | case SORT_ALPHA: | ||
244 | case SORT_ALPHA_REVERSED: | ||
235 | if (global_settings.sort_case) | 245 | if (global_settings.sort_case) |
236 | return strncmp(e2->name, e1->name, MAX_PATH); | 246 | return strncmp(e1->name, e2->name, MAX_PATH) |
247 | * (criteria == SORT_ALPHA_REVERSED ? -1 : 1); | ||
237 | else | 248 | else |
238 | return strncasecmp(e2->name, e1->name, MAX_PATH); | 249 | return strncasecmp(e1->name, e2->name, MAX_PATH) |
239 | 250 | * (criteria == SORT_ALPHA_REVERSED ? -1 : 1); | |
240 | case 1: /* sort date */ | ||
241 | return e1->time_write - e2->time_write; | ||
242 | 251 | ||
243 | case 2: /* sort date, newest first */ | ||
244 | return e2->time_write - e1->time_write; | ||
245 | } | 252 | } |
246 | return 0; /* never reached */ | 253 | return 0; /* never reached */ |
247 | } | 254 | } |
@@ -345,6 +352,7 @@ int ft_load(struct tree_context* c, const char* tempdir) | |||
345 | c->dirlength = i; | 352 | c->dirlength = i; |
346 | closedir(dir); | 353 | closedir(dir); |
347 | 354 | ||
355 | compare_sort_dir = c->sort_dir; | ||
348 | qsort(c->dircache,i,sizeof(struct entry),compare); | 356 | qsort(c->dircache,i,sizeof(struct entry),compare); |
349 | 357 | ||
350 | /* If thumbnail talking is enabled, make an extra run to mark files with | 358 | /* If thumbnail talking is enabled, make an extra run to mark files with |
diff --git a/apps/playlist.c b/apps/playlist.c index 018a39ae41..6768ac8708 100644 --- a/apps/playlist.c +++ b/apps/playlist.c | |||
@@ -179,7 +179,7 @@ static int get_filename(struct playlist_info* playlist, int index, int seek, | |||
179 | static int get_next_directory(char *dir); | 179 | static int get_next_directory(char *dir); |
180 | static int get_next_dir(char *dir, bool is_forward, bool recursion); | 180 | static int get_next_dir(char *dir, bool is_forward, bool recursion); |
181 | static int get_previous_directory(char *dir); | 181 | static int get_previous_directory(char *dir); |
182 | static int check_subdir_for_music(char *dir, char *subdir, bool recurse); | 182 | static int check_subdir_for_music(char *dir, const char *subdir, bool recurse); |
183 | static int format_track_path(char *dest, char *src, int buf_length, int max, | 183 | static int format_track_path(char *dest, char *src, int buf_length, int max, |
184 | const char *dir); | 184 | const char *dir); |
185 | static void display_playlist_count(int count, const unsigned char *fmt, | 185 | 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) | |||
1425 | { | 1425 | { |
1426 | struct playlist_info* playlist = ¤t_playlist; | 1426 | struct playlist_info* playlist = ¤t_playlist; |
1427 | int result = -1; | 1427 | int result = -1; |
1428 | int sort_dir = global_settings.sort_dir; | ||
1429 | char *start_dir = NULL; | 1428 | char *start_dir = NULL; |
1430 | bool exit = false; | 1429 | bool exit = false; |
1430 | int i; | ||
1431 | struct tree_context* tc = tree_get_context(); | 1431 | struct tree_context* tc = tree_get_context(); |
1432 | int dirfilter = *(tc->dirfilter); | 1432 | int saved_dirfilter = *(tc->dirfilter); |
1433 | |||
1434 | /* process random folder advance */ | ||
1433 | if (global_settings.next_folder == FOLDER_ADVANCE_RANDOM) | 1435 | if (global_settings.next_folder == FOLDER_ADVANCE_RANDOM) |
1434 | { | 1436 | { |
1435 | int fd = open(ROCKBOX_DIR "/folder_advance_list.dat",O_RDONLY); | 1437 | int fd = open(ROCKBOX_DIR "/folder_advance_list.dat", O_RDONLY); |
1436 | char buffer[MAX_PATH]; | ||
1437 | int folder_count = 0,i; | ||
1438 | srand(current_tick); | ||
1439 | *(tc->dirfilter) = SHOW_MUSIC; | ||
1440 | if (fd >= 0) | 1438 | if (fd >= 0) |
1441 | { | 1439 | { |
1440 | char buffer[MAX_PATH]; | ||
1441 | int folder_count = 0; | ||
1442 | srand(current_tick); | ||
1443 | *(tc->dirfilter) = SHOW_MUSIC; | ||
1444 | tc->sort_dir = global_settings.sort_dir; | ||
1442 | read(fd,&folder_count,sizeof(int)); | 1445 | read(fd,&folder_count,sizeof(int)); |
1443 | if (!folder_count) | 1446 | if (!folder_count) |
1444 | exit = true; | 1447 | exit = true; |
@@ -1453,17 +1456,21 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion) | |||
1453 | if (folder_count) | 1456 | if (folder_count) |
1454 | strcpy(dir,buffer); | 1457 | strcpy(dir,buffer); |
1455 | close(fd); | 1458 | close(fd); |
1456 | *(tc->dirfilter) = dirfilter; | 1459 | *(tc->dirfilter) = saved_dirfilter; |
1460 | tc->sort_dir = global_settings.sort_dir; | ||
1457 | reload_directory(); | 1461 | reload_directory(); |
1458 | return 0; | 1462 | return 0; |
1459 | } | 1463 | } |
1460 | } | 1464 | } |
1461 | /* not random folder advance */ | 1465 | |
1462 | if (recursion){ | 1466 | /* not random folder advance (or random folder advance unavailable) */ |
1467 | if (recursion) | ||
1468 | { | ||
1463 | /* start with root */ | 1469 | /* start with root */ |
1464 | dir[0] = '\0'; | 1470 | dir[0] = '\0'; |
1465 | } | 1471 | } |
1466 | else{ | 1472 | else |
1473 | { | ||
1467 | /* start with current directory */ | 1474 | /* start with current directory */ |
1468 | strncpy(dir, playlist->filename, playlist->dirlen-1); | 1475 | strncpy(dir, playlist->filename, playlist->dirlen-1); |
1469 | dir[playlist->dirlen-1] = '\0'; | 1476 | dir[playlist->dirlen-1] = '\0'; |
@@ -1472,16 +1479,27 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion) | |||
1472 | /* use the tree browser dircache to load files */ | 1479 | /* use the tree browser dircache to load files */ |
1473 | *(tc->dirfilter) = SHOW_ALL; | 1480 | *(tc->dirfilter) = SHOW_ALL; |
1474 | 1481 | ||
1475 | /* sort in another direction if previous dir is requested */ | 1482 | /* set up sorting/direction */ |
1476 | if(!is_forward){ | 1483 | tc->sort_dir = global_settings.sort_dir; |
1477 | if ((global_settings.sort_dir == 0) || (global_settings.sort_dir == 3)) | 1484 | if (!is_forward) |
1478 | global_settings.sort_dir = 4; | 1485 | { |
1479 | else if (global_settings.sort_dir == 1) | 1486 | /* Sort options, indices of forward/reverse options differ in bit 0 */ |
1480 | global_settings.sort_dir = 2; | 1487 | const int sortpairs[] = |
1481 | else if (global_settings.sort_dir == 2) | 1488 | { |
1482 | global_settings.sort_dir = 1; | 1489 | SORT_ALPHA, SORT_ALPHA_REVERSED, |
1483 | else if (global_settings.sort_dir == 4) | 1490 | SORT_DATE, SORT_DATE_REVERSED, |
1484 | global_settings.sort_dir = 0; | 1491 | SORT_TYPE, SORT_TYPE_REVERSED, |
1492 | -1 | ||
1493 | }; | ||
1494 | |||
1495 | for (i = 0; sortpairs[i] >= 0; i++) | ||
1496 | { | ||
1497 | if (sortpairs[i] == global_settings.sort_dir) | ||
1498 | { | ||
1499 | tc->sort_dir = sortpairs[i^1]; | ||
1500 | break; | ||
1501 | } | ||
1502 | } | ||
1485 | } | 1503 | } |
1486 | 1504 | ||
1487 | while (!exit) | 1505 | while (!exit) |
@@ -1492,7 +1510,6 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion) | |||
1492 | 1510 | ||
1493 | if (ft_load(tc, (dir[0]=='\0')?"/":dir) < 0) | 1511 | if (ft_load(tc, (dir[0]=='\0')?"/":dir) < 0) |
1494 | { | 1512 | { |
1495 | splash(HZ*2, ID2P(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); | ||
1496 | exit = true; | 1513 | exit = true; |
1497 | result = -1; | 1514 | result = -1; |
1498 | break; | 1515 | break; |
@@ -1542,13 +1559,13 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion) | |||
1542 | } | 1559 | } |
1543 | } | 1560 | } |
1544 | 1561 | ||
1545 | /* restore dirfilter & sort_dir */ | 1562 | /* restore dirfilter */ |
1546 | *(tc->dirfilter) = dirfilter; | 1563 | *(tc->dirfilter) = saved_dirfilter; |
1547 | global_settings.sort_dir = sort_dir; | 1564 | tc->sort_dir = global_settings.sort_dir; |
1548 | 1565 | ||
1549 | /* special case if nothing found: try start searching again from root */ | 1566 | /* special case if nothing found: try start searching again from root */ |
1550 | if (result == -1 && !recursion){ | 1567 | if (result == -1 && !recursion){ |
1551 | result = get_next_dir(dir,is_forward, true); | 1568 | result = get_next_dir(dir, is_forward, true); |
1552 | } | 1569 | } |
1553 | 1570 | ||
1554 | return result; | 1571 | return result; |
@@ -1558,7 +1575,7 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion) | |||
1558 | * Checks if there are any music files in the dir or any of its | 1575 | * Checks if there are any music files in the dir or any of its |
1559 | * subdirectories. May be called recursively. | 1576 | * subdirectories. May be called recursively. |
1560 | */ | 1577 | */ |
1561 | static int check_subdir_for_music(char *dir, char *subdir, bool recurse) | 1578 | static int check_subdir_for_music(char *dir, const char *subdir, bool recurse) |
1562 | { | 1579 | { |
1563 | int result = -1; | 1580 | int result = -1; |
1564 | int dirlen = strlen(dir); | 1581 | int dirlen = strlen(dir); |
@@ -1573,7 +1590,6 @@ static int check_subdir_for_music(char *dir, char *subdir, bool recurse) | |||
1573 | 1590 | ||
1574 | if (ft_load(tc, dir) < 0) | 1591 | if (ft_load(tc, dir) < 0) |
1575 | { | 1592 | { |
1576 | splash(HZ*2, ID2P(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); | ||
1577 | return -2; | 1593 | return -2; |
1578 | } | 1594 | } |
1579 | 1595 | ||
diff --git a/apps/settings.h b/apps/settings.h index f1fd7cc2c4..9ba4396f9d 100644 --- a/apps/settings.h +++ b/apps/settings.h | |||
@@ -139,6 +139,10 @@ enum { SHOW_ALL, SHOW_SUPPORTED, SHOW_MUSIC, SHOW_PLAYLIST, SHOW_ID3DB, | |||
139 | NUM_FILTER_MODES, | 139 | NUM_FILTER_MODES, |
140 | SHOW_WPS, SHOW_RWPS, SHOW_FMR, SHOW_CFG, SHOW_LNG, SHOW_MOD, SHOW_FONT, SHOW_PLUGINS}; | 140 | SHOW_WPS, SHOW_RWPS, SHOW_FMR, SHOW_CFG, SHOW_LNG, SHOW_MOD, SHOW_FONT, SHOW_PLUGINS}; |
141 | 141 | ||
142 | /* file and dir sort options */ | ||
143 | enum { SORT_ALPHA, SORT_DATE, SORT_DATE_REVERSED, SORT_TYPE, /* available as settings */ | ||
144 | SORT_ALPHA_REVERSED, SORT_TYPE_REVERSED }; /* internal use only */ | ||
145 | |||
142 | /* recursive dir insert options */ | 146 | /* recursive dir insert options */ |
143 | enum { RECURSE_OFF, RECURSE_ON, RECURSE_ASK }; | 147 | enum { RECURSE_OFF, RECURSE_ON, RECURSE_ASK }; |
144 | 148 | ||
diff --git a/apps/tree.c b/apps/tree.c index 3e469247c8..768223ec4d 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -900,6 +900,7 @@ int rockbox_browse(const char *root, int dirfilter) | |||
900 | int ret_val = 0; | 900 | int ret_val = 0; |
901 | int *last_filter = tc.dirfilter; | 901 | int *last_filter = tc.dirfilter; |
902 | tc.dirfilter = &dirfilter; | 902 | tc.dirfilter = &dirfilter; |
903 | tc.sort_dir = global_settings.sort_dir; | ||
903 | 904 | ||
904 | reload_dir = true; | 905 | reload_dir = true; |
905 | if (dirfilter >= NUM_FILTER_MODES) | 906 | if (dirfilter >= NUM_FILTER_MODES) |
@@ -940,6 +941,7 @@ void tree_mem_init(void) | |||
940 | /* initialize tree context struct */ | 941 | /* initialize tree context struct */ |
941 | memset(&tc, 0, sizeof(tc)); | 942 | memset(&tc, 0, sizeof(tc)); |
942 | tc.dirfilter = &global_settings.dirfilter; | 943 | tc.dirfilter = &global_settings.dirfilter; |
944 | tc.sort_dir = global_settings.sort_dir; | ||
943 | 945 | ||
944 | tc.name_buffer_size = AVERAGE_FILENAME_LENGTH * max_files; | 946 | tc.name_buffer_size = AVERAGE_FILENAME_LENGTH * max_files; |
945 | tc.name_buffer = buffer_alloc(tc.name_buffer_size); | 947 | tc.name_buffer = buffer_alloc(tc.name_buffer_size); |
diff --git a/apps/tree.h b/apps/tree.h index 5cf743c2f8..a4f36d96fa 100644 --- a/apps/tree.h +++ b/apps/tree.h | |||
@@ -67,6 +67,7 @@ struct tree_context { | |||
67 | int name_buffer_size; | 67 | int name_buffer_size; |
68 | int dentry_size; | 68 | int dentry_size; |
69 | bool dirfull; | 69 | bool dirfull; |
70 | int sort_dir; /* directory sort order */ | ||
70 | }; | 71 | }; |
71 | 72 | ||
72 | void tree_mem_init(void); | 73 | void tree_mem_init(void); |