summaryrefslogtreecommitdiff
path: root/apps/playlist.c
diff options
context:
space:
mode:
authorNick Peskett <rockbox@peskett.co.uk>2012-03-19 09:56:38 +0000
committerNick Peskett <rockbox@peskett.co.uk>2012-03-19 11:49:55 +0100
commitbe10817e1c09d5a41710435cf6d58deb6dde9301 (patch)
tree4635fcb1ab51d2ef6dc1db28db045c369cf1abaf /apps/playlist.c
parent69978d7046cd7e537c5079a5e306d22621a1767a (diff)
downloadrockbox-be10817e1c09d5a41710435cf6d58deb6dde9301.tar.gz
rockbox-be10817e1c09d5a41710435cf6d58deb6dde9301.zip
Option to constrain get_next_dir() to directories below global_settings.start_directory.
When enabled, if the user has set "Start File Browser Here" (config.cfg: start directory) to anything other than root and "Auto-Change Directory" is set to "Yes" or "Random", the directory returned when an auto change is required will be constrained to the value of "start directory" or below. Change-Id: Iaab773868c4cab5a54f6ae67bdb22e84642a9e4b Reviewed-on: http://gerrit.rockbox.org/182 Reviewed-by: Nick Peskett <rockbox@peskett.co.uk> Tested-by: Nick Peskett <rockbox@peskett.co.uk>
Diffstat (limited to 'apps/playlist.c')
-rw-r--r--apps/playlist.c167
1 files changed, 103 insertions, 64 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index bf55671bf1..5b5f489cde 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -175,7 +175,7 @@ static int compare(const void* p1, const void* p2);
175static int get_filename(struct playlist_info* playlist, int index, int seek, 175static int get_filename(struct playlist_info* playlist, int index, int seek,
176 bool control_file, char *buf, int buf_length); 176 bool control_file, char *buf, int buf_length);
177static int get_next_directory(char *dir); 177static int get_next_directory(char *dir);
178static int get_next_dir(char *dir, bool is_forward, bool recursion); 178static int get_next_dir(char *dir, bool is_forward);
179static int get_previous_directory(char *dir); 179static int get_previous_directory(char *dir);
180static int check_subdir_for_music(char *dir, const char *subdir, bool recurse); 180static int check_subdir_for_music(char *dir, const char *subdir, bool recurse);
181static int format_track_path(char *dest, char *src, int buf_length, int max, 181static int format_track_path(char *dest, char *src, int buf_length, int max,
@@ -608,32 +608,33 @@ static int create_and_play_dir(int direction, bool play_last)
608 else 608 else
609 res = get_previous_directory(dir); 609 res = get_previous_directory(dir);
610 610
611 if (!res) 611 if (res < 0)
612 /* return the error encountered */
613 return res;
614
615 if (playlist_create(dir, NULL) != -1)
612 { 616 {
613 if (playlist_create(dir, NULL) != -1) 617 ft_build_playlist(tree_get_context(), 0);
614 {
615 ft_build_playlist(tree_get_context(), 0);
616 618
617 if (global_settings.playlist_shuffle) 619 if (global_settings.playlist_shuffle)
618 playlist_shuffle(current_tick, -1); 620 playlist_shuffle(current_tick, -1);
619 621
620 if (play_last && direction <= 0) 622 if (play_last && direction <= 0)
621 index = current_playlist.amount - 1; 623 index = current_playlist.amount - 1;
622 else 624 else
623 index = 0; 625 index = 0;
624 626
625#if (CONFIG_CODEC == SWCODEC) 627#if (CONFIG_CODEC == SWCODEC)
626 current_playlist.started = true; 628 current_playlist.started = true;
627#else 629#else
628 playlist_start(index, 0); 630 playlist_start(index, 0);
629#endif 631#endif
630 }
631
632 /* we've overwritten the dircache when getting the next/previous dir,
633 so the tree browser context will need to be reloaded */
634 reload_directory();
635 } 632 }
636 633
634 /* we've overwritten the dircache when getting the next/previous dir,
635 so the tree browser context will need to be reloaded */
636 reload_directory();
637
637 return index; 638 return index;
638} 639}
639 640
@@ -1435,18 +1436,18 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1435} 1436}
1436 1437
1437static int get_next_directory(char *dir){ 1438static int get_next_directory(char *dir){
1438 return get_next_dir(dir,true,false); 1439 return get_next_dir(dir, true);
1439} 1440}
1440 1441
1441static int get_previous_directory(char *dir){ 1442static int get_previous_directory(char *dir){
1442 return get_next_dir(dir,false,false); 1443 return get_next_dir(dir, false);
1443} 1444}
1444 1445
1445/* 1446/*
1446 * search through all the directories (starting with the current) to find 1447 * search through all the directories (starting with the current) to find
1447 * one that has tracks to play 1448 * one that has tracks to play
1448 */ 1449 */
1449static int get_next_dir(char *dir, bool is_forward, bool recursion) 1450static int get_next_dir(char *dir, bool is_forward)
1450{ 1451{
1451 struct playlist_info* playlist = &current_playlist; 1452 struct playlist_info* playlist = &current_playlist;
1452 int result = -1; 1453 int result = -1;
@@ -1454,6 +1455,27 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
1454 bool exit = false; 1455 bool exit = false;
1455 struct tree_context* tc = tree_get_context(); 1456 struct tree_context* tc = tree_get_context();
1456 int saved_dirfilter = *(tc->dirfilter); 1457 int saved_dirfilter = *(tc->dirfilter);
1458 unsigned int base_len;
1459
1460 if (global_settings.constrain_next_folder)
1461 {
1462 /* constrain results to directories below user's start directory */
1463 strcpy(dir, global_settings.start_directory);
1464 base_len = strlen(dir);
1465
1466 /* strip any trailing slash from base directory */
1467 if (base_len > 0 && dir[base_len - 1] == '/')
1468 {
1469 base_len--;
1470 dir[base_len] = '\0';
1471 }
1472 }
1473 else
1474 {
1475 /* start from root directory */
1476 dir[0] = '\0';
1477 base_len = 0;
1478 }
1457 1479
1458 /* process random folder advance */ 1480 /* process random folder advance */
1459 if (global_settings.next_folder == FOLDER_ADVANCE_RANDOM) 1481 if (global_settings.next_folder == FOLDER_ADVANCE_RANDOM)
@@ -1461,43 +1483,46 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
1461 int fd = open(ROCKBOX_DIR "/folder_advance_list.dat", O_RDONLY); 1483 int fd = open(ROCKBOX_DIR "/folder_advance_list.dat", O_RDONLY);
1462 if (fd >= 0) 1484 if (fd >= 0)
1463 { 1485 {
1464 char buffer[MAX_PATH];
1465 int folder_count = 0; 1486 int folder_count = 0;
1466 srand(current_tick);
1467 *(tc->dirfilter) = SHOW_MUSIC;
1468 tc->sort_dir = global_settings.sort_dir;
1469 read(fd,&folder_count,sizeof(int)); 1487 read(fd,&folder_count,sizeof(int));
1470 if (!folder_count) 1488 if (folder_count)
1471 exit = true;
1472 while (!exit)
1473 { 1489 {
1474 int i = rand()%folder_count; 1490 char buffer[MAX_PATH];
1475 lseek(fd,sizeof(int) + (MAX_PATH*i),SEEK_SET); 1491 /* give up looking for a directory after we've had four
1476 read(fd,buffer,MAX_PATH); 1492 times as many tries as there are directories. */
1477 if (check_subdir_for_music(buffer, "", false) ==0) 1493 unsigned long allowed_tries = folder_count * 4;
1478 exit = true; 1494 int i;
1495 srand(current_tick);
1496 *(tc->dirfilter) = SHOW_MUSIC;
1497 tc->sort_dir = global_settings.sort_dir;
1498 while (!exit && allowed_tries--)
1499 {
1500 i = rand() % folder_count;
1501 lseek(fd, sizeof(int) + (MAX_PATH * i), SEEK_SET);
1502 read(fd, buffer, MAX_PATH);
1503 /* is the current dir within our base dir and has music? */
1504 if ((base_len == 0 || !strncmp(buffer, dir, base_len))
1505 && check_subdir_for_music(buffer, "", false) == 0)
1506 exit = true;
1507 }
1508 close(fd);
1509 *(tc->dirfilter) = saved_dirfilter;
1510 tc->sort_dir = global_settings.sort_dir;
1511 reload_directory();
1512 if (exit)
1513 {
1514 strcpy(dir,buffer);
1515 return 0;
1516 }
1479 } 1517 }
1480 if (folder_count) 1518 else
1481 strcpy(dir,buffer); 1519 close(fd);
1482 close(fd);
1483 *(tc->dirfilter) = saved_dirfilter;
1484 tc->sort_dir = global_settings.sort_dir;
1485 reload_directory();
1486 return 0;
1487 } 1520 }
1488 } 1521 }
1489 1522
1490 /* not random folder advance (or random folder advance unavailable) */ 1523 /* if the current file is within our base dir, use its dir instead */
1491 if (recursion) 1524 if (base_len == 0 || !strncmp(playlist->filename, dir, base_len))
1492 {
1493 /* start with root */
1494 dir[0] = '\0';
1495 }
1496 else
1497 {
1498 /* start with current directory */
1499 strlcpy(dir, playlist->filename, playlist->dirlen); 1525 strlcpy(dir, playlist->filename, playlist->dirlen);
1500 }
1501 1526
1502 /* use the tree browser dircache to load files */ 1527 /* use the tree browser dircache to load files */
1503 *(tc->dirfilter) = SHOW_ALL; 1528 *(tc->dirfilter) = SHOW_ALL;
@@ -1546,7 +1571,7 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
1546 exit = true; 1571 exit = true;
1547 break; 1572 break;
1548 } 1573 }
1549 1574
1550 if (files[i].attr & ATTR_DIRECTORY) 1575 if (files[i].attr & ATTR_DIRECTORY)
1551 { 1576 {
1552 if (!start_dir) 1577 if (!start_dir)
@@ -1566,16 +1591,30 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
1566 1591
1567 if (!exit) 1592 if (!exit)
1568 { 1593 {
1569 /* move down to parent directory. current directory name is 1594 /* we've already descended to the base dir with nothing found,
1570 stored as the starting point for the search in parent */ 1595 check whether that contains music */
1571 start_dir = strrchr(dir, '/'); 1596 if (strlen(dir) <= base_len)
1572 if (start_dir)
1573 { 1597 {
1574 *start_dir = '\0'; 1598 result = check_subdir_for_music(dir, "", true);
1575 start_dir++; 1599 if (result == -1)
1600 /* there's no music files in the base directory,
1601 treat as a fatal error */
1602 result = -2;
1603 break;
1576 } 1604 }
1577 else 1605 else
1578 break; 1606 {
1607 /* move down to parent directory. current directory name is
1608 stored as the starting point for the search in parent */
1609 start_dir = strrchr(dir, '/');
1610 if (start_dir)
1611 {
1612 *start_dir = '\0';
1613 start_dir++;
1614 }
1615 else
1616 break;
1617 }
1579 } 1618 }
1580 } 1619 }
1581 1620
@@ -1583,11 +1622,6 @@ static int get_next_dir(char *dir, bool is_forward, bool recursion)
1583 *(tc->dirfilter) = saved_dirfilter; 1622 *(tc->dirfilter) = saved_dirfilter;
1584 tc->sort_dir = global_settings.sort_dir; 1623 tc->sort_dir = global_settings.sort_dir;
1585 1624
1586 /* special case if nothing found: try start searching again from root */
1587 if (result == -1 && !recursion){
1588 result = get_next_dir(dir, is_forward, true);
1589 }
1590
1591 return result; 1625 return result;
1592} 1626}
1593 1627
@@ -1606,7 +1640,12 @@ static int check_subdir_for_music(char *dir, const char *subdir, bool recurse)
1606 bool has_subdir = false; 1640 bool has_subdir = false;
1607 struct tree_context* tc = tree_get_context(); 1641 struct tree_context* tc = tree_get_context();
1608 1642
1609 snprintf(dir+dirlen, MAX_PATH-dirlen, "/%s", subdir); 1643 snprintf(
1644 dir + dirlen, MAX_PATH - dirlen,
1645 /* only add a trailing slash if we need one */
1646 dirlen && dir[dirlen - 1] == '/' ? "%s" : "/%s",
1647 subdir
1648 );
1610 1649
1611 if (ft_load(tc, dir) < 0) 1650 if (ft_load(tc, dir) < 0)
1612 { 1651 {