HAVE_ADJUSTABLE_CPU_FREQ isn't defined for simulators, so we don't have to check...
[Rockbox.git] / apps / playlist_viewer.c
blobae27211ac2ee67faff7b21310d62a42672548516
1 /***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id$
11 * Copyright (C) 2003 Hardeep Sidhu
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
21 * Kevin Ferrare 2005/10/16
22 * multi-screen support, rewrote a lot of code
24 #include <string.h>
25 #include <sprintf.h>
26 #include "playlist.h"
27 #include "audio.h"
28 #include "screens.h"
29 #include "status.h"
30 #include "settings.h"
31 #include "icons.h"
32 #include "menu.h"
33 #include "plugin.h"
34 #include "keyboard.h"
35 #include "tree.h"
36 #include "onplay.h"
37 #include "talk.h"
38 #include "misc.h"
39 #include "action.h"
40 #include "debug.h"
41 #include "backlight.h"
43 #include "lang.h"
45 #include "playlist_viewer.h"
46 #include "icon.h"
47 #include "list.h"
48 #include "statusbar.h"
49 #include "splash.h"
50 #include "playlist_menu.h"
52 /* Maximum number of tracks we can have loaded at one time */
53 #define MAX_PLAYLIST_ENTRIES 200
55 /* The number of items between the selected one and the end/start of
56 * the buffer under which the buffer must reload */
57 #define MIN_BUFFER_MARGIN screens[0].nb_lines
59 /* Default playlist name for saving */
60 #define DEFAULT_VIEWER_PLAYLIST_NAME "/viewer.m3u"
63 /* Information about a specific track */
64 struct playlist_entry {
65 char *name; /* Formatted track name */
66 int index; /* Playlist index */
67 int display_index; /* Display index */
68 bool queued; /* Is track queued? */
69 bool skipped; /* Is track marked as bad? */
72 enum direction
74 FORWARD,
75 BACKWARD
78 struct playlist_buffer
80 char *name_buffer; /* Buffer used to store track names */
81 int buffer_size; /* Size of name buffer */
83 int first_index; /* Real index of first track loaded inside
84 the buffer */
86 enum direction direction; /* Direction of the buffer (if the buffer
87 was loaded BACKWARD, the last track in
88 the buffer has a real index < to the
89 real index of the the first track)*/
91 struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES];
92 int num_loaded; /* Number of track entries loaded in buffer */
95 /* Global playlist viewer settings */
96 struct playlist_viewer {
97 struct playlist_info* playlist; /* playlist being viewed */
98 int num_tracks; /* Number of tracks in playlist */
99 int current_playing_track; /* Index of current playing track */
100 int selected_track; /* The selected track, relative (first is 0)*/
101 int move_track; /* Playlist index of track to move or -1 */
102 struct playlist_buffer buffer;
105 static struct playlist_viewer viewer;
107 /* Used when viewing playlists on disk */
108 static struct playlist_info temp_playlist;
110 void playlist_buffer_init(struct playlist_buffer * pb, char * names_buffer,
111 int names_buffer_size);
112 void playlist_buffer_load_entries(struct playlist_buffer * pb, int index,
113 enum direction direction);
114 int playlist_entry_load(struct playlist_entry *entry, int index,
115 char* name_buffer, int remaining_size);
117 struct playlist_entry * playlist_buffer_get_track(struct playlist_buffer * pb,
118 int index);
120 static bool playlist_viewer_init(struct playlist_viewer * viewer,
121 char* filename, bool reload);
123 static void format_name(char* dest, const char* src);
124 static void format_line(const struct playlist_entry* track, char* str,
125 int len);
127 static bool update_playlist(bool force);
128 static int onplay_menu(int index);
129 static bool viewer_menu(void);
130 static bool show_icons(void);
131 static bool show_indices(void);
132 static bool track_display(void);
133 static bool save_playlist(void);
135 void playlist_buffer_init(struct playlist_buffer * pb, char * names_buffer,
136 int names_buffer_size)
138 pb->name_buffer=names_buffer;
139 pb->buffer_size=names_buffer_size;
140 pb->first_index=0;
141 pb->num_loaded=0;
145 * Loads the entries following 'index' in the playlist buffer
147 void playlist_buffer_load_entries(struct playlist_buffer * pb, int index,
148 enum direction direction)
150 int num_entries = viewer.num_tracks;
151 char* p = pb->name_buffer;
152 int remaining = pb->buffer_size;
153 int i;
155 pb->first_index = index;
156 if (num_entries > MAX_PLAYLIST_ENTRIES)
157 num_entries = MAX_PLAYLIST_ENTRIES;
159 for(i=0; i<num_entries; i++)
161 int len = playlist_entry_load(&(pb->tracks[i]), index, p, remaining);
162 if (len < 0)
164 /* Out of name buffer space */
165 num_entries = i;
166 break;
169 p += len;
170 remaining -= len;
172 if(direction==FORWARD)
173 index++;
174 else
175 index--;
176 index+=viewer.num_tracks;
177 index%=viewer.num_tracks;
179 pb->direction=direction;
180 pb->num_loaded = i;
183 void playlist_buffer_load_entries_screen(struct playlist_buffer * pb,
184 enum direction direction)
186 if(direction==FORWARD)
188 int min_start=viewer.selected_track-2*screens[0].nb_lines;
189 while(min_start<0)
190 min_start+=viewer.num_tracks;
191 min_start %= viewer.num_tracks;
192 playlist_buffer_load_entries(pb, min_start, FORWARD);
194 else
196 int max_start=viewer.selected_track+2*screens[0].nb_lines;
197 max_start%=viewer.num_tracks;
198 playlist_buffer_load_entries(pb, max_start, BACKWARD);
202 int playlist_entry_load(struct playlist_entry *entry, int index,
203 char* name_buffer, int remaining_size)
205 struct playlist_track_info info;
206 int len;
208 /* Playlist viewer orders songs based on display index. We need to
209 convert to real playlist index to access track */
210 index = (index + playlist_get_first_index(viewer.playlist)) %
211 viewer.num_tracks;
212 if (playlist_get_track_info(viewer.playlist, index, &info) < 0)
213 return -1;
215 len = strlen(info.filename) + 1;
217 if (len <= remaining_size)
219 strcpy(name_buffer, info.filename);
221 entry->name = name_buffer;
222 entry->index = info.index;
223 entry->display_index = info.display_index;
224 entry->queued = info.attr & PLAYLIST_ATTR_QUEUED;
225 entry->skipped = info.attr & PLAYLIST_ATTR_SKIPPED;
226 return len;
228 return -1;
231 int playlist_buffer_get_index(struct playlist_buffer * pb, int index )
233 int buffer_index;
234 if(pb->direction==FORWARD)
236 if(index>=pb->first_index)
237 buffer_index=index-pb->first_index;
238 else /* rotation : track0 in buffer + requested track */
239 buffer_index=(viewer.num_tracks-pb->first_index)+(index);
241 else
243 if(index<=pb->first_index)
244 buffer_index=pb->first_index-index;
245 else /* rotation : track0 in buffer + dist from the last track
246 to the requested track (num_tracks-requested track) */
247 buffer_index=(pb->first_index)+(viewer.num_tracks-index);
249 return(buffer_index);
252 #define distance(a, b) \
253 a>b? (a) - (b) : (b) - (a)
254 bool playlist_buffer_needs_reload(struct playlist_buffer* pb, int track_index)
256 if(pb->num_loaded==viewer.num_tracks)
257 return(false);
258 int selected_index=playlist_buffer_get_index(pb, track_index);
259 int first_buffer_index=playlist_buffer_get_index(pb, pb->first_index);
260 int distance_beginning=distance(selected_index, first_buffer_index);
261 if(distance_beginning<MIN_BUFFER_MARGIN)
262 return(true);
264 if(pb->num_loaded - distance_beginning < MIN_BUFFER_MARGIN)
265 return(true);
266 return(false);
269 struct playlist_entry * playlist_buffer_get_track(struct playlist_buffer * pb,
270 int index)
272 int buffer_index=playlist_buffer_get_index(pb, index);
273 return(&(pb->tracks[buffer_index]));
276 /* Initialize the playlist viewer. */
277 static bool playlist_viewer_init(struct playlist_viewer * viewer,
278 char* filename, bool reload)
280 char* buffer;
281 int buffer_size;
282 bool is_playing = audio_status() & AUDIO_STATUS_PLAY;
284 if (!filename && !is_playing)
285 /* Nothing is playing, exit */
286 return false;
288 buffer = plugin_get_buffer(&buffer_size);
289 if (!buffer)
290 return false;
292 if (!filename)
293 viewer->playlist = NULL;
294 else
296 /* Viewing playlist on disk */
297 char *dir, *file, *temp_ptr;
298 char *index_buffer = NULL;
299 int index_buffer_size = 0;
301 viewer->playlist = &temp_playlist;
303 /* Separate directory from filename */
304 temp_ptr = strrchr(filename+1,'/');
305 if (temp_ptr)
307 *temp_ptr = 0;
308 dir = filename;
309 file = temp_ptr + 1;
311 else
313 dir = "/";
314 file = filename+1;
317 if (is_playing)
319 /* Something is playing, use half the plugin buffer for playlist
320 indices */
321 index_buffer_size = buffer_size / 2;
322 index_buffer = buffer;
325 playlist_create_ex(viewer->playlist, dir, file, index_buffer,
326 index_buffer_size, buffer+index_buffer_size,
327 buffer_size-index_buffer_size);
329 if (temp_ptr)
330 *temp_ptr = '/';
332 buffer += index_buffer_size;
333 buffer_size -= index_buffer_size;
335 playlist_buffer_init(&viewer->buffer, buffer, buffer_size );
337 viewer->move_track = -1;
339 if (!reload)
341 if (viewer->playlist)
342 viewer->selected_track = 0;
343 else
344 viewer->selected_track = playlist_get_display_index() - 1;
347 if (!update_playlist(true))
348 return false;
349 return true;
352 /* Format trackname for display purposes */
353 static void format_name(char* dest, const char* src)
355 switch (global_settings.playlist_viewer_track_display)
357 case 0:
358 default:
360 /* Only display the mp3 filename */
361 char* p = strrchr(src, '/');
362 int len;
364 strcpy(dest, p+1);
365 len = strlen(dest);
367 /* Remove the extension */
368 if (!strcasecmp(&dest[len-4], ".mp3") ||
369 !strcasecmp(&dest[len-4], ".mp2") ||
370 !strcasecmp(&dest[len-4], ".mpa"))
371 dest[len-4] = '\0';
373 break;
375 case 1:
376 /* Full path */
377 strcpy(dest, src);
378 break;
382 /* Format display line */
383 static void format_line(const struct playlist_entry* track, char* str,
384 int len)
386 char name[MAX_PATH];
387 char *skipped = "";
389 format_name(name, track->name);
391 if (track->skipped)
392 skipped = "(ERR) ";
394 if (global_settings.playlist_viewer_indices)
395 /* Display playlist index */
396 snprintf(str, len, "%d. %s%s", track->display_index, skipped, name);
397 else
398 snprintf(str, len, "%s%s", skipped, name);
402 /* Update playlist in case something has changed or forced */
403 static bool update_playlist(bool force)
405 if (!viewer.playlist)
406 playlist_get_resume_info(&viewer.current_playing_track);
407 else
408 viewer.current_playing_track = -1;
409 int nb_tracks=playlist_amount_ex(viewer.playlist);
410 force=force || nb_tracks != viewer.num_tracks;
411 if (force)
413 /* Reload tracks */
414 viewer.num_tracks = nb_tracks;
415 if (viewer.num_tracks < 0)
416 return false;
417 playlist_buffer_load_entries_screen(&viewer.buffer, FORWARD);
418 if (viewer.buffer.num_loaded <= 0)
419 return false;
421 return true;
424 /* Menu of playlist commands. Invoked via ON+PLAY on main viewer screen.
425 Returns -1 if USB attached, 0 if no playlist change, and 1 if playlist
426 changed. */
427 static int onplay_menu(int index)
429 struct menu_item items[3]; /* increase this if you add entries! */
430 int m, i=0, result, ret = 0;
431 struct playlist_entry * current_track=
432 playlist_buffer_get_track(&viewer.buffer, index);
433 bool current = (current_track->index == viewer.current_playing_track);
435 items[i].desc = ID2P(LANG_REMOVE);
436 i++;
438 items[i].desc = ID2P(LANG_MOVE);
439 i++;
441 items[i].desc = ID2P(LANG_FILE_OPTIONS);
442 i++;
444 m = menu_init(items, i, NULL, NULL, NULL, NULL);
445 result = menu_show(m);
446 if (result == MENU_ATTACHED_USB)
447 ret = -1;
448 else if (result >= 0)
450 /* Abort current move */
451 viewer.move_track = -1;
453 switch (result)
455 case 0:
456 /* delete track */
457 playlist_delete(viewer.playlist, current_track->index);
458 if (current)
460 /* Start playing new track except if it's the last track
461 in the playlist and repeat mode is disabled */
462 current_track=
463 playlist_buffer_get_track(&viewer.buffer, index);
464 if (current_track->display_index != viewer.num_tracks ||
465 global_settings.repeat_mode == REPEAT_ALL)
467 talk_buffer_steal(); /* will use the mp3 buffer */
468 audio_play(0);
469 viewer.current_playing_track = -1;
472 ret = 1;
473 break;
474 case 1:
475 /* move track */
476 viewer.move_track = current_track->index;
477 ret = 0;
478 break;
479 case 2:
481 onplay(current_track->name, TREE_ATTR_MPA, CONTEXT_TREE);
483 if (!viewer.playlist)
484 ret = 1;
485 else
486 ret = 0;
487 break;
491 menu_exit(m);
492 return ret;
495 /* Menu of viewer options. Invoked via F1(r) or Menu(p). */
496 static bool viewer_menu(void)
498 int m;
499 bool result;
501 static const struct menu_item items[] = {
502 { ID2P(LANG_SHOW_ICONS), show_icons },
503 { ID2P(LANG_SHOW_INDICES), show_indices },
504 { ID2P(LANG_TRACK_DISPLAY), track_display },
505 { ID2P(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist },
508 m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
509 NULL, NULL, NULL );
510 result = menu_run(m);
511 menu_exit(m);
513 settings_save();
515 return result;
518 /* Show icons in viewer? */
519 static bool show_icons(void)
521 return set_bool((char *)str(LANG_SHOW_ICONS),
522 &global_settings.playlist_viewer_icons);
525 /* Show indices of tracks? */
526 static bool show_indices(void)
528 return set_bool((char *)str(LANG_SHOW_INDICES),
529 &global_settings.playlist_viewer_indices);
532 /* How to display a track */
533 static bool track_display(void)
535 static const struct opt_items names[] = {
536 { STR(LANG_DISPLAY_TRACK_NAME_ONLY) },
537 { STR(LANG_DISPLAY_FULL_PATH) }
540 return set_option((char *)str(LANG_TRACK_DISPLAY),
541 &global_settings.playlist_viewer_track_display, INT, names, 2,
542 NULL);
545 /* Save playlist to disk */
546 static bool save_playlist(void)
548 save_playlist_screen(viewer.playlist);
549 return false;
552 /* View current playlist */
553 bool playlist_viewer(void)
555 return playlist_viewer_ex(NULL);
558 char * playlist_callback_name(int selected_item, void * data, char *buffer)
560 struct playlist_viewer * local_viewer = (struct playlist_viewer *)data;
561 struct playlist_entry *track=
562 playlist_buffer_get_track(&(local_viewer->buffer), selected_item);
563 format_line(track, buffer, MAX_PATH);
564 return(buffer);
568 void playlist_callback_icons(int selected_item, void * data, ICON * icon)
570 struct playlist_viewer * local_viewer=(struct playlist_viewer *)data;
571 struct playlist_entry *track=
572 playlist_buffer_get_track(&(local_viewer->buffer), selected_item);
573 if (track->index == local_viewer->current_playing_track)
575 /* Current playing track */
576 #ifdef HAVE_LCD_BITMAP
577 *icon=bitmap_icons_6x8[Icon_Audio];
578 #else
579 *icon=Icon_Audio;
580 #endif
582 else if (track->index == local_viewer->move_track)
584 /* Track we are moving */
585 #ifdef HAVE_LCD_BITMAP
586 *icon=bitmap_icons_6x8[Icon_Moving];
587 #else
588 *icon=Icon_Moving;
589 #endif
591 else if (track->queued)
593 /* Queued track */
594 #ifdef HAVE_LCD_BITMAP
595 *icon=bitmap_icons_6x8[Icon_Queued];
596 #else
597 *icon=Icon_Queued;
598 #endif
600 else
601 #ifdef HAVE_LCD_BITMAP
602 *icon=0;
603 #else
604 *icon=-1;
605 #endif
608 /* Main viewer function. Filename identifies playlist to be viewed. If NULL,
609 view current playlist. */
610 bool playlist_viewer_ex(char* filename)
612 bool ret = false; /* return value */
613 bool exit=false; /* exit viewer */
614 int button, lastbutton = BUTTON_NONE;
615 struct gui_synclist playlist_lists;
616 if (!playlist_viewer_init(&viewer, filename, false))
617 goto exit;
619 gui_synclist_init(&playlist_lists, playlist_callback_name, &viewer);
620 gui_synclist_set_icon_callback(&playlist_lists,
621 global_settings.playlist_viewer_icons?
622 &playlist_callback_icons:NULL);
623 gui_synclist_set_nb_items(&playlist_lists, viewer.num_tracks);
624 gui_synclist_select_item(&playlist_lists, viewer.selected_track);
625 gui_synclist_draw(&playlist_lists);
626 while (!exit)
628 int track;
629 if (!viewer.playlist && !(audio_status() & AUDIO_STATUS_PLAY))
631 /* Play has stopped */
632 #ifdef HAVE_LCD_CHARCELLS
633 gui_syncsplash(HZ, true, str(LANG_END_PLAYLIST_PLAYER));
634 #else
635 gui_syncsplash(HZ, true, str(LANG_END_PLAYLIST_RECORDER));
636 #endif
637 goto exit;
640 if (viewer.move_track != -1)
641 gui_synclist_flash(&playlist_lists);
643 if (!viewer.playlist)
644 playlist_get_resume_info(&track);
645 else
646 track = -1;
648 if (track != viewer.current_playing_track ||
649 playlist_amount_ex(viewer.playlist) != viewer.num_tracks)
651 /* Playlist has changed (new track started?) */
652 if (!update_playlist(false))
653 goto exit;
654 gui_synclist_set_nb_items(&playlist_lists, viewer.num_tracks);
655 /* Abort move on playlist change */
656 viewer.move_track = -1;
659 /* Timeout so we can determine if play status has changed */
660 button = button_get_w_tmo(HZ/2);
661 int list_action;
662 if( (list_action=gui_synclist_do_button(&playlist_lists, button))!=0 )
664 viewer.selected_track=gui_synclist_get_sel_pos(&playlist_lists);
665 if(playlist_buffer_needs_reload(&viewer.buffer,
666 viewer.selected_track))
667 playlist_buffer_load_entries_screen(&viewer.buffer,
668 list_action==LIST_NEXT?
669 FORWARD
671 BACKWARD
674 switch (button)
676 case TREE_EXIT:
677 #ifdef TREE_RC_EXIT
678 case TREE_RC_EXIT:
679 #endif
680 #ifdef TREE_OFF
681 case TREE_OFF:
682 #endif
683 exit = true;
684 break;
686 #ifdef TREE_ENTER
687 case TREE_ENTER:
688 case TREE_ENTER | BUTTON_REPEAT:
689 #endif
690 #ifdef TREE_RC_RUN
691 case TREE_RC_RUN:
692 #endif
693 case TREE_RUN:
694 #ifdef TREE_RUN_PRE
695 if (((button == TREE_RUN)
696 #ifdef TREE_RC_RUN_PRE
697 || (button == TREE_RC_RUN))
698 && ((lastbutton != TREE_RC_RUN_PRE)
699 #endif
700 && (lastbutton != TREE_RUN_PRE)))
701 break;
702 #endif
703 struct playlist_entry * current_track =
704 playlist_buffer_get_track(&viewer.buffer,
705 viewer.selected_track);
706 if (viewer.move_track >= 0)
708 /* Move track */
709 int ret;
711 ret = playlist_move(viewer.playlist, viewer.move_track,
712 current_track->index);
713 if (ret < 0)
714 gui_syncsplash(HZ, true, str(LANG_MOVE_FAILED));
716 update_playlist(true);
717 viewer.move_track = -1;
719 else if (!viewer.playlist)
721 /* play new track */
722 playlist_start(current_track->index, 0);
723 update_playlist(false);
725 else
727 /* New playlist */
728 if (playlist_set_current(viewer.playlist) < 0)
729 goto exit;
731 playlist_start(current_track->index, 0);
733 /* Our playlist is now the current list */
734 if (!playlist_viewer_init(&viewer, NULL, true))
735 goto exit;
737 gui_synclist_draw(&playlist_lists);
739 break;
741 case TREE_CONTEXT:
742 #ifdef TREE_CONTEXT2
743 case TREE_CONTEXT2:
744 #endif
745 #ifdef TREE_RC_CONTEXT
746 case TREE_RC_CONTEXT:
747 #endif
749 /* ON+PLAY menu */
750 int ret;
752 ret = onplay_menu(viewer.selected_track);
754 if (ret < 0)
756 ret = true;
757 goto exit;
759 else if (ret > 0)
761 /* Playlist changed */
762 gui_synclist_del_item(&playlist_lists);
763 update_playlist(true);
764 if (viewer.num_tracks <= 0)
765 exit = true;
767 gui_synclist_draw(&playlist_lists);
768 break;
770 #ifdef TREE_MENU_PRE
771 case TREE_MENU_PRE:
772 #else
773 case TREE_MENU:
774 #endif
775 #ifdef TREE_RC_MENU
776 case TREE_RC_MENU:
777 #endif
778 if (viewer_menu())
780 ret = true;
781 goto exit;
783 gui_synclist_set_icon_callback(
784 &playlist_lists,
785 global_settings.playlist_viewer_icons?
786 &playlist_callback_icons:NULL
788 gui_synclist_draw(&playlist_lists);
789 break;
791 case BUTTON_NONE:
792 gui_syncstatusbar_draw(&statusbars, false);
793 break;
795 default:
796 if(default_event_handler(button) == SYS_USB_CONNECTED)
798 ret = true;
799 goto exit;
801 break;
803 lastbutton = button;
806 exit:
807 if (viewer.playlist)
808 playlist_close(viewer.playlist);
809 return ret;
811 char * playlist_search_callback_name(int selected_item, void * data, char *buffer)
813 int *found_indicies = (int*)data;
814 static struct playlist_track_info track;
815 playlist_get_track_info(viewer.playlist,found_indicies[selected_item],&track);
816 format_name(buffer,track.filename);
817 return(buffer);
821 void playlist_search_callback_icons(int selected_item, void * data, ICON * icon)
823 (void)selected_item;
824 (void)data;
825 #ifdef HAVE_LCD_BITMAP
826 *icon=0;
827 #else
828 *icon=-1;
829 #endif
831 bool search_playlist(void)
833 char search_str[32] = "";
834 bool ret = false, exit = false;
835 int i, playlist_count;
836 int found_indicies[MAX_PLAYLIST_ENTRIES],found_indicies_count = 0;
837 int button;
838 struct gui_synclist playlist_lists;
839 struct playlist_track_info track;
841 if (!playlist_viewer_init(&viewer, 0, false))
842 return ret;
843 if (kbd_input(search_str,sizeof(search_str)) == -1)
844 return ret;
845 lcd_clear_display();
846 playlist_count = playlist_amount_ex(viewer.playlist);
847 for (i=0;(i<playlist_count)&&(found_indicies_count<MAX_PLAYLIST_ENTRIES);i++)
849 gui_syncsplash(0, true, str(LANG_PLAYLIST_SEARCH_MSG),found_indicies_count,
850 #if CONFIG_KEYPAD == PLAYER_PAD
851 str(LANG_STOP_ABORT)
852 #else
853 str(LANG_OFF_ABORT)
854 #endif
856 if (SETTINGS_CANCEL == button_get(false))
857 return ret;
858 playlist_get_track_info(viewer.playlist,i,&track);
859 if (strcasestr(track.filename,search_str))
861 found_indicies[found_indicies_count++] = track.index;
864 if (!found_indicies_count)
866 return ret;
868 backlight_on();
869 gui_synclist_init(&playlist_lists, playlist_search_callback_name,
870 found_indicies);
871 gui_synclist_set_icon_callback(&playlist_lists,
872 global_settings.playlist_viewer_icons?
873 &playlist_search_callback_icons:NULL);
874 gui_synclist_set_nb_items(&playlist_lists, found_indicies_count);
875 gui_synclist_select_item(&playlist_lists, 0);
876 gui_synclist_draw(&playlist_lists);
877 while (!exit)
879 button = button_get(true);
880 if (gui_synclist_do_button(&playlist_lists, button))
881 continue;
882 switch (button)
884 case TREE_EXIT:
885 #ifdef TREE_RC_EXIT
886 case TREE_RC_EXIT:
887 #endif
888 #ifdef TREE_OFF
889 case TREE_OFF:
890 #endif
891 exit = true;
892 break;
894 #ifdef TREE_ENTER
895 case TREE_ENTER:
896 case TREE_ENTER | BUTTON_REPEAT:
897 #endif
898 #ifdef TREE_RC_RUN
899 case TREE_RC_RUN:
900 #endif
901 case TREE_RUN:
902 playlist_start(
903 found_indicies[gui_synclist_get_sel_pos(&playlist_lists)]
904 ,0);
905 exit = 1;
906 break;
907 case BUTTON_NONE:
908 break;
909 default:
910 if(default_event_handler(button) == SYS_USB_CONNECTED)
912 ret = true;
913 exit = true;
915 break;
918 return ret;