Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_file/filelist.c')
-rw-r--r--source/blender/editors/space_file/filelist.c966
1 files changed, 502 insertions, 464 deletions
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 871abbda48a..bcef0817ffe 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -45,9 +45,10 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_fileops_types.h"
+#include "BLI_fnmatch.h"
#include "BLI_linklist.h"
#include "BLI_utildefines.h"
-#include "BLI_fileops_types.h"
#ifdef WIN32
# include "BLI_winstuff.h"
@@ -64,8 +65,8 @@
#include "DNA_space_types.h"
-#include "ED_fileselect.h"
#include "ED_datafiles.h"
+#include "ED_fileselect.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -80,6 +81,119 @@
#include "filelist.h"
+
+/* ----------------- FOLDERLIST (previous/next) -------------- */
+
+typedef struct FolderList {
+ struct FolderList *next, *prev;
+ char *foldername;
+} FolderList;
+
+ListBase *folderlist_new(void)
+{
+ ListBase *p = MEM_callocN(sizeof(ListBase), "folderlist");
+ return p;
+}
+
+void folderlist_popdir(struct ListBase *folderlist, char *dir)
+{
+ const char *prev_dir;
+ struct FolderList *folder;
+ folder = folderlist->last;
+
+ if (folder) {
+ /* remove the current directory */
+ MEM_freeN(folder->foldername);
+ BLI_freelinkN(folderlist, folder);
+
+ folder = folderlist->last;
+ if (folder) {
+ prev_dir = folder->foldername;
+ BLI_strncpy(dir, prev_dir, FILE_MAXDIR);
+ }
+ }
+ /* delete the folder next or use setdir directly before PREVIOUS OP */
+}
+
+void folderlist_pushdir(ListBase *folderlist, const char *dir)
+{
+ struct FolderList *folder, *previous_folder;
+ previous_folder = folderlist->last;
+
+ /* check if already exists */
+ if (previous_folder && previous_folder->foldername) {
+ if (BLI_path_cmp(previous_folder->foldername, dir) == 0) {
+ return;
+ }
+ }
+
+ /* create next folder element */
+ folder = (FolderList *)MEM_mallocN(sizeof(FolderList), "FolderList");
+ folder->foldername = BLI_strdup(dir);
+
+ /* add it to the end of the list */
+ BLI_addtail(folderlist, folder);
+}
+
+const char *folderlist_peeklastdir(ListBase *folderlist)
+{
+ struct FolderList *folder;
+
+ if (!folderlist->last)
+ return NULL;
+
+ folder = folderlist->last;
+ return folder->foldername;
+}
+
+int folderlist_clear_next(struct SpaceFile *sfile)
+{
+ struct FolderList *folder;
+
+ /* if there is no folder_next there is nothing we can clear */
+ if (!sfile->folders_next)
+ return 0;
+
+ /* if previous_folder, next_folder or refresh_folder operators are executed it doesn't clear folder_next */
+ folder = sfile->folders_prev->last;
+ if ((!folder) || (BLI_path_cmp(folder->foldername, sfile->params->dir) == 0))
+ return 0;
+
+ /* eventually clear flist->folders_next */
+ return 1;
+}
+
+/* not listbase itself */
+void folderlist_free(ListBase *folderlist)
+{
+ if (folderlist) {
+ FolderList *folder;
+ for (folder = folderlist->first; folder; folder = folder->next)
+ MEM_freeN(folder->foldername);
+ BLI_freelistN(folderlist);
+ }
+}
+
+ListBase *folderlist_duplicate(ListBase *folderlist)
+{
+
+ if (folderlist) {
+ ListBase *folderlistn = MEM_callocN(sizeof(ListBase), "copy folderlist");
+ FolderList *folder;
+
+ BLI_duplicatelist(folderlistn, folderlist);
+
+ for (folder = folderlistn->first; folder; folder = folder->next) {
+ folder->foldername = MEM_dupallocN(folder->foldername);
+ }
+ return folderlistn;
+ }
+ return NULL;
+}
+
+
+/* ------------------FILELIST------------------------ */
+
struct FileList;
typedef struct FileImage {
@@ -91,77 +205,87 @@ typedef struct FileImage {
ImBuf *img;
} FileImage;
-typedef struct ThumbnailJob {
- ListBase loadimages;
- const short *stop;
- const short *do_update;
- struct FileList *filelist;
- ReportList reports;
-} ThumbnailJob;
+typedef struct FileListFilter {
+ bool hide_dot;
+ bool hide_parent;
+ unsigned int filter;
+ char filter_glob[64];
+ char filter_search[66]; /* + 2 for heading/trailing implicit '*' wildcards. */
+} FileListFilter;
typedef struct FileList {
struct direntry *filelist;
- int *fidx;
int numfiles;
- int numfiltered;
char dir[FILE_MAX];
short prv_w;
short prv_h;
- short hide_dot;
- unsigned int filter;
- char filter_glob[64];
- short changed;
+
+ bool changed;
+
+ short sort;
+ bool need_sorting;
+
+ FileListFilter filter_data;
+ int *fidx; /* Also used to detect when we need to filter! */
+ int numfiltered;
+
+ bool need_thumbnails;
struct BlendHandle *libfiledata;
- short hide_parent;
void (*readf)(struct FileList *);
- bool (*filterf)(struct direntry *file, const char *dir, unsigned int filter, short hide_dot);
-
+ bool (*filterf)(struct direntry *, const char *, FileListFilter *);
} FileList;
-typedef struct FolderList {
- struct FolderList *next, *prev;
- char *foldername;
-} FolderList;
+#define FILENAME_IS_BREADCRUMBS(_n) \
+ ((_n)[0] == '.' && ((_n)[1] == '\0' || ((_n)[1] == '.' && (_n)[2] == '\0')))
#define SPECIAL_IMG_SIZE 48
#define SPECIAL_IMG_ROWS 4
#define SPECIAL_IMG_COLS 4
-#define SPECIAL_IMG_FOLDER 0
-#define SPECIAL_IMG_PARENT 1
-#define SPECIAL_IMG_REFRESH 2
-#define SPECIAL_IMG_BLENDFILE 3
-#define SPECIAL_IMG_SOUNDFILE 4
-#define SPECIAL_IMG_MOVIEFILE 5
-#define SPECIAL_IMG_PYTHONFILE 6
-#define SPECIAL_IMG_TEXTFILE 7
-#define SPECIAL_IMG_FONTFILE 8
-#define SPECIAL_IMG_UNKNOWNFILE 9
-#define SPECIAL_IMG_LOADING 10
-#define SPECIAL_IMG_BACKUP 11
-#define SPECIAL_IMG_MAX SPECIAL_IMG_BACKUP + 1
+enum {
+ SPECIAL_IMG_FOLDER = 0,
+ SPECIAL_IMG_PARENT = 1,
+ SPECIAL_IMG_REFRESH = 2,
+ SPECIAL_IMG_BLENDFILE = 3,
+ SPECIAL_IMG_SOUNDFILE = 4,
+ SPECIAL_IMG_MOVIEFILE = 5,
+ SPECIAL_IMG_PYTHONFILE = 6,
+ SPECIAL_IMG_TEXTFILE = 7,
+ SPECIAL_IMG_FONTFILE = 8,
+ SPECIAL_IMG_UNKNOWNFILE = 9,
+ SPECIAL_IMG_LOADING = 10,
+ SPECIAL_IMG_BACKUP = 11,
+ SPECIAL_IMG_MAX
+};
static ImBuf *gSpecialFileImages[SPECIAL_IMG_MAX];
-/* ******************* SORT ******************* */
+static void filelist_from_main(struct FileList *filelist);
+static void filelist_from_library(struct FileList *filelist);
+
+static void filelist_read_main(struct FileList *filelist);
+static void filelist_read_library(struct FileList *filelist);
+static void filelist_read_dir(struct FileList *filelist);
+
+static void filelist_filter_clear(FileList *filelist);
+
+/* ********** Sort helpers ********** */
static bool compare_is_directory(const struct direntry *entry)
{
/* for library browse .blend files may be treated as directories, but
* for sorting purposes they should be considered regular files */
if (S_ISDIR(entry->type))
- return !(entry->flags & (BLENDERFILE | BLENDERFILE_BACKUP));
+ return !(entry->flags & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP));
return false;
}
-static int compare_name(const void *a1, const void *a2)
+static int compare_direntry_generic(const struct direntry *entry1, const struct direntry *entry2)
{
- const struct direntry *entry1 = a1, *entry2 = a2;
-
/* type is equal to stat.st_mode */
if (compare_is_directory(entry1)) {
@@ -185,35 +309,29 @@ static int compare_name(const void *a1, const void *a2)
if (strcmp(entry1->relname, "..") == 0) return (-1);
if (strcmp(entry2->relname, "..") == 0) return (1);
+ return 0;
+}
+
+static int compare_name(const void *a1, const void *a2)
+{
+ const struct direntry *entry1 = a1, *entry2 = a2;
+ int ret;
+
+ if ((ret = compare_direntry_generic(entry1, entry2))) {
+ return ret;
+ }
+
return (BLI_natstrcmp(entry1->relname, entry2->relname));
}
static int compare_date(const void *a1, const void *a2)
{
const struct direntry *entry1 = a1, *entry2 = a2;
+ int ret;
- /* type is equal to stat.st_mode */
-
- if (compare_is_directory(entry1)) {
- if (compare_is_directory(entry2) == 0) return (-1);
+ if ((ret = compare_direntry_generic(entry1, entry2))) {
+ return ret;
}
- else {
- if (compare_is_directory(entry2)) return (1);
- }
- if (S_ISREG(entry1->type)) {
- if (S_ISREG(entry2->type) == 0) return (-1);
- }
- else {
- if (S_ISREG(entry2->type)) return (1);
- }
- if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
- if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
-
- /* make sure "." and ".." are always first */
- if (strcmp(entry1->relname, ".") == 0) return (-1);
- if (strcmp(entry2->relname, ".") == 0) return (1);
- if (strcmp(entry1->relname, "..") == 0) return (-1);
- if (strcmp(entry2->relname, "..") == 0) return (1);
if (entry1->s.st_mtime < entry2->s.st_mtime) return 1;
if (entry1->s.st_mtime > entry2->s.st_mtime) return -1;
@@ -224,29 +342,11 @@ static int compare_date(const void *a1, const void *a2)
static int compare_size(const void *a1, const void *a2)
{
const struct direntry *entry1 = a1, *entry2 = a2;
+ int ret;
- /* type is equal to stat.st_mode */
-
- if (compare_is_directory(entry1)) {
- if (compare_is_directory(entry2) == 0) return (-1);
- }
- else {
- if (compare_is_directory(entry2)) return (1);
- }
- if (S_ISREG(entry1->type)) {
- if (S_ISREG(entry2->type) == 0) return (-1);
+ if ((ret = compare_direntry_generic(entry1, entry2))) {
+ return ret;
}
- else {
- if (S_ISREG(entry2->type)) return (1);
- }
- if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
- if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
-
- /* make sure "." and ".." are always first */
- if (strcmp(entry1->relname, ".") == 0) return (-1);
- if (strcmp(entry2->relname, ".") == 0) return (1);
- if (strcmp(entry1->relname, "..") == 0) return (-1);
- if (strcmp(entry2->relname, "..") == 0) return (1);
if (entry1->s.st_size < entry2->s.st_size) return 1;
if (entry1->s.st_size > entry2->s.st_size) return -1;
@@ -258,6 +358,11 @@ static int compare_extension(const void *a1, const void *a2)
const struct direntry *entry1 = a1, *entry2 = a2;
const char *sufix1, *sufix2;
const char *nil = "";
+ int ret;
+
+ if ((ret = compare_direntry_generic(entry1, entry2))) {
+ return ret;
+ }
if (!(sufix1 = strstr(entry1->relname, ".blend.gz")))
sufix1 = strrchr(entry1->relname, '.');
@@ -266,126 +371,191 @@ static int compare_extension(const void *a1, const void *a2)
if (!sufix1) sufix1 = nil;
if (!sufix2) sufix2 = nil;
- /* type is equal to stat.st_mode */
+ return (BLI_strcasecmp(sufix1, sufix2));
+}
- if (compare_is_directory(entry1)) {
- if (compare_is_directory(entry2) == 0) return (-1);
- }
- else {
- if (compare_is_directory(entry2)) return (1);
- }
- if (S_ISREG(entry1->type)) {
- if (S_ISREG(entry2->type) == 0) return (-1);
+bool filelist_need_sorting(struct FileList *filelist)
+{
+ return filelist->need_sorting && (filelist->sort != FILE_SORT_NONE);
+}
+
+void filelist_sort(struct FileList *filelist)
+{
+ if (filelist_need_sorting(filelist)) {
+ filelist->need_sorting = false;
+
+ switch (filelist->sort) {
+ case FILE_SORT_ALPHA:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_name);
+ break;
+ case FILE_SORT_TIME:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_date);
+ break;
+ case FILE_SORT_SIZE:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_size);
+ break;
+ case FILE_SORT_EXTENSION:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension);
+ break;
+ case FILE_SORT_NONE: /* Should never reach this point! */
+ default:
+ BLI_assert(0);
+ return;
+ }
+
+ filelist_filter_clear(filelist);
}
- else {
- if (S_ISREG(entry2->type)) return (1);
+}
+
+void filelist_setsorting(struct FileList *filelist, const short sort)
+{
+ if (filelist->sort != sort) {
+ filelist->sort = sort;
+ filelist->need_sorting = true;
}
- if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
- if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
-
- /* make sure "." and ".." are always first */
- if (strcmp(entry1->relname, ".") == 0) return (-1);
- if (strcmp(entry2->relname, ".") == 0) return (1);
- if (strcmp(entry1->relname, "..") == 0) return (-1);
- if (strcmp(entry2->relname, "..") == 0) return (1);
-
- return (BLI_strcasecmp(sufix1, sufix2));
}
-static bool is_hidden_file(const char *filename, short hide_dot)
+/* ********** Filter helpers ********** */
+
+static bool is_hidden_file(const char *filename, FileListFilter *filter)
{
bool is_hidden = false;
- if (hide_dot) {
- if (filename[0] == '.' && filename[1] != '.' && filename[1] != 0) {
- is_hidden = 1; /* ignore .file */
- }
- else if (((filename[0] == '.') && (filename[1] == 0))) {
- is_hidden = 1; /* ignore . */
+ if (filter->hide_dot) {
+ if (filename[0] == '.' && filename[1] != '.' && filename[1] != '\0') {
+ is_hidden = true; /* ignore .file */
}
else {
int len = strlen(filename);
if ((len > 0) && (filename[len - 1] == '~')) {
- is_hidden = 1; /* ignore file~ */
+ is_hidden = true; /* ignore file~ */
}
}
}
- else {
- if (((filename[0] == '.') && (filename[1] == 0))) {
- is_hidden = 1; /* ignore . */
+ if (!is_hidden && filter->hide_parent) {
+ if (filename[0] == '.' && filename[1] == '.' && filename[2] == '\0') {
+ is_hidden = true; /* ignore .. */
}
}
+ if (!is_hidden && ((filename[0] == '.') && (filename[1] == '\0'))) {
+ is_hidden = true; /* ignore . */
+ }
return is_hidden;
}
-static bool is_filtered_file(struct direntry *file, const char *UNUSED(dir), unsigned int filter, short hide_dot)
+static bool is_filtered_file(struct direntry *file, const char *UNUSED(root), FileListFilter *filter)
{
- bool is_filtered = false;
- if (filter) {
- if (file->flags & filter) {
- is_filtered = 1;
+ bool is_filtered = !is_hidden_file(file->relname, filter);
+
+ if (is_filtered && filter->filter && !FILENAME_IS_BREADCRUMBS(file->relname)) {
+ if ((file->type & S_IFDIR) && !(filter->filter & FILE_TYPE_FOLDER)) {
+ is_filtered = false;
}
- else if (file->type & S_IFDIR) {
- if (filter & FOLDERFILE) {
- is_filtered = 1;
+ 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;
}
}
}
- else {
- is_filtered = 1;
- }
- return is_filtered && !is_hidden_file(file->relname, hide_dot);
+
+ return is_filtered;
}
-static bool is_filtered_lib(struct direntry *file, const char *dir, unsigned int filter, short hide_dot)
+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)) {
- is_filtered = !is_hidden_file(file->relname, hide_dot);
+ 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_BREADCRUMBS(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, dir, filter, hide_dot);
+ is_filtered = is_filtered_file(file, root, filter);
}
+
return is_filtered;
}
-static bool is_filtered_main(struct direntry *file, const char *UNUSED(dir), unsigned int UNUSED(filter), short hide_dot)
+static bool is_filtered_main(struct direntry *file, const char *UNUSED(dir), FileListFilter *filter)
+{
+ return !is_hidden_file(file->relname, filter);
+}
+
+static void filelist_filter_clear(FileList *filelist)
{
- return !is_hidden_file(file->relname, hide_dot);
+ MEM_SAFE_FREE(filelist->fidx);
+ filelist->numfiltered = 0;
}
void filelist_filter(FileList *filelist)
{
int num_filtered = 0;
- int i, j;
+ int *fidx_tmp;
+ int i;
- if (!filelist->filelist)
+ if (!filelist->filelist) {
return;
+ }
- /* How many files are left after filter ? */
+ if (filelist->fidx) {
+ /* Assume it has already been filtered, nothing else to do! */
+ return;
+ }
+
+ fidx_tmp = MEM_mallocN(sizeof(*fidx_tmp) * (size_t)filelist->numfiles, __func__);
+
+ /* Filter remap & count how many files are left after filter in a single loop. */
for (i = 0; i < filelist->numfiles; ++i) {
struct direntry *file = &filelist->filelist[i];
- if (filelist->filterf(file, filelist->dir, filelist->filter, filelist->hide_dot)) {
- num_filtered++;
+
+ if (filelist->filterf(file, filelist->dir, &filelist->filter_data)) {
+ fidx_tmp[num_filtered++] = i;
}
}
-
- if (filelist->fidx) {
- MEM_freeN(filelist->fidx);
- filelist->fidx = NULL;
- }
- filelist->fidx = (int *)MEM_callocN(num_filtered * sizeof(int), "filteridx");
+
+ /* Note: maybe we could even accept filelist->fidx to be filelist->numfiles -len allocated? */
+ filelist->fidx = (int *)MEM_mallocN(sizeof(*filelist->fidx) * (size_t)num_filtered, __func__);
+ memcpy(filelist->fidx, fidx_tmp, sizeof(*filelist->fidx) * (size_t)num_filtered);
filelist->numfiltered = num_filtered;
- for (i = 0, j = 0; i < filelist->numfiles; ++i) {
- struct direntry *file = &filelist->filelist[i];
- if (filelist->filterf(file, filelist->dir, filelist->filter, filelist->hide_dot)) {
- filelist->fidx[j++] = i;
- }
+ MEM_freeN(fidx_tmp);
+}
+
+void filelist_setfilter_options(FileList *filelist, const bool hide_dot, const bool hide_parent,
+ const unsigned int filter,
+ const char *filter_glob, const char *filter_search)
+{
+ if ((filelist->filter_data.hide_dot != hide_dot) ||
+ (filelist->filter_data.hide_parent != hide_parent) ||
+ (filelist->filter_data.filter != filter) ||
+ !STREQ(filelist->filter_data.filter_glob, filter_glob) ||
+ (BLI_strcmp_ignore_pad(filelist->filter_data.filter_search, filter_search, '*') != 0))
+ {
+ filelist->filter_data.hide_dot = hide_dot;
+ filelist->filter_data.hide_parent = hide_parent;
+
+ filelist->filter_data.filter = filter;
+ BLI_strncpy(filelist->filter_data.filter_glob, filter_glob, sizeof(filelist->filter_data.filter_glob));
+ BLI_strncpy_ensure_pad(filelist->filter_data.filter_search, filter_search, '*',
+ sizeof(filelist->filter_data.filter_search));
+
+ /* And now, free filtered data so that we now we have to filter again. */
+ filelist_filter_clear(filelist);
}
}
+/* ********** Icon/image helpers ********** */
+
void filelist_init_icons(void)
{
short x, y, k;
@@ -428,115 +598,86 @@ void filelist_free_icons(void)
}
}
-/* -----------------FOLDERLIST (previous/next) -------------- */
-ListBase *folderlist_new(void)
-{
- ListBase *p = MEM_callocN(sizeof(ListBase), "folderlist");
- return p;
-}
-
-void folderlist_popdir(struct ListBase *folderlist, char *dir)
+void filelist_imgsize(struct FileList *filelist, short w, short h)
{
- const char *prev_dir;
- struct FolderList *folder;
- folder = folderlist->last;
-
- if (folder) {
- /* remove the current directory */
- MEM_freeN(folder->foldername);
- BLI_freelinkN(folderlist, folder);
-
- folder = folderlist->last;
- if (folder) {
- prev_dir = folder->foldername;
- BLI_strncpy(dir, prev_dir, FILE_MAXDIR);
- }
- }
- /* delete the folder next or use setdir directly before PREVIOUS OP */
+ filelist->prv_w = w;
+ filelist->prv_h = h;
}
-void folderlist_pushdir(ListBase *folderlist, const char *dir)
+ImBuf *filelist_getimage(struct FileList *filelist, const int index)
{
- struct FolderList *folder, *previous_folder;
- previous_folder = folderlist->last;
-
- /* check if already exists */
- if (previous_folder && previous_folder->foldername) {
- if (BLI_path_cmp(previous_folder->foldername, dir) == 0) {
- return;
- }
- }
-
- /* create next folder element */
- folder = (FolderList *)MEM_mallocN(sizeof(FolderList), "FolderList");
- folder->foldername = BLI_strdup(dir);
-
- /* add it to the end of the list */
- BLI_addtail(folderlist, folder);
-}
+ ImBuf *ibuf = NULL;
+ int fidx = 0;
-const char *folderlist_peeklastdir(ListBase *folderlist)
-{
- struct FolderList *folder;
+ BLI_assert(G.background == false);
- if (!folderlist->last)
+ if ((index < 0) || (index >= filelist->numfiltered)) {
return NULL;
+ }
+ fidx = filelist->fidx[index];
+ ibuf = filelist->filelist[fidx].image;
- folder = folderlist->last;
- return folder->foldername;
+ return ibuf;
}
-int folderlist_clear_next(struct SpaceFile *sfile)
+ImBuf *filelist_geticon(struct FileList *filelist, const int index)
{
- struct FolderList *folder;
-
- /* if there is no folder_next there is nothing we can clear */
- if (!sfile->folders_next)
- return 0;
-
- /* if previous_folder, next_folder or refresh_folder operators are executed it doesn't clear folder_next */
- folder = sfile->folders_prev->last;
- if ((!folder) || (BLI_path_cmp(folder->foldername, sfile->params->dir) == 0))
- return 0;
+ ImBuf *ibuf = NULL;
+ struct direntry *file = NULL;
+ int fidx = 0;
- /* eventually clear flist->folders_next */
- return 1;
-}
+ BLI_assert(G.background == false);
-/* not listbase itself */
-void folderlist_free(ListBase *folderlist)
-{
- if (folderlist) {
- FolderList *folder;
- for (folder = folderlist->first; folder; folder = folder->next)
- MEM_freeN(folder->foldername);
- BLI_freelistN(folderlist);
+ if ((index < 0) || (index >= filelist->numfiltered)) {
+ return NULL;
}
-}
-
-ListBase *folderlist_duplicate(ListBase *folderlist)
-{
-
- if (folderlist) {
- ListBase *folderlistn = MEM_callocN(sizeof(ListBase), "copy folderlist");
- FolderList *folder;
-
- BLI_duplicatelist(folderlistn, folderlist);
-
- for (folder = folderlistn->first; folder; folder = folder->next) {
- folder->foldername = MEM_dupallocN(folder->foldername);
+ fidx = filelist->fidx[index];
+ file = &filelist->filelist[fidx];
+ if (file->type & S_IFDIR) {
+ if (strcmp(filelist->filelist[fidx].relname, "..") == 0) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT];
+ }
+ else if (strcmp(filelist->filelist[fidx].relname, ".") == 0) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_REFRESH];
+ }
+ else {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_FOLDER];
}
- return folderlistn;
}
- return NULL;
-}
+ else {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE];
+ }
+ if (file->flags & FILE_TYPE_BLENDER) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_BLENDFILE];
+ }
+ else if ((file->flags & FILE_TYPE_MOVIE) || (file->flags & FILE_TYPE_MOVIE_ICON)) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_MOVIEFILE];
+ }
+ else if (file->flags & FILE_TYPE_SOUND) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_SOUNDFILE];
+ }
+ else if (file->flags & FILE_TYPE_PYSCRIPT) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_PYTHONFILE];
+ }
+ else if (file->flags & FILE_TYPE_FTFONT) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_FONTFILE];
+ }
+ else if (file->flags & FILE_TYPE_TEXT) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_TEXTFILE];
+ }
+ else if (file->flags & FILE_TYPE_IMAGE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_LOADING];
+ }
+ else if (file->flags & FILE_TYPE_BLENDER_BACKUP) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_BACKUP];
+ }
-static void filelist_read_main(struct FileList *filelist);
-static void filelist_read_library(struct FileList *filelist);
-static void filelist_read_dir(struct FileList *filelist);
+ return ibuf;
+}
+
+/* ********** Main ********** */
-/* ------------------FILELIST------------------------ */
FileList *filelist_new(short type)
{
FileList *p = MEM_callocN(sizeof(FileList), "filelist");
@@ -558,7 +699,6 @@ FileList *filelist_new(short type)
return p;
}
-
void filelist_free(struct FileList *filelist)
{
if (!filelist) {
@@ -566,18 +706,16 @@ void filelist_free(struct FileList *filelist)
return;
}
- if (filelist->fidx) {
- MEM_freeN(filelist->fidx);
- filelist->fidx = NULL;
- }
+ MEM_SAFE_FREE(filelist->fidx);
+ filelist->numfiltered = 0;
+ memset(&filelist->filter_data, 0, sizeof(filelist->filter_data));
+
+ filelist->need_sorting = false;
+ filelist->sort = FILE_SORT_NONE;
- BLI_free_filelist(filelist->filelist, filelist->numfiles);
+ BLI_filelist_free(filelist->filelist, filelist->numfiles, NULL);
filelist->numfiles = 0;
filelist->filelist = NULL;
- filelist->filter = 0;
- filelist->filter_glob[0] = '\0';
- filelist->numfiltered = 0;
- filelist->hide_dot = 0;
}
void filelist_freelib(struct FileList *filelist)
@@ -607,89 +745,11 @@ void filelist_setdir(struct FileList *filelist, const char *dir)
BLI_strncpy(filelist->dir, dir, sizeof(filelist->dir));
}
-void filelist_imgsize(struct FileList *filelist, short w, short h)
-{
- filelist->prv_w = w;
- filelist->prv_h = h;
-}
-
short filelist_changed(struct FileList *filelist)
{
return filelist->changed;
}
-ImBuf *filelist_getimage(struct FileList *filelist, int index)
-{
- ImBuf *ibuf = NULL;
- int fidx = 0;
-
- BLI_assert(G.background == false);
-
- if ((index < 0) || (index >= filelist->numfiltered)) {
- return NULL;
- }
- fidx = filelist->fidx[index];
- ibuf = filelist->filelist[fidx].image;
-
- return ibuf;
-}
-
-ImBuf *filelist_geticon(struct FileList *filelist, int index)
-{
- ImBuf *ibuf = NULL;
- struct direntry *file = NULL;
- int fidx = 0;
-
- BLI_assert(G.background == false);
-
- if ((index < 0) || (index >= filelist->numfiltered)) {
- return NULL;
- }
- fidx = filelist->fidx[index];
- file = &filelist->filelist[fidx];
- if (file->type & S_IFDIR) {
- if (strcmp(filelist->filelist[fidx].relname, "..") == 0) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT];
- }
- else if (strcmp(filelist->filelist[fidx].relname, ".") == 0) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_REFRESH];
- }
- else {
- ibuf = gSpecialFileImages[SPECIAL_IMG_FOLDER];
- }
- }
- else {
- ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE];
- }
-
- if (file->flags & BLENDERFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_BLENDFILE];
- }
- else if ((file->flags & MOVIEFILE) || (file->flags & MOVIEFILE_ICON)) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_MOVIEFILE];
- }
- else if (file->flags & SOUNDFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_SOUNDFILE];
- }
- else if (file->flags & PYSCRIPTFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_PYTHONFILE];
- }
- else if (file->flags & FTFONTFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_FONTFILE];
- }
- else if (file->flags & TEXTFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_TEXTFILE];
- }
- else if (file->flags & IMAGEFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_LOADING];
- }
- else if (file->flags & BLENDERFILE_BACKUP) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_BACKUP];
- }
-
- return ibuf;
-}
-
struct direntry *filelist_file(struct FileList *filelist, int index)
{
int fidx = 0;
@@ -728,21 +788,6 @@ int filelist_find(struct FileList *filelist, const char *filename)
return fidx;
}
-void filelist_hidedot(struct FileList *filelist, short hide)
-{
- filelist->hide_dot = hide;
-}
-
-void filelist_setfilter(struct FileList *filelist, unsigned int filter)
-{
- filelist->filter = filter;
-}
-
-void filelist_setfilter_types(struct FileList *filelist, const char *filter_glob)
-{
- BLI_strncpy(filelist->filter_glob, filter_glob, sizeof(filelist->filter_glob));
-}
-
/* would recognize .blend as well */
static bool file_is_blend_backup(const char *str)
{
@@ -772,47 +817,47 @@ static bool file_is_blend_backup(const char *str)
static int path_extension_type(const char *path)
{
if (BLO_has_bfile_extension(path)) {
- return BLENDERFILE;
+ return FILE_TYPE_BLENDER;
}
else if (file_is_blend_backup(path)) {
- return BLENDERFILE_BACKUP;
+ return FILE_TYPE_BLENDER_BACKUP;
}
else if (BLI_testextensie(path, ".app")) {
- return APPLICATIONBUNDLE;
+ return FILE_TYPE_APPLICATIONBUNDLE;
}
else if (BLI_testextensie(path, ".py")) {
- return PYSCRIPTFILE;
+ return FILE_TYPE_PYSCRIPT;
}
else if (BLI_testextensie_n(path, ".txt", ".glsl", ".osl", ".data", NULL)) {
- return TEXTFILE;
+ return FILE_TYPE_TEXT;
}
else if (BLI_testextensie_n(path, ".ttf", ".ttc", ".pfb", ".otf", ".otc", NULL)) {
- return FTFONTFILE;
+ return FILE_TYPE_FTFONT;
}
else if (BLI_testextensie(path, ".btx")) {
- return BTXFILE;
+ return FILE_TYPE_BTX;
}
else if (BLI_testextensie(path, ".dae")) {
- return COLLADAFILE;
+ return FILE_TYPE_COLLADA;
}
else if (BLI_testextensie_array(path, imb_ext_image) ||
(G.have_quicktime && BLI_testextensie_array(path, imb_ext_image_qt)))
{
- return IMAGEFILE;
+ return FILE_TYPE_IMAGE;
}
else if (BLI_testextensie(path, ".ogg")) {
if (IMB_isanim(path)) {
- return MOVIEFILE;
+ return FILE_TYPE_MOVIE;
}
else {
- return SOUNDFILE;
+ return FILE_TYPE_SOUND;
}
}
else if (BLI_testextensie_array(path, imb_ext_movie)) {
- return MOVIEFILE;
+ return FILE_TYPE_MOVIE;
}
else if (BLI_testextensie_array(path, imb_ext_audio)) {
- return SOUNDFILE;
+ return FILE_TYPE_SOUND;
}
return 0;
}
@@ -828,25 +873,25 @@ int ED_file_extension_icon(const char *path)
{
int type = path_extension_type(path);
- if (type == BLENDERFILE)
+ if (type == FILE_TYPE_BLENDER)
return ICON_FILE_BLEND;
- else if (type == BLENDERFILE_BACKUP)
+ else if (type == FILE_TYPE_BLENDER_BACKUP)
return ICON_FILE_BACKUP;
- else if (type == IMAGEFILE)
+ else if (type == FILE_TYPE_IMAGE)
return ICON_FILE_IMAGE;
- else if (type == MOVIEFILE)
+ else if (type == FILE_TYPE_MOVIE)
return ICON_FILE_MOVIE;
- else if (type == PYSCRIPTFILE)
+ else if (type == FILE_TYPE_PYSCRIPT)
return ICON_FILE_SCRIPT;
- else if (type == SOUNDFILE)
+ else if (type == FILE_TYPE_SOUND)
return ICON_FILE_SOUND;
- else if (type == FTFONTFILE)
+ else if (type == FILE_TYPE_FTFONT)
return ICON_FILE_FONT;
- else if (type == BTXFILE)
+ else if (type == FILE_TYPE_BTX)
return ICON_FILE_BLANK;
- else if (type == COLLADAFILE)
+ else if (type == FILE_TYPE_COLLADA)
return ICON_FILE_BLANK;
- else if (type == TEXTFILE)
+ else if (type == FILE_TYPE_TEXT)
return ICON_FILE_TEXT;
return ICON_FILE_BLANK;
@@ -869,12 +914,11 @@ static void filelist_setfiletypes(struct FileList *filelist)
#endif
file->flags = file_extension_type(filelist->dir, file->relname);
- if (filelist->filter_glob[0] &&
- BLI_testextensie_glob(file->relname, filelist->filter_glob))
+ if (filelist->filter_data.filter_glob[0] &&
+ BLI_testextensie_glob(file->relname, filelist->filter_data.filter_glob))
{
- file->flags = OPERATORFILE;
+ file->flags = FILE_TYPE_OPERATOR;
}
-
}
}
@@ -885,11 +929,15 @@ static void filelist_read_dir(struct FileList *filelist)
filelist->fidx = NULL;
filelist->filelist = NULL;
+ BLI_make_exist(filelist->dir);
BLI_cleanup_dir(G.main->name, filelist->dir);
- filelist->numfiles = BLI_dir_contents(filelist->dir, &(filelist->filelist));
+ filelist->numfiles = BLI_filelist_dir_contents(filelist->dir, &(filelist->filelist));
+
+ /* We shall *never* get an empty list here, since we now the dir exists and is readable
+ * (ensured by BLI_make_exist()). So we expect at the very least the parent '..' entry. */
+ BLI_assert(filelist->numfiles != 0);
filelist_setfiletypes(filelist);
- filelist_filter(filelist);
}
static void filelist_read_main(struct FileList *filelist)
@@ -907,7 +955,6 @@ static void filelist_read_library(struct FileList *filelist)
int num;
struct direntry *file;
- BLI_make_exist(filelist->dir);
filelist_read_dir(filelist);
file = filelist->filelist;
for (num = 0; num < filelist->numfiles; num++, file++) {
@@ -929,18 +976,15 @@ static void filelist_read_library(struct FileList *filelist)
void filelist_readdir(struct FileList *filelist)
{
filelist->readf(filelist);
-}
-int filelist_empty(struct FileList *filelist)
-{
- return filelist->filelist == NULL;
+ filelist->need_sorting = true;
+ filelist->need_thumbnails = true;
+ filelist_filter_clear(filelist);
}
-void filelist_parent(struct FileList *filelist)
+int filelist_empty(struct FileList *filelist)
{
- BLI_parent_dir(filelist->dir);
- BLI_make_exist(filelist->dir);
- filelist_readdir(filelist);
+ return filelist->filelist == NULL;
}
void filelist_select_file(struct FileList *filelist, int index, FileSelType select, unsigned int flag, FileCheckType check)
@@ -995,35 +1039,15 @@ bool filelist_is_selected(struct FileList *filelist, int index, FileCheckType ch
}
switch (check) {
case CHECK_DIRS:
- return S_ISDIR(file->type) && (file->selflag & SELECTED_FILE);
+ return S_ISDIR(file->type) && (file->selflag & FILE_SEL_SELECTED);
case CHECK_FILES:
- return S_ISREG(file->type) && (file->selflag & SELECTED_FILE);
+ return S_ISREG(file->type) && (file->selflag & FILE_SEL_SELECTED);
case CHECK_ALL:
default:
- return (file->selflag & SELECTED_FILE) != 0;
+ return (file->selflag & FILE_SEL_SELECTED) != 0;
}
}
-void filelist_sort(struct FileList *filelist, short sort)
-{
- switch (sort) {
- case FILE_SORT_ALPHA:
- qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_name);
- break;
- case FILE_SORT_TIME:
- qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_date);
- break;
- case FILE_SORT_SIZE:
- qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_size);
- break;
- case FILE_SORT_EXTENSION:
- qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension);
- break;
- }
-
- filelist_filter(filelist);
-}
-
bool filelist_islibrary(struct FileList *filelist, char *dir, char *group)
{
@@ -1042,8 +1066,8 @@ static int groupname_to_code(const char *group)
return buf[0] ? BKE_idcode_from_name(buf) : 0;
}
-
-void filelist_from_library(struct FileList *filelist)
+
+static void filelist_from_library(struct FileList *filelist)
{
LinkNode *l, *names, *previews;
struct ImBuf *ima;
@@ -1124,7 +1148,7 @@ void filelist_from_library(struct FileList *filelist)
ima = IMB_allocImBuf(w, h, 32, IB_rect);
memcpy(ima->rect, rect, w * h * sizeof(unsigned int));
filelist->filelist[i + 1].image = ima;
- filelist->filelist[i + 1].flags = IMAGEFILE;
+ filelist->filelist[i + 1].flags = FILE_TYPE_IMAGE;
}
}
}
@@ -1133,20 +1157,10 @@ void filelist_from_library(struct FileList *filelist)
BLI_linklist_free(names, free);
if (previews) BLI_linklist_free(previews, BKE_previewimg_freefunc);
- filelist_sort(filelist, FILE_SORT_ALPHA);
-
BLI_strncpy(G.main->name, filename, sizeof(filename)); /* prevent G.main->name to change */
-
- filelist->filter = 0;
- filelist_filter(filelist);
-}
-
-void filelist_hideparent(struct FileList *filelist, short hide)
-{
- filelist->hide_parent = hide;
}
-void filelist_from_main(struct FileList *filelist)
+static void filelist_from_main(struct FileList *filelist)
{
ID *id;
struct direntry *files, *firstlib = NULL;
@@ -1166,9 +1180,9 @@ void filelist_from_main(struct FileList *filelist)
/* make directories */
#ifdef WITH_FREESTYLE
- filelist->numfiles = 25;
-#else
filelist->numfiles = 24;
+#else
+ filelist->numfiles = 23;
#endif
filelist->filelist = (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
@@ -1178,32 +1192,31 @@ void filelist_from_main(struct FileList *filelist)
}
filelist->filelist[0].relname = BLI_strdup("..");
- filelist->filelist[2].relname = BLI_strdup("Scene");
- filelist->filelist[3].relname = BLI_strdup("Object");
- filelist->filelist[4].relname = BLI_strdup("Mesh");
- filelist->filelist[5].relname = BLI_strdup("Curve");
- filelist->filelist[6].relname = BLI_strdup("Metaball");
- filelist->filelist[7].relname = BLI_strdup("Material");
- filelist->filelist[8].relname = BLI_strdup("Texture");
- filelist->filelist[9].relname = BLI_strdup("Image");
- filelist->filelist[10].relname = BLI_strdup("Ika");
- filelist->filelist[11].relname = BLI_strdup("Wave");
- filelist->filelist[12].relname = BLI_strdup("Lattice");
- filelist->filelist[13].relname = BLI_strdup("Lamp");
- filelist->filelist[14].relname = BLI_strdup("Camera");
- filelist->filelist[15].relname = BLI_strdup("Ipo");
- filelist->filelist[16].relname = BLI_strdup("World");
- filelist->filelist[17].relname = BLI_strdup("Screen");
- filelist->filelist[18].relname = BLI_strdup("VFont");
- filelist->filelist[19].relname = BLI_strdup("Text");
- filelist->filelist[20].relname = BLI_strdup("Armature");
- filelist->filelist[21].relname = BLI_strdup("Action");
- filelist->filelist[22].relname = BLI_strdup("NodeTree");
- filelist->filelist[23].relname = BLI_strdup("Speaker");
+ filelist->filelist[1].relname = BLI_strdup("Scene");
+ filelist->filelist[2].relname = BLI_strdup("Object");
+ filelist->filelist[3].relname = BLI_strdup("Mesh");
+ filelist->filelist[4].relname = BLI_strdup("Curve");
+ filelist->filelist[5].relname = BLI_strdup("Metaball");
+ filelist->filelist[6].relname = BLI_strdup("Material");
+ filelist->filelist[7].relname = BLI_strdup("Texture");
+ filelist->filelist[8].relname = BLI_strdup("Image");
+ filelist->filelist[9].relname = BLI_strdup("Ika");
+ filelist->filelist[10].relname = BLI_strdup("Wave");
+ filelist->filelist[11].relname = BLI_strdup("Lattice");
+ filelist->filelist[12].relname = BLI_strdup("Lamp");
+ filelist->filelist[13].relname = BLI_strdup("Camera");
+ filelist->filelist[14].relname = BLI_strdup("Ipo");
+ filelist->filelist[15].relname = BLI_strdup("World");
+ filelist->filelist[16].relname = BLI_strdup("Screen");
+ filelist->filelist[17].relname = BLI_strdup("VFont");
+ filelist->filelist[18].relname = BLI_strdup("Text");
+ filelist->filelist[19].relname = BLI_strdup("Armature");
+ filelist->filelist[20].relname = BLI_strdup("Action");
+ filelist->filelist[21].relname = BLI_strdup("NodeTree");
+ filelist->filelist[22].relname = BLI_strdup("Speaker");
#ifdef WITH_FREESTYLE
- filelist->filelist[24].relname = BLI_strdup("FreestyleLineStyle");
+ filelist->filelist[23].relname = BLI_strdup("FreestyleLineStyle");
#endif
- filelist_sort(filelist, FILE_SORT_ALPHA);
}
else {
@@ -1216,7 +1229,7 @@ void filelist_from_main(struct FileList *filelist)
id = lb->first;
filelist->numfiles = 0;
while (id) {
- if (!filelist->hide_dot || id->name[2] != '.') {
+ if (!filelist->filter_data.hide_dot || id->name[2] != '.') {
filelist->numfiles++;
}
@@ -1224,12 +1237,12 @@ void filelist_from_main(struct FileList *filelist)
}
/* XXXXX TODO: if databrowse F4 or append/link filelist->hide_parent has to be set */
- if (!filelist->hide_parent) filelist->numfiles += 1;
+ if (!filelist->filter_data.hide_parent) filelist->numfiles += 1;
filelist->filelist = filelist->numfiles > 0 ? (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry)) : NULL;
files = filelist->filelist;
- if (!filelist->hide_parent) {
+ if (!filelist->filter_data.hide_parent) {
memset(&(filelist->filelist[0]), 0, sizeof(struct direntry));
filelist->filelist[0].relname = BLI_strdup("..");
filelist->filelist[0].type |= S_IFDIR;
@@ -1243,7 +1256,7 @@ void filelist_from_main(struct FileList *filelist)
while (id) {
ok = 1;
if (ok) {
- if (!filelist->hide_dot || id->name[2] != '.') {
+ if (!filelist->filter_data.hide_dot || id->name[2] != '.') {
memset(files, 0, sizeof(struct direntry));
if (id->lib == NULL) {
files->relname = BLI_strdup(id->name + 2);
@@ -1256,10 +1269,10 @@ void filelist_from_main(struct FileList *filelist)
#if 0 /* XXXXX TODO show the selection status of the objects */
if (!filelist->has_func) { /* F4 DATA BROWSE */
if (idcode == ID_OB) {
- if ( ((Object *)id)->flag & SELECT) files->selflag |= SELECTED_FILE;
+ if ( ((Object *)id)->flag & SELECT) files->selflag |= FILE_SEL_SELECTED;
}
else if (idcode == ID_SCE) {
- if ( ((Scene *)id)->r.scemode & R_BG_RENDER) files->selflag |= SELECTED_FILE;
+ if ( ((Scene *)id)->r.scemode & R_BG_RENDER) files->selflag |= FILE_SEL_SELECTED;
}
}
#endif
@@ -1267,7 +1280,7 @@ void filelist_from_main(struct FileList *filelist)
files->poin = id;
fake = id->flag & LIB_FAKEUSER;
if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
- files->flags |= IMAGEFILE;
+ files->flags |= FILE_TYPE_IMAGE;
}
if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us);
else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us);
@@ -1292,8 +1305,22 @@ void filelist_from_main(struct FileList *filelist)
qsort(firstlib, totlib, sizeof(struct direntry), compare_name);
}
}
- filelist->filter = 0;
- filelist_filter(filelist);
+}
+
+/* ********** Thumbnails job ********** */
+
+typedef struct ThumbnailJob {
+ ListBase loadimages;
+ ImBuf *static_icons_buffers[BIFICONID_LAST];
+ const short *stop;
+ const short *do_update;
+ struct FileList *filelist;
+ ReportList reports;
+} ThumbnailJob;
+
+bool filelist_need_thumbnails(FileList *filelist)
+{
+ return filelist->need_thumbnails;
}
static void thumbnail_joblist_free(ThumbnailJob *tj)
@@ -1318,18 +1345,18 @@ static void thumbnails_startjob(void *tjv, short *stop, short *do_update, float
tj->do_update = do_update;
while ((*stop == 0) && (limg)) {
- if (limg->flags & IMAGEFILE) {
+ if (limg->flags & FILE_TYPE_IMAGE) {
limg->img = IMB_thumb_manage(limg->path, THB_NORMAL, THB_SOURCE_IMAGE);
}
- else if (limg->flags & (BLENDERFILE | BLENDERFILE_BACKUP)) {
+ else if (limg->flags & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
limg->img = IMB_thumb_manage(limg->path, THB_NORMAL, THB_SOURCE_BLEND);
}
- else if (limg->flags & MOVIEFILE) {
+ else if (limg->flags & FILE_TYPE_MOVIE) {
limg->img = IMB_thumb_manage(limg->path, THB_NORMAL, THB_SOURCE_MOVIE);
if (!limg->img) {
/* remember that file can't be loaded via IMB_open_anim */
- limg->flags &= ~MOVIEFILE;
- limg->flags |= MOVIEFILE_ICON;
+ limg->flags &= ~FILE_TYPE_MOVIE;
+ limg->flags |= FILE_TYPE_MOVIE_ICON;
}
}
*do_update = true;
@@ -1348,9 +1375,9 @@ static void thumbnails_update(void *tjv)
if (!limg->done && limg->img) {
tj->filelist->filelist[limg->index].image = limg->img;
/* update flag for movie files where thumbnail can't be created */
- if (limg->flags & MOVIEFILE_ICON) {
- tj->filelist->filelist[limg->index].flags &= ~MOVIEFILE;
- tj->filelist->filelist[limg->index].flags |= MOVIEFILE_ICON;
+ if (limg->flags & FILE_TYPE_MOVIE_ICON) {
+ tj->filelist->filelist[limg->index].flags &= ~FILE_TYPE_MOVIE;
+ tj->filelist->filelist[limg->index].flags |= FILE_TYPE_MOVIE_ICON;
}
limg->done = true;
}
@@ -1359,6 +1386,15 @@ static void thumbnails_update(void *tjv)
}
}
+static void thumbnails_endjob(void *tjv)
+{
+ ThumbnailJob *tj = tjv;
+
+ if (!*tj->stop) {
+ tj->filelist->need_thumbnails = false;
+ }
+}
+
static void thumbnails_free(void *tjv)
{
ThumbnailJob *tj = tjv;
@@ -1378,7 +1414,9 @@ void thumbnails_start(FileList *filelist, const bContext *C)
tj->filelist = filelist;
for (idx = 0; idx < filelist->numfiles; idx++) {
if (!filelist->filelist[idx].image) {
- if ((filelist->filelist[idx].flags & (IMAGEFILE | MOVIEFILE | BLENDERFILE | BLENDERFILE_BACKUP))) {
+ if (filelist->filelist[idx].flags & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE |
+ FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))
+ {
FileImage *limg = MEM_callocN(sizeof(FileImage), "loadimage");
BLI_strncpy(limg->path, filelist->filelist[idx].path, FILE_MAX);
limg->index = idx;
@@ -1395,7 +1433,7 @@ void thumbnails_start(FileList *filelist, const bContext *C)
0, WM_JOB_TYPE_FILESEL_THUMBNAIL);
WM_jobs_customdata_set(wm_job, tj, thumbnails_free);
WM_jobs_timer(wm_job, 0.5, NC_WINDOW, NC_WINDOW);
- WM_jobs_callbacks(wm_job, thumbnails_startjob, NULL, thumbnails_update, NULL);
+ WM_jobs_callbacks(wm_job, thumbnails_startjob, NULL, thumbnails_update, thumbnails_endjob);
/* start the job */
WM_jobs_start(CTX_wm_manager(C), wm_job);
@@ -1403,7 +1441,7 @@ void thumbnails_start(FileList *filelist, const bContext *C)
void thumbnails_stop(wmWindowManager *wm, FileList *filelist)
{
- WM_jobs_kill(wm, filelist, NULL);
+ WM_jobs_kill_type(wm, filelist, WM_JOB_TYPE_FILESEL_THUMBNAIL);
}
int thumbnails_running(wmWindowManager *wm, FileList *filelist)