예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
/**
 * 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;
}
예제 #6
0
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);

}