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:
-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;