diff options
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 83 |
1 files changed, 72 insertions, 11 deletions
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 46d8101e20..e6b4e5f754 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>> ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** @@ -55,6 +56,7 @@ #if defined(Q_OS_MAC) # include <QtCore/private/qcore_mac_p.h> +# include <CoreFoundation/CFBundle.h> #endif QT_BEGIN_NAMESPACE @@ -78,6 +80,74 @@ static inline bool _q_isMacHidden(const char *nativePath) FileInfo * const fileInfo = reinterpret_cast<FileInfo*>(&catInfo.finderInfo); return (fileInfo->finderFlags & kIsInvisible); } + +static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &entry) +{ + if (!data.isDirectory()) + return false; + + QFileInfo info(entry.filePath()); + QString suffix = info.suffix(); + + // First step: is the extenstion known ? + if (suffix == QLatin1String("app") + || suffix == QLatin1String("debug") + || suffix == QLatin1String("profile") + || suffix == QLatin1String("bundle") + || suffix == QLatin1String("pkg")) { + return true; + } + + // Second step: check if an application knows the package type + const QByteArray &native = entry.nativeFilePath(); + const char *nativeFilePath = native.constData(); + int nativeFilePathLength = native.size(); + + QCFType<CFStringRef> path = CFStringCreateWithBytes(0, + reinterpret_cast<const UInt8*>(nativeFilePath), + nativeFilePathLength, + kCFStringEncodingUTF8, + false); + + QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, path, kCFURLPOSIXPathStyle, true); + + UInt32 type, creator; + // Well created packages have the PkgInfo file + if (CFBundleGetPackageInfoInDirectory(url, &type, &creator)) + return true; + + // Find if an application other than Finder claims to know how to handle the package + if (suffix.length() > 0) { + QCFType<CFURLRef> application; + LSGetApplicationForURL(url, + kLSRolesEditor|kLSRolesViewer|kLSRolesViewer, + NULL, + &application); + + if (application) { + CFStringRef path = CFURLGetString(application); + QString applicationPath = QCFString::toQString(path); + if (applicationPath != QLatin1String("file://localhost/System/Library/CoreServices/Finder.app/")) + return true; + } + } + + // Third step: check if the directory has the package bit set + FSRef packageRef; + FSPathMakeRef((UInt8 *)nativeFilePath, &packageRef, NULL); + + FSCatalogInfo catalogInfo; + FSGetCatalogInfo(&packageRef, + kFSCatInfoFinderInfo, + &catalogInfo, + NULL, + NULL, + NULL); + + FolderInfo *folderInfo = reinterpret_cast<FolderInfo *>(catalogInfo.finderInfo); + return folderInfo->finderFlags & kHasBundle; +} + #else static inline bool _q_isMacHidden(const char *nativePath) { @@ -473,17 +543,8 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM #if defined(Q_OS_MACX) if (what & QFileSystemMetaData::BundleType) { - if (entryExists && data.isDirectory()) { - QCFType<CFStringRef> path = CFStringCreateWithBytes(0, - (const UInt8*)nativeFilePath, nativeFilePathLength, - kCFStringEncodingUTF8, false); - QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, path, - kCFURLPOSIXPathStyle, true); - - UInt32 type, creator; - if (CFBundleGetPackageInfoInDirectory(url, &type, &creator)) - data.entryFlags |= QFileSystemMetaData::BundleType; - } + if (entryExists && isPackage(data, entry)) + data.entryFlags |= QFileSystemMetaData::BundleType; data.knownFlagsMask |= QFileSystemMetaData::BundleType; } |