Index: apps/action.h =================================================================== --- apps/action.h (revision 25313) +++ apps/action.h (working copy) @@ -126,7 +126,9 @@ ACTION_WPS_CONTEXT, ACTION_WPS_QUICKSCREEN,/* optional */ ACTION_WPS_MENU, /*this should be the same as ACTION_STD_MENU */ +#ifndef HOTKEY ACTION_WPS_VIEW_PLAYLIST, +#endif ACTION_WPS_REC, #if 0 ACTION_WPSAB_SINGLE, /* This needs to be #defined in @@ -195,8 +197,13 @@ ACTION_SETTINGS_DECBIGSTEP, ACTION_SETTINGS_RESET, + /* hotkey */ +#ifdef HOTKEY + ACTION_HOTKEY, +#else /* bookmark screen */ ACTION_BMS_DELETE, +#endif /* quickscreen */ ACTION_QS_LEFT, Index: apps/tree.c =================================================================== --- apps/tree.c (revision 25313) +++ apps/tree.c (working copy) @@ -757,12 +757,22 @@ #endif case ACTION_STD_CONTEXT: +#ifdef HOTKEY + case ACTION_HOTKEY: { + bool hotkey = button == ACTION_HOTKEY; +#else + { +#endif int onplay_result; int attr = 0; if(!numentries) - onplay_result = onplay(NULL, 0, curr_context); + onplay_result = onplay(NULL, 0, curr_context +#ifdef HOTKEY + , hotkey +#endif + ); else { #ifdef HAVE_TAGCACHE if (id3db) @@ -788,7 +798,11 @@ snprintf(buf, sizeof buf, "/%s", dircache[tc.selected_item].name); } - onplay_result = onplay(buf, attr, curr_context); + onplay_result = onplay(buf, attr, curr_context +#ifdef HOTKEY + , hotkey +#endif + ); } switch (onplay_result) { Index: apps/lang/english.lang =================================================================== --- apps/lang/english.lang (revision 25313) +++ 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 25313) +++ 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,114 @@ 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 +#ifdef HOTKEY + , bool hotkey +#endif + ) +{ 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; +#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 25313) +++ apps/gui/wps.c (working copy) @@ -888,10 +888,20 @@ switch(button) { case ACTION_WPS_CONTEXT: +#ifdef HOTKEY + case ACTION_HOTKEY: { + bool hotkey = button == ACTION_HOTKEY; +#else + { +#endif gwps_leave_wps(); int retval = onplay(wps_state.id3->path, - FILE_ATTR_AUDIO, CONTEXT_WPS); + FILE_ATTR_AUDIO, CONTEXT_WPS +#ifdef HOTKEY + , hotkey +#endif + ); /* if music is stopped in the context menu we want to exit the wps */ if (retval == ONPLAY_MAINMENU || !audio_status()) @@ -1182,10 +1192,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 25313) +++ 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 25313) +++ 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 25313) +++ apps/onplay.h (working copy) @@ -21,7 +21,11 @@ #ifndef _ONPLAY_H_ #define _ONPLAY_H_ -int onplay(char* file, int attr, int from_screen); +int onplay(char* file, int attr, int from_screen +#ifdef HOTKEY + , bool hotkey +#endif + ); enum { ONPLAY_MAINMENU = -1, Index: apps/settings_list.c =================================================================== --- apps/settings_list.c (revision 25313) +++ 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 25313) +++ 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 25313) +++ 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 25313) +++ 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 25313) +++ apps/keymaps/keymap-e200.c (working copy) @@ -80,11 +80,16 @@ { ACTION_WPS_QUICKSCREEN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_DOWN }, { ACTION_WPS_MENU, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN }, +#ifndef HOTKEY { ACTION_WPS_VIEW_PLAYLIST, BUTTON_REC|BUTTON_REL, BUTTON_REC }, +#endif { 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 }, +#ifdef HOTKEY + { ACTION_HOTKEY, BUTTON_REC|BUTTON_REL, BUTTON_REC }, +#endif LAST_ITEM_IN_LIST }; /* button_context_wps */ @@ -108,6 +113,9 @@ static const struct button_mapping button_context_list[] = { { ACTION_LISTTREE_PGUP, BUTTON_REC|BUTTON_SCROLL_BACK, BUTTON_REC }, { ACTION_LISTTREE_PGDOWN, BUTTON_REC|BUTTON_SCROLL_FWD, BUTTON_REC }, +#ifdef HOTKEY + { ACTION_HOTKEY, BUTTON_REC|BUTTON_REL, BUTTON_REC }, +#endif LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) }; /* button_context_list */ @@ -272,11 +280,13 @@ LAST_ITEM_IN_LIST }; /* button_context_keyboard */ +#ifndef HOTKEY 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 */ +#endif #ifdef USB_ENABLE_HID static const struct button_mapping button_context_usb_hid[] = { @@ -418,7 +428,11 @@ case CONTEXT_FM: return button_context_radio; case CONTEXT_BOOKMARKSCREEN: +#ifdef HOTKEY + return button_context_list; +#else return button_context_bmark; +#endif case CONTEXT_QUICKSCREEN: return button_context_quickscreen; case CONTEXT_PITCHSCREEN: Index: apps/playlist_catalog.c =================================================================== --- apps/playlist_catalog.c (revision 25313) +++ apps/playlist_catalog.c (working copy) @@ -280,8 +280,11 @@ snprintf(playlist, MAX_PATH, "%s/%s", playlist_dir, sel_file); - if (onplay(playlist, FILE_ATTR_M3U, - CONTEXT_TREE) != ONPLAY_OK) + if (onplay(playlist, FILE_ATTR_M3U, CONTEXT_TREE +#ifdef HOTKEY + , false +#endif + ) != ONPLAY_OK) { result = 0; exit = true; Index: firmware/export/config/sansae200.h =================================================================== --- firmware/export/config/sansae200.h (revision 25313) +++ 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