diff -u -r -N rockbox-3.4_orig/apps/plugins/CATEGORIES rockbox-3.4/apps/plugins/CATEGORIES --- rockbox-3.4_orig/apps/plugins/CATEGORIES 2009-09-24 09:13:34.000000000 +0100 +++ rockbox-3.4/apps/plugins/CATEGORIES 2009-11-27 21:51:40.000000000 +0000 @@ -77,6 +77,7 @@ search,viewers searchengine,viewers settings_dumper,apps +shopper,apps shortcuts_append,viewers shortcuts_view,viewers sliding_puzzle,games diff -u -r -N rockbox-3.4_orig/apps/plugins/SOURCES rockbox-3.4/apps/plugins/SOURCES --- rockbox-3.4_orig/apps/plugins/SOURCES 2009-09-24 09:13:34.000000000 +0100 +++ rockbox-3.4/apps/plugins/SOURCES 2009-11-27 21:51:40.000000000 +0000 @@ -59,6 +59,7 @@ brickmania.c maze.c mazezam.c +shopper.c text_editor.c wavview.c robotfindskitten.c diff -u -r -N rockbox-3.4_orig/apps/plugins/shopper.c rockbox-3.4/apps/plugins/shopper.c --- rockbox-3.4_orig/apps/plugins/shopper.c 1970-01-01 00:00:00.000000000 +0000 +++ rockbox-3.4/apps/plugins/shopper.c 2009-11-28 09:36:08.421875000 +0000 @@ -0,0 +1,384 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: + * + * Copyright (C) 2009 Daniel Rigby + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "plugin.h" +#include "lib/playback_control.h" + +PLUGIN_HEADER + +#define MAX_LIST_SIZE 400 +#define DESC_SIZE 40 +#define MAX_LINE_LEN (DESC_SIZE + 1) + +typedef enum flag_type {FL_CLEARED, FL_SET, FL_CATEGORY} flag_type; +typedef enum view_type {EDIT_SHOPPING_LIST, VIEW_SHOPPING_LIST} view_type; +typedef struct items_list_s { + unsigned int id; + flag_type flag; + char desc[DESC_SIZE]; +} items_list_s; +#define ITEM_SIZE sizeof items_list_s; + +static items_list_s items_list[MAX_LIST_SIZE]; +static int total_item_count = 0; +static int view_id_list[MAX_LIST_SIZE]; +static int view_item_count; +static view_type view = EDIT_SHOPPING_LIST; +static char filename[MAX_PATH]; +static bool changed = false; +static bool show_categories = true; +static char category_string[] = "Hide categories"; + +static const char *list_get_name_cb(int selected_item, void* data, + char* buf, size_t buf_len) { + (void)data; + rb->strlcpy(buf, items_list[view_id_list[selected_item]].desc, buf_len); + return buf; +} + +static enum themable_icons list_get_icon_cb(int selected_item, void *data) { + (void)data; + if (items_list[view_id_list[selected_item]].flag == FL_CATEGORY) + return Icon_Rockbox; + else if (items_list[view_id_list[selected_item]].flag == FL_SET) + return Icon_Cursor; + else + return Icon_NOICON; +} + +bool save_changes(void) { + int fd; + int i; + + fd = rb->open(filename,O_WRONLY|O_CREAT|O_TRUNC); + if (fd < 0) { + rb->splash(HZ*2, "Changes NOT saved"); + return false; + } + + rb->lcd_clear_display(); +#ifdef HAVE_ADJUSTABLE_CPU_FREQ + rb->cpu_boost(1); +#endif + for (i = 0;i < total_item_count; i++) { + switch (items_list[i].flag) { + case FL_CATEGORY: + rb->fdprintf(fd,"#%s\n",items_list[i].desc); + break; + case FL_SET: + rb->fdprintf(fd,"!%s\n",items_list[i].desc); + break; + case FL_CLEARED: + rb->fdprintf(fd," %s\n",items_list[i].desc); + break; + } + } + /* save current view */ + rb->fdprintf(fd,"$%d%d\n",view, show_categories); + +#ifdef HAVE_ADJUSTABLE_CPU_FREQ + rb->cpu_boost(0); +#endif + rb->close(fd); + + return true; +} + +enum { + MENU_RET_SAVE = -1, + MENU_RET_NO_UPDATE, + MENU_RET_UPDATE, +}; + +void create_view(struct gui_synclist *lists) { + unsigned int cnt = 0; + int i, j; + + switch (view) { + case EDIT_SHOPPING_LIST: { + for (i = 0; i < total_item_count; i++) { + if (show_categories || (items_list[i].flag != FL_CATEGORY)) + view_id_list[cnt++] = i; + } + view_item_count = cnt; + rb->gui_synclist_set_title(lists,"Select items",Icon_Playlist); + break; + } + case VIEW_SHOPPING_LIST: { + for (i = 0; i < total_item_count; i++) { + if ((items_list[i].flag == FL_CATEGORY) && show_categories) { + for (j = i+1; j < total_item_count; j++) { + if (items_list[j].flag == FL_SET) { + view_id_list[cnt++] = i; + break; + } + if (items_list[j].flag == FL_CATEGORY) + break; + } + } else if (items_list[i].flag == FL_SET) { + view_id_list[cnt++] = i; + } + } + view_item_count = cnt; + rb->gui_synclist_set_title(lists,"Shopping list",Icon_Playlist); + break; + } + } +} + +bool toggle(int selected_item) { + if (items_list[view_id_list[selected_item]].flag == FL_CATEGORY) + return false; + else if (items_list[view_id_list[selected_item]].flag == FL_SET) + items_list[view_id_list[selected_item]].flag = FL_CLEARED; + else + items_list[view_id_list[selected_item]].flag = FL_SET; + return true; +} + +void update_category_string(void) { + if (show_categories) { + rb->strcpy(category_string,"Hide categories"); + } else { + rb->strcpy(category_string,"Show categories"); + } +} + +enum plugin_status load_file(void) { + int fd; + static char temp_line[DESC_SIZE]; + static items_list_s new_item; + static int count = 0; + int linelen; + total_item_count = 0; + + fd = rb->open(filename,O_RDONLY); + if (fd<0) { + rb->splashf(HZ*2,"Couldn't open file: %s",filename); + return PLUGIN_ERROR; + } + + /* read in the file */ + while (rb->read_line(fd,temp_line,MAX_LINE_LEN)) { + if (rb->strncmp(temp_line, "$", 1) == 0) { + /* read view preferences */ + linelen = rb->strlen(temp_line); + if (linelen >= 2) { + view = temp_line[1] - '0'; + } + if (linelen >= 3) { + show_categories = ((temp_line[2] - '0') > 0); + update_category_string(); + } + } else { + new_item.id = count; + if (rb->strncmp(temp_line, " ", 1) == 0) { + /* read description, flag = cleared */ + new_item.flag = FL_CLEARED; + rb->memcpy(new_item.desc, &temp_line[1], DESC_SIZE); + } else if (rb->strncmp(temp_line, "!", 1) == 0) { + /* read description, flag = set */ + new_item.flag = FL_SET; + rb->memcpy(new_item.desc, &temp_line[1], DESC_SIZE); + } else if (rb->strncmp(temp_line, "#", 1) == 0) { + /* read description, flag = category */ + new_item.flag = FL_CATEGORY; + rb->memcpy(new_item.desc, &temp_line[1], DESC_SIZE); + } else { + /* read description, flag = cleared */ + new_item.flag = FL_CLEARED; + rb->memcpy(new_item.desc, temp_line, DESC_SIZE); + } + items_list[total_item_count] = new_item; + total_item_count++; + } + } + rb->close(fd); + changed = false; + return PLUGIN_OK; +} + +/* this is the plugin entry point */ +enum plugin_status plugin_start(const void* parameter) { + struct gui_synclist lists; + bool exit = false; + int button; + int cur_sel=0; + static char copy_buffer[MAX_LINE_LEN]; + copy_buffer[0]='\0'; + +#if LCD_DEPTH > 1 + rb->lcd_set_backdrop(NULL); +#endif + +#ifdef HAVE_ADJUSTABLE_CPU_FREQ + rb->cpu_boost(1); +#endif + if (parameter) { + rb->strcpy(filename,(char*)parameter); + + if (load_file() == PLUGIN_ERROR) + return PLUGIN_ERROR; + } else { + return PLUGIN_ERROR; + } +#ifdef HAVE_ADJUSTABLE_CPU_FREQ + rb->cpu_boost(0); +#endif + /* now dump it in the list */ + rb->gui_synclist_init(&lists,list_get_name_cb,0, false, 1, NULL); + rb->gui_synclist_set_icon_callback(&lists, list_get_icon_cb); + rb->gui_synclist_limit_scroll(&lists,true); + create_view(&lists); + rb->gui_synclist_set_nb_items(&lists,view_item_count); + rb->gui_synclist_select_item(&lists, 0); + rb->gui_synclist_draw(&lists); + rb->lcd_update(); + + while (!exit) { + rb->gui_synclist_draw(&lists); + cur_sel = rb->gui_synclist_get_sel_pos(&lists); + button = rb->get_action(CONTEXT_LIST,TIMEOUT_BLOCK); + if (rb->gui_synclist_do_button(&lists,&button,LIST_WRAP_UNLESS_HELD)) + continue; + switch (button) { + case ACTION_STD_CONTEXT: + case ACTION_STD_OK: { + changed |= toggle(cur_sel); + break; + } + case ACTION_STD_MENU: { + switch(view) + { + case EDIT_SHOPPING_LIST: { + MENUITEM_STRINGLIST(menu, "Options", NULL, + "View shopping list", + "Clear all items", + "Mark all items", + category_string, + "Revert to saved", + "Show Playback Menu",); + + switch (rb->do_menu(&menu, NULL, NULL, false)) { + case 0: { /* view shopping list */ + view = VIEW_SHOPPING_LIST; + changed = true; + break; + } + case 1: { /* clear all items */ + int i; + for (i = 0; i < total_item_count; i++) { + if (items_list[i].flag == FL_SET) { + items_list[i].flag = FL_CLEARED; + } + } + changed = true; + break; + } + case 2: { /* mark all items */ + int i; + for (i = 0; i < total_item_count; i++) { + if (items_list[i].flag == FL_CLEARED) { + items_list[i].flag = FL_SET; + } + } + changed = true; + break; + } + case 3: { /* toggle categories */ + show_categories ^= true; + update_category_string(); + changed = true; + break; + } + case 4: /* revert to saved */ + if (load_file() == PLUGIN_ERROR) + return PLUGIN_ERROR; + break; + case 5: /* playback menu */ + playback_control(NULL); + break; + default: + break; + + } + break; + } + + case VIEW_SHOPPING_LIST: { + MENUITEM_STRINGLIST(menu, "Options", NULL, + "Edit list", + "Reset list", + category_string, + "Revert to saved", + "Show Playback Menu",); + + switch (rb->do_menu(&menu, NULL, NULL, false)) { + case 0: { /* edit list */ + view = EDIT_SHOPPING_LIST; + changed = true; + break; + } + case 1: { /* reset list */ + int i; + for (i = 0; i < total_item_count; i++) { + if (items_list[i].flag == FL_SET) { + items_list[i].flag = FL_CLEARED; + } + } + view = EDIT_SHOPPING_LIST; + changed = true; + break; + } + case 2: { /* toggle categories */ + show_categories ^= true; + update_category_string(); + changed = true; + break; + } + case 3: /* revert to saved */ + if (load_file() == PLUGIN_ERROR) + return PLUGIN_ERROR; + break; + case 4: /* playback menu */ + playback_control(NULL); + break; + default: + break; + } + break; + } + } + } + break; + case ACTION_STD_CANCEL: + if (changed) + save_changes(); + exit = 1; + break; + } + + create_view(&lists); + rb->gui_synclist_set_nb_items(&lists,view_item_count); + if (view_item_count > 0 && view_item_count <= cur_sel) + rb->gui_synclist_select_item(&lists,view_item_count-1); + } + return PLUGIN_OK; +} diff -u -r -N rockbox-3.4_orig/apps/plugins/viewers.config rockbox-3.4/apps/plugins/viewers.config --- rockbox-3.4_orig/apps/plugins/viewers.config 2009-09-24 09:13:37.000000000 +0100 +++ rockbox-3.4/apps/plugins/viewers.config 2009-11-27 21:51:40.015625000 +0000 @@ -58,3 +58,4 @@ *,viewers/shortcuts_append,- *,apps/md5sum,- lua,viewers/lua,- +list,viewers/shopper,1