Index: apps/action.h =================================================================== --- apps/action.h (revision 25310) +++ apps/action.h (working copy) @@ -92,6 +92,7 @@ ACTION_REDRAW, /* returned if keys are locked and we splash()'ed */ ACTION_TOUCHSCREEN, ACTION_TOUCHSCREEN_MODE, /* toggle the touchscreen mode */ + ACTION_HOTKEY, /* standard actions, use these first */ ACTION_STD_PREV, Index: apps/tree.c =================================================================== --- apps/tree.c (revision 25310) +++ apps/tree.c (working copy) @@ -756,13 +756,15 @@ break; #endif + case ACTION_HOTKEY: case ACTION_STD_CONTEXT: { + bool hotkey = button == ACTION_HOTKEY; int onplay_result; int attr = 0; if(!numentries) - onplay_result = onplay(NULL, 0, curr_context); + onplay_result = onplay(NULL, 0, curr_context, hotkey); else { #ifdef HAVE_TAGCACHE if (id3db) @@ -788,7 +790,7 @@ snprintf(buf, sizeof buf, "/%s", dircache[tc.selected_item].name); } - onplay_result = onplay(buf, attr, curr_context); + onplay_result = onplay(buf, attr, curr_context, hotkey); } switch (onplay_result) { Index: apps/lang/english.lang =================================================================== --- apps/lang/english.lang (revision 25310) +++ apps/lang/english.lang (working copy) @@ -13394,3 +13394,37 @@ lineout_poweroff: "Line Out" + + id: LANG_SET_HOTKEY + desc: hotkey splash + user: core + + *: none + hotkey: "Set Hotkey: %s" + + + *: none + hotkey: "Set Hotkey: %s" + + + *: none + hotkey: "Set Hotkey: %s" + + + + id: LANG_HOTKEY_NOT_SET + desc: hotkey splash + user: core + + *: none + hotkey: "Hotkey Not Set" + + + *: none + hotkey: "Hotkey Not Set" + + + *: none + hotkey: "Hotkey Not Set" + + Index: apps/onplay.c =================================================================== --- apps/onplay.c (revision 25310) +++ apps/onplay.c (working copy) @@ -73,6 +73,20 @@ static int clipboard_selection_attr = 0; static bool clipboard_is_copy = false; +/* hotkey settings */ +#ifdef HOTKEY +extern const struct menu_item_ex *selected_menu_item; +extern bool hotkey_settable_menu; + +enum { + HOTKEY_OFF = 0, + HOTKEY_VIEW_PLAYLIST = 1, + HOTKEY_DELETE, + HOTKEY_INSERT, + HOTKEY_PITCHSCREEN, +}; +#endif + /* redefine MAKE_MENU so the MENU_EXITAFTERTHISMENU flag can be added easily */ #define MAKE_ONPLAYMENU( name, str, callback, icon, ... ) \ static const struct menu_item_ex *name##_[] = {__VA_ARGS__}; \ @@ -1176,23 +1190,112 @@ break; case ACTION_EXIT_MENUITEM: return ACTION_EXIT_AFTER_THIS_MENUITEM; - break; } return action; } -int onplay(char* file, int attr, int from) + +#ifdef HOTKEY +static int execute_hotkey(int context) { + if (context == CONTEXT_WPS) /* WPS view */ + { + switch (global_settings.hotkey_wps) + { + case HOTKEY_VIEW_PLAYLIST: + return ONPLAY_PLAYLIST; +#ifdef HAVE_PITCHSCREEN + case HOTKEY_PITCHSCREEN: + gui_syncpitchscreen_run(); + return ONPLAY_RELOAD_DIR; +#endif + default: + splash(HZ, ID2P(LANG_HOTKEY_NOT_SET)); + return ONPLAY_RELOAD_DIR; + } + } + else /* tree view */ + { + switch (global_settings.hotkey_tree) + { + case HOTKEY_DELETE: + delete_handler(selected_file_attr & ATTR_DIRECTORY); + return ONPLAY_RELOAD_DIR; + case HOTKEY_INSERT: + playlist_insert_func((intptr_t*)PLAYLIST_INSERT); + return ONPLAY_START_PLAY; + default: + splash(HZ, ID2P(LANG_HOTKEY_NOT_SET)); + return ONPLAY_RELOAD_DIR; + } + } +} + +static void set_hotkey(int context) +{ + bool hotkey_set = true; + if (context == CONTEXT_WPS) /* WPS view */ + { + if (selected_menu_item == &view_cur_playlist) + global_settings.hotkey_wps = HOTKEY_VIEW_PLAYLIST; +#ifdef HAVE_PITCHSCREEN + else if(selected_menu_item == &pitch_screen_item) + global_settings.hotkey_wps = HOTKEY_PITCHSCREEN; +#endif + else + { + hotkey_set = false; + global_settings.hotkey_wps = HOTKEY_OFF; + } + } + else /* tree view */ + { + if ((selected_menu_item == &delete_file_item) || + (selected_menu_item == &delete_dir_item)) + global_settings.hotkey_tree = HOTKEY_DELETE; + else if (selected_menu_item == &i_pl_item) + global_settings.hotkey_tree = HOTKEY_INSERT; + else + { + hotkey_set = false; + global_settings.hotkey_tree = HOTKEY_OFF; + } + } + settings_save(); + if (hotkey_set) + splashf(HZ*2, str(LANG_SET_HOTKEY), + P2STR((selected_menu_item->callback_and_desc)->desc)); + else + splashf(HZ*2, str(LANG_SET_HOTKEY), + str(LANG_OFF)); +} +#endif + +int onplay(char* file, int attr, int from, bool hotkey) +{ const struct menu_item_ex *menu; onplay_result = ONPLAY_OK; context = from; selected_file = file; selected_file_attr = attr; +#ifdef HOTKEY + if (hotkey) + return execute_hotkey(context); + hotkey_settable_menu = true; +#else + (void)hotkey; +#endif if (context == CONTEXT_WPS) menu = &wps_onplay_menu; else menu = &tree_onplay_menu; switch (do_menu(menu, NULL, NULL, false)) { +#ifdef HOTKEY + hotkey_settable_menu = false; + case MENU_SELECTED_HOTKEY: + set_hotkey(context); + return ONPLAY_RELOAD_DIR; +#endif case GO_TO_WPS: return ONPLAY_START_PLAY; case GO_TO_ROOT: Index: apps/gui/wps.c =================================================================== --- apps/gui/wps.c (revision 25310) +++ apps/gui/wps.c (working copy) @@ -887,11 +887,13 @@ #endif switch(button) { + case ACTION_HOTKEY: case ACTION_WPS_CONTEXT: { + bool hotkey = button == ACTION_HOTKEY; gwps_leave_wps(); int retval = onplay(wps_state.id3->path, - FILE_ATTR_AUDIO, CONTEXT_WPS); + FILE_ATTR_AUDIO, CONTEXT_WPS, hotkey); /* if music is stopped in the context menu we want to exit the wps */ if (retval == ONPLAY_MAINMENU || !audio_status()) @@ -1182,10 +1184,12 @@ case SYS_POWEROFF: default_event_handler(SYS_POWEROFF); break; +#ifndef HOTKEY case ACTION_WPS_VIEW_PLAYLIST: gwps_leave_wps(); return GO_TO_PLAYLIST_VIEWER; break; +#endif default: if(default_event_handler(button) == SYS_USB_CONNECTED) { Index: apps/menu.c =================================================================== --- apps/menu.c (revision 25310) +++ apps/menu.c (working copy) @@ -61,6 +61,12 @@ #include "list.h" #include "buttonbar.h" +/* hotkey settings */ +#ifdef HOTKEY +const struct menu_item_ex *selected_menu_item; +bool hotkey_settable_menu = false; +#endif + #define MAX_MENUS 8 /* used to allow for dynamic menus */ #define MAX_MENU_SUBITEMS 64 @@ -426,6 +432,15 @@ done = true; } #endif +#ifdef HOTKEY + else if ((action == ACTION_HOTKEY) && hotkey_settable_menu) + { + ret = MENU_SELECTED_HOTKEY; + done = true; + selected = get_menu_selection(gui_synclist_get_sel_pos(&lists),menu); + selected_menu_item = menu->submenus[selected]; + } +#endif else if (action == ACTION_TREE_WPS) { ret = GO_TO_PREVIOUS_MUSIC; Index: apps/settings.h =================================================================== --- apps/settings.h (revision 25310) +++ apps/settings.h (working copy) @@ -816,6 +816,11 @@ bool morse_input; /* text input method setting */ #endif +#ifdef HOTKEY + int hotkey_tree; + int hotkey_wps; +#endif + }; /** global variables **/ Index: apps/onplay.h =================================================================== --- apps/onplay.h (revision 25310) +++ apps/onplay.h (working copy) @@ -21,7 +21,7 @@ #ifndef _ONPLAY_H_ #define _ONPLAY_H_ -int onplay(char* file, int attr, int from_screen); +int onplay(char* file, int attr, int from_screen, bool hotkey); enum { ONPLAY_MAINMENU = -1, Index: apps/settings_list.c =================================================================== --- apps/settings_list.c (revision 25310) +++ apps/settings_list.c (working copy) @@ -1660,6 +1660,11 @@ #ifdef HAVE_MORSE_INPUT OFFON_SETTING(0, morse_input, LANG_MORSE_INPUT, false, "morse input", NULL), #endif + +#ifdef HOTKEY + CHOICE_SETTING(0, hotkey_tree, 0, 0, "hotkey tree", 0, NULL, 0), + CHOICE_SETTING(0, hotkey_wps, 1, 0, "hotkey wps", 0, NULL, 0), +#endif }; const int nb_settings = sizeof(settings)/sizeof(*settings); Index: apps/features.txt =================================================================== --- apps/features.txt (revision 25310) +++ apps/features.txt (working copy) @@ -70,6 +70,10 @@ remote_button_hold #endif +#if defined(HOTKEY) +hotkey +#endif + #if defined(HAVE_LCD_BITMAP) lcd_bitmap #endif Index: apps/bookmark.c =================================================================== --- apps/bookmark.c (revision 25310) +++ apps/bookmark.c (working copy) @@ -728,7 +728,12 @@ ID2P(LANG_BOOKMARK_CONTEXT_DELETE)); static const int menu_actions[] = { - ACTION_STD_OK, ACTION_BMS_DELETE + ACTION_STD_OK, +#ifdef HOTKEY + ACTION_HOTKEY +#else + ACTION_BMS_DELETE +#endif }; int selection = do_menu(&menu_items, NULL, NULL, false); @@ -757,7 +762,11 @@ exit = true; break; +#ifdef HOTKEY + case ACTION_HOTKEY: +#else case ACTION_BMS_DELETE: +#endif if (item >= 0) { const char *lines[]={ Index: apps/root_menu.h =================================================================== --- apps/root_menu.h (revision 25310) +++ apps/root_menu.h (working copy) @@ -53,6 +53,9 @@ GO_TO_BROWSEPLUGINS, GO_TO_TIMESCREEN, GO_TO_PLAYLIST_VIEWER, +#ifdef HOTKEY + MENU_SELECTED_HOTKEY, +#endif }; extern const struct menu_item_ex root_menu_; Index: apps/keymaps/keymap-e200.c =================================================================== --- apps/keymaps/keymap-e200.c (revision 25310) +++ apps/keymaps/keymap-e200.c (working copy) @@ -80,11 +80,11 @@ { ACTION_WPS_QUICKSCREEN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_DOWN }, { ACTION_WPS_MENU, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN }, - { ACTION_WPS_VIEW_PLAYLIST, BUTTON_REC|BUTTON_REL, BUTTON_REC }, { ACTION_WPS_REC, BUTTON_REC|BUTTON_REPEAT, BUTTON_NONE }, { ACTION_WPS_PITCHSCREEN, BUTTON_SELECT|BUTTON_UP, BUTTON_SELECT }, { ACTION_WPS_ID3SCREEN, BUTTON_SELECT|BUTTON_DOWN, BUTTON_SELECT }, + { ACTION_HOTKEY, BUTTON_REC|BUTTON_REL, BUTTON_REC }, LAST_ITEM_IN_LIST }; /* button_context_wps */ @@ -115,6 +115,7 @@ static const struct button_mapping button_context_tree[] = { { ACTION_TREE_WPS, BUTTON_UP|BUTTON_REL, BUTTON_UP }, { ACTION_TREE_STOP, BUTTON_POWER|BUTTON_REL, BUTTON_POWER }, + { ACTION_HOTKEY, BUTTON_REC|BUTTON_REL, BUTTON_REC }, LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST), }; /* button_context_tree */ @@ -272,12 +273,6 @@ LAST_ITEM_IN_LIST }; /* button_context_keyboard */ -static const struct button_mapping button_context_bmark[] = { - { ACTION_BMS_DELETE, BUTTON_REC, BUTTON_NONE }, - - LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST), -}; /* button_context_bmark */ - #ifdef USB_ENABLE_HID static const struct button_mapping button_context_usb_hid[] = { { ACTION_USB_HID_MODE_SWITCH_NEXT, BUTTON_REC|BUTTON_REL, BUTTON_REC }, @@ -418,7 +413,7 @@ case CONTEXT_FM: return button_context_radio; case CONTEXT_BOOKMARKSCREEN: - return button_context_bmark; + return button_context_list; case CONTEXT_QUICKSCREEN: return button_context_quickscreen; case CONTEXT_PITCHSCREEN: Index: apps/playlist_catalog.c =================================================================== --- apps/playlist_catalog.c (revision 25310) +++ apps/playlist_catalog.c (working copy) @@ -281,7 +281,7 @@ sel_file); if (onplay(playlist, FILE_ATTR_M3U, - CONTEXT_TREE) != ONPLAY_OK) + CONTEXT_TREE, false) != ONPLAY_OK) { result = 0; exit = true; Index: firmware/export/config/sansae200.h =================================================================== --- firmware/export/config/sansae200.h (revision 25310) +++ firmware/export/config/sansae200.h (working copy) @@ -214,3 +214,5 @@ #define IRAMORIG 0x40004000 #endif +/* Define this if a programmable hotkey is available */ +#define HOTKEY