void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath) { BLI_join_dirfile(filepath, FILE_MAX, sfile->params->dir, sfile->params->file); /* XXX, not real length */ if(RNA_struct_find_property(op->ptr, "relative_path")) { if(RNA_boolean_get(op->ptr, "relative_path")) { BLI_path_rel(filepath, G.main->name); } } if(RNA_struct_find_property(op->ptr, "filename")) { RNA_string_set(op->ptr, "filename", sfile->params->file); } if(RNA_struct_find_property(op->ptr, "directory")) { RNA_string_set(op->ptr, "directory", sfile->params->dir); } if(RNA_struct_find_property(op->ptr, "filepath")) { RNA_string_set(op->ptr, "filepath", filepath); } /* some ops have multiple files to select */ /* this is called on operators check() so clear collections first since * they may be already set. */ { PointerRNA itemptr; PropertyRNA *prop_files= RNA_struct_find_property(op->ptr, "files"); PropertyRNA *prop_dirs= RNA_struct_find_property(op->ptr, "dirs"); int i, numfiles = filelist_numfiles(sfile->files); if(prop_files) { RNA_property_collection_clear(op->ptr, prop_files); for (i=0; i<numfiles; i++) { if (filelist_is_selected(sfile->files, i, CHECK_FILES)) { struct direntry *file= filelist_file(sfile->files, i); RNA_property_collection_add(op->ptr, prop_files, &itemptr); RNA_string_set(&itemptr, "name", file->relname); } } } if(prop_dirs) { RNA_property_collection_clear(op->ptr, prop_dirs); for (i=0; i<numfiles; i++) { if (filelist_is_selected(sfile->files, i, CHECK_DIRS)) { struct direntry *file= filelist_file(sfile->files, i); RNA_property_collection_add(op->ptr, prop_dirs, &itemptr); RNA_string_set(&itemptr, "name", file->relname); } } } } }
static int file_select_all_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); SpaceFile *sfile = CTX_wm_space_file(C); FileSelection sel; int numfiles = filelist_numfiles(sfile->files); int i; bool is_selected = false; sel.first = 0; sel.last = numfiles - 1; /* Is any file selected ? */ for (i = 0; i < numfiles; ++i) { if (filelist_is_selected(sfile->files, i, CHECK_ALL)) { is_selected = true; break; } } /* select all only if previously no file was selected */ if (is_selected) { filelist_select(sfile->files, &sel, FILE_SEL_REMOVE, SELECTED_FILE, CHECK_ALL); } else { const FileCheckType check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_FILES; filelist_select(sfile->files, &sel, FILE_SEL_ADD, SELECTED_FILE, check_type); } ED_area_tag_redraw(sa); return OPERATOR_FINISHED; }
static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select, bool fill, bool do_diropen) { SpaceFile *sfile = CTX_wm_space_file(C); FileSelect retval = FILE_SELECT_NOTHING; FileSelection sel = file_selection_get(C, rect, fill); /* get the selection */ const FileCheckType check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_ALL; /* flag the files as selected in the filelist */ filelist_select(sfile->files, &sel, select, SELECTED_FILE, check_type); /* Don't act on multiple selected files */ if (sel.first != sel.last) select = 0; /* Do we have a valid selection and are we actually selecting */ if ((sel.last >= 0) && ((select == FILE_SEL_ADD) || (select == FILE_SEL_TOGGLE))) { /* Check last selection, if selected, act on the file or dir */ if (filelist_is_selected(sfile->files, sel.last, check_type)) { retval = file_select_do(C, sel.last, do_diropen); } } /* update operator for name change event */ file_draw_check_cb(C, NULL, NULL); return retval; }
static FileSelection file_selection_get(bContext *C, const rcti *rect, bool fill) { ARegion *ar = CTX_wm_region(C); SpaceFile *sfile = CTX_wm_space_file(C); int numfiles = filelist_numfiles(sfile->files); FileSelection sel; sel = find_file_mouse_rect(sfile, ar, rect); if (!((sel.first == -1) && (sel.last == -1)) ) { clamp_to_filelist(numfiles, &sel); } /* if desired, fill the selection up from the last selected file to the current one */ if (fill && (sel.last >= 0) && (sel.last < numfiles) ) { int f = sel.last; while (f >= 0) { if (filelist_is_selected(sfile->files, f, CHECK_ALL) ) break; f--; } if (f >= 0) { sel.first = f + 1; } } return sel; }
/* 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); char filepath[FILE_MAX]; if (sfile->op) { wmOperator *op = sfile->op; /* when used as a macro, for doubleclick, * to prevent closing when doubleclicking on .. item */ if (RNA_boolean_get(exec_op->ptr, "need_active")) { int i, active = 0; for (i = 0; i < filelist_numfiles(sfile->files); i++) { if (filelist_is_selected(sfile->files, i, CHECK_ALL)) { active = 1; break; } } if (active == 0) return OPERATOR_CANCELLED; } sfile->op = NULL; file_sfile_to_operator(op, sfile, filepath); if (BLI_exists(sfile->params->dir)) { fsmenu_insert_entry(fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, FS_INSERT_SAVE | FS_INSERT_FIRST); } BLI_make_file_string(G.main->name, filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu_get(), filepath); WM_event_fileselect_event(wm, op, EVT_FILESELECT_EXEC); } return OPERATOR_FINISHED; }
/* only meant for timer usage */ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { ScrArea *sa = CTX_wm_area(C); SpaceFile *sfile = CTX_wm_space_file(C); ARegion *ar, *oldar = CTX_wm_region(C); int offset; int numfiles, numfiles_layout; int edit_idx = 0; int i; /* escape if not our timer */ if (sfile->smoothscroll_timer == NULL || sfile->smoothscroll_timer != event->customdata) return OPERATOR_PASS_THROUGH; numfiles = filelist_numfiles(sfile->files); /* check if we are editing a name */ for (i = 0; i < numfiles; ++i) { if (filelist_is_selected(sfile->files, i, CHECK_ALL) ) { edit_idx = i; break; } } /* if we are not editing, we are done */ if (0 == edit_idx) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_PASS_THROUGH; } /* we need the correct area for scrolling */ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (!ar || ar->regiontype != RGN_TYPE_WINDOW) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_PASS_THROUGH; } offset = ED_fileselect_layout_offset(sfile->layout, (int)ar->v2d.cur.xmin, (int)-ar->v2d.cur.ymax); if (offset < 0) offset = 0; /* scroll offset is the first file in the row/column we are editing in */ if (sfile->scroll_offset == 0) { if (sfile->layout->flag & FILE_LAYOUT_HOR) { sfile->scroll_offset = (edit_idx / sfile->layout->rows) * sfile->layout->rows; if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->rows; } else { sfile->scroll_offset = (edit_idx / sfile->layout->columns) * sfile->layout->columns; if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->columns; } } numfiles_layout = ED_fileselect_layout_numfiles(sfile->layout, ar); /* check if we have reached our final scroll position */ if ( (sfile->scroll_offset >= offset) && (sfile->scroll_offset < offset + numfiles_layout) ) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_FINISHED; } /* temporarily set context to the main window region, * so the scroll operators work */ CTX_wm_region_set(C, ar); /* scroll one step in the desired direction */ if (sfile->scroll_offset < offset) { if (sfile->layout->flag & FILE_LAYOUT_HOR) { WM_operator_name_call(C, "VIEW2D_OT_scroll_left", 0, NULL); } else { WM_operator_name_call(C, "VIEW2D_OT_scroll_up", 0, NULL); } } else { if (sfile->layout->flag & FILE_LAYOUT_HOR) { WM_operator_name_call(C, "VIEW2D_OT_scroll_right", 0, NULL); } else { WM_operator_name_call(C, "VIEW2D_OT_scroll_down", 0, NULL); } } ED_region_tag_redraw(ar); /* and restore context */ CTX_wm_region_set(C, oldar); return OPERATOR_FINISHED; }