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:
authorHarley Acheson <harley.acheson@gmail.com>2020-02-21 19:18:29 +0300
committerHarley Acheson <harley.acheson@gmail.com>2020-02-21 19:20:58 +0300
commit1fb62d1272db477277534c5d31ce220afd100637 (patch)
tree152044d21435b9f3d347b132b8b860d0d706b1f4 /source/blender/editors
parentb1b020806e2d5ca403de62dc956c4a27f36bc377 (diff)
UI: Windows File Attributes and Hidden Items
File Browser using Windows file attributes for decorating and hiding items. Differential Revision: https://developer.blender.org/D6816 Reviewed by Campbell Barton
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/include/UI_icons.h2
-rw-r--r--source/blender/editors/space_file/file_draw.c30
-rw-r--r--source/blender/editors/space_file/filelist.c116
3 files changed, 106 insertions, 42 deletions
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index fabf6baed23..6739f7cb12c 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -793,7 +793,7 @@ DEF_ICON(BOOKMARKS)
DEF_ICON(FONTPREVIEW)
DEF_ICON(FILTER)
DEF_ICON(NEWFOLDER)
-DEF_ICON(FOLDER_REDIRECT)
+DEF_ICON_FOLDER(FOLDER_REDIRECT)
DEF_ICON(FILE_PARENT)
DEF_ICON(FILE_REFRESH)
DEF_ICON_FOLDER(FILE_FOLDER)
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 0aec6d5e6a0..1739c15cbc6 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -133,8 +133,15 @@ static void draw_tile(int sx, int sy, int width, int height, int colorid, int sh
true, (float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f, color);
}
-static void file_draw_icon(
- uiBlock *block, const char *path, int sx, int sy, int icon, int width, int height, bool drag)
+static void file_draw_icon(uiBlock *block,
+ const char *path,
+ int sx,
+ int sy,
+ int icon,
+ int width,
+ int height,
+ bool drag,
+ bool dimmed)
{
uiBut *but;
int x, y;
@@ -142,8 +149,11 @@ static void file_draw_icon(
x = sx;
y = sy - height;
+ /* For uiDefIconBut(), if a1==1.0 then a2 is alpha 0.0 - 1.0 */
+ const float a1 = dimmed ? 1.0f : 0.0f;
+ const float a2 = dimmed ? 0.3f : 0.0f;
but = uiDefIconBut(
- block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, 0.0f, 0.0f, NULL);
+ block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, a1, a2, NULL);
UI_but_func_tooltip_set(but, file_draw_tooltip_func, BLI_strdup(path));
if (drag) {
@@ -210,7 +220,8 @@ static void file_draw_preview(uiBlock *block,
FileLayout *layout,
const bool is_icon,
const int typeflags,
- const bool drag)
+ const bool drag,
+ const bool dimmed)
{
uiBut *but;
float fx, fy;
@@ -273,6 +284,10 @@ static void file_draw_preview(uiBlock *block,
UI_GetThemeColor4fv(TH_TEXT, col);
}
+ if (dimmed) {
+ col[3] *= 0.3f;
+ }
+
if (!is_icon && typeflags & FILE_TYPE_BLENDERLIB) {
/* Datablock preview images use premultiplied alpha. */
GPU_blend_set_func_separate(
@@ -775,6 +790,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
/* don't drag parent or refresh items */
do_drag = !(FILENAME_IS_CURRPAR(file->relpath));
+ const bool is_hidden = (file->attributes & FILE_ATTR_HIDDEN);
if (FILE_IMGDISPLAY == params->display) {
const int icon = filelist_geticon(files, i, false);
@@ -795,7 +811,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
layout,
is_icon,
file->typeflag,
- do_drag);
+ do_drag,
+ is_hidden);
}
else {
file_draw_icon(block,
@@ -805,7 +822,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
filelist_geticon(files, i, true),
ICON_DEFAULT_WIDTH_SCALE,
ICON_DEFAULT_HEIGHT_SCALE,
- do_drag);
+ do_drag,
+ is_hidden);
icon_ofs += ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X;
}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index b328b32263c..28e6d95beb3 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -213,6 +213,9 @@ typedef struct FileListInternEntry {
/** not strictly needed, but used during sorting, avoids to have to recompute it there... */
char *name;
+ /** Defined in BLI_fileops.h */
+ eFileAttributes attributes;
+
BLI_stat_t st;
} FileListInternEntry;
@@ -609,54 +612,76 @@ void filelist_setsorting(struct FileList *filelist, const short sort, bool inver
/* ********** Filter helpers ********** */
-static bool is_hidden_file(const char *filename, FileListFilter *filter)
+/* True if filename is meant to be hidden, eg. starting with period. */
+static bool is_hidden_dot_filename(const char *filename, FileListInternEntry *file)
{
- char *sep = (char *)BLI_last_slash(filename);
- bool is_hidden = false;
-
- if (filter->flags & FLF_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 = true; /* ignore file~ */
- }
- }
+ if (filename[0] == '.' && !ELEM(filename[1], '.', '\0')) {
+ return true; /* ignore .file */
}
- if (!is_hidden && (filter->flags & FLF_HIDE_PARENT)) {
- if (filename[0] == '.' && filename[1] == '.' && filename[2] == '\0') {
- is_hidden = true; /* ignore .. */
+ else {
+ int len = strlen(filename);
+ if ((len > 0) && (filename[len - 1] == '~')) {
+ return true; /* ignore file~ */
}
}
- if (!is_hidden && ((filename[0] == '.') && (filename[1] == '\0'))) {
- is_hidden = true; /* ignore . */
- }
+
/* filename might actually be a piece of path, in which case we have to check all its parts. */
- if (!is_hidden && sep) {
+
+ bool hidden = false;
+ char *sep = (char *)BLI_last_slash(filename);
+
+ if (!hidden && sep) {
char tmp_filename[FILE_MAX_LIBEXTRA];
BLI_strncpy(tmp_filename, filename, sizeof(tmp_filename));
sep = tmp_filename + (sep - filename);
while (sep) {
BLI_assert(sep[1] != '\0');
- if (is_hidden_file(sep + 1, filter)) {
- is_hidden = true;
+ if (is_hidden_dot_filename(sep + 1, file)) {
+ hidden = true;
break;
}
*sep = '\0';
sep = (char *)BLI_last_slash(tmp_filename);
}
}
- return is_hidden;
+ return hidden;
+}
+
+/* True if should be hidden, based on current filtering. */
+static bool is_filtered_hidden(const char *filename,
+ FileListFilter *filter,
+ FileListInternEntry *file)
+{
+ if ((filename[0] == '.') && (filename[1] == '\0')) {
+ return true; /* Ignore . */
+ }
+
+ if (filter->flags & FLF_HIDE_PARENT) {
+ if (filename[0] == '.' && filename[1] == '.' && filename[2] == '\0') {
+ return true; /* Ignore .. */
+ }
+ }
+
+ if ((filter->flags & FLF_HIDE_DOT) && (file->attributes & FILE_ATTR_HIDDEN)) {
+ return true; /* Ignore files with Hidden attribute. */
+ }
+
+#ifndef WIN32
+ /* Check for unix-style names starting with period. */
+ if ((filter->flags & FLF_HIDE_DOT) && is_hidden_dot_filename(filename, file)) {
+ return true;
+ }
+#endif
+
+ return false;
}
static bool is_filtered_file(FileListInternEntry *file,
const char *UNUSED(root),
FileListFilter *filter)
{
- bool is_filtered = !is_hidden_file(file->relpath, filter);
+ bool is_filtered = !is_filtered_hidden(file->relpath, filter, file);
if (is_filtered && !FILENAME_IS_CURRPAR(file->relpath)) {
/* We only check for types if some type are enabled in filtering. */
@@ -699,7 +724,7 @@ static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileLis
BLI_join_dirfile(path, sizeof(path), root, file->relpath);
if (BLO_library_path_explode(path, dir, &group, &name)) {
- is_filtered = !is_hidden_file(file->relpath, filter);
+ is_filtered = !is_filtered_hidden(file->relpath, filter, file);
if (is_filtered && !FILENAME_IS_CURRPAR(file->relpath)) {
/* We only check for types if some type are enabled in filtering. */
if ((filter->filter || filter->filter_id) && (filter->flags & FLF_DO_FILTER)) {
@@ -747,7 +772,7 @@ static bool is_filtered_main(FileListInternEntry *file,
const char *UNUSED(dir),
FileListFilter *filter)
{
- return !is_hidden_file(file->relpath, filter);
+ return !is_filtered_hidden(file->relpath, filter, file);
}
static void filelist_filter_clear(FileList *filelist)
@@ -968,7 +993,7 @@ static int filelist_geticon_ex(FileDirEntry *file,
else if (is_main) {
/* Do not return icon for folders if icons are not 'main' draw type
* (e.g. when used over previews). */
- return ICON_FILE_FOLDER;
+ return (file->attributes & FILE_ATTR_ANY_LINK) ? ICON_FOLDER_REDIRECT : ICON_FILE_FOLDER;
}
else {
/* If this path is in System list then use that icon. */
@@ -984,6 +1009,19 @@ static int filelist_geticon_ex(FileDirEntry *file,
}
}
}
+
+ if (file->attributes & FILE_ATTR_ANY_LINK) {
+ return ICON_LOOP_FORWARDS;
+ }
+ else if (file->attributes & FILE_ATTR_OFFLINE) {
+ return ICON_ERROR;
+ }
+ else if (file->attributes & FILE_ATTR_TEMPORARY) {
+ return ICON_FILE_CACHE;
+ }
+ else if (file->attributes & FILE_ATTR_SYSTEM) {
+ return ICON_SYSTEM;
+ }
}
if (typeflag & FILE_TYPE_BLENDER) {
@@ -1621,7 +1659,7 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
memcpy(ret->uuid, entry->uuid, sizeof(ret->uuid));
ret->blentype = entry->blentype;
ret->typeflag = entry->typeflag;
-
+ ret->attributes = entry->attributes;
BLI_addtail(&cache->cached_entries, ret);
return ret;
}
@@ -2401,6 +2439,7 @@ static int filelist_readjob_list_dir(const char *root,
{
struct direntry *files;
int nbr_files, nbr_entries = 0;
+ char path[FILE_MAX];
nbr_files = BLI_filelist_dir_contents(root, &files);
if (files) {
@@ -2416,20 +2455,17 @@ static int filelist_readjob_list_dir(const char *root,
entry->relpath = MEM_dupallocN(files[i].relname);
entry->st = files[i].s;
+ BLI_join_dirfile(path, sizeof(path), root, entry->relpath);
+
/* Set file type. */
if (S_ISDIR(files[i].s.st_mode)) {
entry->typeflag = FILE_TYPE_DIR;
}
else if (do_lib && BLO_has_bfile_extension(entry->relpath)) {
/* If we are considering .blend files as libs, promote them to directory status. */
- char name[FILE_MAX];
-
entry->typeflag = FILE_TYPE_BLENDER;
-
- BLI_join_dirfile(name, sizeof(name), root, entry->relpath);
-
/* prevent current file being used as acceptable dir */
- if (BLI_path_cmp(main_name, name) != 0) {
+ if (BLI_path_cmp(main_name, path) != 0) {
entry->typeflag |= FILE_TYPE_DIR;
}
}
@@ -2441,6 +2477,16 @@ static int filelist_readjob_list_dir(const char *root,
}
}
+ /* Set file attributes. */
+ entry->attributes = BLI_file_attributes(path);
+
+#ifndef WIN32
+ /* Set linux-style dot files hidden too. */
+ if (is_hidden_dot_filename(entry->relpath, entry)) {
+ entry->attributes |= FILE_ATTR_HIDDEN;
+ }
+#endif
+
BLI_addtail(entries, entry);
nbr_entries++;
}