diff options
-rw-r--r-- | src/gui/dialogs/qfiledialog_mac.mm | 66 |
1 files changed, 48 insertions, 18 deletions
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm index 77a2ac5..15a2e70 100644 --- a/src/gui/dialogs/qfiledialog_mac.mm +++ b/src/gui/dialogs/qfiledialog_mac.mm @@ -291,6 +291,22 @@ QT_USE_NAMESPACE contextInfo:nil]; } +- (BOOL)isHiddenFile:(NSString *)filename isDir:(BOOL)isDir +{ + CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)filename, kCFURLPOSIXPathStyle, isDir); + CFBooleanRef isHidden; + Boolean errorOrHidden = false; + if (!CFURLCopyResourcePropertyForKey(url, kCFURLIsHiddenKey, &isHidden, NULL)) { + errorOrHidden = true; + } else { + if (CFBooleanGetValue(isHidden)) + errorOrHidden = true; + CFRelease(isHidden); + } + CFRelease(url); + return errorOrHidden; +} + - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename { Q_UNUSED(sender); @@ -299,8 +315,13 @@ QT_USE_NAMESPACE return NO; // Always accept directories regardless of their names (unless it is a bundle): - BOOL isDir; - if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir) { + NSFileManager *fm = [NSFileManager defaultManager]; + NSDictionary *fileAttrs = [fm attributesOfItemAtPath:filename error:nil]; + if (!fileAttrs) + return NO; // Error accessing the file means 'no'. + NSString *fileType = [fileAttrs fileType]; + bool isDir = [fileType isEqualToString:NSFileTypeDirectory]; + if (isDir) { if ([mSavePanel treatsFilePackagesAsDirectories] == NO) { if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename] == NO) return YES; @@ -308,26 +329,35 @@ QT_USE_NAMESPACE } QString qtFileName = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)(filename); - QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C))); - QString path = info.absolutePath(); - QString name = info.fileName(); - if (path != *mLastFilterCheckPath){ - *mLastFilterCheckPath = path; - *mQDirFilterEntryList = info.dir().entryList(*mQDirFilter); + // No filter means accept everything + bool nameMatches = mSelectedNameFilter->isEmpty(); + // Check if the current file name filter accepts the file: + for (int i = 0; !nameMatches && i < mSelectedNameFilter->size(); ++i) { + if (QDir::match(mSelectedNameFilter->at(i), qtFileName)) + nameMatches = true; } - // Check if the QDir filter accepts the file: - if (!mQDirFilterEntryList->contains(name)) + if (!nameMatches) return NO; - // No filter means accept everything - if (mSelectedNameFilter->isEmpty()) - return YES; - // Check if the current file name filter accepts the file: - for (int i=0; i<mSelectedNameFilter->size(); ++i) { - if (QDir::match(mSelectedNameFilter->at(i), name)) - return YES; + QDir::Filters filter = *mQDirFilter; + if ((!(filter & (QDir::Dirs | QDir::AllDirs)) && isDir) + || (!(filter & QDir::Files) && [fileType isEqualToString:NSFileTypeRegular]) + || ((filter & QDir::NoSymLinks) && [fileType isEqualToString:NSFileTypeSymbolicLink])) + return NO; + + bool filterPermissions = ((filter & QDir::PermissionMask) + && (filter & QDir::PermissionMask) != QDir::PermissionMask); + if (filterPermissions) { + if ((!(filter & QDir::Readable) && [fm isReadableFileAtPath:filename]) + || (!(filter & QDir::Writable) && [fm isWritableFileAtPath:filename]) + || (!(filter & QDir::Executable) && [fm isExecutableFileAtPath:filename])) + return NO; } - return NO; + if (!(filter & QDir::Hidden) + && (qtFileName.startsWith(QLatin1Char('.')) || [self isHiddenFile:filename isDir:isDir])) + return NO; + + return YES; } - (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag |