Add QFileInfo::isAlias() to reflect whether the file is a macOS alias

Change-Id: I772066d0d8e69893f7c4aee1cd2305d46d5834c4
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Tor Arne Vestbø 2022-03-03 17:14:24 +01:00
parent 34b5e38f20
commit 9e01827193
4 changed files with 88 additions and 2 deletions

View File

@ -1118,8 +1118,8 @@ bool QFileInfo::isSymLink() const
opens the \l{symLinkTarget()}{link's target}.
In contrast to isSymLink(), false will be returned for shortcuts
(\c *.lnk files) on Windows and aliases on \macos.
Use QFileInfo::isShortcut() on Windows instead.
(\c *.lnk files) on Windows and aliases on \macos. Use QFileInfo::isShortcut()
and QFileInfo::isAlias() instead.
\note If the symlink points to a non existing file, exists() returns
false.
@ -1162,6 +1162,29 @@ bool QFileInfo::isShortcut() const
[d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
}
/*!
Returns \c true if this object points to an alias;
otherwise returns \c false.
\since 6.4
Aliases only exist on \macos. They are treated as regular files, so
opening an alias will open the file itself. In order to open the file
or directory an alias references use symLinkTarget().
\note Even if an alias points to a non existing file,
isAlias() returns true.
\sa isFile(), isDir(), isSymLink(), symLinkTarget()
*/
bool QFileInfo::isAlias() const
{
Q_D(const QFileInfo);
return d->checkAttribute<bool>(
QFileSystemMetaData::LegacyLinkType,
[d]() { return d->metaData.isAlias(); },
[d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
}
/*!
\since 5.15

View File

@ -156,6 +156,7 @@ public:
bool isSymLink() const;
bool isSymbolicLink() const;
bool isShortcut() const;
bool isAlias() const;
bool isJunction() const;
bool isRoot() const;
bool isBundle() const;

View File

@ -45,3 +45,7 @@ qt_internal_extend_target(tst_qfileinfo CONDITION WIN32
advapi32
netapi32
)
if (APPLE)
target_compile_options(tst_qfileinfo PRIVATE -x objective-c++)
endif()

View File

@ -62,6 +62,10 @@
#include <private/qfileinfo_p.h>
#include "../../../../shared/filesystem.h"
#if defined(Q_OS_MACOS)
#include <Foundation/Foundation.h>
#endif
#if defined(Q_OS_VXWORKS)
#define Q_NO_SYMLINKS
#endif
@ -218,6 +222,9 @@ private slots:
void isShortcut_data();
void isShortcut();
void isAlias_data();
void isAlias();
void link_data();
void link();
@ -1345,6 +1352,57 @@ void tst_QFileInfo::isShortcut()
QCOMPARE(fi.isShortcut(), isShortcut);
}
void tst_QFileInfo::isAlias_data()
{
QFile::remove("symlink");
QFile::remove("file-alias");
QFile::remove("directory-alias");
QTest::addColumn<QString>("path");
QTest::addColumn<bool>("isAlias");
QFile regularFile(m_sourceFile);
QTest::newRow("regular-file") << regularFile.fileName() << false;
QTest::newRow("directory") << QDir::currentPath() << false;
#if defined(Q_OS_MACOS)
auto createAlias = [](const QString &target, const QString &alias) {
NSURL *targetUrl = [NSURL fileURLWithPath:target.toNSString()];
NSURL *aliasUrl = [NSURL fileURLWithPath:alias.toNSString()];
NSData *bookmarkData = [targetUrl bookmarkDataWithOptions:NSURLBookmarkCreationSuitableForBookmarkFile
includingResourceValuesForKeys:nil relativeToURL:nil error:nullptr];
Q_ASSERT(bookmarkData);
bool success = [NSURL writeBookmarkData:bookmarkData toURL:aliasUrl
options:NSURLBookmarkCreationSuitableForBookmarkFile error:nullptr];
Q_ASSERT(success);
};
regularFile.link("symlink");
QTest::newRow("symlink") << "symlink" << false;
createAlias(regularFile.fileName(), QDir::current().filePath("file-alias"));
QTest::newRow("file-alias") << "file-alias" << true;
createAlias(QDir::currentPath(), QDir::current().filePath("directory-alias"));
QTest::newRow("directory-alias") << "directory-alias" << true;
regularFile.copy("non-existing-file");
createAlias("non-existing-file", QDir::current().filePath("non-existing-file-alias"));
QDir::current().remove("non-existing-file");
QTest::newRow("non-existing-file-alias") << "non-existing-file-alias" << true;
#endif
}
void tst_QFileInfo::isAlias()
{
QFETCH(QString, path);
QFETCH(bool, isAlias);
QFileInfo fi(path);
QCOMPARE(fi.isAlias(), isAlias);
}
void tst_QFileInfo::isSymbolicLink_data()
{
QTest::addColumn<QString>("path");