29 #include <QtGui/QCheckBox>
30 #include <QtGui/QKeyEvent>
31 #include <QtGui/QFileDialog>
32 #include <QtGui/QApplication>
33 #include <QtGui/QDesktopWidget>
48 #if defined(Q_WS_WIN) || defined(Q_WS_MAEMO_5)
51 const bool NATIVE_FILEDIALOGS_BY_DEFAULT =
false;
59 foreach(
const QString& mimeType, mimeTypes ) {
62 allExt += mime->patterns();
63 kdeFilter.append(mime->patterns().join(QLatin1String(
" ")) +
65 mime->comment(emptyUrl));
70 *allExtensions = allExt.join(QLatin1String(
" "));
82 foreach (
const QString& current, filters) {
85 int p = current.indexOf(
'|');
91 new_f = current.left(p);
92 new_name = current.mid(p+1);
95 new_name = new_name.replace(
'(',
'[').replace(
')',
']').trimmed();
99 const QStringList origList( new_f.split(
' ', QString::SkipEmptyParts) );
100 foreach (
const QString& origFilter, origList) {
101 if (!allfiltersUnique.contains(origFilter, Qt::CaseInsensitive))
102 allfiltersUnique += origFilter.toLower();
105 if (!converted.isEmpty())
108 converted += (new_name +
" (" + allfiltersUnique.join(
" ") + QLatin1Char(
')'));
112 converted.replace(
"\\/",
"/");
125 if (filter.isEmpty())
126 filters +=
i18n(
"*|All files");
129 int pos = filter.indexOf(
'/');
130 if (pos > 0 && filter[pos - 1] !=
'\\')
131 filters =
mime2KdeFilter(filter.split(QLatin1Char(
' '), QString::SkipEmptyParts));
133 filters = filter.split(
'\n', QString::SkipEmptyParts);
142 if(fileModuleService)
154 kDebug() <<
"Failed to load configured file module" << moduleName;
156 kDebug() <<
"Falling back to default file module.";
164 class KFileDialogPrivate
177 KUrl startDir()
const
179 if (!s_startDir.isEmpty())
181 if (!selectedUrls.isEmpty())
182 return selectedUrls.first();
187 static KUrl staticStartDir(
const KUrl& defaultDir )
189 if ( s_startDir.isEmpty() )
193 static KUrl s_startDir;
194 static bool s_allowNative;
208 if (cfgGroup.readEntry(
"Native", NATIVE_FILEDIALOGS_BY_DEFAULT) &&
209 KFileDialogPrivate::Native::s_allowNative)
213 static bool isNative()
215 if(!KFileDialogPrivate::Native::s_allowNative)
218 return cfgGroup.readEntry(
"Native", NATIVE_FILEDIALOGS_BY_DEFAULT);
235 KFileDialog::Options options,
QString *selectedFilter);
238 KFileDialog::Options options,
QString *selectedFilter);
240 ~KFileDialogPrivate()
250 KUrl KFileDialogPrivate::Native::s_startDir;
251 bool KFileDialogPrivate::Native::s_allowNative =
true;
256 :
KDialog( parent , Qt::WindowMinMaxButtonsHint),
260 d(
new KFileDialogPrivate )
270 KFileDialogPrivate::Native::s_startDir = startDir;
272 int pos = filter.indexOf(
'/');
273 if (pos > 0 && filter[pos - 1] !=
'\\')
274 setMimeFilter(filter.split(QLatin1Char(
' '), QString::SkipEmptyParts));
280 setButtons( KDialog::None );
281 restoreDialogSize(d->cfgGroup);
284 d->w->setFilter(filter);
285 setMainWidget(fileQWidget);
287 d->w->okButton()->show();
288 connect(d->w->okButton(), SIGNAL(clicked()), SLOT(slotOk()));
289 d->w->cancelButton()->show();
290 connect(d->w->cancelButton(), SIGNAL(clicked()), SLOT(slotCancel()));
299 connect(fileQWidget, SIGNAL(fileSelected(
KUrl)),
300 SIGNAL(fileSelected(
KUrl)));
301 connect(fileQWidget, SIGNAL(fileHighlighted(
KUrl)),
302 SIGNAL(fileHighlighted(
KUrl)));
303 connect(fileQWidget, SIGNAL(fileSelected(
QString)),
304 SIGNAL(fileSelected(
QString)));
305 connect(fileQWidget, SIGNAL(fileHighlighted(
QString)),
306 SIGNAL(fileHighlighted(
QString)));
307 connect(fileQWidget, SIGNAL(selectionChanged()),
308 SIGNAL(selectionChanged()));
309 connect(fileQWidget, SIGNAL(filterChanged(
QString)),
310 SIGNAL(filterChanged(
QString)));
312 connect(fileQWidget, SIGNAL(accepted()), SLOT(accept()));
316 d->w->setCustomWidget(
QString(), customWidget);
329 d->w->setLocationLabel(text);
335 d->native->filter = filter;
338 d->w->setFilter(filter);
345 return d->w->currentFilter();
351 d->w->setMimeFilter(mimeTypes, defaultType);
356 if (defaultType.isEmpty() && (mimeTypes.count() > 1)) {
357 filters.prepend(allExtensions + QLatin1Char(
'|') +
i18n(
"All Supported Files"));
359 d->native->filter = filters.join(QLatin1String(
"\n"));
366 d->native->filter.clear();
376 QString filter = d->native->selectedFilter.split(
";;").replaceInStrings(
"/",
"\\/")[0];
377 filter = filter.mid(filter.indexOf(
'(') + 1, filter.indexOf(
')') - filter.indexOf(
'(') - 1);
381 return d->w->currentMimeFilter();
393 d->w->setPreviewWidget(w);
401 d->w->setInlinePreviewShown(show);
407 int fontSize = fontMetrics().height();
408 QSize goodSize(48 * fontSize, 30 * fontSize);
409 QSize screenSize = QApplication::desktop()->availableGeometry(
this).size();
410 QSize minSize(screenSize / 2);
411 QSize maxSize(screenSize * qreal(0.9));
412 return (goodSize.expandedTo(minSize).boundedTo(maxSize));
428 setResult( QDialog::Accepted );
447 d->native->selectedUrls.clear();
448 d->native->selectedUrls.append(url);
451 d->w->setUrl(url, clearforward);
457 d->native->selectedUrls.clear();
458 d->native->selectedUrls.append(
KUrl(name) );
461 d->w->setSelection(name);
468 return KFileDialogPrivate::getOpenFileName(startDir, filter, parent, caption, 0);
471 QString KFileDialogPrivate::getOpenFileName(
const KUrl& startDir,
477 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.
isLocalFile())) {
478 return QFileDialog::getOpenFileName(
480 caption.isEmpty() ?
i18n(
"Open") : caption,
481 KFileDialogPrivate::Native::staticStartDir( startDir ).toLocalFile(),
490 dlg.setCaption(caption.isEmpty() ?
i18n(
"Open") : caption);
493 if(selectedFilter) *selectedFilter = dlg.currentMimeFilter();
494 return dlg.selectedFile();
499 WId parent_id,
const QString& caption)
501 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.
isLocalFile()))
504 KFileDialogPrivate::Native::s_allowNative =
false;
506 if( parent == NULL && parent_id != 0 )
511 dlg.setCaption(caption.isEmpty() ?
i18n(
"Open") : caption);
523 return KFileDialogPrivate::getOpenFileNames(startDir, filter, parent, caption, 0);
532 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.
isLocalFile())) {
533 return QFileDialog::getOpenFileNames(
535 caption.isEmpty() ?
i18n(
"Open") : caption,
536 KFileDialogPrivate::Native::staticStartDir( startDir ).toLocalFile(),
537 qtFilter( filter ), selectedFilter );
540 KFileDialogPrivate::Native::s_allowNative =
false;
545 dlg.setCaption(caption.isEmpty() ?
i18n(
"Open") : caption);
548 if(selectedFilter) *selectedFilter = dlg.currentMimeFilter();
549 return dlg.selectedFiles();
555 return KFileDialogPrivate::getOpenUrl(startDir, filter, parent, caption, 0);
557 KUrl KFileDialogPrivate::getOpenUrl(
const KUrl& startDir,
const QString& filter,
561 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.
isLocalFile())) {
562 const QString fileName( KFileDialogPrivate::getOpenFileName(
563 startDir, filter, parent, caption, selectedFilter) );
564 return fileName.isEmpty() ?
KUrl() :
KUrl::fromPath(fileName);
566 KFileDialogPrivate::Native::s_allowNative =
false;
571 dlg.setCaption(caption.isEmpty() ?
i18n(
"Open") : caption);
574 if(selectedFilter) *selectedFilter = dlg.currentMimeFilter();
575 return dlg.selectedUrl();
583 return KFileDialogPrivate::getOpenUrls(startDir, filter, parent, caption, 0);
592 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.
isLocalFile())) {
593 const QStringList fileNames( KFileDialogPrivate::getOpenFileNames(
594 startDir, filter, parent, caption, selectedFilter) );
597 KFileDialogPrivate::Native::s_allowNative =
false;
603 dlg.setCaption(caption.isEmpty() ?
i18n(
"Open") : caption);
606 if(selectedFilter) *selectedFilter = dlg.currentMimeFilter();
607 return dlg.selectedUrls();
613 d->w->setConfirmOverwrite(enable);
621 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.
isLocalFile())) {
622 QString result( QFileDialog::getExistingDirectory(parent, caption,
623 KFileDialogPrivate::Native::staticStartDir( startDir ).toLocalFile(),
624 QFileDialog::ShowDirsOnly) );
634 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.
isLocalFile())) {
635 return QFileDialog::getExistingDirectory(parent, caption,
636 KFileDialogPrivate::Native::staticStartDir( startDir ).toLocalFile(),
637 QFileDialog::ShowDirsOnly);
648 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.
isLocalFile())) {
653 KFileDialogPrivate::Native::s_allowNative =
false;
654 KFileDialog dlg(startDir, mimetypes.join(
" "), parent);
658 dlg.setCaption( caption.isEmpty() ?
i18n(
"Open") : caption );
659 dlg.setInlinePreviewShown(
true );
663 return dlg.selectedUrl();
669 return d->native->selectedUrls.isEmpty() ?
KUrl() : d->native->selectedUrls.first();
670 return d->w->selectedUrl();
676 return d->native->selectedUrls;
677 return d->w->selectedUrls();
684 return d->w->selectedFile();
691 return d->w->selectedFiles();
698 return d->w->baseUrl();
707 return KFileDialogPrivate::getSaveFileName(dir, filter, parent, caption, Options(0), 0);
712 const QString& caption, Options options)
714 return KFileDialogPrivate::getSaveFileName(dir, filter, parent, caption, options, 0);
719 KFileDialog::Options options,
QString *selectedFilter)
721 if (KFileDialogPrivate::isNative()) {
722 bool defaultDir = dir.isEmpty();
723 bool specialDir = !defaultDir && dir.
protocol() ==
"kfiledialog";
729 else if ( !specialDir && !defaultDir ) {
736 const QString result = QFileDialog::getSaveFileName(
738 caption.isEmpty() ?
i18n(
"Save As") : caption,
739 KFileDialogPrivate::Native::staticStartDir( startDir ).toLocalFile(),
742 selectedFilter, opts );
743 if (!result.isEmpty()) {
744 if (!recentDirClass.isEmpty())
757 dlg.setCaption(caption.isEmpty() ?
i18n(
"Save As") : caption);
761 QString filename = dlg.selectedFile();
762 if (!filename.isEmpty())
779 const QString& caption, Options options)
781 if (KFileDialogPrivate::isNative()) {
787 if( parent == NULL && parent_id != 0 )
794 dlg.setCaption(caption.isEmpty() ?
i18n(
"Save As") : caption);
799 if (!filename.isEmpty())
810 return KFileDialogPrivate::getSaveUrl(dir, filter, parent, caption, Options(0), 0);
816 return KFileDialogPrivate::getSaveUrl(dir, filter, parent, caption, options, 0);
818 KUrl KFileDialogPrivate::getSaveUrl(
const KUrl& dir,
const QString& filter,
820 KFileDialog::Options options,
QString *selectedFilter)
822 if (KFileDialogPrivate::isNative() && (!dir.isValid() || dir.
isLocalFile())) {
823 const QString fileName( KFileDialogPrivate::getSaveFileName(
824 dir, filter, parent, caption, options, selectedFilter) );
825 return fileName.isEmpty() ?
KUrl() :
KUrl::fromPath(fileName);
828 KFileDialogPrivate::Native::s_allowNative =
false;
834 dlg.setConfirmOverwrite(options & KFileDialog::ConfirmOverwrite);
835 dlg.setInlinePreviewShown(options & KFileDialog::ShowInlinePreview);
836 dlg.setCaption(caption.isEmpty() ?
i18n(
"Save As") : caption);
839 if(selectedFilter) *selectedFilter = dlg.currentMimeFilter();
840 KUrl url = dlg.selectedUrl();
858 return d->native->mode;
864 return d->w->okButton();
869 return d->w->cancelButton();
874 return d->w->locationEdit();
879 return d->w->filterWidget();
884 return d->w->actionCollection();
891 d->w->setKeepLocation(keep);
898 return d->w->keepsLocation();
906 d->w->setOperationMode(static_cast<KAbstractFileWidget::OperationMode>(mode));
921 if ( e->key() == Qt::Key_Escape )
924 d->w->cancelButton()->animateClick();
927 KDialog::keyPressEvent( e );
935 saveDialogSize(d->cfgGroup, KConfigBase::Persistent);
937 KDialog::hideEvent( e );
949 if (KFileDialogPrivate::isNative())
950 KFileDialogPrivate::Native::s_startDir = directory;
956 return d->w->toolBar();
967 if (!d->native || !KFileDialogPrivate::Native::s_allowNative) {
968 KFileDialogPrivate::Native::s_allowNative =
true;
969 return KDialog::exec();
974 int res = QDialog::Rejected;
975 switch (d->native->operationMode) {
979 KUrl url( KFileDialogPrivate::getOpenUrl(
980 d->native->startDir(), d->native->filter, parentWidget(), windowTitle(), &d->native->selectedFilter ) );
981 if (url.isEmpty() || !url.isValid()) {
982 res = QDialog::Rejected;
985 d->native->selectedUrls.clear();
986 d->native->selectedUrls.append(url);
987 res = QDialog::Accepted;
991 KUrl::List urls( KFileDialogPrivate::getOpenUrls(
992 d->native->startDir(), d->native->filter, parentWidget(), windowTitle(), &d->native->selectedFilter ) );
993 if (urls.isEmpty()) {
994 res = QDialog::Rejected;
997 d->native->selectedUrls = urls;
998 res = QDialog::Accepted;
1003 d->native->startDir(), parentWidget(), windowTitle()) );
1004 if (url.isEmpty() || !url.isValid()) {
1005 res = QDialog::Rejected;
1008 d->native->selectedUrls.clear();
1009 d->native->selectedUrls.append(url);
1010 res = QDialog::Accepted;
1016 KUrl url( KFileDialogPrivate::getSaveUrl(
1017 d->native->startDir(), d->native->filter, parentWidget(), windowTitle(), Options(0), &d->native->selectedFilter ) );
1018 if (url.isEmpty() || !url.isValid()) {
1019 res = QDialog::Rejected;
1022 d->native->selectedUrls.clear();
1023 d->native->selectedUrls.append(url);
1024 res = QDialog::Accepted;
1029 d->native->startDir(), parentWidget(), windowTitle()) );
1030 if (url.isEmpty() || !url.isValid()) {
1031 res = QDialog::Rejected;
1034 d->native->selectedUrls.clear();
1035 d->native->selectedUrls.append(url);
1036 res = QDialog::Accepted;
1046 if (res == QDialog::Accepted) {
1057 #define KF_EXTERN extern __declspec(dllimport)
1059 #define KF_EXTERN extern
1064 QFileDialog::Options options);
1070 QFileDialog::Options options);
1076 QFileDialog::Options options);
1082 QFileDialog::Options options);
1090 class KFileDialogQtOverride
1093 KFileDialogQtOverride()
1095 if(!qt_filedialog_existing_directory_hook)
1096 qt_filedialog_existing_directory_hook=&getExistingDirectory;
1097 if(!qt_filedialog_open_filename_hook)
1098 qt_filedialog_open_filename_hook=&getOpenFileName;
1099 if(!qt_filedialog_open_filenames_hook)
1100 qt_filedialog_open_filenames_hook=&getOpenFileNames;
1101 if(!qt_filedialog_save_filename_hook)
1102 qt_filedialog_save_filename_hook=&getSaveFileName;
1105 ~KFileDialogQtOverride() {
1106 if(qt_filedialog_existing_directory_hook == &getExistingDirectory)
1107 qt_filedialog_existing_directory_hook = 0;
1108 if(qt_filedialog_open_filename_hook == &getOpenFileName)
1109 qt_filedialog_open_filename_hook = 0;
1110 if(qt_filedialog_open_filenames_hook == &getOpenFileNames)
1111 qt_filedialog_open_filenames_hook=0;
1112 if(qt_filedialog_save_filename_hook == &getSaveFileName)
1113 qt_filedialog_save_filename_hook=0;
1122 QTextStream str(&filter, QIODevice::WriteOnly);
1124 QStringList::const_iterator it(
list.begin()),
1128 for(; it!=
end; ++it)
1130 int ob=(*it).lastIndexOf(
'('),
1131 cb=(*it).lastIndexOf(
')');
1139 str << (*it).mid(ob+1, (cb-ob)-1) <<
'|' << (*it).mid(0, ob);
1154 QStringList::const_iterator it(
list.begin()),
1158 for(; it!=
end; ++it)
1159 if(-1!=(pos=(*it).indexOf(kde)) && pos>0 &&
1160 (
'('==(*it)[pos-1] ||
' '==(*it)[pos-1]) &&
1161 (*it).length()>=kde.length()+pos &&
1162 (
')'==(*it)[pos+kde.length()] ||
' '==(*it)[pos+kde.length()]))
1171 QFileDialog::Options options)
1173 if (KFileDialogPrivate::isNative()) {
1174 if(qt_filedialog_existing_directory_hook)
1175 qt_filedialog_existing_directory_hook=0;
1176 return QFileDialog::getExistingDirectory(parent, caption, dir, options);
1190 QFileDialog::Options options)
1192 if (KFileDialogPrivate::isNative()) {
1193 if(qt_filedialog_open_filename_hook)
1194 qt_filedialog_open_filename_hook=0;
1195 return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
1203 dlg.setCaption(caption);
1216 QFileDialog::Options options)
1218 if (KFileDialogPrivate::isNative()) {
1219 if(qt_filedialog_open_filenames_hook)
1220 qt_filedialog_open_filenames_hook=0;
1221 return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
1229 dlg.setCaption(caption);
1242 QFileDialog::Options options)
1244 if (KFileDialogPrivate::isNative()) {
1245 if(qt_filedialog_save_filename_hook)
1246 qt_filedialog_save_filename_hook=0;
1247 return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options);
1255 dlg.setCaption(caption);
1271 #include "kfiledialog.moc"