static bool delete_recursive(const char *dir) { struct direntry *filelist, *fl; bool err = false; unsigned int nbr, i; i = nbr = BLI_filelist_dir_contents(dir, &filelist); fl = filelist; while (i--) { char file[8]; BLI_split_file_part(fl->path, file, sizeof(file)); if (FILENAME_IS_CURRPAR(file)) { /* Skip! */ } else if (S_ISDIR(fl->type)) { if (delete_recursive(fl->path)) { err = true; } } else { if (delete_unique(fl->path, false)) { err = true; } } ++fl; } if (!err && delete_unique(dir, true)) { err = true; } BLI_filelist_free(filelist, nbr, NULL); return err; }
int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) { SpaceFile *sfile = CTX_wm_space_file(C); int match = AUTOCOMPLETE_NO_MATCH; /* search if str matches the beginning of name */ if (str[0] && sfile->files) { char dirname[FILE_MAX]; DIR *dir; struct dirent *de; BLI_split_dir_part(str, dirname, sizeof(dirname)); dir = opendir(dirname); if (dir) { AutoComplete *autocpl = UI_autocomplete_begin(str, FILE_MAX); while ((de = readdir(dir)) != NULL) { if (FILENAME_IS_CURRPAR(de->d_name)) { /* pass */ } else { char path[FILE_MAX]; BLI_stat_t status; BLI_join_dirfile(path, sizeof(path), dirname, de->d_name); if (BLI_stat(path, &status) == 0) { if (S_ISDIR(status.st_mode)) { /* is subdir */ UI_autocomplete_update_name(autocpl, path); } } } } closedir(dir); match = UI_autocomplete_end(autocpl, str); if (match == AUTOCOMPLETE_FULL_MATCH) { BLI_add_slash(str); } } } return match; }
static bool is_filtered_file(struct direntry *file, const char *UNUSED(root), FileListFilter *filter) { bool is_filtered = !is_hidden_file(file->relname, filter); if (is_filtered && filter->filter && !FILENAME_IS_CURRPAR(file->relname)) { if ((file->type & S_IFDIR) && !(filter->filter & FILE_TYPE_FOLDER)) { is_filtered = false; } if (!(file->type & S_IFDIR) && !(file->flags & filter->filter)) { is_filtered = false; } if (is_filtered && (filter->filter_search[0] != '\0')) { if (fnmatch(filter->filter_search, file->relname, FNM_CASEFOLD) != 0) { is_filtered = false; } } } return is_filtered; }
static bool is_filtered_lib(struct direntry *file, const char *root, FileListFilter *filter) { bool is_filtered = !is_hidden_file(file->relname, filter); char dir[FILE_MAXDIR], group[BLO_GROUP_MAX]; if (BLO_is_a_library(root, dir, group)) { is_filtered = !is_hidden_file(file->relname, filter); if (is_filtered && filter->filter && !FILENAME_IS_CURRPAR(file->relname)) { if (is_filtered && (filter->filter_search[0] != '\0')) { if (fnmatch(filter->filter_search, file->relname, FNM_CASEFOLD) != 0) { is_filtered = false; } } } } else { is_filtered = is_filtered_file(file, root, filter); } return is_filtered; }
/** * Scans \a startfrom, generating a corresponding destination name for each item found by * prefixing it with startto, recursively scanning subdirectories, and invoking the specified * callbacks for files and subdirectories found as appropriate. * * \param startfrom Top-level source path. * \param startto Top-level destination path. * \param callback_dir_pre Optional, to be invoked before entering a subdirectory, can return * RecursiveOp_Callback_StopRecurs to skip the subdirectory. * \param callback_file Optional, to be invoked on each file found. * \param callback_dir_post optional, to be invoked after leaving a subdirectory. * \return */ static int recursive_operation(const char *startfrom, const char *startto, RecursiveOp_Callback callback_dir_pre, RecursiveOp_Callback callback_file, RecursiveOp_Callback callback_dir_post) { struct stat st; char *from = NULL, *to = NULL; char *from_path = NULL, *to_path = NULL; struct dirent **dirlist = NULL; size_t from_alloc_len = -1, to_alloc_len = -1; int i, n, ret = 0; do { /* once */ /* ensure there's no trailing slash in file path */ from = strip_last_slash(startfrom); if (startto) to = strip_last_slash(startto); ret = lstat(from, &st); if (ret < 0) /* source wasn't found, nothing to operate with */ break; if (!S_ISDIR(st.st_mode)) { /* source isn't a directory, can't do recursive walking for it, * so just call file callback and leave */ if (callback_file != NULL) { ret = callback_file(from, to); if (ret != RecursiveOp_Callback_OK) ret = -1; } break; } n = scandir(startfrom, &dirlist, NULL, alphasort); if (n < 0) { /* error opening directory for listing */ perror("scandir"); ret = -1; break; } if (callback_dir_pre != NULL) { ret = callback_dir_pre(from, to); if (ret != RecursiveOp_Callback_OK) { if (ret == RecursiveOp_Callback_StopRecurs) /* callback requested not to perform recursive walking, not an error */ ret = 0; else ret = -1; break; } } for (i = 0; i < n; i++) { const struct dirent * const dirent = dirlist[i]; if (FILENAME_IS_CURRPAR(dirent->d_name)) continue; join_dirfile_alloc(&from_path, &from_alloc_len, from, dirent->d_name); if (to) join_dirfile_alloc(&to_path, &to_alloc_len, to, dirent->d_name); if (dirent->d_type == DT_DIR) { /* recursively dig into a subfolder */ ret = recursive_operation(from_path, to_path, callback_dir_pre, callback_file, callback_dir_post); } else if (callback_file != NULL) { ret = callback_file(from_path, to_path); if (ret != RecursiveOp_Callback_OK) ret = -1; } if (ret != 0) break; } if (ret != 0) break; if (callback_dir_post != NULL) { ret = callback_dir_post(from, to); if (ret != RecursiveOp_Callback_OK) ret = -1; } } while (false); if (dirlist != NULL) { for (i = 0; i < n; i++) { free(dirlist[i]); } free(dirlist); } if (from_path != NULL) MEM_freeN(from_path); if (to_path != NULL) MEM_freeN(to_path); if (from != NULL) MEM_freeN(from); if (to != NULL) MEM_freeN(to); return ret; }
void file_draw_list(const bContext *C, ARegion *ar) { SpaceFile *sfile = CTX_wm_space_file(C); FileSelectParams *params = ED_fileselect_get_params(sfile); FileLayout *layout = ED_fileselect_get_layout(sfile, ar); View2D *v2d = &ar->v2d; struct FileList *files = sfile->files; struct direntry *file; ImBuf *imb; uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS); int numfiles; int numfiles_layout; int sx, sy; int offset; int textwidth, textheight; int i; bool is_icon; short align; bool do_drag; int column_space = 0.6f * UI_UNIT_X; numfiles = filelist_numfiles(files); if (params->display != FILE_IMGDISPLAY) { draw_background(layout, v2d); draw_dividers(layout, v2d); } offset = ED_fileselect_layout_offset(layout, (int)ar->v2d.cur.xmin, (int)-ar->v2d.cur.ymax); if (offset < 0) offset = 0; numfiles_layout = ED_fileselect_layout_numfiles(layout, ar); /* adjust, so the next row is already drawn when scrolling */ if (layout->flag & FILE_LAYOUT_HOR) { numfiles_layout += layout->rows; } else { numfiles_layout += layout->columns; } textwidth = (FILE_IMGDISPLAY == params->display) ? layout->tile_w : (int)layout->column_widths[COLUMN_NAME]; textheight = (int)(layout->textheight * 3.0 / 2.0 + 0.5); align = (FILE_IMGDISPLAY == params->display) ? UI_STYLE_TEXT_CENTER : UI_STYLE_TEXT_LEFT; for (i = offset; (i < numfiles) && (i < offset + numfiles_layout); i++) { ED_fileselect_layout_tilepos(layout, i, &sx, &sy); sx += (int)(v2d->tot.xmin + 0.1f * UI_UNIT_X); sy = (int)(v2d->tot.ymax - sy); file = filelist_file(files, i); UI_ThemeColor4(TH_TEXT); if (!(file->selflag & FILE_SEL_EDITING)) { if ((params->highlight_file == i) || (file->selflag & FILE_SEL_HIGHLIGHTED) || (file->selflag & FILE_SEL_SELECTED)) { int colorid = (file->selflag & FILE_SEL_SELECTED) ? TH_HILITE : TH_BACK; int shade = (params->highlight_file == i) || (file->selflag & FILE_SEL_HIGHLIGHTED) ? 35 : 0; BLI_assert(i > 0 || FILENAME_IS_CURRPAR(file->relname)); draw_tile(sx, sy - 1, layout->tile_w + 4, sfile->layout->tile_h + layout->tile_border_y, colorid, shade); } } UI_draw_roundbox_corner_set(UI_CNR_NONE); /* don't drag parent or refresh items */ do_drag = !(FILENAME_IS_CURRPAR(file->relname)); if (FILE_IMGDISPLAY == params->display) { is_icon = 0; imb = filelist_getimage(files, i); if (!imb) { imb = filelist_geticon(files, i); is_icon = 1; } file_draw_preview(block, file, sx, sy, imb, layout, is_icon, do_drag); } else { file_draw_icon(block, file->path, sx, sy - (UI_UNIT_Y / 6), get_file_icon(file), ICON_DEFAULT_WIDTH_SCALE, ICON_DEFAULT_HEIGHT_SCALE, do_drag); sx += ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X; } UI_ThemeColor4(TH_TEXT); if (file->selflag & FILE_SEL_EDITING) { uiBut *but; short width; if (params->display == FILE_SHORTDISPLAY) { width = layout->tile_w - (ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X); } else if (params->display == FILE_LONGDISPLAY) { width = layout->column_widths[COLUMN_NAME] + layout->column_widths[COLUMN_MODE1] + layout->column_widths[COLUMN_MODE2] + layout->column_widths[COLUMN_MODE3] + (column_space * 3.5f); } else { BLI_assert(params->display == FILE_IMGDISPLAY); width = textwidth; } but = uiDefBut(block, UI_BTYPE_TEXT, 1, "", sx, sy - layout->tile_h - 0.15f * UI_UNIT_X, width, textheight, sfile->params->renameedit, 1.0f, (float)sizeof(sfile->params->renameedit), 0, 0, ""); UI_but_func_rename_set(but, renamebutton_cb, file); UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */ UI_but_flag_disable(but, UI_BUT_UNDO); if (false == UI_but_active_only(C, ar, block, but)) { file->selflag &= ~FILE_SEL_EDITING; } } if (!(file->selflag & FILE_SEL_EDITING)) { int tpos = (FILE_IMGDISPLAY == params->display) ? sy - layout->tile_h + layout->textheight : sy; file_draw_string(sx + 1, tpos, file->relname, (float)textwidth, textheight, align); } if (params->display == FILE_SHORTDISPLAY) { sx += (int)layout->column_widths[COLUMN_NAME] + column_space; if (!(file->type & S_IFDIR)) { file_draw_string(sx, sy, file->size, layout->column_widths[COLUMN_SIZE], layout->tile_h, align); sx += (int)layout->column_widths[COLUMN_SIZE] + column_space; } } else if (params->display == FILE_LONGDISPLAY) { sx += (int)layout->column_widths[COLUMN_NAME] + column_space; #ifndef WIN32 /* rwx rwx rwx */ file_draw_string(sx, sy, file->mode1, layout->column_widths[COLUMN_MODE1], layout->tile_h, align); sx += layout->column_widths[COLUMN_MODE1] + column_space; file_draw_string(sx, sy, file->mode2, layout->column_widths[COLUMN_MODE2], layout->tile_h, align); sx += layout->column_widths[COLUMN_MODE2] + column_space; file_draw_string(sx, sy, file->mode3, layout->column_widths[COLUMN_MODE3], layout->tile_h, align); sx += layout->column_widths[COLUMN_MODE3] + column_space; file_draw_string(sx, sy, file->owner, layout->column_widths[COLUMN_OWNER], layout->tile_h, align); sx += layout->column_widths[COLUMN_OWNER] + column_space; #endif file_draw_string(sx, sy, file->date, layout->column_widths[COLUMN_DATE], layout->tile_h, align); sx += (int)layout->column_widths[COLUMN_DATE] + column_space; file_draw_string(sx, sy, file->time, layout->column_widths[COLUMN_TIME], layout->tile_h, align); sx += (int)layout->column_widths[COLUMN_TIME] + column_space; if (!(file->type & S_IFDIR)) { file_draw_string(sx, sy, file->size, layout->column_widths[COLUMN_SIZE], layout->tile_h, align); sx += (int)layout->column_widths[COLUMN_SIZE] + column_space; } } } UI_block_end(C, block); UI_block_draw(C, block); }