diff options
Diffstat (limited to 'apps/playlist_viewer.c')
-rw-r--r-- | apps/playlist_viewer.c | 400 |
1 files changed, 321 insertions, 79 deletions
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c index 00da973732..20ac6c05a2 100644 --- a/apps/playlist_viewer.c +++ b/apps/playlist_viewer.c | |||
@@ -28,6 +28,9 @@ | |||
28 | #include "icons.h" | 28 | #include "icons.h" |
29 | #include "menu.h" | 29 | #include "menu.h" |
30 | #include "plugin.h" | 30 | #include "plugin.h" |
31 | #include "keyboard.h" | ||
32 | #include "tree.h" | ||
33 | #include "onplay.h" | ||
31 | 34 | ||
32 | #ifdef HAVE_LCD_BITMAP | 35 | #ifdef HAVE_LCD_BITMAP |
33 | #include "widgets.h" | 36 | #include "widgets.h" |
@@ -35,6 +38,8 @@ | |||
35 | 38 | ||
36 | #include "lang.h" | 39 | #include "lang.h" |
37 | 40 | ||
41 | #include "playlist_viewer.h" | ||
42 | |||
38 | /* Defines for LCD display purposes. Taken from tree.c */ | 43 | /* Defines for LCD display purposes. Taken from tree.c */ |
39 | #ifdef HAVE_LCD_BITMAP | 44 | #ifdef HAVE_LCD_BITMAP |
40 | #define CURSOR_X (global_settings.scrollbar && \ | 45 | #define CURSOR_X (global_settings.scrollbar && \ |
@@ -46,7 +51,9 @@ | |||
46 | 51 | ||
47 | #define MARGIN_X ((global_settings.scrollbar && \ | 52 | #define MARGIN_X ((global_settings.scrollbar && \ |
48 | viewer.num_tracks > viewer.num_display_lines ? \ | 53 | viewer.num_tracks > viewer.num_display_lines ? \ |
49 | SCROLLBAR_WIDTH : 0) + CURSOR_WIDTH + ICON_WIDTH) | 54 | SCROLLBAR_WIDTH : 0) + CURSOR_WIDTH + \ |
55 | (global_settings.playlist_viewer_icons ? \ | ||
56 | ICON_WIDTH : 0)) | ||
50 | #define MARGIN_Y (global_settings.statusbar ? STATUSBAR_HEIGHT : 0) | 57 | #define MARGIN_Y (global_settings.statusbar ? STATUSBAR_HEIGHT : 0) |
51 | 58 | ||
52 | #define LINE_X 0 | 59 | #define LINE_X 0 |
@@ -67,11 +74,15 @@ | |||
67 | /* Maximum number of tracks we can have loaded at one time */ | 74 | /* Maximum number of tracks we can have loaded at one time */ |
68 | #define MAX_PLAYLIST_ENTRIES 200 | 75 | #define MAX_PLAYLIST_ENTRIES 200 |
69 | 76 | ||
77 | /* Default playlist name for saving */ | ||
78 | #define DEFAULT_PLAYLIST_NAME "/viewer.m3u" | ||
79 | |||
70 | /* Index of track on display line _pos */ | 80 | /* Index of track on display line _pos */ |
71 | #define INDEX(_pos) (viewer.first_display_index - viewer.first_index + (_pos)) | 81 | #define INDEX(_pos) (viewer.first_display_index - viewer.first_index + (_pos)) |
72 | 82 | ||
73 | /* Global playlist viewer settings */ | 83 | /* Global playlist viewer settings */ |
74 | struct playlist_viewer_info { | 84 | struct playlist_viewer_info { |
85 | struct playlist_info* playlist; /* playlist being viewed */ | ||
75 | char *name_buffer; /* Buffer used to store track names */ | 86 | char *name_buffer; /* Buffer used to store track names */ |
76 | int buffer_size; /* Size of name buffer */ | 87 | int buffer_size; /* Size of name buffer */ |
77 | 88 | ||
@@ -103,15 +114,19 @@ struct playlist_entry { | |||
103 | static struct playlist_viewer_info viewer; | 114 | static struct playlist_viewer_info viewer; |
104 | static struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES]; | 115 | static struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES]; |
105 | 116 | ||
117 | /* Used when viewing playlists on disk */ | ||
118 | static struct playlist_info temp_playlist; | ||
119 | |||
106 | #ifdef HAVE_LCD_BITMAP | 120 | #ifdef HAVE_LCD_BITMAP |
107 | extern unsigned char bitmap_icons_6x8[LastIcon][6]; | 121 | extern unsigned char bitmap_icons_6x8[LastIcon][6]; |
108 | #endif | 122 | #endif |
109 | 123 | ||
110 | static bool initialize(void); | 124 | static bool initialize(char* filename, bool reload); |
111 | static void load_playlist_entries(int start_index); | 125 | static void load_playlist_entries(int start_index); |
112 | static void load_playlist_entries_r(int end_index); | 126 | static void load_playlist_entries_r(int end_index); |
113 | static int load_entry(int index, int pos, char* p, int size); | 127 | static int load_entry(int index, int pos, char* p, int size); |
114 | static void format_name(char* dest, char* src); | 128 | static void format_name(char* dest, char* src); |
129 | static void format_line(struct playlist_entry* track, char* str, int len); | ||
115 | static void display_playlist(void); | 130 | static void display_playlist(void); |
116 | static void update_display_line(int line, bool scroll); | 131 | static void update_display_line(int line, bool scroll); |
117 | static void scroll_display(int lines); | 132 | static void scroll_display(int lines); |
@@ -120,18 +135,74 @@ static bool update_playlist(bool force); | |||
120 | #ifdef BUTTON_ON | 135 | #ifdef BUTTON_ON |
121 | static int onplay_menu(int index); | 136 | static int onplay_menu(int index); |
122 | #endif | 137 | #endif |
123 | 138 | static bool viewer_menu(void); | |
124 | /* Initialize the playlist viewer */ | 139 | static bool show_icons(void); |
125 | static bool initialize(void) | 140 | static bool show_indices(void); |
141 | static bool track_display(void); | ||
142 | static bool save_playlist(void); | ||
143 | |||
144 | /* Initialize the playlist viewer. */ | ||
145 | static bool initialize(char* filename, bool reload) | ||
126 | { | 146 | { |
127 | if (!(mpeg_status() & MPEG_STATUS_PLAY)) | 147 | char* buffer; |
148 | int buffer_size; | ||
149 | bool is_playing = mpeg_status() & MPEG_STATUS_PLAY; | ||
150 | |||
151 | if (!filename && !is_playing) | ||
128 | /* Nothing is playing, exit */ | 152 | /* Nothing is playing, exit */ |
129 | return false; | 153 | return false; |
130 | 154 | ||
131 | viewer.name_buffer = plugin_get_buffer(&viewer.buffer_size); | 155 | buffer = plugin_get_buffer(&buffer_size); |
132 | if (!viewer.name_buffer) | 156 | if (!buffer) |
133 | return false; | 157 | return false; |
134 | 158 | ||
159 | if (!filename) | ||
160 | viewer.playlist = NULL; | ||
161 | else | ||
162 | { | ||
163 | /* Viewing playlist on disk */ | ||
164 | char *dir, *file, *temp_ptr; | ||
165 | char *index_buffer = NULL; | ||
166 | int index_buffer_size = 0; | ||
167 | |||
168 | viewer.playlist = &temp_playlist; | ||
169 | |||
170 | /* Separate directory from filename */ | ||
171 | temp_ptr = strrchr(filename+1,'/'); | ||
172 | if (temp_ptr) | ||
173 | { | ||
174 | *temp_ptr = 0; | ||
175 | dir = filename; | ||
176 | file = temp_ptr + 1; | ||
177 | } | ||
178 | else | ||
179 | { | ||
180 | dir = "/"; | ||
181 | file = filename+1; | ||
182 | } | ||
183 | |||
184 | if (is_playing) | ||
185 | { | ||
186 | /* Something is playing, use half the plugin buffer for playlist | ||
187 | indices */ | ||
188 | index_buffer_size = buffer_size / 2; | ||
189 | index_buffer = buffer; | ||
190 | } | ||
191 | |||
192 | playlist_create_ex(viewer.playlist, dir, file, index_buffer, | ||
193 | index_buffer_size, buffer+index_buffer_size, | ||
194 | buffer_size-index_buffer_size); | ||
195 | |||
196 | if (temp_ptr) | ||
197 | *temp_ptr = '/'; | ||
198 | |||
199 | buffer += index_buffer_size; | ||
200 | buffer_size -= index_buffer_size; | ||
201 | } | ||
202 | |||
203 | viewer.name_buffer = buffer; | ||
204 | viewer.buffer_size = buffer_size; | ||
205 | |||
135 | #ifdef HAVE_LCD_BITMAP | 206 | #ifdef HAVE_LCD_BITMAP |
136 | { | 207 | { |
137 | char icon_chars[] = "MQ"; /* characters used as icons */ | 208 | char icon_chars[] = "MQ"; /* characters used as icons */ |
@@ -166,12 +237,20 @@ static bool initialize(void) | |||
166 | viewer.line_height = 1; | 237 | viewer.line_height = 1; |
167 | #endif | 238 | #endif |
168 | 239 | ||
169 | viewer.cursor_pos = 0; | ||
170 | viewer.move_track = -1; | 240 | viewer.move_track = -1; |
171 | 241 | ||
172 | /* Start displaying at current playing track */ | 242 | if (!reload) |
173 | viewer.first_display_index = playlist_get_display_index() - 1; | 243 | { |
174 | update_first_index(); | 244 | viewer.cursor_pos = 0; |
245 | |||
246 | if (!viewer.playlist) | ||
247 | /* Start displaying at current playing track */ | ||
248 | viewer.first_display_index = playlist_get_display_index() - 1; | ||
249 | else | ||
250 | viewer.first_display_index = 0; | ||
251 | |||
252 | update_first_index(); | ||
253 | } | ||
175 | 254 | ||
176 | if (!update_playlist(true)) | 255 | if (!update_playlist(true)) |
177 | return false; | 256 | return false; |
@@ -287,21 +366,19 @@ static int load_entry(int index, int pos, char* p, int size) | |||
287 | struct playlist_track_info info; | 366 | struct playlist_track_info info; |
288 | int len; | 367 | int len; |
289 | int result = 0; | 368 | int result = 0; |
290 | char name[MAX_PATH]; | ||
291 | 369 | ||
292 | /* Playlist viewer orders songs based on display index. We need to | 370 | /* Playlist viewer orders songs based on display index. We need to |
293 | convert to real playlist index to access track */ | 371 | convert to real playlist index to access track */ |
294 | index = (index + playlist_get_first_index()) % viewer.num_tracks; | 372 | index = (index + playlist_get_first_index(viewer.playlist)) % |
295 | if (playlist_get_track_info(index, &info) < 0) | 373 | viewer.num_tracks; |
374 | if (playlist_get_track_info(viewer.playlist, index, &info) < 0) | ||
296 | return -1; | 375 | return -1; |
297 | 376 | ||
298 | format_name(name, info.filename); | 377 | len = strlen(info.filename) + 1; |
299 | |||
300 | len = strlen(name) + 1; | ||
301 | 378 | ||
302 | if (len <= size) | 379 | if (len <= size) |
303 | { | 380 | { |
304 | strcpy(p, name); | 381 | strcpy(p, info.filename); |
305 | 382 | ||
306 | tracks[pos].name = p; | 383 | tracks[pos].name = p; |
307 | tracks[pos].index = info.index; | 384 | tracks[pos].index = info.index; |
@@ -319,18 +396,46 @@ static int load_entry(int index, int pos, char* p, int size) | |||
319 | /* Format trackname for display purposes */ | 396 | /* Format trackname for display purposes */ |
320 | static void format_name(char* dest, char* src) | 397 | static void format_name(char* dest, char* src) |
321 | { | 398 | { |
322 | char* p = strrchr(src, '/'); | 399 | switch (global_settings.playlist_viewer_track_display) |
323 | int len; | 400 | { |
401 | case 0: | ||
402 | default: | ||
403 | { | ||
404 | /* Only display the mp3 filename */ | ||
405 | char* p = strrchr(src, '/'); | ||
406 | int len; | ||
407 | |||
408 | strcpy(dest, p+1); | ||
409 | len = strlen(dest); | ||
410 | |||
411 | /* Remove the extension */ | ||
412 | if (!strcasecmp(&dest[len-4], ".mp3") || | ||
413 | !strcasecmp(&dest[len-4], ".mp2") || | ||
414 | !strcasecmp(&dest[len-4], ".mpa")) | ||
415 | dest[len-4] = '\0'; | ||
416 | |||
417 | break; | ||
418 | } | ||
419 | case 1: | ||
420 | /* Full path */ | ||
421 | strcpy(dest, src); | ||
422 | break; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | /* Format display line */ | ||
427 | static void format_line(struct playlist_entry* track, char* str, int len) | ||
428 | { | ||
429 | char name[MAX_PATH]; | ||
324 | 430 | ||
325 | /* Only display the mp3 filename */ | 431 | format_name(name, track->name); |
326 | strcpy(dest, p+1); | 432 | |
327 | len = strlen(dest); | 433 | if (global_settings.playlist_viewer_indices) |
434 | /* Display playlist index */ | ||
435 | snprintf(str, len, "%d. %s", track->display_index, name); | ||
436 | else | ||
437 | snprintf(str, len, "%s", name); | ||
328 | 438 | ||
329 | /* Remove the extension */ | ||
330 | if (!strcasecmp(&dest[len-4], ".mp3") || | ||
331 | !strcasecmp(&dest[len-4], ".mp2") || | ||
332 | !strcasecmp(&dest[len-4], ".mpa")) | ||
333 | dest[len-4] = '\0'; | ||
334 | } | 439 | } |
335 | 440 | ||
336 | /* Display tracks on screen */ | 441 | /* Display tracks on screen */ |
@@ -349,41 +454,44 @@ static void display_playlist(void) | |||
349 | 454 | ||
350 | for (i=0; i<=num_display_tracks; i++) | 455 | for (i=0; i<=num_display_tracks; i++) |
351 | { | 456 | { |
352 | /* Icons */ | 457 | if (global_settings.playlist_viewer_icons) |
353 | if (tracks[INDEX(i)].index == viewer.current_playing_track) | ||
354 | { | 458 | { |
355 | /* Current playing track */ | 459 | /* Icons */ |
460 | if (tracks[INDEX(i)].index == viewer.current_playing_track) | ||
461 | { | ||
462 | /* Current playing track */ | ||
356 | #ifdef HAVE_LCD_BITMAP | 463 | #ifdef HAVE_LCD_BITMAP |
357 | int offset=0; | 464 | int offset=0; |
358 | if ( viewer.line_height > 8 ) | 465 | if ( viewer.line_height > 8 ) |
359 | offset = (viewer.line_height - 8) / 2; | 466 | offset = (viewer.line_height - 8) / 2; |
360 | lcd_bitmap(bitmap_icons_6x8[File], | 467 | lcd_bitmap(bitmap_icons_6x8[File], |
361 | CURSOR_X * 6 + CURSOR_WIDTH, | 468 | CURSOR_X * 6 + CURSOR_WIDTH, |
362 | MARGIN_Y+(i*viewer.line_height) + offset, | 469 | MARGIN_Y+(i*viewer.line_height) + offset, |
363 | 6, 8, true); | 470 | 6, 8, true); |
364 | #else | 471 | #else |
365 | lcd_putc(LINE_X-1, i, File); | 472 | lcd_putc(LINE_X-1, i, File); |
366 | #endif | 473 | #endif |
367 | } | 474 | } |
368 | else if (tracks[INDEX(i)].index == viewer.move_track) | 475 | else if (tracks[INDEX(i)].index == viewer.move_track) |
369 | { | 476 | { |
370 | /* Track we are moving */ | 477 | /* Track we are moving */ |
371 | #ifdef HAVE_LCD_BITMAP | 478 | #ifdef HAVE_LCD_BITMAP |
372 | lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH, | 479 | lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH, |
373 | MARGIN_Y+(i*viewer.line_height), "M"); | 480 | MARGIN_Y+(i*viewer.line_height), "M"); |
374 | #else | 481 | #else |
375 | lcd_putc(LINE_X-1, i, 'M'); | 482 | lcd_putc(LINE_X-1, i, 'M'); |
376 | #endif | 483 | #endif |
377 | } | 484 | } |
378 | else if (tracks[INDEX(i)].queued) | 485 | else if (tracks[INDEX(i)].queued) |
379 | { | 486 | { |
380 | /* Queued track */ | 487 | /* Queued track */ |
381 | #ifdef HAVE_LCD_BITMAP | 488 | #ifdef HAVE_LCD_BITMAP |
382 | lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH, | 489 | lcd_putsxy(CURSOR_X * 6 + CURSOR_WIDTH, |
383 | MARGIN_Y+(i*viewer.line_height), "Q"); | 490 | MARGIN_Y+(i*viewer.line_height), "Q"); |
384 | #else | 491 | #else |
385 | lcd_putc(LINE_X-1, i, 'Q'); | 492 | lcd_putc(LINE_X-1, i, 'Q'); |
386 | #endif | 493 | #endif |
494 | } | ||
387 | } | 495 | } |
388 | 496 | ||
389 | update_display_line(i, false); | 497 | update_display_line(i, false); |
@@ -494,10 +602,8 @@ static void update_display_line(int line, bool scroll) | |||
494 | { | 602 | { |
495 | char str[MAX_PATH + 16]; | 603 | char str[MAX_PATH + 16]; |
496 | 604 | ||
497 | snprintf(str, sizeof(str), "%d. %s", | 605 | format_line(&tracks[INDEX(line)], str, sizeof(str)); |
498 | tracks[INDEX(line)].display_index, | 606 | |
499 | tracks[INDEX(line)].name); | ||
500 | |||
501 | if (scroll) | 607 | if (scroll) |
502 | { | 608 | { |
503 | #ifdef HAVE_LCD_BITMAP | 609 | #ifdef HAVE_LCD_BITMAP |
@@ -516,7 +622,7 @@ static void update_display_line(int line, bool scroll) | |||
516 | static void update_first_index(void) | 622 | static void update_first_index(void) |
517 | { | 623 | { |
518 | /* viewer.num_tracks may be invalid at this point */ | 624 | /* viewer.num_tracks may be invalid at this point */ |
519 | int num_tracks = playlist_amount(); | 625 | int num_tracks = playlist_amount_ex(viewer.playlist); |
520 | 626 | ||
521 | if ((num_tracks - viewer.first_display_index) < viewer.num_display_lines) | 627 | if ((num_tracks - viewer.first_display_index) < viewer.num_display_lines) |
522 | { | 628 | { |
@@ -535,14 +641,17 @@ static void update_first_index(void) | |||
535 | /* Update playlist in case something has changed or forced */ | 641 | /* Update playlist in case something has changed or forced */ |
536 | static bool update_playlist(bool force) | 642 | static bool update_playlist(bool force) |
537 | { | 643 | { |
538 | playlist_get_resume_info(&viewer.current_playing_track); | 644 | if (!viewer.playlist) |
645 | playlist_get_resume_info(&viewer.current_playing_track); | ||
646 | else | ||
647 | viewer.current_playing_track = -1; | ||
539 | 648 | ||
540 | if (force || playlist_amount() != viewer.num_tracks) | 649 | if (force || playlist_amount_ex(viewer.playlist) != viewer.num_tracks) |
541 | { | 650 | { |
542 | int index; | 651 | int index; |
543 | 652 | ||
544 | /* Reload tracks */ | 653 | /* Reload tracks */ |
545 | viewer.num_tracks = playlist_amount(); | 654 | viewer.num_tracks = playlist_amount_ex(viewer.playlist); |
546 | if (viewer.num_tracks < 0) | 655 | if (viewer.num_tracks < 0) |
547 | return false; | 656 | return false; |
548 | 657 | ||
@@ -571,16 +680,19 @@ static bool update_playlist(bool force) | |||
571 | changed. */ | 680 | changed. */ |
572 | static int onplay_menu(int index) | 681 | static int onplay_menu(int index) |
573 | { | 682 | { |
574 | struct menu_items menu[2]; /* increase this if you add entries! */ | 683 | struct menu_items menu[3]; /* increase this if you add entries! */ |
575 | int m, i=0, result, ret = 0; | 684 | int m, i=0, result, ret = 0; |
576 | bool current = (tracks[index].index == viewer.current_playing_track); | 685 | bool current = (tracks[index].index == viewer.current_playing_track); |
577 | 686 | ||
578 | menu[i].desc = str(LANG_DELETE); | 687 | menu[i].desc = str(LANG_REMOVE); |
579 | i++; | 688 | i++; |
580 | 689 | ||
581 | menu[i].desc = str(LANG_MOVE); | 690 | menu[i].desc = str(LANG_MOVE); |
582 | i++; | 691 | i++; |
583 | 692 | ||
693 | menu[i].desc = str(LANG_FILE_OPTIONS); | ||
694 | i++; | ||
695 | |||
584 | m = menu_init(menu, i); | 696 | m = menu_init(menu, i); |
585 | result = menu_show(m); | 697 | result = menu_show(m); |
586 | if (result == MENU_ATTACHED_USB) | 698 | if (result == MENU_ATTACHED_USB) |
@@ -597,7 +709,7 @@ static int onplay_menu(int index) | |||
597 | if (current) | 709 | if (current) |
598 | mpeg_stop(); | 710 | mpeg_stop(); |
599 | 711 | ||
600 | playlist_delete(tracks[index].index); | 712 | playlist_delete(viewer.playlist, tracks[index].index); |
601 | 713 | ||
602 | if (current) | 714 | if (current) |
603 | { | 715 | { |
@@ -618,6 +730,17 @@ static int onplay_menu(int index) | |||
618 | viewer.move_track = tracks[index].index; | 730 | viewer.move_track = tracks[index].index; |
619 | ret = 0; | 731 | ret = 0; |
620 | break; | 732 | break; |
733 | case 2: | ||
734 | { | ||
735 | onplay(tracks[index].name, TREE_ATTR_MPA); | ||
736 | |||
737 | if (!viewer.playlist) | ||
738 | ret = 1; | ||
739 | else | ||
740 | ret = 0; | ||
741 | |||
742 | break; | ||
743 | } | ||
621 | } | 744 | } |
622 | } | 745 | } |
623 | 746 | ||
@@ -627,17 +750,91 @@ static int onplay_menu(int index) | |||
627 | } | 750 | } |
628 | #endif | 751 | #endif |
629 | 752 | ||
630 | /* Main viewer function */ | 753 | /* Menu of viewer options. Invoked via F1(r) or Menu(p). */ |
754 | static bool viewer_menu(void) | ||
755 | { | ||
756 | int m; | ||
757 | bool result; | ||
758 | |||
759 | struct menu_items items[] = { | ||
760 | { str(LANG_SHOW_ICONS), show_icons }, | ||
761 | { str(LANG_SHOW_INDICES), show_indices }, | ||
762 | { str(LANG_TRACK_DISPLAY), track_display }, | ||
763 | { str(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist }, | ||
764 | }; | ||
765 | |||
766 | m=menu_init( items, sizeof(items) / sizeof(*items) ); | ||
767 | result = menu_run(m); | ||
768 | menu_exit(m); | ||
769 | |||
770 | settings_save(); | ||
771 | |||
772 | return result; | ||
773 | } | ||
774 | |||
775 | /* Show icons in viewer? */ | ||
776 | static bool show_icons(void) | ||
777 | { | ||
778 | return set_bool(str(LANG_SHOW_ICONS), | ||
779 | &global_settings.playlist_viewer_icons); | ||
780 | } | ||
781 | |||
782 | /* Show indices of tracks? */ | ||
783 | static bool show_indices(void) | ||
784 | { | ||
785 | return set_bool(str(LANG_SHOW_INDICES), | ||
786 | &global_settings.playlist_viewer_indices); | ||
787 | } | ||
788 | |||
789 | /* How to display a track */ | ||
790 | static bool track_display(void) | ||
791 | { | ||
792 | char* names[] = { | ||
793 | str(LANG_DISPLAY_TRACK_NAME_ONLY), | ||
794 | str(LANG_DISPLAY_FULL_PATH) | ||
795 | }; | ||
796 | |||
797 | return set_option(str(LANG_TRACK_DISPLAY), | ||
798 | &global_settings.playlist_viewer_track_display, INT, names, 2, NULL); | ||
799 | } | ||
800 | |||
801 | /* Save playlist to disk */ | ||
802 | static bool save_playlist(void) | ||
803 | { | ||
804 | char filename[MAX_PATH+1]; | ||
805 | |||
806 | strncpy(filename, DEFAULT_PLAYLIST_NAME, sizeof(filename)); | ||
807 | |||
808 | if (!kbd_input(filename, sizeof(filename))) | ||
809 | { | ||
810 | playlist_save(viewer.playlist, filename); | ||
811 | |||
812 | /* reload in case playlist was saved to cwd */ | ||
813 | reload_directory(); | ||
814 | } | ||
815 | |||
816 | return false; | ||
817 | } | ||
818 | |||
819 | /* View current playlist */ | ||
631 | bool playlist_viewer(void) | 820 | bool playlist_viewer(void) |
632 | { | 821 | { |
822 | return playlist_viewer_ex(NULL); | ||
823 | } | ||
824 | |||
825 | /* Main viewer function. Filename identifies playlist to be viewed. If NULL, | ||
826 | view current playlist. */ | ||
827 | bool playlist_viewer_ex(char* filename) | ||
828 | { | ||
829 | bool ret = false; /* return value */ | ||
633 | bool exit=false; /* exit viewer */ | 830 | bool exit=false; /* exit viewer */ |
634 | bool update=true; /* update display */ | 831 | bool update=true; /* update display */ |
635 | bool cursor_on=true; /* used for flashing cursor */ | 832 | bool cursor_on=true; /* used for flashing cursor */ |
636 | int old_cursor_pos; /* last cursor position */ | 833 | int old_cursor_pos; /* last cursor position */ |
637 | int button; | 834 | int button; |
638 | 835 | ||
639 | if (!initialize()) | 836 | if (!initialize(filename, false)) |
640 | return false; | 837 | goto exit; |
641 | 838 | ||
642 | old_cursor_pos = viewer.cursor_pos; | 839 | old_cursor_pos = viewer.cursor_pos; |
643 | 840 | ||
@@ -648,7 +845,7 @@ bool playlist_viewer(void) | |||
648 | /* Timeout so we can determine if play status has changed */ | 845 | /* Timeout so we can determine if play status has changed */ |
649 | button = button_get_w_tmo(HZ/2); | 846 | button = button_get_w_tmo(HZ/2); |
650 | 847 | ||
651 | if (!(mpeg_status() & MPEG_STATUS_PLAY)) | 848 | if (!viewer.playlist && !(mpeg_status() & MPEG_STATUS_PLAY)) |
652 | { | 849 | { |
653 | /* Play has stopped */ | 850 | /* Play has stopped */ |
654 | #ifdef HAVE_LCD_CHARCELLS | 851 | #ifdef HAVE_LCD_CHARCELLS |
@@ -657,7 +854,7 @@ bool playlist_viewer(void) | |||
657 | splash(HZ, true, str(LANG_END_PLAYLIST_RECORDER)); | 854 | splash(HZ, true, str(LANG_END_PLAYLIST_RECORDER)); |
658 | #endif | 855 | #endif |
659 | status_set_playmode(STATUS_STOP); | 856 | status_set_playmode(STATUS_STOP); |
660 | return false;; | 857 | goto exit; |
661 | } | 858 | } |
662 | 859 | ||
663 | if (viewer.move_track != -1 || !cursor_on) | 860 | if (viewer.move_track != -1 || !cursor_on) |
@@ -685,10 +882,13 @@ bool playlist_viewer(void) | |||
685 | #endif | 882 | #endif |
686 | } | 883 | } |
687 | 884 | ||
688 | playlist_get_resume_info(&track); | 885 | if (!viewer.playlist) |
886 | playlist_get_resume_info(&track); | ||
887 | else | ||
888 | track = -1; | ||
689 | 889 | ||
690 | if (track != viewer.current_playing_track || | 890 | if (track != viewer.current_playing_track || |
691 | playlist_amount() != viewer.num_tracks) | 891 | playlist_amount_ex(viewer.playlist) != viewer.num_tracks) |
692 | { | 892 | { |
693 | /* Playlist has changed (new track started?) */ | 893 | /* Playlist has changed (new track started?) */ |
694 | update_first_index(); | 894 | update_first_index(); |
@@ -769,7 +969,7 @@ bool playlist_viewer(void) | |||
769 | /* Move track */ | 969 | /* Move track */ |
770 | int ret; | 970 | int ret; |
771 | 971 | ||
772 | ret = playlist_move(viewer.move_track, | 972 | ret = playlist_move(viewer.playlist, viewer.move_track, |
773 | tracks[INDEX(viewer.cursor_pos)].index); | 973 | tracks[INDEX(viewer.cursor_pos)].index); |
774 | if (ret < 0) | 974 | if (ret < 0) |
775 | splash(HZ, true, str(LANG_MOVE_FAILED)); | 975 | splash(HZ, true, str(LANG_MOVE_FAILED)); |
@@ -777,7 +977,7 @@ bool playlist_viewer(void) | |||
777 | update_playlist(true); | 977 | update_playlist(true); |
778 | viewer.move_track = -1; | 978 | viewer.move_track = -1; |
779 | } | 979 | } |
780 | else | 980 | else if (!viewer.playlist) |
781 | { | 981 | { |
782 | /* Stop current track and play new track */ | 982 | /* Stop current track and play new track */ |
783 | mpeg_stop(); | 983 | mpeg_stop(); |
@@ -785,6 +985,22 @@ bool playlist_viewer(void) | |||
785 | status_set_playmode(STATUS_PLAY); | 985 | status_set_playmode(STATUS_PLAY); |
786 | update_playlist(false); | 986 | update_playlist(false); |
787 | } | 987 | } |
988 | else | ||
989 | { | ||
990 | /* Play track from playlist on disk */ | ||
991 | mpeg_stop(); | ||
992 | |||
993 | /* New playlist */ | ||
994 | if (playlist_set_current(viewer.playlist) < 0) | ||
995 | goto exit; | ||
996 | |||
997 | playlist_start(tracks[INDEX(viewer.cursor_pos)].index, 0); | ||
998 | status_set_playmode(STATUS_PLAY); | ||
999 | |||
1000 | /* Our playlist is now the current list */ | ||
1001 | if (!initialize(NULL, true)) | ||
1002 | goto exit; | ||
1003 | } | ||
788 | 1004 | ||
789 | display_playlist(); | 1005 | display_playlist(); |
790 | update = true; | 1006 | update = true; |
@@ -799,13 +1015,15 @@ bool playlist_viewer(void) | |||
799 | ret = onplay_menu(INDEX(viewer.cursor_pos)); | 1015 | ret = onplay_menu(INDEX(viewer.cursor_pos)); |
800 | 1016 | ||
801 | if (ret < 0) | 1017 | if (ret < 0) |
802 | /* USB attached */ | 1018 | { |
803 | return true; | 1019 | ret = true; |
1020 | goto exit; | ||
1021 | } | ||
804 | else if (ret > 0) | 1022 | else if (ret > 0) |
805 | { | 1023 | { |
806 | /* Playlist changed */ | 1024 | /* Playlist changed */ |
807 | update_first_index(); | 1025 | update_first_index(); |
808 | update_playlist(true); | 1026 | update_playlist(false); |
809 | if (viewer.num_tracks <= 0) | 1027 | if (viewer.num_tracks <= 0) |
810 | exit = true; | 1028 | exit = true; |
811 | } | 1029 | } |
@@ -816,9 +1034,30 @@ bool playlist_viewer(void) | |||
816 | break; | 1034 | break; |
817 | } | 1035 | } |
818 | #endif /* BUTTON_ON */ | 1036 | #endif /* BUTTON_ON */ |
1037 | #ifdef HAVE_RECORDER_KEYPAD | ||
1038 | case BUTTON_F1: | ||
1039 | #else | ||
1040 | case BUTTON_MENU: | ||
1041 | #endif | ||
1042 | if (viewer_menu()) | ||
1043 | { | ||
1044 | ret = true; | ||
1045 | goto exit; | ||
1046 | } | ||
1047 | |||
1048 | display_playlist(); | ||
1049 | update = true; | ||
1050 | break; | ||
1051 | |||
819 | case SYS_USB_CONNECTED: | 1052 | case SYS_USB_CONNECTED: |
820 | usb_screen(); | 1053 | usb_screen(); |
821 | return true; | 1054 | ret = true; |
1055 | goto exit; | ||
1056 | break; | ||
1057 | |||
1058 | case BUTTON_NONE: | ||
1059 | status_draw(false); | ||
1060 | break; | ||
822 | } | 1061 | } |
823 | 1062 | ||
824 | if (update && !exit) | 1063 | if (update && !exit) |
@@ -852,5 +1091,8 @@ bool playlist_viewer(void) | |||
852 | } | 1091 | } |
853 | } | 1092 | } |
854 | 1093 | ||
855 | return false; | 1094 | exit: |
1095 | if (viewer.playlist) | ||
1096 | playlist_close(viewer.playlist); | ||
1097 | return ret; | ||
856 | } | 1098 | } |