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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to