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:
authorBrecht Van Lommel <brecht@blender.org>2020-03-26 19:52:41 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-03-26 21:57:30 +0300
commitafb1a64ccb81b7ed792f64151986f40f53af8da5 (patch)
treed7dfdb1f1b8d6dda67c91ea813e09fdbb826b335
parentd1972e50cbef6e2a40ffc259f10e08493511dc66 (diff)
Fix T60682: adds macOS alias redirection for directories
This adds support for macOS aliases in addition to symlinks. It also adds support for hidden, readonly and system file attributes. Contributed by Ankit (ankitm) with modifications by me. Differential Revision: https://developer.blender.org/D6679
-rw-r--r--source/blender/blenlib/BLI_fileops.h1
-rw-r--r--source/blender/blenlib/CMakeLists.txt7
-rw-r--r--source/blender/blenlib/intern/storage.c32
-rw-r--r--source/blender/blenlib/intern/storage_apple.mm96
-rw-r--r--source/blender/editors/space_file/file_ops.c4
-rw-r--r--source/blender/editors/space_file/filelist.c31
-rw-r--r--source/blender/makesdna/DNA_space_types.h3
7 files changed, 153 insertions, 21 deletions
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 89f7d01ffd6..4eb6f184a76 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -147,6 +147,7 @@ int BLI_access(const char *filename, int mode) ATTR_WARN_UNUSED_RESULT ATTR_NONN
bool BLI_file_is_writable(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
bool BLI_file_touch(const char *file) ATTR_NONNULL();
+bool BLI_file_alias_target(char *target, const char *filepath);
#if 0 /* UNUSED */
int BLI_file_gzip(const char *from, const char *to) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 1de0c192a20..5f5145cab70 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -277,6 +277,13 @@ if(WIN32)
)
endif()
+
+if(APPLE)
+ list(APPEND SRC
+ intern/storage_apple.mm
+ )
+endif()
+
if(UNIX AND NOT APPLE)
list(APPEND LIB
bf_intern_libc_compat
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index da80777e6d6..7274a15661a 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -226,11 +226,12 @@ size_t BLI_file_size(const char *path)
return stats.st_size;
}
+#ifndef __APPLE__
eFileAttributes BLI_file_attributes(const char *path)
{
int ret = 0;
-#ifdef WIN32
+# ifdef WIN32
wchar_t wline[FILE_MAXDIR];
BLI_strncpy_wchar_from_utf8(wline, path, ARRAY_SIZE(wline));
DWORD attr = GetFileAttributesW(wline);
@@ -265,19 +266,9 @@ eFileAttributes BLI_file_attributes(const char *path)
ret |= FILE_ATTR_REPARSE_POINT;
}
-#endif
-
-#ifdef __APPLE__
-
- /* TODO:
- * If Hidden (Invisible) set FILE_ATTR_HIDDEN
- * If Locked set FILE_ATTR_READONLY
- * If Restricted set FILE_ATTR_RESTRICTED
- */
-
-#endif
+# endif
-#ifdef __linux__
+# ifdef __linux__
UNUSED_VARS(path);
/* TODO:
@@ -285,10 +276,23 @@ eFileAttributes BLI_file_attributes(const char *path)
* If Archived set FILE_ATTR_ARCHIVE
*/
-#endif
+# endif
return ret;
}
+#endif
+
+/**
+ * Returns the target path of a file-based redirection, like Mac Alias or Win32 Shortcut file.
+ */
+#ifndef __APPLE__
+bool BLI_file_alias_target(char UNUSED(target[FILE_MAXDIR]), const char *UNUSED(filepath))
+{
+ /* TODO: Find target in Win32 Shortcut - Shell Link (.lnk) file.
+ * Format: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/ */
+ return false;
+}
+#endif
/**
* Returns the st_mode from stat-ing the specified path name, or 0 if stat fails
diff --git a/source/blender/blenlib/intern/storage_apple.mm b/source/blender/blenlib/intern/storage_apple.mm
new file mode 100644
index 00000000000..7cb8ca28e24
--- /dev/null
+++ b/source/blender/blenlib/intern/storage_apple.mm
@@ -0,0 +1,96 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bli
+ *
+ * macOS specific implementations for storage.c.
+ */
+
+#import <Foundation/Foundation.h>
+
+#include "BLI_fileops.h"
+#include "BLI_path_util.h"
+
+bool BLI_file_alias_target(char targetpath[FILE_MAXDIR], const char *filepath)
+{
+ @autoreleasepool {
+ NSError *error = nil;
+ NSURL *shortcutURL = [[NSURL alloc] initFileURLWithFileSystemRepresentation:filepath
+ isDirectory:NO
+ relativeToURL:nil];
+ NSURL *targetURL = [NSURL URLByResolvingAliasFileAtURL:shortcutURL
+ options:NSURLBookmarkResolutionWithoutUI
+ error:&error];
+ BOOL isSame = [shortcutURL isEqual:targetURL] and
+ ([[[shortcutURL path] stringByStandardizingPath]
+ isEqualToString:[[targetURL path] stringByStandardizingPath]]);
+
+ if (targetURL == nil) {
+ return false;
+ }
+ else if (isSame) {
+ [targetURL getFileSystemRepresentation:targetpath maxLength:FILE_MAXDIR];
+ return false;
+ }
+ else if (![targetURL getFileSystemRepresentation:targetpath maxLength:FILE_MAXDIR]) {
+ return false;
+ }
+
+ NSNumber *targetIsDirectory = 0;
+ [targetURL getResourceValue:&targetIsDirectory forKey:NSURLIsDirectoryKey error:nil];
+ }
+
+ return true;
+}
+
+eFileAttributes BLI_file_attributes(const char *path)
+{
+ int ret = 0;
+
+ @autoreleasepool {
+ NSURL *fileURL = [[NSURL alloc] initFileURLWithFileSystemRepresentation:path
+ isDirectory:NO
+ relativeToURL:nil];
+ NSArray *resourceKeys =
+ @[ NSURLIsAliasFileKey, NSURLIsHiddenKey, NSURLIsReadableKey, NSURLIsWritableKey ];
+
+ NSDictionary *resourceKeyValues = [fileURL resourceValuesForKeys:resourceKeys error:nil];
+
+ const bool is_alias = [resourceKeyValues[(void)(@"@%"), NSURLIsAliasFileKey] boolValue];
+ const bool is_hidden = [resourceKeyValues[(void)(@"@%"), NSURLIsHiddenKey] boolValue];
+ const bool is_readable = [resourceKeyValues[(void)(@"@%"), NSURLIsReadableKey] boolValue];
+ const bool is_writable = [resourceKeyValues[(void)(@"@%"), NSURLIsWritableKey] boolValue];
+
+ if (is_alias) {
+ ret |= FILE_ATTR_ALIAS;
+ }
+ if (is_hidden) {
+ ret |= FILE_ATTR_HIDDEN;
+ }
+ if (is_readable && !is_writable) {
+ ret |= FILE_ATTR_READONLY;
+ }
+ if (is_readable) {
+ ret |= FILE_ATTR_SYSTEM;
+ }
+ }
+
+ return (eFileAttributes)ret;
+}
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index a34fcba99be..5258892d55d 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -1634,7 +1634,9 @@ static int file_exec(bContext *C, wmOperator *exec_op)
BLI_path_append(sfile->params->dir, sizeof(sfile->params->dir) - 1, file->relpath);
BLI_add_slash(sfile->params->dir);
}
-
+ if (file->redirection_path) {
+ STRNCPY(sfile->params->dir, file->redirection_path);
+ }
ED_file_change_dir(C);
}
/* opening file - sends events now, so things get handled on windowqueue level */
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index caab1ac74d0..dec38501d38 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -210,12 +210,13 @@ typedef struct FileListInternEntry {
int blentype;
char *relpath;
+ /** Optional argument for shortcuts, aliases etc. */
+ char *redirection_path;
/** 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;
@@ -961,12 +962,12 @@ ImBuf *filelist_getimage(struct FileList *filelist, const int index)
return file->image;
}
-static ImBuf *filelist_geticon_image_ex(const unsigned int typeflag, const char *relpath)
+static ImBuf *filelist_geticon_image_ex(FileDirEntry *file)
{
ImBuf *ibuf = NULL;
- if (typeflag & FILE_TYPE_DIR) {
- if (FILENAME_IS_PARENT(relpath)) {
+ if (file->typeflag & FILE_TYPE_DIR) {
+ if (FILENAME_IS_PARENT(file->relpath)) {
ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT];
}
else {
@@ -983,8 +984,7 @@ static ImBuf *filelist_geticon_image_ex(const unsigned int typeflag, const char
ImBuf *filelist_geticon_image(struct FileList *filelist, const int index)
{
FileDirEntry *file = filelist_geticon_get_file(filelist, index);
-
- return filelist_geticon_image_ex(file->typeflag, file->relpath);
+ return filelist_geticon_image_ex(file);
}
static int filelist_geticon_ex(FileDirEntry *file,
@@ -1170,6 +1170,9 @@ static void filelist_entry_clear(FileDirEntry *entry)
if (entry->relpath) {
MEM_freeN(entry->relpath);
}
+ if (entry->redirection_path) {
+ MEM_freeN(entry->redirection_path);
+ }
if (entry->image) {
IMB_freeImBuf(entry->image);
}
@@ -1239,6 +1242,9 @@ static void filelist_intern_entry_free(FileListInternEntry *entry)
if (entry->relpath) {
MEM_freeN(entry->relpath);
}
+ if (entry->redirection_path) {
+ MEM_freeN(entry->redirection_path);
+ }
if (entry->name) {
MEM_freeN(entry->name);
}
@@ -1690,6 +1696,9 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
ret->blentype = entry->blentype;
ret->typeflag = entry->typeflag;
ret->attributes = entry->attributes;
+ if (entry->redirection_path) {
+ ret->redirection_path = BLI_strdup(entry->redirection_path);
+ }
BLI_addtail(&cache->cached_entries, ret);
return ret;
}
@@ -2523,6 +2532,16 @@ static int filelist_readjob_list_dir(const char *root,
/* Set file attributes. */
entry->attributes = BLI_file_attributes(path);
+ if (entry->attributes & FILE_ATTR_ALIAS) {
+ entry->redirection_path = MEM_callocN(FILE_MAXDIR, __func__);
+ if (BLI_file_alias_target(entry->redirection_path, path)) {
+ if (BLI_is_dir(entry->redirection_path)) {
+ entry->typeflag = FILE_TYPE_DIR;
+ }
+ else
+ entry->typeflag = ED_path_extension_type(entry->redirection_path);
+ }
+ }
#ifndef WIN32
/* Set linux-style dot files hidden too. */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index d3cce8d1510..3020e5a1708 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -955,7 +955,10 @@ typedef struct FileDirEntry {
/** ID type, in case typeflag has FILE_TYPE_BLENDERLIB set. */
int blentype;
+ /* Path to item that is relative to current folder root. */
char *relpath;
+ /** Optional argument for shortcuts, aliases etc. */
+ char *redirection_path;
/** TODO: make this a real ID pointer? */
void *poin;