src/gui/dialogs/qfiledialog_mac.mm
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
    80 QT_FORWARD_DECLARE_CLASS(QWidget)
    80 QT_FORWARD_DECLARE_CLASS(QWidget)
    81 QT_FORWARD_DECLARE_CLASS(QAction)
    81 QT_FORWARD_DECLARE_CLASS(QAction)
    82 QT_FORWARD_DECLARE_CLASS(QFileInfo)
    82 QT_FORWARD_DECLARE_CLASS(QFileInfo)
    83 QT_USE_NAMESPACE
    83 QT_USE_NAMESPACE
    84 
    84 
    85 @class QNSOpenSavePanelDelegate;
    85 @class QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate);
    86 
    86 
    87 @interface QNSOpenSavePanelDelegate : NSObject {
    87 @interface QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) : NSObject {
    88     @public
    88     @public
    89     NSOpenPanel *mOpenPanel;
    89     NSOpenPanel *mOpenPanel;
    90     NSSavePanel *mSavePanel;
    90     NSSavePanel *mSavePanel;
    91     NSView *mAccessoryView;
    91     NSView *mAccessoryView;
    92     NSPopUpButton *mPopUpButton;
    92     NSPopUpButton *mPopUpButton;
   121 - (void)createPopUpButton:(const QString &)selectedFilter hideDetails:(BOOL)hideDetails;
   121 - (void)createPopUpButton:(const QString &)selectedFilter hideDetails:(BOOL)hideDetails;
   122 - (void)createAccessory;
   122 - (void)createAccessory;
   123 
   123 
   124 @end
   124 @end
   125 
   125 
   126 @implementation QNSOpenSavePanelDelegate
   126 @implementation QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate)
   127 
   127 
   128 - (id)initWithAcceptMode:(QT_PREPEND_NAMESPACE(QFileDialog::AcceptMode))acceptMode
   128 - (id)initWithAcceptMode:(QT_PREPEND_NAMESPACE(QFileDialog::AcceptMode))acceptMode
   129     title:(const QString &)title
   129     title:(const QString &)title
   130     nameFilters:(const QStringList &)nameFilters
   130     nameFilters:(const QStringList &)nameFilters
   131     selectedNameFilter:(const QString &)selectedNameFilter
   131     selectedNameFilter:(const QString &)selectedNameFilter
   293     }
   293     }
   294     // Check if the QDir filter accepts the file:
   294     // Check if the QDir filter accepts the file:
   295     if (!mQDirFilterEntryList->contains(info.fileName()))
   295     if (!mQDirFilterEntryList->contains(info.fileName()))
   296         return NO;
   296         return NO;
   297 
   297 
   298     // Always accept directories regardless of their names:
   298     // Always accept directories regardless of their names (unless it is a bundle):
   299     BOOL isDir;
   299     BOOL isDir;
   300     if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir)
   300     if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir) {
   301         return YES;
   301         if ([mSavePanel treatsFilePackagesAsDirectories] == NO) {
       
   302             if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename] == NO)
       
   303                 return YES;
       
   304         }
       
   305     }
   302 
   306 
   303     // No filter means accept everything
   307     // No filter means accept everything
   304     if (mSelectedNameFilter->isEmpty())
   308     if (mSelectedNameFilter->isEmpty())
   305         return YES;
   309         return YES;
   306     // Check if the current file name filter accepts the file:
   310     // Check if the current file name filter accepts the file:
   487     QStringList *filters = mNameFilterDropDownList;
   491     QStringList *filters = mNameFilterDropDownList;
   488     if (filters->size() > 0){
   492     if (filters->size() > 0){
   489         for (int i=0; i<mNameFilterDropDownList->size(); ++i) {
   493         for (int i=0; i<mNameFilterDropDownList->size(); ++i) {
   490             QString filter = hideDetails ? [self removeExtensions:filters->at(i)] : filters->at(i);
   494             QString filter = hideDetails ? [self removeExtensions:filters->at(i)] : filters->at(i);
   491             [mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(filter)];
   495             [mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(filter)];
   492             if (filters->at(i) == selectedFilter)
   496             if (filters->at(i).startsWith(selectedFilter))
   493                 [mPopUpButton selectItemAtIndex:i];
   497                 [mPopUpButton selectItemAtIndex:i];
   494         }
   498         }
   495     }
   499     }
   496 }
   500 }
   497 
   501 
   548         if (AECreateDesc(typeFSRef, &fsRef, sizeof(FSRef), &desc) == noErr)
   552         if (AECreateDesc(typeFSRef, &fsRef, sizeof(FSRef), &desc) == noErr)
   549             NavCustomControl(mDialog, kNavCtlSetLocation, (void*)&desc);
   553             NavCustomControl(mDialog, kNavCtlSetLocation, (void*)&desc);
   550     }
   554     }
   551 #else
   555 #else
   552     QMacCocoaAutoReleasePool pool;
   556     QMacCocoaAutoReleasePool pool;
   553     QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
   557     QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
   554     [delegate->mSavePanel setDirectory:qt_mac_QStringToNSString(directory)];
   558     [delegate->mSavePanel setDirectory:qt_mac_QStringToNSString(directory)];
   555 #endif
   559 #endif
   556 }
   560 }
   557 
   561 
   558 QString QFileDialogPrivate::directory_sys() const
   562 QString QFileDialogPrivate::directory_sys() const
   559 {
   563 {
   560 #ifndef QT_MAC_USE_COCOA
   564 #ifndef QT_MAC_USE_COCOA
   561     return mCurrentLocation;
   565     return mCurrentLocation;
   562 #else
   566 #else
   563     QMacCocoaAutoReleasePool pool;
   567     QMacCocoaAutoReleasePool pool;
   564     QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
   568     QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
   565     return qt_mac_NSStringToQString([delegate->mSavePanel directory]);
   569     return qt_mac_NSStringToQString([delegate->mSavePanel directory]);
   566 #endif
   570 #endif
   567 }
   571 }
   568 
   572 
   569 void QFileDialogPrivate::selectFile_sys(const QString &filename)
   573 void QFileDialogPrivate::selectFile_sys(const QString &filename)
   616         return QStringList() << mCurrentLocation + QLatin1Char('/')
   620         return QStringList() << mCurrentLocation + QLatin1Char('/')
   617                                 + QCFString::toQString(NavDialogGetSaveFileName(mDialog));
   621                                 + QCFString::toQString(NavDialogGetSaveFileName(mDialog));
   618     }
   622     }
   619 #else
   623 #else
   620     QMacCocoaAutoReleasePool pool;
   624     QMacCocoaAutoReleasePool pool;
   621     QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
   625     QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
   622     return [delegate selectedFiles];
   626     return [delegate selectedFiles];
   623 #endif
   627 #endif
   624 }
   628 }
   625 
   629 
   626 void QFileDialogPrivate::setNameFilters_sys(const QStringList &filters)
   630 void QFileDialogPrivate::setNameFilters_sys(const QStringList &filters)
   627 {
   631 {
   628 #ifndef QT_MAC_USE_COCOA
   632 #ifndef QT_MAC_USE_COCOA
   629     Q_UNUSED(filters);
   633     Q_UNUSED(filters);
   630 #else
   634 #else
   631     QMacCocoaAutoReleasePool pool;
   635     QMacCocoaAutoReleasePool pool;
   632     QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
   636     QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
   633     bool hideDetails = q_func()->testOption(QFileDialog::HideNameFilterDetails);
   637     bool hideDetails = q_func()->testOption(QFileDialog::HideNameFilterDetails);
   634     [delegate setNameFilters:filters hideDetails:hideDetails];
   638     [delegate setNameFilters:filters hideDetails:hideDetails];
   635 #endif
   639 #endif
   636 }
   640 }
   637 
   641 
   639 {
   643 {
   640 #ifndef QT_MAC_USE_COCOA
   644 #ifndef QT_MAC_USE_COCOA
   641 #else
   645 #else
   642     Q_Q(QFileDialog);
   646     Q_Q(QFileDialog);
   643     QMacCocoaAutoReleasePool pool;
   647     QMacCocoaAutoReleasePool pool;
   644     QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
   648     QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
   645     *(delegate->mQDirFilter) = model->filter();
   649     *(delegate->mQDirFilter) = model->filter();
   646     delegate->mFileMode = fileMode;
   650     delegate->mFileMode = fileMode;
   647     [delegate->mSavePanel setTitle:qt_mac_QStringToNSString(q->windowTitle())];
   651     [delegate->mSavePanel setTitle:qt_mac_QStringToNSString(q->windowTitle())];
   648     [delegate->mSavePanel setPrompt:[delegate strip:acceptLabel]];
   652     [delegate->mSavePanel setPrompt:[delegate strip:acceptLabel]];
   649     if (fileNameLabelExplicitlySat)
   653     if (fileNameLabelExplicitlySat)
   662         bzero(&navSpec, sizeof(NavMenuItemSpec));
   666         bzero(&navSpec, sizeof(NavMenuItemSpec));
   663         navSpec.menuType = index;
   667         navSpec.menuType = index;
   664         NavCustomControl(mDialog, kNavCtlSelectCustomType, &navSpec);
   668         NavCustomControl(mDialog, kNavCtlSelectCustomType, &navSpec);
   665 #else
   669 #else
   666         QMacCocoaAutoReleasePool pool;
   670         QMacCocoaAutoReleasePool pool;
   667         QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
   671         QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
   668         [delegate->mPopUpButton selectItemAtIndex:index];
   672         [delegate->mPopUpButton selectItemAtIndex:index];
   669         [delegate filterChanged:nil];
   673         [delegate filterChanged:nil];
   670 #endif
   674 #endif
   671     }
   675     }
   672 }
   676 }
   675 {
   679 {
   676 #ifndef QT_MAC_USE_COCOA
   680 #ifndef QT_MAC_USE_COCOA
   677     int index = filterInfo.currentSelection;
   681     int index = filterInfo.currentSelection;
   678 #else
   682 #else
   679     QMacCocoaAutoReleasePool pool;
   683     QMacCocoaAutoReleasePool pool;
   680     QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
   684     QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
   681     int index = [delegate->mPopUpButton indexOfSelectedItem];
   685     int index = [delegate->mPopUpButton indexOfSelectedItem];
   682 #endif
   686 #endif
   683     return index != -1 ? nameFilters.at(index) : QString();
   687     return index != -1 ? nameFilters.at(index) : QString();
   684 }
   688 }
   685 
   689 
   690         NavDialogDispose(mDialog);
   694         NavDialogDispose(mDialog);
   691     mDialog = 0;
   695     mDialog = 0;
   692     mDialogStarted = false;
   696     mDialogStarted = false;
   693 #else
   697 #else
   694     QMacCocoaAutoReleasePool pool;
   698     QMacCocoaAutoReleasePool pool;
   695     [reinterpret_cast<QNSOpenSavePanelDelegate *>(mDelegate) release];
   699     [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate) release];
   696     mDelegate = 0;
   700     mDelegate = 0;
   697 #endif
   701 #endif
   698     nativeDialogInUse = false;
   702     nativeDialogInUse = false;
   699 }
   703 }
   700 
   704 
   723                         >= fileDialogPrivate->filterInfo.filters.size()))
   727                         >= fileDialogPrivate->filterInfo.filters.size()))
   724         return true;
   728         return true;
   725 
   729 
   726     NavFileOrFolderInfo *theInfo = static_cast<NavFileOrFolderInfo *>(info);
   730     NavFileOrFolderInfo *theInfo = static_cast<NavFileOrFolderInfo *>(info);
   727     QString file;
   731     QString file;
       
   732     QString path;
   728     const QtMacFilterName &fn
   733     const QtMacFilterName &fn
   729            = fileDialogPrivate->filterInfo.filters.at(fileDialogPrivate->filterInfo.currentSelection);
   734            = fileDialogPrivate->filterInfo.filters.at(fileDialogPrivate->filterInfo.currentSelection);
   730     if (theItem->descriptorType == typeFSRef) {
   735     if (theItem->descriptorType == typeFSRef) {
   731         FSRef ref;
   736         FSRef ref;
   732         AEGetDescData(theItem, &ref, sizeof(ref));
   737         AEGetDescData(theItem, &ref, sizeof(ref));
   733         UInt8 str_buffer[1024];
   738         UInt8 str_buffer[1024];
   734         FSRefMakePath(&ref, str_buffer, 1024);
   739         FSRefMakePath(&ref, str_buffer, 1024);
   735         file = QString::fromUtf8(reinterpret_cast<const char *>(str_buffer));
   740         path = QString::fromUtf8(reinterpret_cast<const char *>(str_buffer));
   736         int slsh = file.lastIndexOf(QLatin1Char('/'));
   741         int slsh = path.lastIndexOf(QLatin1Char('/'));
   737         if (slsh != -1)
   742         if (slsh != -1)
   738             file = file.right(file.length() - slsh - 1);
   743             file = path.right(path.length() - slsh - 1);
       
   744         else
       
   745             file = path;
   739     }
   746     }
   740     QStringList reg = fn.regexp.split(QLatin1String(";"));
   747     QStringList reg = fn.regexp.split(QLatin1String(";"));
   741     for (QStringList::const_iterator it = reg.constBegin(); it != reg.constEnd(); ++it) {
   748     for (QStringList::const_iterator it = reg.constBegin(); it != reg.constEnd(); ++it) {
   742         QRegExp rg(*it, Qt::CaseInsensitive, QRegExp::Wildcard);
   749         QRegExp rg(*it, Qt::CaseInsensitive, QRegExp::Wildcard);
   743 #ifdef DEBUG_FILEDIALOG_FILTERS
   750 #ifdef DEBUG_FILEDIALOG_FILTERS
   745                 qPrintable(file), qPrintable(*it));
   752                 qPrintable(file), qPrintable(*it));
   746 #endif
   753 #endif
   747         if (rg.exactMatch(file))
   754         if (rg.exactMatch(file))
   748             return true;
   755             return true;
   749     }
   756     }
   750     return (theInfo->isFolder && !file.endsWith(QLatin1String(".app")));
   757 
       
   758     if (theInfo->isFolder) {
       
   759         if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:qt_mac_QStringToNSString(path)])
       
   760             return false;
       
   761         return true;
       
   762     }
       
   763     return false;
   751 }
   764 }
   752 
   765 
   753 void QFileDialogPrivate::qt_mac_filedialog_event_proc(const NavEventCallbackMessage msg,
   766 void QFileDialogPrivate::qt_mac_filedialog_event_proc(const NavEventCallbackMessage msg,
   754         NavCBRecPtr p, NavCallBackUserData data)
   767         NavCBRecPtr p, NavCallBackUserData data)
   755 {
   768 {
  1019     if (mDelegate)
  1032     if (mDelegate)
  1020         return;
  1033         return;
  1021 
  1034 
  1022     bool selectDir = q->selectedFiles().isEmpty();
  1035     bool selectDir = q->selectedFiles().isEmpty();
  1023     QString selection(selectDir ? q->directory().absolutePath() : q->selectedFiles().value(0));
  1036     QString selection(selectDir ? q->directory().absolutePath() : q->selectedFiles().value(0));
  1024     QNSOpenSavePanelDelegate *delegate = [[QNSOpenSavePanelDelegate alloc]
  1037     QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) alloc]
  1025         initWithAcceptMode:acceptMode
  1038         initWithAcceptMode:acceptMode
  1026         title:q->windowTitle()
  1039         title:q->windowTitle()
  1027         nameFilters:q->nameFilters()
  1040         nameFilters:q->nameFilters()
  1028         selectedNameFilter:q->selectedNameFilter()
  1041         selectedNameFilter:q->selectedNameFilter()
  1029         hideNameFilterDetails:q->testOption(QFileDialog::HideNameFilterDetails)
  1042         hideNameFilterDetails:q->testOption(QFileDialog::HideNameFilterDetails)
  1040 bool QFileDialogPrivate::showCocoaFilePanel()
  1053 bool QFileDialogPrivate::showCocoaFilePanel()
  1041 {
  1054 {
  1042     Q_Q(QFileDialog);
  1055     Q_Q(QFileDialog);
  1043     QMacCocoaAutoReleasePool pool;
  1056     QMacCocoaAutoReleasePool pool;
  1044     createNSOpenSavePanelDelegate();
  1057     createNSOpenSavePanelDelegate();
  1045     QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
  1058     QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
  1046     if (qt_mac_is_macsheet(q))
  1059     if (qt_mac_is_macsheet(q))
  1047         [delegate showWindowModalSheet:q->parentWidget()];
  1060         [delegate showWindowModalSheet:q->parentWidget()];
  1048     else
  1061     else
  1049         [delegate showModelessPanel];
  1062         [delegate showModelessPanel];
  1050     return true;
  1063     return true;
  1056         // Nothing to do. We return false to leave the question
  1069         // Nothing to do. We return false to leave the question
  1057         // open regarding whether or not to go native:
  1070         // open regarding whether or not to go native:
  1058         return false;
  1071         return false;
  1059     } else {
  1072     } else {
  1060         QMacCocoaAutoReleasePool pool;
  1073         QMacCocoaAutoReleasePool pool;
  1061         QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
  1074         QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
  1062         [delegate closePanel];
  1075         [delegate closePanel];
  1063         // Even when we hide it, we are still using a
  1076         // Even when we hide it, we are still using a
  1064         // native dialog, so return true:
  1077         // native dialog, so return true:
  1065         return true;
  1078         return true;
  1066     }
  1079     }
  1089 #ifndef QT_MAC_USE_COCOA
  1102 #ifndef QT_MAC_USE_COCOA
  1090     NavDialogRun(mDialog);
  1103     NavDialogRun(mDialog);
  1091 #else
  1104 #else
  1092     Q_Q(QFileDialog);
  1105     Q_Q(QFileDialog);
  1093     QMacCocoaAutoReleasePool pool;
  1106     QMacCocoaAutoReleasePool pool;
  1094     QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
  1107     QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
  1095     [delegate runApplicationModalPanel];
  1108     [delegate runApplicationModalPanel];
  1096     dialogResultCode_sys() == QDialog::Accepted ? q->accept() : q->reject();
  1109     dialogResultCode_sys() == QDialog::Accepted ? q->accept() : q->reject();
  1097 #endif
  1110 #endif
  1098 }
  1111 }
  1099 
  1112 
  1104     if (result == kNavUserActionCancel || result == kNavUserActionNone)
  1117     if (result == kNavUserActionCancel || result == kNavUserActionNone)
  1105         return QDialog::Rejected;
  1118         return QDialog::Rejected;
  1106     else
  1119     else
  1107         return QDialog::Accepted;
  1120         return QDialog::Accepted;
  1108 #else
  1121 #else
  1109     QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
  1122     QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
  1110     return [delegate dialogResultCode];
  1123     return [delegate dialogResultCode];
  1111 #endif
  1124 #endif
  1112 }
  1125 }
  1113 
  1126 
  1114 
  1127