diff options
Diffstat (limited to 'apps/playlist.c')
-rw-r--r-- | apps/playlist.c | 256 |
1 files changed, 143 insertions, 113 deletions
diff --git a/apps/playlist.c b/apps/playlist.c index 93293d75ed..a08ecdfe34 100644 --- a/apps/playlist.c +++ b/apps/playlist.c | |||
@@ -133,6 +133,13 @@ | |||
133 | 133 | ||
134 | #define PLAYLIST_DISPLAY_COUNT 10 | 134 | #define PLAYLIST_DISPLAY_COUNT 10 |
135 | 135 | ||
136 | struct directory_search_context { | ||
137 | struct playlist_info* playlist; | ||
138 | int position; | ||
139 | bool queue; | ||
140 | int count; | ||
141 | }; | ||
142 | |||
136 | static bool changing_dir = false; | 143 | static bool changing_dir = false; |
137 | 144 | ||
138 | static struct playlist_info current_playlist; | 145 | static struct playlist_info current_playlist; |
@@ -151,9 +158,7 @@ static int add_indices_to_playlist(struct playlist_info* playlist, | |||
151 | static int add_track_to_playlist(struct playlist_info* playlist, | 158 | static int add_track_to_playlist(struct playlist_info* playlist, |
152 | const char *filename, int position, | 159 | const char *filename, int position, |
153 | bool queue, int seek_pos); | 160 | bool queue, int seek_pos); |
154 | static int add_directory_to_playlist(struct playlist_info* playlist, | 161 | static int directory_search_callback(char* filename, void* context); |
155 | const char *dirname, int *position, | ||
156 | bool queue, int *count, bool recurse); | ||
157 | static int remove_track_from_playlist(struct playlist_info* playlist, | 162 | static int remove_track_from_playlist(struct playlist_info* playlist, |
158 | int position, bool write); | 163 | int position, bool write); |
159 | static int randomise_playlist(struct playlist_info* playlist, | 164 | static int randomise_playlist(struct playlist_info* playlist, |
@@ -681,121 +686,46 @@ static int add_track_to_playlist(struct playlist_info* playlist, | |||
681 | } | 686 | } |
682 | 687 | ||
683 | /* | 688 | /* |
684 | * Insert directory into playlist. May be called recursively. | 689 | * Callback for playlist_directory_tracksearch to insert track into |
690 | * playlist. | ||
685 | */ | 691 | */ |
686 | static int add_directory_to_playlist(struct playlist_info* playlist, | 692 | static int directory_search_callback(char* filename, void* context) |
687 | const char *dirname, int *position, | ||
688 | bool queue, int *count, bool recurse) | ||
689 | { | 693 | { |
690 | char buf[MAX_PATH+1]; | 694 | struct directory_search_context* c = |
691 | unsigned char *count_str; | 695 | (struct directory_search_context*) context; |
692 | int result = 0; | 696 | int insert_pos; |
693 | int num_files = 0; | ||
694 | int i; | ||
695 | struct entry *files; | ||
696 | struct tree_context* tc = tree_get_context(); | ||
697 | int dirfilter = *(tc->dirfilter); | ||
698 | 697 | ||
699 | /* use the tree browser dircache to load files */ | 698 | insert_pos = add_track_to_playlist(c->playlist, filename, c->position, |
700 | *(tc->dirfilter) = SHOW_ALL; | 699 | c->queue, -1); |
701 | 700 | ||
702 | if (ft_load(tc, dirname) < 0) | 701 | if (insert_pos < 0) |
703 | { | ||
704 | gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); | ||
705 | *(tc->dirfilter) = dirfilter; | ||
706 | return -1; | 702 | return -1; |
707 | } | 703 | |
708 | 704 | (c->count)++; | |
709 | files = (struct entry*) tc->dircache; | 705 | |
710 | num_files = tc->filesindir; | 706 | /* Make sure tracks are inserted in correct order if user requests |
711 | 707 | INSERT_FIRST */ | |
712 | /* we've overwritten the dircache so tree browser will need to be | 708 | if (c->position == PLAYLIST_INSERT_FIRST || c->position >= 0) |
713 | reloaded */ | 709 | c->position = insert_pos + 1; |
714 | reload_directory(); | 710 | |
715 | 711 | if (((c->count)%PLAYLIST_DISPLAY_COUNT) == 0) | |
716 | if (queue) | ||
717 | count_str = str(LANG_PLAYLIST_QUEUE_COUNT); | ||
718 | else | ||
719 | count_str = str(LANG_PLAYLIST_INSERT_COUNT); | ||
720 | |||
721 | for (i=0; i<num_files; i++) | ||
722 | { | 712 | { |
723 | /* user abort */ | 713 | unsigned char* count_str; |
724 | if (button_get(false) == SETTINGS_CANCEL) | ||
725 | { | ||
726 | result = -1; | ||
727 | break; | ||
728 | } | ||
729 | 714 | ||
730 | if (files[i].attr & ATTR_DIRECTORY) | 715 | if (c->queue) |
731 | { | 716 | count_str = str(LANG_PLAYLIST_QUEUE_COUNT); |
732 | if (recurse) | 717 | else |
733 | { | 718 | count_str = str(LANG_PLAYLIST_INSERT_COUNT); |
734 | /* recursively add directories */ | ||
735 | snprintf(buf, sizeof(buf), "%s/%s", dirname, files[i].name); | ||
736 | result = add_directory_to_playlist(playlist, buf, position, | ||
737 | queue, count, recurse); | ||
738 | if (result < 0) | ||
739 | break; | ||
740 | |||
741 | /* we now need to reload our current directory */ | ||
742 | if(ft_load(tc, dirname) < 0) | ||
743 | { | ||
744 | result = -1; | ||
745 | break; | ||
746 | } | ||
747 | |||
748 | files = (struct entry*) tc->dircache; | ||
749 | num_files = tc->filesindir; | ||
750 | if (!num_files) | ||
751 | { | ||
752 | result = -1; | ||
753 | break; | ||
754 | } | ||
755 | } | ||
756 | else | ||
757 | continue; | ||
758 | } | ||
759 | else if ((files[i].attr & TREE_ATTR_MASK) == TREE_ATTR_MPA) | ||
760 | { | ||
761 | int insert_pos; | ||
762 | |||
763 | snprintf(buf, sizeof(buf), "%s/%s", dirname, files[i].name); | ||
764 | |||
765 | insert_pos = add_track_to_playlist(playlist, buf, *position, | ||
766 | queue, -1); | ||
767 | if (insert_pos < 0) | ||
768 | { | ||
769 | result = -1; | ||
770 | break; | ||
771 | } | ||
772 | |||
773 | (*count)++; | ||
774 | |||
775 | /* Make sure tracks are inserted in correct order if user requests | ||
776 | INSERT_FIRST */ | ||
777 | if (*position == PLAYLIST_INSERT_FIRST || *position >= 0) | ||
778 | *position = insert_pos + 1; | ||
779 | |||
780 | if ((*count%PLAYLIST_DISPLAY_COUNT) == 0) | ||
781 | { | ||
782 | display_playlist_count(*count, count_str); | ||
783 | 719 | ||
784 | if (*count == PLAYLIST_DISPLAY_COUNT && | 720 | display_playlist_count(c->count, count_str); |
785 | (audio_status() & AUDIO_STATUS_PLAY) && | 721 | |
786 | playlist->started) | 722 | if ((c->count) == PLAYLIST_DISPLAY_COUNT && |
787 | audio_flush_and_reload_tracks(); | 723 | (audio_status() & AUDIO_STATUS_PLAY) && |
788 | } | 724 | c->playlist->started) |
789 | 725 | audio_flush_and_reload_tracks(); | |
790 | /* let the other threads work */ | ||
791 | yield(); | ||
792 | } | ||
793 | } | 726 | } |
794 | 727 | ||
795 | /* restore dirfilter */ | 728 | return 0; |
796 | *(tc->dirfilter) = dirfilter; | ||
797 | |||
798 | return result; | ||
799 | } | 729 | } |
800 | 730 | ||
801 | /* | 731 | /* |
@@ -2811,9 +2741,9 @@ int playlist_insert_directory(struct playlist_info* playlist, | |||
2811 | const char *dirname, int position, bool queue, | 2741 | const char *dirname, int position, bool queue, |
2812 | bool recurse) | 2742 | bool recurse) |
2813 | { | 2743 | { |
2814 | int count = 0; | ||
2815 | int result; | 2744 | int result; |
2816 | unsigned char *count_str; | 2745 | unsigned char *count_str; |
2746 | struct directory_search_context context; | ||
2817 | 2747 | ||
2818 | if (!playlist) | 2748 | if (!playlist) |
2819 | playlist = ¤t_playlist; | 2749 | playlist = ¤t_playlist; |
@@ -2829,18 +2759,23 @@ int playlist_insert_directory(struct playlist_info* playlist, | |||
2829 | else | 2759 | else |
2830 | count_str = str(LANG_PLAYLIST_INSERT_COUNT); | 2760 | count_str = str(LANG_PLAYLIST_INSERT_COUNT); |
2831 | 2761 | ||
2832 | display_playlist_count(count, count_str); | 2762 | display_playlist_count(0, count_str); |
2763 | |||
2764 | context.playlist = playlist; | ||
2765 | context.position = position; | ||
2766 | context.queue = queue; | ||
2767 | context.count = 0; | ||
2833 | 2768 | ||
2834 | cpu_boost(true); | 2769 | cpu_boost(true); |
2835 | 2770 | ||
2836 | result = add_directory_to_playlist(playlist, dirname, &position, queue, | 2771 | result = playlist_directory_tracksearch(dirname, recurse, |
2837 | &count, recurse); | 2772 | directory_search_callback, &context); |
2838 | 2773 | ||
2839 | sync_control(playlist, false); | 2774 | sync_control(playlist, false); |
2840 | 2775 | ||
2841 | cpu_boost(false); | 2776 | cpu_boost(false); |
2842 | 2777 | ||
2843 | display_playlist_count(count, count_str); | 2778 | display_playlist_count(context.count, count_str); |
2844 | 2779 | ||
2845 | if ((audio_status() & AUDIO_STATUS_PLAY) && playlist->started) | 2780 | if ((audio_status() & AUDIO_STATUS_PLAY) && playlist->started) |
2846 | audio_flush_and_reload_tracks(); | 2781 | audio_flush_and_reload_tracks(); |
@@ -3403,3 +3338,98 @@ int playlist_save(struct playlist_info* playlist, char *filename) | |||
3403 | 3338 | ||
3404 | return result; | 3339 | return result; |
3405 | } | 3340 | } |
3341 | |||
3342 | /* | ||
3343 | * Search specified directory for tracks and notify via callback. May be | ||
3344 | * called recursively. | ||
3345 | */ | ||
3346 | int playlist_directory_tracksearch(const char* dirname, bool recurse, | ||
3347 | int (*callback)(char*, void*), | ||
3348 | void* context) | ||
3349 | { | ||
3350 | char buf[MAX_PATH+1]; | ||
3351 | int result = 0; | ||
3352 | int num_files = 0; | ||
3353 | int i; | ||
3354 | struct entry *files; | ||
3355 | struct tree_context* tc = tree_get_context(); | ||
3356 | int old_dirfilter = *(tc->dirfilter); | ||
3357 | |||
3358 | if (!callback) | ||
3359 | return -1; | ||
3360 | |||
3361 | /* use the tree browser dircache to load files */ | ||
3362 | *(tc->dirfilter) = SHOW_ALL; | ||
3363 | |||
3364 | if (ft_load(tc, dirname) < 0) | ||
3365 | { | ||
3366 | gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR)); | ||
3367 | *(tc->dirfilter) = old_dirfilter; | ||
3368 | return -1; | ||
3369 | } | ||
3370 | |||
3371 | files = (struct entry*) tc->dircache; | ||
3372 | num_files = tc->filesindir; | ||
3373 | |||
3374 | /* we've overwritten the dircache so tree browser will need to be | ||
3375 | reloaded */ | ||
3376 | reload_directory(); | ||
3377 | |||
3378 | for (i=0; i<num_files; i++) | ||
3379 | { | ||
3380 | /* user abort */ | ||
3381 | if (button_get(false) == SETTINGS_CANCEL) | ||
3382 | { | ||
3383 | result = -1; | ||
3384 | break; | ||
3385 | } | ||
3386 | |||
3387 | if (files[i].attr & ATTR_DIRECTORY) | ||
3388 | { | ||
3389 | if (recurse) | ||
3390 | { | ||
3391 | /* recursively add directories */ | ||
3392 | snprintf(buf, sizeof(buf), "%s/%s", dirname, files[i].name); | ||
3393 | result = playlist_directory_tracksearch(buf, recurse, | ||
3394 | callback, context); | ||
3395 | if (result < 0) | ||
3396 | break; | ||
3397 | |||
3398 | /* we now need to reload our current directory */ | ||
3399 | if(ft_load(tc, dirname) < 0) | ||
3400 | { | ||
3401 | result = -1; | ||
3402 | break; | ||
3403 | } | ||
3404 | |||
3405 | files = (struct entry*) tc->dircache; | ||
3406 | num_files = tc->filesindir; | ||
3407 | if (!num_files) | ||
3408 | { | ||
3409 | result = -1; | ||
3410 | break; | ||
3411 | } | ||
3412 | } | ||
3413 | else | ||
3414 | continue; | ||
3415 | } | ||
3416 | else if ((files[i].attr & TREE_ATTR_MASK) == TREE_ATTR_MPA) | ||
3417 | { | ||
3418 | snprintf(buf, sizeof(buf), "%s/%s", dirname, files[i].name); | ||
3419 | |||
3420 | if (callback(buf, context) != 0) | ||
3421 | { | ||
3422 | result = -1; | ||
3423 | break; | ||
3424 | } | ||
3425 | |||
3426 | /* let the other threads work */ | ||
3427 | yield(); | ||
3428 | } | ||
3429 | } | ||
3430 | |||
3431 | /* restore dirfilter */ | ||
3432 | *(tc->dirfilter) = old_dirfilter; | ||
3433 | |||
3434 | return result; | ||
3435 | } | ||