src/gui/dialogs/qfiledialog_mac.mm
changeset 30 5dc02b23752f
parent 18 2f34d5167611
child 33 3e2da88830cd
--- a/src/gui/dialogs/qfiledialog_mac.mm	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/gui/dialogs/qfiledialog_mac.mm	Tue Jul 06 15:10:48 2010 +0300
@@ -82,9 +82,9 @@
 QT_FORWARD_DECLARE_CLASS(QFileInfo)
 QT_USE_NAMESPACE
 
-@class QNSOpenSavePanelDelegate;
+@class QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate);
 
-@interface QNSOpenSavePanelDelegate : NSObject {
+@interface QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) : NSObject {
     @public
     NSOpenPanel *mOpenPanel;
     NSSavePanel *mSavePanel;
@@ -123,7 +123,7 @@
 
 @end
 
-@implementation QNSOpenSavePanelDelegate
+@implementation QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate)
 
 - (id)initWithAcceptMode:(QT_PREPEND_NAMESPACE(QFileDialog::AcceptMode))acceptMode
     title:(const QString &)title
@@ -295,10 +295,14 @@
     if (!mQDirFilterEntryList->contains(info.fileName()))
         return NO;
 
-    // Always accept directories regardless of their names:
+    // Always accept directories regardless of their names (unless it is a bundle):
     BOOL isDir;
-    if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir)
-        return YES;
+    if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir) {
+        if ([mSavePanel treatsFilePackagesAsDirectories] == NO) {
+            if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename] == NO)
+                return YES;
+        }
+    }
 
     // No filter means accept everything
     if (mSelectedNameFilter->isEmpty())
@@ -489,7 +493,7 @@
         for (int i=0; i<mNameFilterDropDownList->size(); ++i) {
             QString filter = hideDetails ? [self removeExtensions:filters->at(i)] : filters->at(i);
             [mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(filter)];
-            if (filters->at(i) == selectedFilter)
+            if (filters->at(i).startsWith(selectedFilter))
                 [mPopUpButton selectItemAtIndex:i];
         }
     }
@@ -550,7 +554,7 @@
     }
 #else
     QMacCocoaAutoReleasePool pool;
-    QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+    QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
     [delegate->mSavePanel setDirectory:qt_mac_QStringToNSString(directory)];
 #endif
 }
@@ -561,7 +565,7 @@
     return mCurrentLocation;
 #else
     QMacCocoaAutoReleasePool pool;
-    QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+    QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
     return qt_mac_NSStringToQString([delegate->mSavePanel directory]);
 #endif
 }
@@ -618,7 +622,7 @@
     }
 #else
     QMacCocoaAutoReleasePool pool;
-    QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+    QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
     return [delegate selectedFiles];
 #endif
 }
@@ -629,7 +633,7 @@
     Q_UNUSED(filters);
 #else
     QMacCocoaAutoReleasePool pool;
-    QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+    QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
     bool hideDetails = q_func()->testOption(QFileDialog::HideNameFilterDetails);
     [delegate setNameFilters:filters hideDetails:hideDetails];
 #endif
@@ -641,7 +645,7 @@
 #else
     Q_Q(QFileDialog);
     QMacCocoaAutoReleasePool pool;
-    QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+    QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
     *(delegate->mQDirFilter) = model->filter();
     delegate->mFileMode = fileMode;
     [delegate->mSavePanel setTitle:qt_mac_QStringToNSString(q->windowTitle())];
@@ -664,7 +668,7 @@
         NavCustomControl(mDialog, kNavCtlSelectCustomType, &navSpec);
 #else
         QMacCocoaAutoReleasePool pool;
-        QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+        QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
         [delegate->mPopUpButton selectItemAtIndex:index];
         [delegate filterChanged:nil];
 #endif
@@ -677,7 +681,7 @@
     int index = filterInfo.currentSelection;
 #else
     QMacCocoaAutoReleasePool pool;
-    QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+    QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
     int index = [delegate->mPopUpButton indexOfSelectedItem];
 #endif
     return index != -1 ? nameFilters.at(index) : QString();
@@ -692,7 +696,7 @@
     mDialogStarted = false;
 #else
     QMacCocoaAutoReleasePool pool;
-    [reinterpret_cast<QNSOpenSavePanelDelegate *>(mDelegate) release];
+    [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate) release];
     mDelegate = 0;
 #endif
     nativeDialogInUse = false;
@@ -725,6 +729,7 @@
 
     NavFileOrFolderInfo *theInfo = static_cast<NavFileOrFolderInfo *>(info);
     QString file;
+    QString path;
     const QtMacFilterName &fn
            = fileDialogPrivate->filterInfo.filters.at(fileDialogPrivate->filterInfo.currentSelection);
     if (theItem->descriptorType == typeFSRef) {
@@ -732,10 +737,12 @@
         AEGetDescData(theItem, &ref, sizeof(ref));
         UInt8 str_buffer[1024];
         FSRefMakePath(&ref, str_buffer, 1024);
-        file = QString::fromUtf8(reinterpret_cast<const char *>(str_buffer));
-        int slsh = file.lastIndexOf(QLatin1Char('/'));
+        path = QString::fromUtf8(reinterpret_cast<const char *>(str_buffer));
+        int slsh = path.lastIndexOf(QLatin1Char('/'));
         if (slsh != -1)
-            file = file.right(file.length() - slsh - 1);
+            file = path.right(path.length() - slsh - 1);
+        else
+            file = path;
     }
     QStringList reg = fn.regexp.split(QLatin1String(";"));
     for (QStringList::const_iterator it = reg.constBegin(); it != reg.constEnd(); ++it) {
@@ -747,7 +754,13 @@
         if (rg.exactMatch(file))
             return true;
     }
-    return (theInfo->isFolder && !file.endsWith(QLatin1String(".app")));
+
+    if (theInfo->isFolder) {
+        if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:qt_mac_QStringToNSString(path)])
+            return false;
+        return true;
+    }
+    return false;
 }
 
 void QFileDialogPrivate::qt_mac_filedialog_event_proc(const NavEventCallbackMessage msg,
@@ -1021,7 +1034,7 @@
 
     bool selectDir = q->selectedFiles().isEmpty();
     QString selection(selectDir ? q->directory().absolutePath() : q->selectedFiles().value(0));
-    QNSOpenSavePanelDelegate *delegate = [[QNSOpenSavePanelDelegate alloc]
+    QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) alloc]
         initWithAcceptMode:acceptMode
         title:q->windowTitle()
         nameFilters:q->nameFilters()
@@ -1042,7 +1055,7 @@
     Q_Q(QFileDialog);
     QMacCocoaAutoReleasePool pool;
     createNSOpenSavePanelDelegate();
-    QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+    QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
     if (qt_mac_is_macsheet(q))
         [delegate showWindowModalSheet:q->parentWidget()];
     else
@@ -1058,7 +1071,7 @@
         return false;
     } else {
         QMacCocoaAutoReleasePool pool;
-        QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+        QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
         [delegate closePanel];
         // Even when we hide it, we are still using a
         // native dialog, so return true:
@@ -1091,7 +1104,7 @@
 #else
     Q_Q(QFileDialog);
     QMacCocoaAutoReleasePool pool;
-    QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+    QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
     [delegate runApplicationModalPanel];
     dialogResultCode_sys() == QDialog::Accepted ? q->accept() : q->reject();
 #endif
@@ -1106,7 +1119,7 @@
     else
         return QDialog::Accepted;
 #else
-    QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
+    QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
     return [delegate dialogResultCode];
 #endif
 }