Scripting: added 'dirsel' command

fixes #287
This commit is contained in:
d0k3 2018-01-09 01:39:37 +01:00
parent 9bdd6a516f
commit 7befb8f1b5
8 changed files with 44 additions and 17 deletions

View File

@ -117,7 +117,7 @@ bool GetDirContentsWorker(DirStruct* contents, char* fpath, int fnsize, const ch
if (fvx_opendir(&pdir, fpath) != FR_OK)
return false;
(fname++)[0] = '/';
if (*(fname-1) != '/') *(fname++) = '/';
while (fvx_readdir(&pdir, &fno) == FR_OK) {
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))

View File

@ -719,11 +719,16 @@ bool PathAttr(const char* path, u8 attr, u8 mask) {
return (f_chmod(path, attr, mask) == FR_OK);
}
bool FileSelector(char* result, const char* text, const char* path, const char* pattern, bool hide_ext, bool no_dirs) {
bool FileSelector(char* result, const char* text, const char* path, const char* pattern, u32 flags) {
DirStruct* contents = (DirStruct*) (void*) TEMP_BUFFER;
char path_local[256];
strncpy(path_local, path, 256);
bool no_dirs = flags & NO_DIRS;
bool no_files = flags & NO_FILES;
bool hide_ext = flags & HIDE_EXT;
bool select_dirs = flags & SELECT_DIRS;
// main loop
while (true) {
u32 n_found = 0;
@ -737,7 +742,7 @@ bool FileSelector(char* result, const char* text, const char* path, const char*
for (; pos < contents->n_entries; pos++) {
DirEntry* entry = &(contents->entry[pos]);
if (((entry->type == T_DIR) && no_dirs) ||
((entry->type == T_FILE) && (fvx_match_name(entry->name, pattern) != FR_OK)) ||
((entry->type == T_FILE) && (no_files || (fvx_match_name(entry->name, pattern) != FR_OK))) ||
(entry->type == T_DOTDOT) || (strncmp(entry->name, "._", 2) == 0))
continue;
if (n_opt == _MAX_FS_OPT) {
@ -765,8 +770,12 @@ bool FileSelector(char* result, const char* text, const char* path, const char*
if (!user_select) return false;
DirEntry* res_local = res_entry[user_select-1];
if (res_local && (res_local->type == T_DIR)) { // selected dir
if (FileSelector(result, text, res_local->path, pattern, hide_ext, no_dirs))
if (select_dirs) {
strncpy(result, res_local->path, 256);
return true;
} else if (FileSelector(result, text, res_local->path, pattern, flags)) {
return true;
}
break;
} else if (res_local && (res_local->type == T_FILE)) { // selected file
strncpy(result, res_local->path, 256);

View File

@ -13,6 +13,13 @@
#define SKIP_ALL (1UL<<7)
#define OVERWRITE_ALL (1UL<<8)
// file selector flags
#define NO_DIRS (1UL<<0)
#define NO_FILES (1UL<<1)
#define HIDE_EXT (1UL<<2)
#define SELECT_DIRS (1UL<<3)
/** Return total size of SD card **/
uint64_t GetSDCardSize();
@ -77,7 +84,7 @@ bool PathRename(const char* path, const char* newname);
bool PathAttr(const char* path, u8 attr, u8 mask);
/** Select a file **/
bool FileSelector(char* result, const char* text, const char* path, const char* pattern, bool hide_ext, bool no_dirs);
bool FileSelector(char* result, const char* text, const char* path, const char* pattern, u32 flags);
/** Create a screenshot of the current framebuffer **/
void CreateScreenshot();

View File

@ -67,9 +67,9 @@ bool CheckSupportDir(const char* dname)
return GetSupportDir(path, dname);
}
bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern, bool hide_ext, bool no_dirs)
bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern)
{
char path[256];
if (!GetSupportDir(path, dname)) return false;
return FileSelector(result, text, path, pattern, hide_ext, no_dirs);
return FileSelector(result, text, path, pattern, HIDE_EXT);
}

View File

@ -10,4 +10,4 @@ bool CheckSupportFile(const char* fname);
size_t LoadSupportFile(const char* fname, void* buffer, size_t max_len);
bool CheckSupportDir(const char* fpath);
bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern, bool hide_ext, bool no_dirs);
bool FileSelectorSupport(char* result, const char* text, const char* dname, const char* pattern);

View File

@ -1853,9 +1853,9 @@ u32 GodMode(int entrypoint) {
godmode9 = true;
} else if (user_select == 2) {
bootloader = true;
} else if ((user_select == 3) && (FileSelectorSupport(loadpath, "Bootloader payloads menu.\nSelect payload:", PAYLOADS_DIR, "*.firm", true, false))) {
} else if ((user_select == 3) && (FileSelectorSupport(loadpath, "Bootloader payloads menu.\nSelect payload:", PAYLOADS_DIR, "*.firm"))) {
BootFirmHandler(loadpath, false, false);
} else if ((user_select == 4) && (FileSelectorSupport(loadpath, "Bootloader scripts menu.\nSelect script:", SCRIPTS_DIR, "*.gm9", true, false))) {
} else if ((user_select == 4) && (FileSelectorSupport(loadpath, "Bootloader scripts menu.\nSelect script:", SCRIPTS_DIR, "*.gm9"))) {
ExecuteGM9Script(loadpath);
} else if (user_select == 5) {
exit_mode = GODMODE_EXIT_POWEROFF;
@ -2252,12 +2252,12 @@ u32 GodMode(int entrypoint) {
(user_select != poweroff) && (user_select != reboot)) {
char loadpath[256];
if ((user_select == more) && (HomeMoreMenu(current_path) == 0)) break; // more... menu
else if ((user_select == scripts) && (FileSelectorSupport(loadpath, "HOME scripts... menu.\nSelect script:", SCRIPTS_DIR, "*.gm9", true, false))) {
else if ((user_select == scripts) && (FileSelectorSupport(loadpath, "HOME scripts... menu.\nSelect script:", SCRIPTS_DIR, "*.gm9"))) {
ExecuteGM9Script(loadpath);
GetDirContents(current_dir, current_path);
ClearScreenF(true, true, COLOR_STD_BG);
break;
} else if ((user_select == payloads) && (FileSelectorSupport(loadpath, "HOME payloads... menu.\nSelect payload:", PAYLOADS_DIR, "*.firm", true, false))) {
} else if ((user_select == payloads) && (FileSelectorSupport(loadpath, "HOME payloads... menu.\nSelect payload:", PAYLOADS_DIR, "*.firm"))) {
BootFirmHandler(loadpath, false, false);
}
}
@ -2326,7 +2326,7 @@ u32 ScriptRunner(int entrypoint) {
ExecuteGM9Script(NULL);
} else if (PathExist("V:/" VRAM0_SCRIPTS)) {
char loadpath[256];
if (FileSelector(loadpath, FLAVOR " scripts menu.\nSelect script:", "V:/" VRAM0_SCRIPTS, "*.gm9", true, false))
if (FileSelector(loadpath, FLAVOR " scripts menu.\nSelect script:", "V:/" VRAM0_SCRIPTS, "*.gm9", HIDE_EXT))
ExecuteGM9Script(loadpath);
} else ShowPrompt(false, "Compiled as script autorunner\nbut no script provided.\n \nDerp!");

View File

@ -70,6 +70,7 @@ typedef enum {
CMD_ID_ASK,
CMD_ID_INPUT,
CMD_ID_FILESEL,
CMD_ID_DIRSEL,
CMD_ID_SET,
CMD_ID_STRSPLIT,
CMD_ID_STRREP,
@ -127,6 +128,7 @@ Gm9ScriptCmd cmd_list[] = {
{ CMD_ID_ASK , "ask" , 1, 0 },
{ CMD_ID_INPUT , "input" , 2, 0 },
{ CMD_ID_FILESEL , "filesel" , 3, _FLG('d') },
{ CMD_ID_DIRSEL , "dirsel" , 3, 0 },
{ CMD_ID_SET , "set" , 2, 0 },
{ CMD_ID_STRSPLIT, "strsplit", 3, _FLG('b') | _FLG('f')},
{ CMD_ID_STRREP , "strrep" , 3, 0 },
@ -815,7 +817,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail");
}
}
else if (id == CMD_ID_FILESEL) {
else if ((id == CMD_ID_FILESEL) || (id == CMD_ID_DIRSEL)) {
char choice[_VAR_CNT_LEN] = { 0 };
char* var = get_var(argv[2], NULL);
strncpy(choice, var, _VAR_CNT_LEN);
@ -829,10 +831,14 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
} else if (!npattern) {
ret = false;
if (err_str) snprintf(err_str, _ERR_STR_LEN, "invalid path");
} else {
} else if (id == CMD_ID_FILESEL) {
u32 flags_ext = (flags & _FLG('d')) ? 0 : NO_DIRS;
*(npattern++) = '\0';
ret = FileSelector(choice, argv[0], path, npattern, false, !(flags & _FLG('d')));
ret = FileSelector(choice, argv[0], path, npattern, flags_ext);
if (err_str) snprintf(err_str, _ERR_STR_LEN, "fileselect abort");
} else {
ret = FileSelector(choice, argv[0], path, npattern, NO_FILES | SELECT_DIRS);
if (err_str) snprintf(err_str, _ERR_STR_LEN, "dirselect abort");
}
if (ret) {

View File

@ -107,7 +107,12 @@ echo $[TESTREP]
# The path is stored inside a variable, and the selection can be limited via wildcards
# -d / --include_dirs allows to browse folders and select files inside
filesel "Please select a file" 0:/*.* SELFILE
echo "You selected $[SELFILE]\nWe'll do nothing with that :)."
# 'dirsel' COMMAND
# The 'dirsel' command works identically to the 'filesel' command, but allows selecting a dir
# Note that a final slash ('/') and no wildcard pattern is expected here.
dirsel "Now, select a dir" 0:/ SELDIR
echo "You selected $[SELFILE]\nand $[SELDIR]\nWe'll do nothing with either :)."
# 'allow' COMMAND
# typically used at the beginning of a script, prompts to allow writes to the location given in the argument