[Bf-blender-cvs] [9939e78] asset-experiments: Reworked 'flat' mode, added it outside of blendfiles (libraries).

Bastien Montagne noreply at git.blender.org
Fri Dec 5 16:47:20 CET 2014


Commit: 9939e783a92b9a056a1b74bfb2b2900769fcb8d1
Author: Bastien Montagne
Date:   Fri Dec 5 16:43:57 2014 +0100
Branches: asset-experiments
https://developer.blender.org/rB9939e783a92b9a056a1b74bfb2b2900769fcb8d1

Reworked 'flat' mode, added it outside of blendfiles (libraries).

Note this is WIP, it 'breaks' load/append/etc. operators to some points,
and many other 'details' that need to be addressed.

===================================================================

M	release/scripts/startup/bl_ui/space_filebrowser.py
M	source/blender/editors/space_file/file_ops.c
M	source/blender/editors/space_file/filelist.c
M	source/blender/editors/space_file/filelist.h
M	source/blender/editors/space_file/filesel.c
M	source/blender/editors/space_file/space_file.c
M	source/blender/makesdna/DNA_space_types.h
M	source/blender/makesrna/intern/rna_space.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py
index 794c8ba..cd4f237 100644
--- a/release/scripts/startup/bl_ui/space_filebrowser.py
+++ b/release/scripts/startup/bl_ui/space_filebrowser.py
@@ -56,6 +56,7 @@ class FILEBROWSER_HT_header(Header):
             layout.prop(params, "sort_method", expand=True, text="")
 
             layout.prop(params, "show_hidden")
+            layout.prop(params, "use_flat_view")
             layout.prop(params, "use_filter", text="", icon='FILTER')
 
             row = layout.row(align=True)
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 6912970..df3f989 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -859,7 +859,7 @@ int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
 		if (BLI_parent_dir(sfile->params->dir)) {
 			BLI_cleanup_dir(G.main->name, sfile->params->dir);
 			/* if not browsing in .blend file, we still want to check whether the path is a directory */
-			if (ELEM(sfile->params->type, FILE_LOADLIB, FILE_ASSET)) {
+			if (sfile->params->type == FILE_LOADLIB) {
 				char tdir[FILE_MAX], tgroup[FILE_MAX];
 				if (BLO_is_a_library(sfile->params->dir, tdir, tgroup)) {
 					file_change_dir(C, 0);
@@ -1334,7 +1334,7 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
 				UI_textbutton_activate_but(C, but);
 				WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
 			}
-			else if (ELEM(sfile->params->type, FILE_LOADLIB, FILE_ASSET)) {
+			else if (sfile->params->type == FILE_LOADLIB) {
 				char tdir[FILE_MAX], tgroup[FILE_MAX];
 				BLI_add_slash(filepath);
 				if (BLO_is_a_library(filepath, tdir, tgroup)) {
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 3339b39..ecfdff9 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -126,8 +126,15 @@ typedef struct FileList {
 	void (*readf)(struct FileList *);
 	bool (*filterf)(struct direntry *file, const char *dir, FileListFilter *filter);
 
+	bool use_recursion;
+	short recursion_level;
 } FileList;
 
+#define FILELIST_MAX_RECURSION 3
+
+#define FILENAME_IS_BREADCRUMBS(_n) \
+	(((_n)[0] == '.' && (_n)[1] == '\0') || ((_n)[0] == '.' && (_n)[1] == '.' && (_n)[2] == '\0'))
+
 typedef struct FolderList {
 	struct FolderList *next, *prev;
 	char *foldername;
@@ -410,7 +417,6 @@ ListBase *folderlist_duplicate(ListBase *folderlist)
 
 static void filelist_read_main(struct FileList *filelist);
 static void filelist_read_library(struct FileList *filelist);
-static void filelist_read_library_flat(struct FileList *filelist);
 static void filelist_read_dir(struct FileList *filelist);
 
 static void filelist_from_library(struct FileList *filelist, const bool add_parent, const bool use_filter);
@@ -426,9 +432,6 @@ static bool is_hidden_file(const char *filename, const bool hide_dot)
 		if (filename[0] == '.' && filename[1] != '.' && filename[1] != 0) {
 			is_hidden = true; /* ignore .file */
 		}
-		else if (((filename[0] == '.') && (filename[1] == 0))) {
-			is_hidden = true; /* ignore . */
-		}
 		else {
 			int len = strlen(filename);
 			if ((len > 0) && (filename[len - 1] == '~')) {
@@ -436,64 +439,48 @@ static bool is_hidden_file(const char *filename, const bool hide_dot)
 			}
 		}
 	}
-	else {
-		if (((filename[0] == '.') && (filename[1] == 0))) {
-			is_hidden = true; /* ignore . */
-		}
+	if (((filename[0] == '.') && (filename[1] == 0))) {
+		is_hidden = true; /* ignore . */
 	}
 	return is_hidden;
 }
 
-static bool is_filtered_file(struct direntry *file, const char *UNUSED(dir), FileListFilter *filter)
+static bool is_filtered_file(struct direntry *file, const char *UNUSED(root), FileListFilter *filter)
 {
 	bool is_filtered = false;
 	if (filter->filter) {
 		if (file->flags & filter->filter) {
 			is_filtered = true;
 		}
-		else if (file->type & S_IFDIR) {
-			if (filter->filter & FOLDERFILE) {
-				is_filtered = true;
-			}
+		else if ((file->type & S_IFDIR) && ((filter->filter & FOLDERFILE) || FILENAME_IS_BREADCRUMBS(file->relname))) {
+			is_filtered = true;
 		}
 	}
 	else {
 		is_filtered = true;
 	}
-	is_filtered = is_filtered && !is_hidden_file(file->relname, filter->hide_dot);
+	if (is_filtered) {
+		is_filtered = !is_hidden_file(file->relname, filter->hide_dot);
+	}
 	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 *dir, FileListFilter *filter)
-{
-	bool is_filtered = false;
-	char tdir[FILE_MAX], tgroup[BLO_GROUP_MAX];
-	if (BLO_is_a_library(dir, tdir, tgroup)) {
-		is_filtered = !is_hidden_file(file->relname, filter->hide_dot);
-		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, dir, filter);
-	}
 	return is_filtered;
 }
 
-static bool is_filtered_lib_flat(struct direntry *file, const char *dir, FileListFilter *filter)
+static bool is_filtered_lib(struct direntry *file, const char *root, FileListFilter *filter)
 {
 	bool is_filtered = false;
-	char tdir[FILE_MAX], tgroup[BLO_GROUP_MAX];
-	if (BLO_is_a_library(dir, tdir, tgroup)) {
+	char path[FILE_MAX_LIBEXTRA], dir[FILE_MAXDIR], group[BLO_GROUP_MAX];
+
+	BLI_join_dirfile(path, sizeof(path), dir, file->relname);
+
+	if (BLO_library_path_explode(path, dir, group, NULL)) {
 		is_filtered = !is_hidden_file(file->relname, filter->hide_dot);
-		if (filter && !(filter->filter & FOLDERFILE) && (file->type & S_IFDIR) && !STREQ(file->relname, "..")) {
+		if (is_filtered && (file->type & S_IFDIR) && !(filter->filter & FOLDERFILE) && !FILENAME_IS_BREADCRUMBS(file->relname)) {
 			is_filtered = false;
 		}
 		if (is_filtered && (filter->filter_search[0] != '\0')) {
@@ -503,8 +490,9 @@ static bool is_filtered_lib_flat(struct direntry *file, const char *dir, FileLis
 		}
 	}
 	else {
-		is_filtered = is_filtered_file(file, dir, filter);
+		is_filtered = is_filtered_file(file, root, filter);
 	}
+
 	return is_filtered;
 }
 
@@ -590,6 +578,7 @@ void filelist_free_icons(void)
 FileList *filelist_new(short type)
 {
 	FileList *p = MEM_callocN(sizeof(FileList), "filelist");
+
 	switch (type) {
 		case FILE_MAIN:
 			p->readf = filelist_read_main;
@@ -599,15 +588,10 @@ FileList *filelist_new(short type)
 			p->readf = filelist_read_library;
 			p->filterf = is_filtered_lib;
 			break;
-		case FILE_ASSET:
-			p->readf = filelist_read_library_flat;
-			p->filterf = is_filtered_lib_flat;
-			break;
 		default:
 			p->readf = filelist_read_dir;
 			p->filterf = is_filtered_file;
 			break;
-
 	}
 	return p;
 }
@@ -659,6 +643,11 @@ void filelist_setdir(struct FileList *filelist, const char *dir)
 	BLI_strncpy(filelist->dir, dir, sizeof(filelist->dir));
 }
 
+void filelist_setrecursive(struct FileList *filelist, const bool use_recursion)
+{
+	filelist->use_recursion = use_recursion;
+}
+
 void filelist_imgsize(struct FileList *filelist, short w, short h)
 {
 	filelist->prv_w = w;
@@ -1049,16 +1038,104 @@ static void filelist_setfiletypes(struct FileList *filelist)
 	}
 }
 
+static void filelist_merge_sublist(struct direntry **filelist_buff, int *filelist_buff_size, int *filelist_used_size,
+                                   const char *root, struct FileList *sublist)
+{
+	if (sublist->numfiles) {
+		struct direntry *f;
+		int new_numfiles = sublist->numfiles + *filelist_used_size;
+		char dir[FILE_MAX];
+		int i, j;
+
+		if (new_numfiles > *filelist_buff_size) {
+			struct direntry *new_filelist;
+
+			*filelist_buff_size = new_numfiles * 2;
+			new_filelist = malloc(sizeof(*new_filelist) * (size_t)*filelist_buff_size);
+			if (*filelist_buff && *filelist_used_size) {
+				memcpy(new_filelist, *filelist_buff, sizeof(*new_filelist) * (size_t)*filelist_used_size);
+				free(*filelist_buff);
+			}
+			*filelist_buff = new_filelist;
+		}
+		for (i = *filelist_used_size, j = 0, f = sublist->filelist; j < sublist->numfiles; j++, f++) {
+			if (FILENAME_IS_BREADCRUMBS(f->relname)) {
+				/* Ignore 'inner' breadcrumbs! */
+				new_numfiles--;
+				continue;
+			}
+			BLI_join_dirfile(dir, sizeof(dir), sublist->dir, f->relname);
+			BLI_cleanup_file(root, dir);
+			BLI_path_rel(dir, root);
+			(*filelist_buff)[i] = *f;
+			(*filelist_buff)[i].relname = BLI_strdup(dir + 2);  /* + 2 to remove '//' added by BLI_path_rel */
+			/* those pointers are given to new_filelist... */
+			f->path = NULL;
+			f->poin = NULL;
+			f->image = NULL;
+			i++;
+		}
+
+		*filelist_used_size = new_numfiles;
+	}
+}
+
 static void filelist_read_dir(struct FileList *filelist)
 {
-	if (!filelist) return;
+	/* only used if recursing, will contain all non-immediate children then. */
+	struct direntry *file;
+	struct direntry *new_filelist = NULL;
+	int new_filelist_size = 0, new_filelist_buffsize = 0;
+	int i;
 
-	filelist->fidx = NULL;
-	filelist->filelist = NULL;
+	if (!filelist) {
+		return;
+	}
+
+	BLI_assert(filelist->fidx == NULL);
+	BLI_assert(filelist->filelist == NULL);
 
 	BLI_cleanup_dir(G.main->name, filelist->dir);
 	filelist->numfiles = BLI_dir_contents(filelist->dir, &(filelist->filelist));
 
+	if (filelist->use_recursion && filelist->recursion_level < FILELIST_MAX_RECURSION) {
+		file = filelist->filelist;
+		for (i = 0; i < filelist->numfiles; i++, file++) {
+			FileList *fl;
+			char dir[FILE_MAX];
+
+			if (FILENAME_IS_BREADCRUMBS(file->relname) || (file->type & S_IFDIR) == 0) {
+				continue;
+			}
+
+			fl = filelist_new(FILE_UNIX);
+			fl->use_recursion = true;
+			fl->recursion_level = filelist->recursion_level + 1;
+
+			BLI_join_dirfile(dir, sizeof(dir), filelist->dir, file->relname);
+			filelist_setdir(fl, dir);
+			BLI_cleanup_dir(G.main->name, fl->dir);
+			filelist_read_dir(fl);
+
+			filelist_merge_sublist(&new_filelist, &new_filelist_buffsize, &new_filelist_size, filelist->dir, fl)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list