Index: apps/plugins/CATEGORIES =================================================================== --- apps/plugins/CATEGORIES (revision 16180) +++ apps/plugins/CATEGORIES (working copy) @@ -50,6 +50,7 @@ pacbox,games pictureflow,demos plasma,demos +playlist_editor,apps pong,games properties,viewers random_folder_advance_config,apps Index: apps/plugins/viewers.config =================================================================== --- apps/plugins/viewers.config (revision 16180) +++ apps/plugins/viewers.config (working copy) @@ -8,6 +8,8 @@ ucl,viewers/rockbox_flash,3 rvf,viewers/video,4 mp3,viewers/vbrfix,5 +m3u,apps/playlist_editor,- +m3u8,apps/playlist_editor,- m3u,viewers/search,- txt,viewers/sort,- gb,viewers/rockboy,6 Index: apps/plugins/playlist_editor.c =================================================================== --- apps/plugins/playlist_editor.c (revision 0) +++ apps/plugins/playlist_editor.c (revision 0) @@ -0,0 +1,235 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: helloworld.c 12807 2007-03-16 21:56:08Z amiconn $ + * + * Copyright (C) 2008 Jonathan Gordon + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "plugin.h" +PLUGIN_HEADER + +#define MAX_TRACKS 4096 + +static struct plugin_api* rb; +char *text_buffer, *trackorder[MAX_TRACKS]; +size_t buf_remaining = 0; +int track_count; +char *filename; +bool modified = false; +struct simplelist_info list_info; + +int list_action_callback(int action, struct gui_synclist *lists); +char * list_name_callback(int selected_item, void * data, char * buffer); +//enum themable_icons list_get_icon(int selected_item, void * data); + +bool init(bool use_audio_buffer) +{ + if (use_audio_buffer == false) + text_buffer = rb->plugin_get_buffer(&buf_remaining); + else + text_buffer = rb->plugin_get_audio_buffer(&buf_remaining); + track_count = 0; + + rb->simplelist_info_init(&list_info, filename, 0, NULL); + list_info.action_callback = list_action_callback; + list_info.get_icon = NULL;//list_get_icon; + list_info.get_name = list_name_callback; + list_info.timeout = TIMEOUT_BLOCK; + + return true; +} + +/* playlist file handling */ +bool read_m3u(const char *filename) +{ + char buf[MAX_PATH]; + int fd = rb->open(filename, O_RDONLY), len, read; + if (fd < 0) + return false; + while (buf_remaining >MAX_PATH && + track_count < MAX_TRACKS && + (read = rb->read_line(fd, buf, MAX_PATH))) + { + if (buf[0] == '#') /* ignore # lines for now */ + continue; + else if (buf[0] == ' ') + continue; + len = rb->strlen(buf); + rb->strncpy(text_buffer, buf, len); + trackorder[track_count++] = text_buffer; + len++; + text_buffer += len; + buf_remaining -= len; + } + if (read != 0) + { + rb->splash(HZ, "Too many tracks (read %d)", track_count); + } + rb->close(fd); + return true; +} + +bool write_m3u(const char *filename) +{ + int fd = rb->open(filename, O_CREAT|O_WRONLY|O_TRUNC); + int i; + bool m3u8 = filename[rb->strlen(filename)-1] == '8'; + if (fd < 0) + return false; + for(i=0;ifdprintf(fd, "%s\n", trackorder[i]); + } + rb->close(fd); + return true; +} + + +/* list and playlist manipulation */ +int moving_item = -1; +struct gui_synclist *infolists = NULL; /* needed so we know if the current selection is the moving track */ +int list_action_callback(int action, struct gui_synclist *lists) +{ + infolists = lists; + if (action == ACTION_STD_OK) + { + if (moving_item == -1) + { + moving_item = rb->gui_synclist_get_sel_pos(lists); + } + else + { + move_item(moving_item, rb->gui_synclist_get_sel_pos(lists)); + moving_item = -1; + modified = true; + return ACTION_REDRAW; + } + } + else if (action == ACTION_STD_CANCEL) + { + if (moving_item == -1) + { + int ret = 0; + MENUITEM_STRINGLIST(menu, "Playlist Editor", NULL, + "Return to editor", "Save and Exit", "Exit (ignore changes)",); + + switch (rb->do_menu(&menu, NULL)) + { + case 0: + break; + case 1: + { + char buf[MAX_PATH]; + rb->strcpy(buf, filename); + if (rb->kbd_input(buf, MAX_PATH)) + { + if (!write_m3u(buf)) + { + rb->splash(HZ, "Error writing m3u to %s", buf); + } + else + return action; + } + break; + } + case 2: + return action; + } + return ACTION_REDRAW; + } + else + { + rb->gui_synclist_select_item(lists, moving_item); + moving_item = -1; + return ACTION_REDRAW; + } + } + else if (action == ACTION_STD_MENU) + { + int sel = rb->gui_synclist_get_sel_pos(lists); + modified = true; + remove_item(sel); + rb->gui_synclist_set_nb_items(lists, track_count); + return ACTION_REDRAW; + } + return action; +} + +char * list_name_callback(int item, void * data, char * buffer) +{ + (void)data; (void)buffer; + int selection = rb->gui_synclist_get_sel_pos(infolists); + + if (moving_item == -1) + return trackorder[item]; + else if (item == selection) + return trackorder[moving_item]; + else if (selection - moving_item > 0) /* moving down the list */ + { + if (item < moving_item || + item > selection) + return trackorder[item]; + else return trackorder[item+1]; + } + else /*if (distance < 0)*/ /* moving up the list */ + { + if (item > moving_item || + item < selection) + return trackorder[item]; + else return trackorder[item-1]; + } +} + +/* moves an item from index "from" to index "to" */ +void move_item(int from, int to) +{ + char *temp; + int i; + temp = trackorder[from]; + if (to < from) + { + for (i=from;i>to;i--) + trackorder[i] = trackorder[i-1]; + } + else + { + for (i=from;isplash(HZ*2, "Playlist editor must be started from the Open With menu"); + return PLUGIN_OK; + } + init(false); + if (read_m3u(filename) == false) + return PLUGIN_ERROR; + list_info.count = track_count; + rb->simplelist_show_list(&list_info); + return PLUGIN_OK; +} Index: apps/plugins/SOURCES =================================================================== --- apps/plugins/SOURCES (revision 16180) +++ apps/plugins/SOURCES (working copy) @@ -21,6 +21,7 @@ stopwatch.c vbrfix.c viewer.c +playlist_editor.c #ifdef OLYMPUS_MROBE_500 /* remove these once the plugins before it are compileable */ Index: apps/plugin.c =================================================================== --- apps/plugin.c (revision 16180) +++ apps/plugin.c (working copy) @@ -587,6 +587,8 @@ sound_unit, sound_val2phys, #endif /* CONFIG_CODEC == SWCODEC */ + simplelist_info_init, + simplelist_show_list }; int plugin_load(const char* plugin, void* parameter) Index: apps/plugin.h =================================================================== --- apps/plugin.h (revision 16180) +++ apps/plugin.h (working copy) @@ -724,6 +724,9 @@ const char * (*sound_unit)(int setting); int (*sound_val2phys)(int setting, int value); #endif /* CONFIG_CODEC == SWCODEC */ + void (*simplelist_info_init)(struct simplelist_info *info, char* title, + int count, void* data); + bool (*simplelist_show_list)(struct simplelist_info *info); }; /* plugin header */