summaryrefslogtreecommitdiff
path: root/apps/playlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/playlist.c')
-rw-r--r--apps/playlist.c256
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
136struct directory_search_context {
137 struct playlist_info* playlist;
138 int position;
139 bool queue;
140 int count;
141};
142
136static bool changing_dir = false; 143static bool changing_dir = false;
137 144
138static struct playlist_info current_playlist; 145static struct playlist_info current_playlist;
@@ -151,9 +158,7 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
151static int add_track_to_playlist(struct playlist_info* playlist, 158static 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);
154static int add_directory_to_playlist(struct playlist_info* playlist, 161static int directory_search_callback(char* filename, void* context);
155 const char *dirname, int *position,
156 bool queue, int *count, bool recurse);
157static int remove_track_from_playlist(struct playlist_info* playlist, 162static int remove_track_from_playlist(struct playlist_info* playlist,
158 int position, bool write); 163 int position, bool write);
159static int randomise_playlist(struct playlist_info* playlist, 164static 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 */
686static int add_directory_to_playlist(struct playlist_info* playlist, 692static 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 = &current_playlist; 2749 playlist = &current_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 */
3346int 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}