From b566adec5255a0d463dd7d16bc7acbb5d6fdbbaf Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Wed, 4 Nov 2015 14:24:46 +0100 Subject: File Selector, support filepath dropping This adds support for dropping a filepath on an open file-selector to set that path. --- source/blender/editors/space_file/file_intern.h | 5 +- source/blender/editors/space_file/file_ops.c | 74 +++++++++++++++++++++++-- source/blender/editors/space_file/space_file.c | 28 +++++++++- 3 files changed, 101 insertions(+), 6 deletions(-) (limited to 'source/blender/editors/space_file') diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index baafefab1f6..71e38f72a7a 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -93,6 +93,7 @@ void FILE_OT_filenum(struct wmOperatorType *ot); void FILE_OT_delete(struct wmOperatorType *ot); void FILE_OT_rename(struct wmOperatorType *ot); void FILE_OT_smoothscroll(struct wmOperatorType *ot); +void FILE_OT_filepath_drop(struct wmOperatorType *ot); int file_exec(bContext *C, struct wmOperator *exec_op); int file_cancel_exec(bContext *C, struct wmOperator *unused); @@ -107,7 +108,9 @@ void file_filename_enter_handle(bContext *C, void *arg_unused, void *arg_but); int file_highlight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my); -void file_sfile_to_operator(struct wmOperator *op, struct SpaceFile *sfile, char *filepath); +void file_sfile_filepath_set(struct SpaceFile *sfile, const char *filepath); +void file_sfile_to_operator_ex(struct wmOperator *op, struct SpaceFile *sfile, char *filepath); +void file_sfile_to_operator(struct wmOperator *op, struct SpaceFile *sfile); void file_operator_to_sfile(struct SpaceFile *sfile, struct wmOperator *op); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 36572d6469d..feea40443fa 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -1188,7 +1188,7 @@ void FILE_OT_cancel(struct wmOperatorType *ot) } -void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath) +void file_sfile_to_operator_ex(wmOperator *op, SpaceFile *sfile, char *filepath) { PropertyRNA *prop; @@ -1258,6 +1258,12 @@ void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath) } } +void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile) +{ + char filepath[FILE_MAX]; + + file_sfile_to_operator_ex(op, sfile, filepath); +} void file_operator_to_sfile(SpaceFile *sfile, wmOperator *op) { @@ -1285,14 +1291,35 @@ void file_operator_to_sfile(SpaceFile *sfile, wmOperator *op) /* XXX, files and dirs updates missing, not really so important though */ } +/** + * Use to set the file selector path from some arbitrary source. + */ +void file_sfile_filepath_set(SpaceFile *sfile, const char *filepath) +{ + BLI_assert(BLI_exists(filepath)); + + if (BLI_is_dir(filepath)) { + BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); + sfile->params->file[0] = '\0'; + } + else { + if ((sfile->params->flag & FILE_DIRSEL_ONLY) == 0) { + BLI_split_dirfile(filepath, sfile->params->dir, sfile->params->file, + sizeof(sfile->params->dir), sizeof(sfile->params->file)); + } + else{ + BLI_split_dir_part(filepath, sfile->params->dir, sizeof(sfile->params->dir)); + } + } +} + void file_draw_check(bContext *C) { SpaceFile *sfile = CTX_wm_space_file(C); wmOperator *op = sfile->op; if (op) { /* fail on reload */ if (op->type->check) { - char filepath[FILE_MAX]; - file_sfile_to_operator(op, sfile, filepath); + file_sfile_to_operator(op, sfile); /* redraw */ if (op->type->check(C, op)) { @@ -1375,7 +1402,7 @@ int file_exec(bContext *C, wmOperator *exec_op) sfile->op = NULL; - file_sfile_to_operator(op, sfile, filepath); + file_sfile_to_operator_ex(op, sfile, filepath); if (BLI_exists(sfile->params->dir)) { fsmenu_insert_entry(ED_fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, NULL, @@ -1652,6 +1679,45 @@ void FILE_OT_smoothscroll(wmOperatorType *ot) } +static int filepath_drop_exec(bContext *C, wmOperator *op) +{ + SpaceFile *sfile = CTX_wm_space_file(C); + + if (sfile) { + char filepath[FILE_MAX]; + + RNA_string_get(op->ptr, "filepath", filepath); + if (!BLI_exists(filepath)) { + BKE_report(op->reports, RPT_ERROR, "File does not exist"); + return OPERATOR_CANCELLED; + } + + file_sfile_filepath_set(sfile, filepath); + + if (sfile->op) { + file_sfile_to_operator(sfile->op, sfile); + file_draw_check(C); + } + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void FILE_OT_filepath_drop(wmOperatorType *ot) +{ + ot->name = "File Selector Drop"; + ot->description = ""; + ot->idname = "FILE_OT_filepath_drop"; + + ot->exec = filepath_drop_exec; + ot->poll = WM_operator_winactive; + + RNA_def_string_file_path(ot->srna, "filepath", "Path", FILE_MAX, "", ""); +} + /* create a new, non-existing folder name, returns 1 if successful, 0 if name couldn't be created. * The actual name is returned in 'name', 'folder' contains the complete path, including the new folder name. */ diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 97c2d75e469..3202164edbd 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -441,6 +441,7 @@ static void file_operatortypes(void) WM_operatortype_append(FILE_OT_delete); WM_operatortype_append(FILE_OT_rename); WM_operatortype_append(FILE_OT_smoothscroll); + WM_operatortype_append(FILE_OT_filepath_drop); } /* NOTE: do not add .blend file reading on this level */ @@ -661,6 +662,30 @@ static void file_ui_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AReg } } +static int filepath_drop_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event)) +{ + if (drag->type == WM_DRAG_PATH) { + SpaceFile *sfile = CTX_wm_space_file(C); + if (sfile) { + return 1; + } + } + return 0; +} + +static void filepath_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + RNA_string_set(drop->ptr, "filepath", drag->path); +} + +/* region dropbox definition */ +static void file_dropboxes(void) +{ + ListBase *lb = WM_dropboxmap_find("Window", SPACE_EMPTY, RGN_TYPE_WINDOW); + + WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy); +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_file(void) { @@ -679,7 +704,8 @@ void ED_spacetype_file(void) st->listener = file_listener; st->operatortypes = file_operatortypes; st->keymap = file_keymap; - + st->dropboxes = file_dropboxes; + /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype file region"); art->regionid = RGN_TYPE_WINDOW; -- cgit v1.2.3