/* Update playlist in case something has changed or forced */
static bool update_playlist(bool force)
{
    if (!viewer.playlist)
        playlist_get_resume_info(&viewer.current_playing_track);
    else
        viewer.current_playing_track = -1;
    int nb_tracks = playlist_amount_ex(viewer.playlist);
    force = force || nb_tracks != viewer.num_tracks;
    if (force)
    {
        /* Reload tracks */
        viewer.num_tracks = nb_tracks;
        if (viewer.num_tracks <= 0)
        {
            global_status.resume_index = -1;
            global_status.resume_offset = -1;
            return false;
        }
        playlist_buffer_load_entries_screen(&viewer.buffer, FORWARD);
        if (viewer.buffer.num_loaded <= 0)
        {
            global_status.resume_index = -1;
            global_status.resume_offset = -1;
            return false;
        }
    }
    return true;
}
Beispiel #2
0
int playlist_amount(void)
{
    return playlist_amount_ex(NULL);
}
bool search_playlist(void)
{
    char search_str[32] = "";
    bool ret = false, exit = false;
    int i, playlist_count;
    int found_indicies[MAX_PLAYLIST_ENTRIES];
    int found_indicies_count = 0, last_found_count = -1;
    int button;
    struct gui_synclist playlist_lists;
    struct playlist_track_info track;

    if (!playlist_viewer_init(&viewer, 0, false))
        return ret;
    if (kbd_input(search_str, sizeof(search_str)) < 0)
        return ret;
    lcd_clear_display();
    playlist_count = playlist_amount_ex(viewer.playlist);

    cpu_boost(true);

    for (i = 0; i < playlist_count &&
        found_indicies_count < MAX_PLAYLIST_ENTRIES; i++)
    {
        if (found_indicies_count != last_found_count)
        {
            splashf(0, str(LANG_PLAYLIST_SEARCH_MSG), found_indicies_count,
                       str(LANG_OFF_ABORT));
            last_found_count = found_indicies_count;
        }

        if (action_userabort(TIMEOUT_NOBLOCK))
            break;

        playlist_get_track_info(viewer.playlist, i, &track);

        if (strcasestr(track.filename,search_str))
            found_indicies[found_indicies_count++] = track.index;

        yield();
    }

    cpu_boost(false);

    if (!found_indicies_count)
    {
        return ret;
    }
    backlight_on();

    gui_synclist_init(&playlist_lists, playlist_search_callback_name,
                      found_indicies, false, 1, NULL);
    gui_synclist_set_title(&playlist_lists, str(LANG_SEARCH_RESULTS), NOICON);
    gui_synclist_set_icon_callback(&playlist_lists, NULL);
    gui_synclist_set_nb_items(&playlist_lists, found_indicies_count);
    gui_synclist_select_item(&playlist_lists, 0);
    gui_synclist_draw(&playlist_lists);
    while (!exit)
    {
        if (list_do_action(CONTEXT_LIST, HZ/4,
                           &playlist_lists, &button, LIST_WRAP_UNLESS_HELD))
            continue;
        switch (button)
        {
            case ACTION_STD_CANCEL:
                exit = true;
                break;

            case ACTION_STD_OK:
            {
                int sel = gui_synclist_get_sel_pos(&playlist_lists);
                playlist_start(found_indicies[sel], 0);
                exit = 1;
            }
                break;

            default:
                if (default_event_handler(button) == SYS_USB_CONNECTED)
                {
                    ret = true;
                    exit = true;
                }
                break;
        }
    }
    return ret;
}
/* Main viewer function.  Filename identifies playlist to be viewed.  If NULL,
   view current playlist. */
enum playlist_viewer_result playlist_viewer_ex(const char* filename)
{
    enum playlist_viewer_result ret = PLAYLIST_VIEWER_OK;
    bool exit = false;        /* exit viewer */
    int button;
    bool dirty = false;
    struct gui_synclist playlist_lists;
    if (!playlist_viewer_init(&viewer, filename, false))
        goto exit;

    push_current_activity(ACTIVITY_PLAYLISTVIEWER);
    gui_synclist_init(&playlist_lists, playlist_callback_name,
                      &viewer, false, 1, NULL);
    gui_synclist_set_voice_callback(&playlist_lists, playlist_callback_voice);
    gui_synclist_set_icon_callback(&playlist_lists,
                  global_settings.playlist_viewer_icons?
                  &playlist_callback_icons:NULL);
    gui_synclist_set_nb_items(&playlist_lists, viewer.num_tracks);
    gui_synclist_set_title(&playlist_lists, str(LANG_PLAYLIST), Icon_Playlist);
    gui_synclist_select_item(&playlist_lists, viewer.selected_track);
    gui_synclist_draw(&playlist_lists);
    gui_synclist_speak_item(&playlist_lists);
    while (!exit)
    {
        int track;

        if (global_status.resume_index != -1 && !viewer.playlist)
            playlist_get_resume_info(&track);
        else
            track = -1;

        if (track != viewer.current_playing_track ||
            playlist_amount_ex(viewer.playlist) != viewer.num_tracks)
        {
            /* Playlist has changed (new track started?) */
            if (!update_playlist(false))
                goto exit;
            /*Needed because update_playlist gives wrong value when
                                                            playing is stopped*/
            viewer.current_playing_track = track;
            gui_synclist_set_nb_items(&playlist_lists, viewer.num_tracks);

            gui_synclist_draw(&playlist_lists);
        }

        /* Timeout so we can determine if play status has changed */
        bool res = list_do_action(CONTEXT_TREE, HZ/2,
                            &playlist_lists, &button, LIST_WRAP_UNLESS_HELD);
        /* during moving, another redraw is going to be needed,
         * since viewer.selected_track is updated too late (after the first draw)
         * drawing the moving item needs it */
        viewer.selected_track=gui_synclist_get_sel_pos(&playlist_lists);
        if (res)
        {
            bool reload = playlist_buffer_needs_reload(&viewer.buffer,
                    viewer.selected_track);
            if (reload)
                playlist_buffer_load_entries_screen(&viewer.buffer,
                    button == ACTION_STD_NEXT ? FORWARD : BACKWARD);
            if (reload || viewer.moving_track >= 0)
                gui_synclist_draw(&playlist_lists);
        }
        switch (button)
        {
            case ACTION_TREE_WPS:
            case ACTION_STD_CANCEL:
            {
                if (viewer.moving_track >= 0)
                {
                    viewer.selected_track = viewer.moving_track;
                    gui_synclist_select_item(&playlist_lists, viewer.moving_track);
                    viewer.moving_track = -1;
                    viewer.moving_playlist_index = -1;
                    gui_synclist_draw(&playlist_lists);
                }
                else
                {
                    exit = true;
                    ret = PLAYLIST_VIEWER_CANCEL;
                }
                break;
            }
            case ACTION_STD_OK:
            {
                struct playlist_entry * current_track =
                            playlist_buffer_get_track(&viewer.buffer,
                                                      viewer.selected_track);

                if (viewer.moving_track >= 0)
                {
                    /* Move track */
                    int ret_val;

                    ret_val = playlist_move(viewer.playlist,
                                            viewer.moving_playlist_index,
                                            current_track->index);
                    if (ret_val < 0)
                         splashf(HZ, (unsigned char *)"%s %s", str(LANG_MOVE),
                                                               str(LANG_FAILED));
                    update_playlist(true);
                    viewer.moving_track = -1;
                    viewer.moving_playlist_index = -1;
                    dirty = true;
                }
                else if (!viewer.playlist)
                {
                    /* play new track */
                    if (!global_settings.party_mode)
                    {
                        playlist_start(current_track->index, 0);
                        update_playlist(false);
                    }
                }
                else if (!global_settings.party_mode)
                {
                    int start_index = current_track->index;
                    if (!warn_on_pl_erase())
                    {
                        gui_synclist_draw(&playlist_lists);
                        break;
                    }
                    /* New playlist */
                    if (playlist_set_current(viewer.playlist) < 0)
                        goto exit;
                    if (global_settings.playlist_shuffle)
                        start_index = playlist_shuffle(current_tick, start_index);
                    playlist_start(start_index, 0);

                    /* Our playlist is now the current list */
                    if (!playlist_viewer_init(&viewer, NULL, true))
                        goto exit;
                    exit = true;
                }
                gui_synclist_draw(&playlist_lists);

                break;
            }
            case ACTION_STD_CONTEXT:
            {
                /* ON+PLAY menu */
                int ret_val;

                ret_val = onplay_menu(viewer.selected_track);

                if (ret_val < 0)
                {
                    ret = PLAYLIST_VIEWER_USB;
                    goto exit;
                }
                else if (ret_val > 0)
                {
                    /* Playlist changed */
                    gui_synclist_del_item(&playlist_lists);
                    update_playlist(true);
                    if (viewer.num_tracks <= 0)
                        exit = true;
                    if (viewer.selected_track >= viewer.num_tracks)
                        viewer.selected_track = viewer.num_tracks-1;
                    dirty = true;
                }
                gui_synclist_draw(&playlist_lists);
                break;
            }
            case ACTION_STD_MENU:
                ret = PLAYLIST_VIEWER_MAINMENU;
                goto exit;
            default:
                if(default_event_handler(button) == SYS_USB_CONNECTED)
                {
                    ret = PLAYLIST_VIEWER_USB;
                    goto exit;
                }
                break;
        }
    }

exit:
    pop_current_activity();
    if (viewer.playlist)
    {
        if(dirty && yesno_pop(ID2P(LANG_SAVE_CHANGES)))
            save_playlist_screen(viewer.playlist);
        playlist_close(viewer.playlist);
    }
    return ret;
}
/* Menu of playlist commands.  Invoked via ON+PLAY on main viewer screen.
   Returns -1 if USB attached, 0 if no playlist change, and 1 if playlist
   changed. */
static int onplay_menu(int index)
{
    int result, ret = 0;
    struct playlist_entry * current_track =
        playlist_buffer_get_track(&viewer.buffer, index);
    MENUITEM_STRINGLIST(menu_items, ID2P(LANG_PLAYLIST), NULL, 
                        ID2P(LANG_CURRENT_PLAYLIST), ID2P(LANG_CATALOG),
                        ID2P(LANG_REMOVE), ID2P(LANG_MOVE), ID2P(LANG_SHUFFLE),
                        ID2P(LANG_SAVE_DYNAMIC_PLAYLIST));
    bool current = (current_track->index == viewer.current_playing_track);

    result = do_menu(&menu_items, NULL, NULL, false);
    if (result == MENU_ATTACHED_USB)
    {
        ret = -1;
    }
    else if (result >= 0)
    {
        /* Abort current move */
        viewer.moving_track = -1;
        viewer.moving_playlist_index = -1;

        switch (result)
        {
            case 0:
                /* playlist */
                onplay_show_playlist_menu(current_track->name);
                ret = 0;
                break;
            case 1:
                /* add to catalog */
                onplay_show_playlist_cat_menu(current_track->name);
                ret = 0;
                break;
            case 2:
                /* delete track */
                playlist_delete(viewer.playlist, current_track->index);
                if (current)
                {
                    if (playlist_amount_ex(viewer.playlist) <= 0)
                        audio_stop();
                    else
                    {
                       /* Start playing new track except if it's the lasttrack
                          track in the playlist and repeat mode is disabled */
                        current_track =
                            playlist_buffer_get_track(&viewer.buffer, index);
                        if (current_track->display_index!=viewer.num_tracks ||
                            global_settings.repeat_mode == REPEAT_ALL)
                        {
                            audio_play(0);
                            viewer.current_playing_track = -1;
                        }
                    }
                }
                ret = 1;
                break;
            case 3:
                /* move track */
                viewer.moving_track = index;
                viewer.moving_playlist_index = current_track->index;
                ret = 0;
                break;
            case 4:
                /* shuffle */
                playlist_randomise(viewer.playlist, current_tick, false);
                ret = 1;
                break;
            case 5:
                /* save playlist */
                save_playlist_screen(viewer.playlist);
                ret = 0;
                break;
        }
    }
    return ret;
}
Beispiel #6
0
/* Menu of playlist commands.  Invoked via ON+PLAY on main viewer screen.
   Returns -1 if USB attached, 0 if no playlist change, and 1 if playlist
   changed. */
static int onplay_menu(int index)
{
    int result, ret = 0;
    struct playlist_entry * current_track=
        playlist_buffer_get_track(&viewer.buffer, index);
    MENUITEM_STRINGLIST(menu_items, ID2P(LANG_PLAYLIST), NULL, 
                        ID2P(LANG_REMOVE), ID2P(LANG_MOVE),
                        ID2P(LANG_CATALOG_ADD_TO), ID2P(LANG_CATALOG_ADD_TO_NEW),
                        ID2P(LANG_PLAYLISTVIEWER_SETTINGS));
    bool current = (current_track->index == viewer.current_playing_track);

    result = do_menu(&menu_items, NULL, NULL, false);
    if (result == MENU_ATTACHED_USB)
    {
        ret = -1;
    }
    else if (result >= 0)
    {
        /* Abort current move */
        viewer.moving_track = -1;
        viewer.moving_playlist_index = -1;

        switch (result)
        {
            case 0:
                /* delete track */
                playlist_delete(viewer.playlist, current_track->index);
                if (current)
                {
                    if (playlist_amount_ex(viewer.playlist) <= 0)
                        audio_stop();
                    else
                    {
                       /* Start playing new track except if it's the lasttrack
                          track in the playlist and repeat mode is disabled */
                        current_track =
                            playlist_buffer_get_track(&viewer.buffer, index);
                        if (current_track->display_index!=viewer.num_tracks ||
                            global_settings.repeat_mode == REPEAT_ALL)
                        {
#if CONFIG_CODEC != SWCODEC
                            talk_buffer_steal(); /* will use the mp3 buffer */
#endif
                            audio_play(0);
                            viewer.current_playing_track = -1;
                        }
                    }
                }
                ret = 1;
                break;
            case 1:
                /* move track */
                viewer.moving_track = index;
                viewer.moving_playlist_index = current_track->index;
                ret = 0;
                break;
            case 2: /* add to catalog */
            case 3: /* add to a new one */
                catalog_add_to_a_playlist(current_track->name,
                                          FILE_ATTR_AUDIO,
                                          result==3, NULL);
                ret = 0;
                break;
            case 4: /* playlist viewer settings */
                /* true on usb connect */
                ret = viewer_menu() ? -1 : 0;
                break;
        }
    }
    return ret;
}