Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_file/file_ops.c
| Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| # include "BLI_winstuff.h" | # include "BLI_winstuff.h" | ||||
| #endif | #endif | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_fileselect.h" | #include "ED_fileselect.h" | ||||
| #include "UI_interface.h" | |||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_define.h" | #include "RNA_define.h" | ||||
| #include "UI_view2d.h" | #include "UI_view2d.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| ▲ Show 20 Lines • Show All 1,070 Lines • ▼ Show 20 Lines | int file_directory_new_exec(bContext *C, wmOperator *op) | ||||
| BLI_strncpy(sfile->params->renamefile, name, FILE_MAXFILE); | BLI_strncpy(sfile->params->renamefile, name, FILE_MAXFILE); | ||||
| /* set timer to smoothly view newly generated file */ | /* set timer to smoothly view newly generated file */ | ||||
| sfile->smoothscroll_timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0 / 1000.0); /* max 30 frs/sec */ | sfile->smoothscroll_timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0 / 1000.0); /* max 30 frs/sec */ | ||||
| sfile->scroll_offset = 0; | sfile->scroll_offset = 0; | ||||
| /* reload dir to make sure we're seeing what's in the directory */ | /* reload dir to make sure we're seeing what's in the directory */ | ||||
| ED_fileselect_clear(wm, sfile); | ED_fileselect_clear(wm, sfile); | ||||
| if (RNA_boolean_get(op->ptr, "open")) { | |||||
| BLI_strncpy(sfile->params->dir, path, sizeof(sfile->params->dir)); | |||||
| file_change_dir(C, 1); | |||||
| } | |||||
| WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); | WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void FILE_OT_directory_new(struct wmOperatorType *ot) | void FILE_OT_directory_new(struct wmOperatorType *ot) | ||||
| { | { | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Create New Directory"; | ot->name = "Create New Directory"; | ||||
| ot->description = "Create a new directory"; | ot->description = "Create a new directory"; | ||||
| ot->idname = "FILE_OT_directory_new"; | ot->idname = "FILE_OT_directory_new"; | ||||
| /* api callbacks */ | /* api callbacks */ | ||||
| ot->invoke = WM_operator_confirm; | ot->invoke = WM_operator_confirm; | ||||
| ot->exec = file_directory_new_exec; | ot->exec = file_directory_new_exec; | ||||
| ot->poll = ED_operator_file_active; /* <- important, handler is on window level */ | ot->poll = ED_operator_file_active; /* <- important, handler is on window level */ | ||||
| prop = RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory"); | prop = RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory"); | ||||
| RNA_def_property_flag(prop, PROP_SKIP_SAVE); | RNA_def_property_flag(prop, PROP_SKIP_SAVE); | ||||
| prop = RNA_def_boolean(ot->srna, "open", false, "Open", "Open new directory"); | |||||
| RNA_def_property_flag(prop, PROP_SKIP_SAVE); | |||||
| } | } | ||||
| static void file_expand_directory(bContext *C) | static void file_expand_directory(bContext *C) | ||||
| { | { | ||||
| SpaceFile *sfile = CTX_wm_space_file(C); | SpaceFile *sfile = CTX_wm_space_file(C); | ||||
| if (sfile->params) { | if (sfile->params) { | ||||
| Show All 24 Lines | #else | ||||
| { | { | ||||
| sfile->params->dir[2] = '\\'; | sfile->params->dir[2] = '\\'; | ||||
| sfile->params->dir[3] = '\0'; | sfile->params->dir[3] = '\0'; | ||||
| } | } | ||||
| #endif | #endif | ||||
| } | } | ||||
| } | } | ||||
| static int file_directory_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UNUSED(arg_but)) | ||||
| { | { | ||||
| SpaceFile *sfile = CTX_wm_space_file(C); | SpaceFile *sfile = CTX_wm_space_file(C); | ||||
| if (sfile->params) { | if (sfile->params) { | ||||
| file_expand_directory(C); | file_expand_directory(C); | ||||
| if (!BLI_exists(sfile->params->dir)) { | |||||
| return WM_operator_confirm_message(C, op, "Create new directory?"); | |||||
| } | |||||
| return file_directory_exec(C, op); | |||||
| } | |||||
| return OPERATOR_CANCELLED; | |||||
| } | |||||
| int file_directory_exec(bContext *C, wmOperator *UNUSED(unused)) | |||||
| { | |||||
| SpaceFile *sfile = CTX_wm_space_file(C); | |||||
| if (sfile->params) { | |||||
| file_expand_directory(C); | |||||
| if (!BLI_exists(sfile->params->dir)) { | |||||
| BLI_dir_create_recursive(sfile->params->dir); | |||||
| } | |||||
| /* special case, user may have pasted a filepath into the directory */ | /* special case, user may have pasted a filepath into the directory */ | ||||
| if (BLI_is_file(sfile->params->dir)) { | if (BLI_is_file(sfile->params->dir)) { | ||||
| char path[sizeof(sfile->params->dir)]; | char path[sizeof(sfile->params->dir)]; | ||||
| BLI_strncpy(path, sfile->params->dir, sizeof(path)); | BLI_strncpy(path, sfile->params->dir, sizeof(path)); | ||||
| BLI_split_dirfile(path, sfile->params->dir, sfile->params->file, sizeof(sfile->params->dir), sizeof(sfile->params->file)); | BLI_split_dirfile(path, sfile->params->dir, sfile->params->file, sizeof(sfile->params->dir), sizeof(sfile->params->file)); | ||||
| } | } | ||||
| BLI_cleanup_dir(G.main->name, sfile->params->dir); | BLI_cleanup_dir(G.main->name, sfile->params->dir); | ||||
| if (BLI_exists(sfile->params->dir)) { | |||||
| /* if directory exists, enter it immediately */ | |||||
| file_change_dir(C, 1); | file_change_dir(C, 1); | ||||
| WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); | /* don't do for now because it selects entire text instead of | ||||
| * placing cursor at the end */ | |||||
| /* UI_textbutton_activate_but(C, but); */ | |||||
| } | } | ||||
| else { | |||||
| const char *lastdir = folderlist_peeklastdir(sfile->folders_prev); | |||||
brecht: Creating new directories should still work, but it's calling the FILE_OT_directory_new operator… | |||||
Not Done Inline ActionsAh sorry, I must have had something in front of my eyes, all fine :) elubie: Ah sorry, I must have had something in front of my eyes, all fine :) | |||||
| return OPERATOR_FINISHED; | /* if not, ask to create it and enter if confirmed */ | ||||
| } | PointerRNA ptr; | ||||
| WM_operator_properties_create(&ptr, "FILE_OT_directory_new"); | |||||
| RNA_string_set(&ptr, "directory", sfile->params->dir); | |||||
| RNA_boolean_set(&ptr, "open", true); | |||||
| static int file_filename_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | if (lastdir) | ||||
| { | BLI_strncpy(sfile->params->dir, lastdir, sizeof(sfile->params->dir)); | ||||
| SpaceFile *sfile = CTX_wm_space_file(C); | |||||
| if (sfile->params) { | |||||
| file_expand_directory(C); | |||||
| return file_filename_exec(C, op); | WM_operator_name_call(C, "FILE_OT_directory_new", WM_OP_INVOKE_DEFAULT, &ptr); | ||||
| WM_operator_properties_free(&ptr); | |||||
| } | } | ||||
| return OPERATOR_CANCELLED; | WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); | ||||
| } | |||||
| } | } | ||||
| int file_filename_exec(bContext *C, wmOperator *UNUSED(unused)) | void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg_but) | ||||
| { | { | ||||
| SpaceFile *sfile = CTX_wm_space_file(C); | SpaceFile *sfile = CTX_wm_space_file(C); | ||||
| uiBut *but = (uiBut*)arg_but; | |||||
| char matched_file[FILE_MAX]; | char matched_file[FILE_MAX]; | ||||
| char filepath[sizeof(sfile->params->dir)]; | char filepath[sizeof(sfile->params->dir)]; | ||||
| if (sfile->params) { | if (sfile->params) { | ||||
| int matches = 0; | int matches; | ||||
| matched_file[0] = '\0'; | matched_file[0] = '\0'; | ||||
| filepath[0] = '\0'; | filepath[0] = '\0'; | ||||
| if ((matches = file_select_match(sfile, sfile->params->file, matched_file))) { | file_expand_directory(C); | ||||
| matches = file_select_match(sfile, sfile->params->file, matched_file); | |||||
| if (matches) { | |||||
| /* int i, numfiles = filelist_numfiles(sfile->files); */ /* XXX UNUSED */ | /* int i, numfiles = filelist_numfiles(sfile->files); */ /* XXX UNUSED */ | ||||
| sfile->params->file[0] = '\0'; | sfile->params->file[0] = '\0'; | ||||
| /* replace the pattern (or filename that the user typed in, with the first selected file of the match */ | /* replace the pattern (or filename that the user typed in, with the first selected file of the match */ | ||||
| BLI_strncpy(sfile->params->file, matched_file, sizeof(sfile->params->file)); | BLI_strncpy(sfile->params->file, matched_file, sizeof(sfile->params->file)); | ||||
| WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); | WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); | ||||
| } | } | ||||
| if (matches == 1) { | if (matches == 1) { | ||||
| BLI_join_dirfile(filepath, sizeof(sfile->params->dir), sfile->params->dir, sfile->params->file); | BLI_join_dirfile(filepath, sizeof(sfile->params->dir), sfile->params->dir, sfile->params->file); | ||||
| /* if directory, open it and empty filename field */ | /* if directory, open it and empty filename field */ | ||||
| if (BLI_is_dir(filepath)) { | if (BLI_is_dir(filepath)) { | ||||
| BLI_cleanup_dir(G.main->name, filepath); | BLI_cleanup_dir(G.main->name, filepath); | ||||
| BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); | BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); | ||||
| sfile->params->file[0] = '\0'; | sfile->params->file[0] = '\0'; | ||||
| file_change_dir(C, 1); | file_change_dir(C, 1); | ||||
| UI_textbutton_activate_but(C, but); | |||||
| WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); | WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); | ||||
| } | } | ||||
| else if (sfile->params->type == FILE_LOADLIB) { | else if (sfile->params->type == FILE_LOADLIB) { | ||||
| char tdir[FILE_MAX], tgroup[FILE_MAX]; | char tdir[FILE_MAX], tgroup[FILE_MAX]; | ||||
| BLI_add_slash(filepath); | BLI_add_slash(filepath); | ||||
| if (BLO_is_a_library(filepath, tdir, tgroup)) { | if (BLO_is_a_library(filepath, tdir, tgroup)) { | ||||
| BLI_cleanup_dir(G.main->name, filepath); | BLI_cleanup_dir(G.main->name, filepath); | ||||
| BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); | BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); | ||||
| sfile->params->file[0] = '\0'; | sfile->params->file[0] = '\0'; | ||||
| file_change_dir(C, 0); | file_change_dir(C, 0); | ||||
| UI_textbutton_activate_but(C, but); | |||||
| WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); | WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return OPERATOR_FINISHED; | |||||
| } | |||||
| /* TODO, directory operator is non-functional while a library is loaded | |||||
| * until this is properly supported just disable it. */ | |||||
| static int file_directory_poll(bContext *C) | |||||
| { | |||||
| /* sfile->files can be NULL on file load */ | |||||
| SpaceFile *sfile = CTX_wm_space_file(C); | |||||
| return ED_operator_file_active(C) && (sfile->files == NULL || filelist_lib(sfile->files) == NULL); | |||||
| } | |||||
| void FILE_OT_directory(struct wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Enter Directory Name"; | |||||
| ot->description = "Enter a directory name"; | |||||
| ot->idname = "FILE_OT_directory"; | |||||
| /* api callbacks */ | |||||
| ot->invoke = file_directory_invoke; | |||||
| ot->exec = file_directory_exec; | |||||
| ot->poll = file_directory_poll; /* <- important, handler is on window level */ | |||||
| } | |||||
| void FILE_OT_filename(struct wmOperatorType *ot) | |||||
| { | |||||
| /* identifiers */ | |||||
| ot->name = "Enter File Name"; | |||||
| ot->description = "Enter a file name"; | |||||
| ot->idname = "FILE_OT_filename"; | |||||
| /* api callbacks */ | |||||
| ot->invoke = file_filename_invoke; | |||||
| ot->exec = file_filename_exec; | |||||
| } | } | ||||
| void FILE_OT_refresh(struct wmOperatorType *ot) | void FILE_OT_refresh(struct wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Refresh Filelist"; | ot->name = "Refresh Filelist"; | ||||
| ot->description = "Refresh the file list"; | ot->description = "Refresh the file list"; | ||||
| ot->idname = "FILE_OT_refresh"; | ot->idname = "FILE_OT_refresh"; | ||||
| ▲ Show 20 Lines • Show All 241 Lines • Show Last 20 Lines | |||||
Creating new directories should still work, but it's calling the FILE_OT_directory_new operator for that now.