summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-11-26 22:30:27 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-11-26 22:35:48 +0100
commit4a8273a6fc2e741e811cf5dabc9a3c240306cf7f (patch)
tree2148abc88f8543eecdc0b97b2dd92594836af9b2 /src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
parent036c5db468164297d213764c59a4b59daa76d90a (diff)
parent1c2be58fecaff1de5f2849192eb712984ebd59bd (diff)
Merge remote-tracking branch 'origin/stable' into dev
For the conflicts in msvc_nmake.cpp the ifdefs are extended since we need to support windows phone in the target branch while it is not there in the current stable branch (as of Qt 5.2). Conflicts: configure qmake/generators/win32/msvc_nmake.cpp src/3rdparty/angle/src/libEGL/Surface.cpp src/angle/src/common/common.pri src/corelib/global/qglobal.h src/corelib/io/qstandardpaths.cpp src/plugins/platforms/qnx/qqnxintegration.cpp src/plugins/platforms/qnx/qqnxscreeneventhandler.h src/plugins/platforms/xcb/qglxintegration.h src/widgets/kernel/win.pri tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp tools/configure/configureapp.cpp Change-Id: I00b579eefebaf61d26ab9b00046d2b5bd5958812
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm95
1 files changed, 50 insertions, 45 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index b3bc4a8ebf..1ad833ee44 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -61,12 +61,12 @@
#include <stdlib.h>
#include <qabstracteventdispatcher.h>
#include "qcocoaautoreleasepool.h"
-#include <QFileSystemWatcher>
#include <QDir>
#include <qpa/qplatformnativeinterface.h>
#import <AppKit/NSSavePanel.h>
+#import <CoreFoundation/CFNumber.h>
QT_FORWARD_DECLARE_CLASS(QString)
QT_FORWARD_DECLARE_CLASS(QStringList)
@@ -74,30 +74,6 @@ QT_FORWARD_DECLARE_CLASS(QFileInfo)
QT_FORWARD_DECLARE_CLASS(QWindow)
QT_USE_NAMESPACE
-class CachedEntries: public QObject {
-public:
- CachedEntries(QDir::Filters filters) : mFilters(filters) {
- QObject::connect(&mFSWatcher, &QFileSystemWatcher::directoryChanged, this, &CachedEntries::updateDirCache);
- }
- QString directory() const {
- const QStringList &dirs = mFSWatcher.directories();
- return (dirs.count() ? dirs[0] : QString());
- }
- QStringList entries() const {
- return mQDirFilterEntryList;
- }
- void updateDirCache(const QString &path) {
- mFSWatcher.removePaths(mFSWatcher.directories());
- mFSWatcher.addPath(path);
- mQDirFilterEntryList = QDir(path).entryList(mFilters);
- }
-
-private:
- QFileSystemWatcher mFSWatcher;
- QStringList mQDirFilterEntryList;
- QDir::Filters mFilters;
-};
-
typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
@class QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate);
@@ -117,7 +93,6 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
int mReturnCode;
SharedPointerFileDialogOptions mOptions;
- CachedEntries *mCachedEntries;
QString *mCurrentSelection;
QStringList *mNameFilterDropDownList;
QStringList *mSelectedNameFilter;
@@ -164,7 +139,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
[mSavePanel setDelegate:self];
mReturnCode = -1;
mHelper = helper;
- mCachedEntries = new CachedEntries(mOptions->filter());
mNameFilterDropDownList = new QStringList(mOptions->nameFilters());
QString selectedVisualNameFilter = mOptions->initiallySelectedNameFilter();
mSelectedNameFilter = new QStringList([self findStrippedFilterWithVisualFilterName:selectedVisualNameFilter]);
@@ -197,7 +171,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
- (void)dealloc
{
- delete mCachedEntries;
delete mNameFilterDropDownList;
delete mSelectedNameFilter;
delete mCurrentSelection;
@@ -308,6 +281,22 @@ static QString strippedText(QString s)
}];
}
+- (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);
@@ -316,8 +305,13 @@ static QString strippedText(QString s)
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;
@@ -325,24 +319,35 @@ static QString strippedText(QString s)
}
QString qtFileName = QCFString::toQString(filename);
- QFileInfo info(qtFileName.normalized(QString::NormalizationForm_C));
- QString path = info.absolutePath();
- if (mCachedEntries->directory() != path) {
- mCachedEntries->updateDirCache(path);
- }
- // Check if the QDir filter accepts the file:
- if (!mCachedEntries->entries().contains(info.fileName()))
- return NO;
-
// No filter means accept everything
- if (mSelectedNameFilter->isEmpty())
- return YES;
+ bool nameMatches = mSelectedNameFilter->isEmpty();
// Check if the current file name filter accepts the file:
- for (int i=0; i<mSelectedNameFilter->size(); ++i) {
+ for (int i = 0; !nameMatches && i < mSelectedNameFilter->size(); ++i) {
if (QDir::match(mSelectedNameFilter->at(i), qtFileName))
- return YES;
+ nameMatches = true;
+ }
+ if (!nameMatches)
+ return NO;
+
+ QDir::Filters filter = mOptions->filter();
+ 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
@@ -461,7 +466,7 @@ static QString strippedText(QString s)
Q_UNUSED(sender);
if (!mHelper)
return;
- if ([path isEqualToString:mCurrentDir])
+ if (!(path && path.length) || [path isEqualToString:mCurrentDir])
return;
[mCurrentDir release];