source: trunk/src/gui/dialogs/qfiledialog_mac.mm@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 40.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qfiledialog.h"
43
44#ifndef QT_NO_FILEDIALOG
45
46/*****************************************************************************
47 QFileDialog debug facilities
48 *****************************************************************************/
49//#define DEBUG_FILEDIALOG_FILTERS
50
51#include <qapplication.h>
52#include <private/qapplication_p.h>
53#include <private/qfiledialog_p.h>
54#include <private/qt_mac_p.h>
55#include <private/qt_cocoa_helpers_mac_p.h>
56#include <qregexp.h>
57#include <qbuffer.h>
58#include <qdebug.h>
59#include <qstringlist.h>
60#include <qaction.h>
61#include <qtextcodec.h>
62#include <qvarlengtharray.h>
63#include <qdesktopwidget.h>
64#include <stdlib.h>
65#include "ui_qfiledialog.h"
66
67QT_BEGIN_NAMESPACE
68
69extern QStringList qt_make_filter_list(const QString &filter); // qfiledialog.cpp
70extern QStringList qt_clean_filter_list(const QString &filter); // qfiledialog.cpp
71extern const char *qt_file_dialog_filter_reg_exp; // qfiledialog.cpp
72extern bool qt_mac_is_macsheet(const QWidget *w); // qwidget_mac.mm
73
74QT_END_NAMESPACE
75
76QT_FORWARD_DECLARE_CLASS(QFileDialogPrivate)
77QT_FORWARD_DECLARE_CLASS(QString)
78QT_FORWARD_DECLARE_CLASS(QStringList)
79QT_FORWARD_DECLARE_CLASS(QWidget)
80QT_FORWARD_DECLARE_CLASS(QAction)
81QT_FORWARD_DECLARE_CLASS(QFileInfo)
82QT_USE_NAMESPACE
83
84@class QNSOpenSavePanelDelegate;
85
86@interface QNSOpenSavePanelDelegate : NSObject {
87 @public
88 NSOpenPanel *mOpenPanel;
89 NSSavePanel *mSavePanel;
90 NSView *mAccessoryView;
91 NSPopUpButton *mPopUpButton;
92 NSTextField *mTextField;
93 QFileDialogPrivate *mPriv;
94 NSString *mCurrentDir;
95 bool mConfirmOverwrite;
96 int mReturnCode;
97
98 QT_PREPEND_NAMESPACE(QFileDialog::AcceptMode) mAcceptMode;
99 QT_PREPEND_NAMESPACE(QDir::Filters) *mQDirFilter;
100 QT_PREPEND_NAMESPACE(QFileDialog::FileMode) mFileMode;
101 QT_PREPEND_NAMESPACE(QFileDialog::Options) *mFileOptions;
102
103 QString *mLastFilterCheckPath;
104 QString *mCurrentSelection;
105 QStringList *mQDirFilterEntryList;
106 QStringList *mNameFilterDropDownList;
107 QStringList *mSelectedNameFilter;
108}
109
110- (NSString *)strip:(const QString &)label;
111- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename;
112- (void)filterChanged:(id)sender;
113- (void)showModelessPanel;
114- (BOOL)runApplicationModalPanel;
115- (void)showWindowModalSheet:(QWidget *)docWidget;
116- (void)updateProperties;
117- (QStringList)acceptableExtensionsForSave;
118- (QString)removeExtensions:(const QString &)filter;
119- (void)createTextField;
120- (void)createPopUpButton:(const QString &)selectedFilter hideDetails:(BOOL)hideDetails;
121- (void)createAccessory;
122
123@end
124
125@implementation QNSOpenSavePanelDelegate
126
127- (id)initWithAcceptMode:(QT_PREPEND_NAMESPACE(QFileDialog::AcceptMode))acceptMode
128 title:(const QString &)title
129 nameFilters:(const QStringList &)nameFilters
130 selectedNameFilter:(const QString &)selectedNameFilter
131 hideNameFilterDetails:(bool)hideNameFilterDetails
132 qDirFilter:(QT_PREPEND_NAMESPACE(QDir::Filters))qDirFilter
133 fileOptions:(QT_PREPEND_NAMESPACE(QFileDialog::Options))fileOptions
134 fileMode:(QT_PREPEND_NAMESPACE(QFileDialog::FileMode))fileMode
135 selectFile:(const QString &)selectFile
136 confirmOverwrite:(bool)confirm
137 priv:(QFileDialogPrivate *)priv
138{
139 self = [super init];
140
141 mAcceptMode = acceptMode;
142 if (mAcceptMode == QT_PREPEND_NAMESPACE(QFileDialog::AcceptOpen)){
143 mOpenPanel = [NSOpenPanel openPanel];
144 mSavePanel = mOpenPanel;
145 } else {
146 mSavePanel = [NSSavePanel savePanel];
147 mOpenPanel = 0;
148 }
149
150 [mSavePanel setLevel:NSModalPanelWindowLevel];
151 [mSavePanel setDelegate:self];
152 mQDirFilter = new QT_PREPEND_NAMESPACE(QDir::Filters)(qDirFilter);
153 mFileOptions = new QT_PREPEND_NAMESPACE(QFileDialog::Options)(fileOptions);
154 mFileMode = fileMode;
155 mConfirmOverwrite = confirm;
156 mReturnCode = -1;
157 mPriv = priv;
158 mLastFilterCheckPath = new QString;
159 mQDirFilterEntryList = new QStringList;
160 mNameFilterDropDownList = new QStringList(nameFilters);
161 mSelectedNameFilter = new QStringList(qt_clean_filter_list(selectedNameFilter));
162 QFileInfo sel(selectFile);
163 if (sel.isDir()){
164 mCurrentDir = [qt_mac_QStringToNSString(sel.absoluteFilePath()) retain];
165 mCurrentSelection = new QString;
166 } else {
167 mCurrentDir = [qt_mac_QStringToNSString(sel.absolutePath()) retain];
168 mCurrentSelection = new QString(sel.absoluteFilePath());
169 }
170 [mSavePanel setTitle:qt_mac_QStringToNSString(title)];
171 [self createPopUpButton:selectedNameFilter hideDetails:hideNameFilterDetails];
172 [self createTextField];
173 [self createAccessory];
174 [mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil];
175
176 if (mPriv){
177 [mSavePanel setPrompt:[self strip:mPriv->acceptLabel]];
178 if (mPriv->fileNameLabelExplicitlySat)
179 [mSavePanel setNameFieldLabel:[self strip:mPriv->qFileDialogUi->fileNameLabel->text()]];
180 }
181
182 [self updateProperties];
183 [mSavePanel retain];
184 return self;
185}
186
187- (void)dealloc
188{
189 delete mQDirFilter;
190 delete mFileOptions;
191 delete mLastFilterCheckPath;
192 delete mQDirFilterEntryList;
193 delete mNameFilterDropDownList;
194 delete mSelectedNameFilter;
195 delete mCurrentSelection;
196
197 [mSavePanel orderOut:mSavePanel];
198 [mSavePanel setAccessoryView:nil];
199 [mPopUpButton release];
200 [mTextField release];
201 [mAccessoryView release];
202 [mSavePanel setDelegate:nil];
203 [mSavePanel release];
204 [mCurrentDir release];
205 [super dealloc];
206}
207
208- (NSString *)strip:(const QString &)label
209{
210 QAction a(label, 0);
211 return qt_mac_QStringToNSString(a.iconText());
212}
213
214- (void)closePanel
215{
216 *mCurrentSelection = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)([mSavePanel filename]);
217 [mSavePanel close];
218}
219
220- (void)showModelessPanel
221{
222 if (mOpenPanel){
223 QFileInfo info(*mCurrentSelection);
224 NSString *filename = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.fileName());
225 NSString *filepath = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.filePath());
226 bool selectable = (mAcceptMode == QFileDialog::AcceptSave)
227 || [self panel:nil shouldShowFilename:filepath];
228 [mOpenPanel
229 beginForDirectory:mCurrentDir
230 file:selectable ? filename : nil
231 types:nil
232 modelessDelegate:self
233 didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
234 contextInfo:nil];
235 }
236}
237
238- (BOOL)runApplicationModalPanel
239{
240 QFileInfo info(*mCurrentSelection);
241 NSString *filename = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.fileName());
242 NSString *filepath = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.filePath());
243 bool selectable = (mAcceptMode == QFileDialog::AcceptSave)
244 || [self panel:nil shouldShowFilename:filepath];
245 mReturnCode = [mSavePanel
246 runModalForDirectory:mCurrentDir
247 file:selectable ? filename : @"untitled"];
248 return (mReturnCode == NSOKButton);
249}
250
251- (QT_PREPEND_NAMESPACE(QDialog::DialogCode))dialogResultCode
252{
253 return (mReturnCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QDialog::Accepted) : QT_PREPEND_NAMESPACE(QDialog::Rejected);
254}
255
256- (void)showWindowModalSheet:(QWidget *)docWidget
257{
258 Q_UNUSED(docWidget);
259 QFileInfo info(*mCurrentSelection);
260 NSString *filename = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.fileName());
261 NSString *filepath = QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(info.filePath());
262 bool selectable = (mAcceptMode == QFileDialog::AcceptSave)
263 || [self panel:nil shouldShowFilename:filepath];
264 [mSavePanel
265 beginSheetForDirectory:mCurrentDir
266 file:selectable ? filename : nil
267#ifdef QT_MAC_USE_COCOA
268 modalForWindow:QT_PREPEND_NAMESPACE(qt_mac_window_for)(docWidget)
269#else
270 modalForWindow:nil
271#endif
272 modalDelegate:self
273 didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
274 contextInfo:nil];
275}
276
277- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename
278{
279 Q_UNUSED(sender);
280 QString qtFileName = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)(filename);
281 QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C)));
282 QString path = info.absolutePath();
283 if (path != *mLastFilterCheckPath){
284 *mLastFilterCheckPath = path;
285 *mQDirFilterEntryList = info.dir().entryList(*mQDirFilter);
286 }
287 // Check if the QDir filter accepts the file:
288 if (!mQDirFilterEntryList->contains(info.fileName()))
289 return NO;
290
291 // Always accept directories regardless of their names:
292 BOOL isDir;
293 if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir)
294 return YES;
295
296 // No filter means accept everything
297 if (mSelectedNameFilter->isEmpty())
298 return YES;
299 // Check if the current file name filter accepts the file:
300 for (int i=0; i<mSelectedNameFilter->size(); ++i) {
301 if (QDir::match(mSelectedNameFilter->at(i), qtFileName))
302 return YES;
303 }
304 return NO;
305}
306
307- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag
308{
309 Q_UNUSED(sender);
310 if (!okFlag)
311 return filename;
312 if (mConfirmOverwrite)
313 return filename;
314
315 // User has clicked save, and no overwrite confirmation should occur.
316 // To get the latter, we need to change the name we return (hence the prefix):
317 return [@"___qt_very_unlikely_prefix_" stringByAppendingString:filename];
318}
319
320- (void)setNameFilters:(const QStringList &)filters hideDetails:(BOOL)hideDetails
321{
322 [mPopUpButton removeAllItems];
323 *mNameFilterDropDownList = filters;
324 if (filters.size() > 0){
325 for (int i=0; i<filters.size(); ++i) {
326 QString filter = hideDetails ? [self removeExtensions:filters.at(i)] : filters.at(i);
327 [mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(filter)];
328 }
329 [mPopUpButton selectItemAtIndex:0];
330 [mSavePanel setAccessoryView:mAccessoryView];
331 } else
332 [mSavePanel setAccessoryView:nil];
333
334 [self filterChanged:self];
335}
336
337- (void)filterChanged:(id)sender
338{
339 // This mDelegate function is called when the _name_ filter changes.
340 Q_UNUSED(sender);
341 QString selection = mNameFilterDropDownList->value([mPopUpButton indexOfSelectedItem]);
342 *mSelectedNameFilter = QT_PREPEND_NAMESPACE(qt_clean_filter_list)(selection);
343 [mSavePanel validateVisibleColumns];
344 [self updateProperties];
345 if (mPriv)
346 mPriv->QNSOpenSavePanelDelegate_filterSelected([mPopUpButton indexOfSelectedItem]);
347}
348
349- (QString)currentNameFilter
350{
351 return mNameFilterDropDownList->value([mPopUpButton indexOfSelectedItem]);
352}
353
354- (QStringList)selectedFiles
355{
356 if (mOpenPanel)
357 return QT_PREPEND_NAMESPACE(qt_mac_NSArrayToQStringList)([mOpenPanel filenames]);
358 else{
359 QStringList result;
360 QString filename = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)([mSavePanel filename]);
361 result << filename.remove(QLatin1String("___qt_very_unlikely_prefix_"));
362 return result;
363 }
364}
365
366- (void)updateProperties
367{
368 // Call this functions if mFileMode, mFileOptions,
369 // mNameFilterDropDownList or mQDirFilter changes.
370 // The savepanel does not contain the neccessary functions for this.
371 bool chooseFilesOnly = mFileMode == QT_PREPEND_NAMESPACE(QFileDialog::ExistingFile)
372 || mFileMode == QT_PREPEND_NAMESPACE(QFileDialog::ExistingFiles);
373 bool chooseDirsOnly = mFileMode == QT_PREPEND_NAMESPACE(QFileDialog::Directory)
374 || mFileMode == QT_PREPEND_NAMESPACE(QFileDialog::DirectoryOnly)
375 || *mFileOptions & QT_PREPEND_NAMESPACE(QFileDialog::ShowDirsOnly);
376
377 [mOpenPanel setCanChooseFiles:!chooseDirsOnly];
378 [mOpenPanel setCanChooseDirectories:!chooseFilesOnly];
379 [mSavePanel setCanCreateDirectories:!(*mFileOptions & QT_PREPEND_NAMESPACE(QFileDialog::ReadOnly))];
380 [mOpenPanel setAllowsMultipleSelection:(mFileMode == QT_PREPEND_NAMESPACE(QFileDialog::ExistingFiles))];
381 [mOpenPanel setResolvesAliases:!(*mFileOptions & QT_PREPEND_NAMESPACE(QFileDialog::DontResolveSymlinks))];
382
383 QStringList ext = [self acceptableExtensionsForSave];
384 if (mPriv && !ext.isEmpty() && !mPriv->defaultSuffix.isEmpty())
385 ext.prepend(mPriv->defaultSuffix);
386 [mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : QT_PREPEND_NAMESPACE(qt_mac_QStringListToNSMutableArray(ext))];
387
388 if ([mSavePanel isVisible])
389 [mOpenPanel validateVisibleColumns];
390}
391
392- (void)panelSelectionDidChange:(id)sender
393{
394 Q_UNUSED(sender);
395 *mCurrentSelection = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString([mSavePanel filename]));
396 if (mPriv)
397 mPriv->QNSOpenSavePanelDelegate_selectionChanged(*mCurrentSelection);
398}
399
400- (void)openPanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
401{
402 Q_UNUSED(panel);
403 Q_UNUSED(contextInfo);
404 mReturnCode = returnCode;
405 if (mPriv)
406 mPriv->QNSOpenSavePanelDelegate_panelClosed(returnCode == NSOKButton);
407}
408
409- (void)panel:(id)sender directoryDidChange:(NSString *)path
410{
411 Q_UNUSED(sender);
412 if (!mPriv)
413 return;
414 if ([path isEqualToString:mCurrentDir])
415 return;
416
417 [mCurrentDir release];
418 mCurrentDir = [path retain];
419 mPriv->QNSOpenSavePanelDelegate_directoryEntered(QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString(mCurrentDir)));
420}
421
422/*
423 Returns a list of extensions (e.g. "png", "jpg", "gif")
424 for the current name filter. If a filter do not conform
425 to the format *.xyz or * or *.*, an empty list
426 is returned meaning accept everything.
427*/
428- (QStringList)acceptableExtensionsForSave
429{
430 QStringList result;
431 for (int i=0; i<mSelectedNameFilter->count(); ++i) {
432 const QString &filter = mSelectedNameFilter->at(i);
433 if (filter.startsWith(QLatin1String("*."))
434 && !filter.contains(QLatin1Char('?'))
435 && filter.count(QLatin1Char('*')) == 1) {
436 result += filter.mid(2);
437 } else {
438 return QStringList(); // Accept everything
439 }
440 }
441 return result;
442}
443
444- (QString)removeExtensions:(const QString &)filter
445{
446 QRegExp regExp(QT_PREPEND_NAMESPACE(QString::fromLatin1)(QT_PREPEND_NAMESPACE(qt_file_dialog_filter_reg_exp)));
447 if (regExp.indexIn(filter) != -1)
448 return regExp.cap(1).trimmed();
449 return filter;
450}
451
452- (void)createTextField
453{
454 NSRect textRect = { { 0.0, 3.0 }, { 100.0, 25.0 } };
455 mTextField = [[NSTextField alloc] initWithFrame:textRect];
456 [[mTextField cell] setFont:[NSFont systemFontOfSize:
457 [NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
458 [mTextField setAlignment:NSRightTextAlignment];
459 [mTextField setEditable:false];
460 [mTextField setSelectable:false];
461 [mTextField setBordered:false];
462 [mTextField setDrawsBackground:false];
463 if (mPriv){
464 [mTextField setStringValue:[self strip:mPriv->qFileDialogUi->fileTypeLabel->text()]];
465 } else
466 [mTextField setStringValue:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(QT_PREPEND_NAMESPACE(QFileDialog::tr)("Files of type:"))];
467}
468
469- (void)createPopUpButton:(const QString &)selectedFilter hideDetails:(BOOL)hideDetails
470{
471 NSRect popUpRect = { { 100.0, 5.0 }, { 250.0, 25.0 } };
472 mPopUpButton = [[NSPopUpButton alloc] initWithFrame:popUpRect pullsDown:NO];
473 [mPopUpButton setTarget:self];
474 [mPopUpButton setAction:@selector(filterChanged:)];
475
476 QStringList *filters = mNameFilterDropDownList;
477 if (filters->size() > 0){
478 for (int i=0; i<mNameFilterDropDownList->size(); ++i) {
479 QString filter = hideDetails ? [self removeExtensions:filters->at(i)] : filters->at(i);
480 [mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(filter)];
481 if (filters->at(i) == selectedFilter)
482 [mPopUpButton selectItemAtIndex:i];
483 }
484 }
485}
486
487- (void)createAccessory
488{
489 NSRect accessoryRect = { { 0.0, 0.0 }, { 450.0, 33.0 } };
490 mAccessoryView = [[NSView alloc] initWithFrame:accessoryRect];
491 [mAccessoryView addSubview:mTextField];
492 [mAccessoryView addSubview:mPopUpButton];
493}
494
495@end
496
497QT_BEGIN_NAMESPACE
498
499void QFileDialogPrivate::QNSOpenSavePanelDelegate_selectionChanged(const QString &newPath)
500{
501 emit q_func()->currentChanged(newPath);
502}
503
504void QFileDialogPrivate::QNSOpenSavePanelDelegate_panelClosed(bool accepted)
505{
506 if (accepted)
507 q_func()->accept();
508 else
509 q_func()->reject();
510}
511
512void QFileDialogPrivate::QNSOpenSavePanelDelegate_directoryEntered(const QString &newDir)
513{
514 setLastVisitedDirectory(newDir);
515 emit q_func()->directoryEntered(newDir);
516}
517
518void QFileDialogPrivate::QNSOpenSavePanelDelegate_filterSelected(int menuIndex)
519{
520 emit q_func()->filterSelected(nameFilters.at(menuIndex));
521}
522
523extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
524extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1); // qglobal.cpp
525
526void QFileDialogPrivate::setDirectory_sys(const QString &directory)
527{
528#ifndef QT_MAC_USE_COCOA
529 if (directory == mCurrentLocation)
530 return;
531 mCurrentLocation = directory;
532 emit q_func()->directoryEntered(mCurrentLocation);
533
534 FSRef fsRef;
535 if (qt_mac_create_fsref(directory, &fsRef) == noErr) {
536 AEDesc desc;
537 if (AECreateDesc(typeFSRef, &fsRef, sizeof(FSRef), &desc) == noErr)
538 NavCustomControl(mDialog, kNavCtlSetLocation, (void*)&desc);
539 }
540#else
541 QMacCocoaAutoReleasePool pool;
542 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
543 [delegate->mSavePanel setDirectory:qt_mac_QStringToNSString(directory)];
544#endif
545}
546
547QString QFileDialogPrivate::directory_sys() const
548{
549#ifndef QT_MAC_USE_COCOA
550 return mCurrentLocation;
551#else
552 QMacCocoaAutoReleasePool pool;
553 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
554 return qt_mac_NSStringToQString([delegate->mSavePanel directory]);
555#endif
556}
557
558void QFileDialogPrivate::selectFile_sys(const QString &filename)
559{
560 QString filePath = filename;
561 if (QDir::isRelativePath(filePath))
562 filePath = QFileInfo(directory_sys(), filePath).filePath();
563
564#ifndef QT_MAC_USE_COCOA
565 // Update the selection list immidiatly, so
566 // subsequent calls to selectedFiles() gets correct:
567 mCurrentSelectionList.clear();
568 mCurrentSelectionList << filename;
569 if (mCurrentSelection != filename){
570 mCurrentSelection = filename;
571 emit q_func()->currentChanged(mCurrentSelection);
572 }
573
574 AEDescList descList;
575 if (AECreateList(0, 0, false, &descList) != noErr)
576 return;
577
578 FSRef fsRef;
579 if (qt_mac_create_fsref(filePath, &fsRef) == noErr) {
580 AEDesc desc;
581 if (AECreateDesc(typeFSRef, &fsRef, sizeof(FSRef), &desc) == noErr){
582 if (AEPutDesc(&descList, 0, &desc) == noErr)
583 NavCustomControl(mDialog, kNavCtlSetSelection, (void*)&descList);
584 }
585 }
586
587 // Type the file name into the save dialog's text field:
588 UInt8 *strBuffer = (UInt8 *)malloc(1024);
589 qt_mac_to_pascal_string(QFileInfo(filename).fileName(), strBuffer);
590 NavCustomControl(mDialog, kNavCtlSetEditFileName, strBuffer);
591 free(strBuffer);
592#else
593 // There seems to no way to select a file once the dialog is running.
594 // So do the next best thing, set the file's directory:
595 setDirectory_sys(QFileInfo(filePath).absolutePath());
596#endif
597}
598
599QStringList QFileDialogPrivate::selectedFiles_sys() const
600{
601#ifndef QT_MAC_USE_COCOA
602 if (q_func()->acceptMode() == QFileDialog::AcceptOpen){
603 return mCurrentSelectionList;
604 } else {
605 return QStringList() << mCurrentLocation + QLatin1Char('/')
606 + QCFString::toQString(NavDialogGetSaveFileName(mDialog));
607 }
608#else
609 QMacCocoaAutoReleasePool pool;
610 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
611 return [delegate selectedFiles];
612#endif
613}
614
615void QFileDialogPrivate::setNameFilters_sys(const QStringList &filters)
616{
617#ifndef QT_MAC_USE_COCOA
618 Q_UNUSED(filters);
619#else
620 QMacCocoaAutoReleasePool pool;
621 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
622 bool hideDetails = q_func()->testOption(QFileDialog::HideNameFilterDetails);
623 [delegate setNameFilters:filters hideDetails:hideDetails];
624#endif
625}
626
627void QFileDialogPrivate::setFilter_sys()
628{
629#ifndef QT_MAC_USE_COCOA
630#else
631 QMacCocoaAutoReleasePool pool;
632 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
633 *(delegate->mQDirFilter) = model->filter();
634 [delegate updateProperties];
635#endif
636}
637
638void QFileDialogPrivate::selectNameFilter_sys(const QString &filter)
639{
640 int index = nameFilters.indexOf(filter);
641 if (index != -1) {
642#ifndef QT_MAC_USE_COCOA
643 NavMenuItemSpec navSpec;
644 bzero(&navSpec, sizeof(NavMenuItemSpec));
645 navSpec.menuType = index;
646 NavCustomControl(mDialog, kNavCtlSelectCustomType, &navSpec);
647#else
648 QMacCocoaAutoReleasePool pool;
649 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
650 [delegate->mPopUpButton selectItemAtIndex:index];
651 [delegate filterChanged:nil];
652#endif
653 }
654}
655
656QString QFileDialogPrivate::selectedNameFilter_sys() const
657{
658#ifndef QT_MAC_USE_COCOA
659 int index = filterInfo.currentSelection;
660#else
661 QMacCocoaAutoReleasePool pool;
662 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
663 int index = [delegate->mPopUpButton indexOfSelectedItem];
664#endif
665 return index != -1 ? nameFilters.at(index) : QString();
666}
667
668void QFileDialogPrivate::deleteNativeDialog_sys()
669{
670#ifndef QT_MAC_USE_COCOA
671 if (mDialog)
672 NavDialogDispose(mDialog);
673 mDialog = 0;
674 mDialogStarted = false;
675#else
676 QMacCocoaAutoReleasePool pool;
677 [reinterpret_cast<QNSOpenSavePanelDelegate *>(mDelegate) release];
678 mDelegate = 0;
679#endif
680 nativeDialogInUse = false;
681}
682
683bool QFileDialogPrivate::setVisible_sys(bool visible)
684{
685 Q_Q(QFileDialog);
686 if (!visible == q->isHidden())
687 return false;
688
689#ifndef QT_MAC_USE_COCOA
690 return visible ? showCarbonNavServicesDialog() : hideCarbonNavServicesDialog();
691#else
692 return visible ? showCocoaFilePanel() : hideCocoaFilePanel();
693#endif
694}
695
696#ifndef QT_MAC_USE_COCOA
697Boolean QFileDialogPrivate::qt_mac_filedialog_filter_proc(AEDesc *theItem, void *info,
698 void *data, NavFilterModes)
699{
700 QFileDialogPrivate *fileDialogPrivate = static_cast<QFileDialogPrivate *>(data);
701
702 if (!fileDialogPrivate || fileDialogPrivate->filterInfo.filters.isEmpty()
703 || (fileDialogPrivate->filterInfo.currentSelection < 0
704 && fileDialogPrivate->filterInfo.currentSelection
705 >= fileDialogPrivate->filterInfo.filters.size()))
706 return true;
707
708 NavFileOrFolderInfo *theInfo = static_cast<NavFileOrFolderInfo *>(info);
709 QString file;
710 const QtMacFilterName &fn
711 = fileDialogPrivate->filterInfo.filters.at(fileDialogPrivate->filterInfo.currentSelection);
712 if (theItem->descriptorType == typeFSRef) {
713 FSRef ref;
714 AEGetDescData(theItem, &ref, sizeof(ref));
715 UInt8 str_buffer[1024];
716 FSRefMakePath(&ref, str_buffer, 1024);
717 file = QString::fromUtf8(reinterpret_cast<const char *>(str_buffer));
718 int slsh = file.lastIndexOf(QLatin1Char('/'));
719 if (slsh != -1)
720 file = file.right(file.length() - slsh - 1);
721 }
722 QStringList reg = fn.regexp.split(QLatin1String(";"));
723 for (QStringList::const_iterator it = reg.constBegin(); it != reg.constEnd(); ++it) {
724 QRegExp rg(*it, Qt::CaseInsensitive, QRegExp::Wildcard);
725#ifdef DEBUG_FILEDIALOG_FILTERS
726 qDebug("QFileDialogPrivate::qt_mac_filedialog_filter_proc:%d, asked to filter.. %s (%s)", __LINE__,
727 qPrintable(file), qPrintable(*it));
728#endif
729 if (rg.exactMatch(file))
730 return true;
731 }
732 return (theInfo->isFolder && !file.endsWith(QLatin1String(".app")));
733}
734
735void QFileDialogPrivate::qt_mac_filedialog_event_proc(const NavEventCallbackMessage msg,
736 NavCBRecPtr p, NavCallBackUserData data)
737{
738 QFileDialogPrivate *fileDialogPrivate = static_cast<QFileDialogPrivate *>(data);
739
740 switch(msg) {
741 case kNavCBPopupMenuSelect: {
742 NavMenuItemSpec *s = static_cast<NavMenuItemSpec *>(p->eventData.eventDataParms.param);
743 if (int(s->menuType) != fileDialogPrivate->filterInfo.currentSelection) {
744 fileDialogPrivate->filterInfo.currentSelection = s->menuType;
745 emit fileDialogPrivate->q_func()->filterSelected(fileDialogPrivate->nameFilters.at(s->menuType));
746 }
747 if (fileDialogPrivate->acceptMode == QFileDialog::AcceptSave) {
748 QString base = QCFString::toQString(NavDialogGetSaveFileName(p->context));
749 QFileInfo fi(base);
750 base = fi.completeBaseName();
751 const QtMacFilterName &fn = fileDialogPrivate->filterInfo.filters.at(
752 fileDialogPrivate->filterInfo.currentSelection);
753 QStringList reg = fn.regexp.split(QLatin1String(";"), QString::SkipEmptyParts);
754 QString r = reg.first();
755 r = r.right(r.length()-1); // Strip the *
756 base += r; //"." + QString::number(s->menuType);
757 NavDialogSetSaveFileName(p->context, QCFString::toCFStringRef(base));
758 }
759#ifdef DEBUG_FILEDIALOG_FILTERS
760 qDebug("QFileDialogPrivate::qt_mac_filedialog_event_proc:%d - Selected a filter: %ld", __LINE__, s->menuType);
761#endif
762 break; }
763 case kNavCBStart:{
764 fileDialogPrivate->mDialogStarted = true;
765 // Set selected file:
766 QModelIndexList indexes = fileDialogPrivate->qFileDialogUi->listView->selectionModel()->selectedRows();
767 QString selected;
768 if (!indexes.isEmpty())
769 selected = indexes.at(0).data(QFileSystemModel::FilePathRole).toString();
770 else
771 selected = fileDialogPrivate->typedFiles().value(0);
772 fileDialogPrivate->selectFile_sys(selected);
773 fileDialogPrivate->selectNameFilter_sys(fileDialogPrivate->qFileDialogUi->fileTypeCombo->currentText());
774 break; }
775 case kNavCBSelectEntry:{
776 // Event: Current selection has changed.
777 QStringList prevSelectionList = fileDialogPrivate->mCurrentSelectionList;
778 fileDialogPrivate->mCurrentSelectionList.clear();
779 QString fileNameToEmit;
780
781 AEDescList *descList = (AEDescList *)p->eventData.eventDataParms.param;
782 // Get the number of files selected:
783 UInt8 strBuffer[1024];
784 long count;
785 OSErr err = AECountItems(descList, &count);
786 if (err != noErr || !count)
787 break;
788
789 for (long index=1; index<=count; ++index) {
790 FSRef ref;
791 err = AEGetNthPtr(descList, index, typeFSRef, 0, 0, &ref, sizeof(ref), 0);
792 if (err != noErr)
793 break;
794 FSRefMakePath(&ref, strBuffer, 1024);
795 QString selected = QString::fromUtf8((const char *)strBuffer);
796 fileDialogPrivate->mCurrentSelectionList << selected;
797 if (!prevSelectionList.contains(selected))
798 fileNameToEmit = selected;
799 }
800
801 if (!fileNameToEmit.isEmpty() && fileNameToEmit != fileDialogPrivate->mCurrentSelection)
802 emit fileDialogPrivate->q_func()->currentChanged(fileNameToEmit);
803 fileDialogPrivate->mCurrentSelection = fileNameToEmit;
804 break; }
805 case kNavCBShowDesktop:
806 case kNavCBNewLocation:{
807 // Event: Current directory has changed.
808 AEDesc *desc = (AEDesc *)p->eventData.eventDataParms.param;
809 FSRef ref;
810 AEGetDescData(desc, &ref, sizeof(ref));
811 UInt8 *strBuffer = (UInt8 *)malloc(1024);
812 FSRefMakePath(&ref, strBuffer, 1024);
813 QString newLocation = QString::fromUtf8((const char *)strBuffer);
814 free(strBuffer);
815 if (fileDialogPrivate->mCurrentLocation != newLocation){
816 fileDialogPrivate->mCurrentLocation = newLocation;
817 QFileDialog::FileMode mode = fileDialogPrivate->fileMode;
818 if (mode == QFileDialog::AnyFile || mode == QFileDialog::ExistingFile
819 || mode == QFileDialog::ExistingFiles){
820 // When changing directory, the current selection is cleared if
821 // we are supposed to be selecting files only:
822 fileDialogPrivate->mCurrentSelectionList.clear();
823 if (!fileDialogPrivate->mCurrentSelection.isEmpty()){
824 fileDialogPrivate->mCurrentSelection.clear();
825 emit fileDialogPrivate->q_func()->currentChanged(fileDialogPrivate->mCurrentSelection);
826 }
827 }
828 fileDialogPrivate->setLastVisitedDirectory(newLocation);
829 emit fileDialogPrivate->q_func()->directoryEntered(newLocation);
830 }
831 break; }
832 case kNavCBAccept:
833 fileDialogPrivate->mDialogClosed = true;
834 fileDialogPrivate->q_func()->accept();
835 break;
836 case kNavCBCancel:
837 fileDialogPrivate->mDialogClosed = true;
838 fileDialogPrivate->q_func()->reject();
839 break;
840 }
841}
842
843static QFileDialogPrivate::QtMacFilterName qt_mac_extract_filter(const QString &rawFilter, bool showDetails)
844{
845 QFileDialogPrivate::QtMacFilterName ret;
846 ret.filter = rawFilter;
847 QString result = rawFilter;
848 QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
849 int index = r.indexIn(result);
850 if (index >= 0)
851 result = r.cap(2);
852
853 if (showDetails) {
854 ret.description = rawFilter;
855 } else {
856 if (index >= 0)
857 ret.description = r.cap(1).trimmed();
858 if (ret.description.isEmpty())
859 ret.description = result;
860 }
861 ret.regexp = result.replace(QLatin1Char(' '), QLatin1Char(';'));
862 return ret;
863}
864
865static QList<QFileDialogPrivate::QtMacFilterName> qt_mac_make_filters_list(const QString &filter, bool showDetails)
866{
867#ifdef DEBUG_FILEDIALOG_FILTERS
868 qDebug("QFileDialog:%d - Got filter (%s)", __LINE__, filter.latin1());
869#endif
870
871 QList<QFileDialogPrivate::QtMacFilterName> ret;
872 QString f(filter);
873 if (f.isEmpty())
874 f = QFileDialog::tr("All Files (*)");
875 if (f.isEmpty())
876 return ret;
877 QStringList filts = qt_make_filter_list(f);
878 for (QStringList::const_iterator it = filts.constBegin(); it != filts.constEnd(); ++it) {
879 QFileDialogPrivate::QtMacFilterName filter = qt_mac_extract_filter(*it, showDetails);
880#ifdef DEBUG_FILEDIALOG_FILTERS
881 qDebug("QFileDialog:%d Split out filter (%d) '%s' '%s' [%s]", __LINE__, ret.count(),
882 filter->regxp.latin1(), filter->description.latin1(), (*it).latin1());
883#endif
884 ret.append(filter);
885 }
886 return ret;
887}
888
889void QFileDialogPrivate::createNavServicesDialog()
890{
891 Q_Q(QFileDialog);
892 if (mDialog)
893 deleteNativeDialog_sys();
894
895 NavDialogCreationOptions navOptions;
896 NavGetDefaultDialogCreationOptions(&navOptions);
897
898 // Translate QFileDialog settings into NavDialog options:
899 if (qt_mac_is_macsheet(q)) {
900 navOptions.modality = kWindowModalityWindowModal;
901 navOptions.parentWindow = qt_mac_window_for(q->parentWidget());
902 } else if (q->windowModality() == Qt::ApplicationModal)
903 navOptions.modality = kWindowModalityAppModal;
904 else
905 navOptions.modality = kWindowModalityNone;
906 navOptions.optionFlags |= kNavSupportPackages;
907 if (q->testOption(QFileDialog::DontConfirmOverwrite))
908 navOptions.optionFlags |= kNavDontConfirmReplacement;
909 if (fileMode != QFileDialog::ExistingFiles)
910 navOptions.optionFlags &= ~kNavAllowMultipleFiles;
911
912 navOptions.windowTitle = QCFString::toCFStringRef(q->windowTitle());
913
914 static const int w = 450, h = 350;
915 navOptions.location.h = navOptions.location.v = -1;
916 QWidget *parent = q->parentWidget();
917 if (parent && parent->isVisible()) {
918 WindowClass wclass;
919 GetWindowClass(qt_mac_window_for(parent), &wclass);
920 parent = parent->window();
921 QString s = parent->windowTitle();
922 navOptions.clientName = QCFString::toCFStringRef(s);
923 navOptions.location.h = (parent->x() + (parent->width() / 2)) - (w / 2);
924 navOptions.location.v = (parent->y() + (parent->height() / 2)) - (h / 2);
925
926 QRect r = QApplication::desktop()->screenGeometry(
927 QApplication::desktop()->screenNumber(parent));
928 const int border = 10;
929 if (navOptions.location.h + w > r.right())
930 navOptions.location.h -= (navOptions.location.h + w) - r.right() + border;
931 if (navOptions.location.v + h > r.bottom())
932 navOptions.location.v -= (navOptions.location.v + h) - r.bottom() + border;
933 if (navOptions.location.h < r.left())
934 navOptions.location.h = r.left() + border;
935 if (navOptions.location.v < r.top())
936 navOptions.location.v = r.top() + border;
937 }
938
939 filterInfo.currentSelection = 0;
940 filterInfo.filters = qt_mac_make_filters_list(nameFilters.join(QLatin1String(";;")), q->isNameFilterDetailsVisible());
941 QCFType<CFArrayRef> filterArray;
942 if (filterInfo.filters.size() > 1) {
943 int i = 0;
944 CFStringRef *cfstringArray = static_cast<CFStringRef *>(malloc(sizeof(CFStringRef)
945 * filterInfo.filters.size()));
946 for (i = 0; i < filterInfo.filters.size(); ++i) {
947 cfstringArray[i] = QCFString::toCFStringRef(filterInfo.filters.at(i).description);
948 }
949 filterArray = CFArrayCreate(kCFAllocatorDefault,
950 reinterpret_cast<const void **>(cfstringArray), filterInfo.filters.size(),
951 &kCFTypeArrayCallBacks);
952 navOptions.popupExtension = filterArray;
953 free(cfstringArray);
954 }
955
956 if (q->acceptMode() == QFileDialog::AcceptSave) {
957 if (NavCreatePutFileDialog(&navOptions, 'cute', kNavGenericSignature,
958 QFileDialogPrivate::qt_mac_filedialog_event_proc, this, &mDialog)) {
959 qDebug("Shouldn't happen %s:%d", __FILE__, __LINE__);
960 return;
961 }
962 } else if (fileMode == QFileDialog::DirectoryOnly || fileMode == QFileDialog::Directory) {
963 if (NavCreateChooseFolderDialog(&navOptions,
964 QFileDialogPrivate::qt_mac_filedialog_event_proc, 0, this, &mDialog)) {
965 qDebug("Shouldn't happen %s:%d", __FILE__, __LINE__);
966 return;
967 }
968 } else {
969 if (NavCreateGetFileDialog(&navOptions, 0,
970 QFileDialogPrivate::qt_mac_filedialog_event_proc, 0,
971 QFileDialogPrivate::qt_mac_filedialog_filter_proc, this, &mDialog)) {
972 qDebug("Shouldn't happen %s:%d", __FILE__, __LINE__);
973 return;
974 }
975 }
976
977 // Set start-up directory:
978 if (mCurrentLocation.isEmpty())
979 mCurrentLocation = rootPath();
980 FSRef fsRef;
981 if (qt_mac_create_fsref(mCurrentLocation, &fsRef) == noErr) {
982 AEDesc desc;
983 if (AECreateDesc(typeFSRef, &fsRef, sizeof(FSRef), &desc) == noErr)
984 NavCustomControl(mDialog, kNavCtlSetLocation, (void*)&desc);
985 }
986}
987
988bool QFileDialogPrivate::showCarbonNavServicesDialog()
989{
990 Q_Q(QFileDialog);
991 if (q->acceptMode() == QFileDialog::AcceptSave && q->windowModality() == Qt::NonModal)
992 return false; // cannot do native no-modal save dialogs.
993 createNavServicesDialog();
994 mDialogClosed = false;
995 if (q->windowModality() != Qt::ApplicationModal)
996 NavDialogRun(mDialog);
997 return true;
998}
999
1000bool QFileDialogPrivate::hideCarbonNavServicesDialog()
1001{
1002 if (!mDialogClosed){
1003 mDialogClosed = true;
1004 NavCustomControl(mDialog, kNavCtlCancel, 0);
1005 }
1006 return true;
1007}
1008
1009#else // Cocoa
1010
1011void QFileDialogPrivate::createNSOpenSavePanelDelegate()
1012{
1013 Q_Q(QFileDialog);
1014 if (mDelegate)
1015 return;
1016
1017 bool selectDir = q->selectedFiles().isEmpty();
1018 QString selection(selectDir ? q->directory().absolutePath() : q->selectedFiles().value(0));
1019 QNSOpenSavePanelDelegate *delegate = [[QNSOpenSavePanelDelegate alloc]
1020 initWithAcceptMode:acceptMode
1021 title:q->windowTitle()
1022 nameFilters:q->nameFilters()
1023 selectedNameFilter:q->selectedNameFilter()
1024 hideNameFilterDetails:q->testOption(QFileDialog::HideNameFilterDetails)
1025 qDirFilter:model->filter()
1026 fileOptions:opts
1027 fileMode:fileMode
1028 selectFile:selection
1029 confirmOverwrite:!q->testOption(QFileDialog::DontConfirmOverwrite)
1030 priv:this];
1031
1032 mDelegate = delegate;
1033}
1034
1035bool QFileDialogPrivate::showCocoaFilePanel()
1036{
1037 Q_Q(QFileDialog);
1038 QMacCocoaAutoReleasePool pool;
1039 createNSOpenSavePanelDelegate();
1040 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
1041 if (qt_mac_is_macsheet(q))
1042 [delegate showWindowModalSheet:q->parentWidget()];
1043 else
1044 [delegate showModelessPanel];
1045 return true;
1046}
1047
1048bool QFileDialogPrivate::hideCocoaFilePanel()
1049{
1050 if (!mDelegate){
1051 // Nothing to do. We return false to leave the question
1052 // open regarding whether or not to go native:
1053 return false;
1054 } else {
1055 QMacCocoaAutoReleasePool pool;
1056 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
1057 [delegate closePanel];
1058 // Even when we hide it, we are still using a
1059 // native dialog, so return true:
1060 return true;
1061 }
1062}
1063
1064#endif
1065
1066void QFileDialogPrivate::mac_nativeDialogModalHelp()
1067{
1068 // Do a queued meta-call to open the native modal dialog so it opens after the new
1069 // event loop has started to execute (in QDialog::exec). Using a timer rather than
1070 // a queued meta call is intentional to ensure that the call is only delivered when
1071 // [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
1072 // running (which is the case if e.g a top-most QEventLoop has been
1073 // interrupted, and the second-most event loop has not yet been reactivated (regardless
1074 // if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
1075 if (nativeDialogInUse){
1076 Q_Q(QFileDialog);
1077 QTimer::singleShot(1, q, SLOT(_q_macRunNativeAppModalPanel()));
1078 }
1079}
1080
1081void QFileDialogPrivate::_q_macRunNativeAppModalPanel()
1082{
1083 QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
1084#ifndef QT_MAC_USE_COCOA
1085 NavDialogRun(mDialog);
1086#else
1087 Q_Q(QFileDialog);
1088 QMacCocoaAutoReleasePool pool;
1089 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
1090 [delegate runApplicationModalPanel];
1091 dialogResultCode_sys() == QDialog::Accepted ? q->accept() : q->reject();
1092#endif
1093}
1094
1095QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys()
1096{
1097#ifndef QT_MAC_USE_COCOA
1098 NavUserAction result = NavDialogGetUserAction(mDialog);
1099 if (result == kNavUserActionCancel || result == kNavUserActionNone)
1100 return QDialog::Rejected;
1101 else
1102 return QDialog::Accepted;
1103#else
1104 QNSOpenSavePanelDelegate *delegate = static_cast<QNSOpenSavePanelDelegate *>(mDelegate);
1105 return [delegate dialogResultCode];
1106#endif
1107}
1108
1109
1110QT_END_NAMESPACE
1111
1112#endif // QT_NO_FILEDIALOG
1113
Note: See TracBrowser for help on using the repository browser.