From aeeb23efa28dc16e207b168866fe60806f8faa2d Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Thu, 9 Jul 2015 18:40:34 +0200 Subject: File Browser: Improve usage of Enter-key to open files/directories From a user-POV this makes following changes: * Adds support for using the Enter-key to open directories * Updates the upper text-buttons for file and directory on selection * Last selected file/directory is opened now (in sync with upper text-buttons) * Changes text in open button to "Open Directory" if a directory is selected D1349, Reviewed by @mont29 --- source/blender/editors/space_file/file_draw.c | 16 ++++++++++--- source/blender/editors/space_file/file_intern.h | 1 + source/blender/editors/space_file/file_ops.c | 30 ++++++++++++++++++------- source/blender/editors/space_file/filesel.c | 14 ++++++++++++ 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 6347ce7c4e8..7a3296d3f3d 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -157,13 +157,19 @@ void file_draw_buttons(const bContext *C, ARegion *ar) /* Text input fields for directory and file. */ if (available_w > 0) { + const struct direntry *file = filelist_file(sfile->files, params->active_file); int overwrite_alert = file_draw_check_exists(sfile); + const bool is_active_dir = file && BLI_is_dir(file->path); + char *dir_path = (is_active_dir && params->active_file > 0) ? file->path : params->dir; + + BLI_add_slash(dir_path); + /* callbacks for operator check functions */ UI_block_func_set(block, file_draw_check_cb, NULL, NULL); but = uiDefBut(block, UI_BTYPE_TEXT, -1, "", min_x, line1_y, line1_w - chan_offs, btn_h, - params->dir, 0.0, (float)FILE_MAX, 0, 0, + dir_path, 0.0, (float)FILE_MAX, 0, 0, TIP_("File path")); UI_but_func_complete_set(but, autocomplete_directory, NULL); UI_but_flag_enable(but, UI_BUT_NO_UTF8); @@ -178,7 +184,8 @@ void file_draw_buttons(const bContext *C, ARegion *ar) if ((params->flag & FILE_DIRSEL_ONLY) == 0) { but = uiDefBut(block, UI_BTYPE_TEXT, -1, "", min_x, line2_y, line2_w - chan_offs, btn_h, - params->file, 0.0, (float)FILE_MAXFILE, 0, 0, + is_active_dir ? (char *)"" : params->file, + 0.0, (float)FILE_MAXFILE, 0, 0, TIP_(overwrite_alert ? N_("File name, overwrite existing") : N_("File name"))); UI_but_func_complete_set(but, autocomplete_file, NULL); UI_but_flag_enable(but, UI_BUT_NO_UTF8); @@ -216,8 +223,11 @@ void file_draw_buttons(const bContext *C, ARegion *ar) /* Execute / cancel buttons. */ if (loadbutton) { + const struct direntry *file = filelist_file(sfile->files, params->active_file); + const char *str_exec = (file && BLI_is_dir(file->path)) ? IFACE_("Open Directory") : params->title; + /* params->title is already translated! */ - uiDefButO(block, UI_BTYPE_BUT, "FILE_OT_execute", WM_OP_EXEC_REGION_WIN, params->title, + uiDefButO(block, UI_BTYPE_BUT, "FILE_OT_execute", WM_OP_EXEC_REGION_WIN, str_exec, max_x - loadbutton, line1_y, loadbutton, btn_h, ""); uiDefButO(block, UI_BTYPE_BUT, "FILE_OT_cancel", WM_OP_EXEC_REGION_WIN, IFACE_("Cancel"), max_x - loadbutton, line2_y, loadbutton, btn_h, ""); diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index d7af6c9b812..b24780c6e05 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -110,6 +110,7 @@ void file_operator_to_sfile(struct SpaceFile *sfile, struct wmOperator *op); /* filesel.c */ +void fileselect_file_set(SpaceFile *sfile, const int index); float file_string_width(const char *str); float file_font_pointsize(void); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 8c9233e3ce5..2146ab39b39 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -206,11 +206,9 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen) } } else { - if (file->relname) { - BLI_strncpy(params->file, file->relname, FILE_MAXFILE); - } retval = FILE_SELECT_FILE; } + fileselect_file_set(sfile, selected_idx); } return retval; } @@ -340,6 +338,7 @@ static int file_border_select_modal(bContext *C, wmOperator *op, const wmEvent * else { params->highlight_file = -1; params->sel_first = params->sel_last = -1; + fileselect_file_set(sfile, params->active_file); file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); } @@ -487,7 +486,7 @@ static bool file_walk_select_selection_set( * selected and either other_side isn't selected/found or we use fill */ deselect = (fill || other_site == -1 || !filelist_is_selected(files, other_site, FILE_SEL_SELECTED)); - /* don't change active here since we either want to deselect active or we want to + /* don't change highlight_file here since we either want to deselect active or we want to * walk through a block of selected files without selecting/deselecting anything */ params->active_file = active_new; /* but we want to change active if we use fill (needed to get correct selection bounds) */ @@ -549,6 +548,7 @@ static bool file_walk_select_selection_set( } BLI_assert(IN_RANGE(active, 0, numfiles)); + fileselect_file_set(sfile, params->active_file); /* selection changed */ return true; @@ -1243,14 +1243,28 @@ bool file_draw_check_exists(SpaceFile *sfile) return false; } -/* sends events now, so things get handled on windowqueue level */ int file_exec(bContext *C, wmOperator *exec_op) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); + const struct direntry *file = filelist_file(sfile->files, sfile->params->active_file); char filepath[FILE_MAX]; - - if (sfile->op) { + + if (!file || !sfile->params->file[0]) + return OPERATOR_CANCELLED; + + BLI_assert(STREQ(file->relname, sfile->params->file)); + + /* directory change */ + if (S_ISDIR(file->type)) { + BLI_cleanup_dir(G.main->name, sfile->params->dir); + strcat(sfile->params->dir, sfile->params->file); + BLI_add_slash(sfile->params->dir); + + ED_file_change_dir(C, false); + } + /* opening file - sends events now, so things get handled on windowqueue level */ + else if (sfile->op) { wmOperator *op = sfile->op; /* when used as a macro, for doubleclick, @@ -1283,7 +1297,7 @@ int file_exec(bContext *C, wmOperator *exec_op) WM_event_fileselect_event(wm, op, EVT_FILESELECT_EXEC); } - + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 66eb79abae2..ef29b720eed 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -287,6 +287,17 @@ void ED_fileselect_reset_params(SpaceFile *sfile) sfile->params->active_file = -1; } +/** + * Sets FileSelectParams->file (name of selected file) + */ +void fileselect_file_set(SpaceFile *sfile, const int index) +{ + const struct direntry *file = filelist_file(sfile->files, index); + if (file && file->relname[0] && !FILENAME_IS_PARENT(file->relname)) { + BLI_strncpy(sfile->params->file, file->relname, FILE_MAXFILE); + } +} + int ED_fileselect_layout_numfiles(FileLayout *layout, ARegion *ar) { int numfiles; @@ -583,6 +594,9 @@ void ED_file_change_dir(bContext *C, const bool checkdir) /* could return but just refresh the current dir */ } filelist_setdir(sfile->files, sfile->params->dir); + /* clear selected file to avoid trying to open it from the new dir with changed path */ + sfile->params->file[0] = '\0'; + sfile->params->active_file = -1; if (folderlist_clear_next(sfile)) folderlist_free(sfile->folders_next); -- cgit v1.2.3