00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "kfiledialog.h"
00027
00028 #include <QtGui/QCheckBox>
00029 #include <QtGui/QKeyEvent>
00030 #include <QtGui/QFileDialog>
00031
00032 #include <kimageio.h>
00033 #include <klocale.h>
00034 #include <kpushbutton.h>
00035 #include <config-kfile.h>
00036 #include <krecentdocument.h>
00037 #include <kimagefilepreview.h>
00038 #include <kpluginloader.h>
00039 #include <kpluginfactory.h>
00040 #include <kdebug.h>
00041 #include <kwindowsystem.h>
00042 #include "kabstractfilewidget.h"
00043 #include "kabstractfilemodule.h"
00044 #include "krecentdirs.h"
00045
00047 #ifdef Q_WS_WIN
00048 const bool NATIVE_FILEDIALOGS_BY_DEFAULT = true;
00049 #else
00050 const bool NATIVE_FILEDIALOGS_BY_DEFAULT = false;
00051 #endif
00052
00053 static QStringList mime2KdeFilter( const QStringList &mimeTypes, QString *allExtensions = 0 )
00054 {
00055 const KUrl emptyUrl;
00056 QStringList kdeFilter;
00057 QStringList allExt;
00058 foreach( const QString& mimeType, mimeTypes ) {
00059 KMimeType::Ptr mime( KMimeType::mimeType(mimeType) );
00060 if (mime) {
00061 allExt += mime->patterns();
00062 kdeFilter.append(mime->patterns().join(QLatin1String(" ")) +
00063 QLatin1Char('|') +
00064 mime->comment(emptyUrl));
00065 }
00066 }
00067 if (allExtensions) {
00068 allExt.sort();
00069 *allExtensions = allExt.join(QLatin1String(" "));
00070 }
00071 return kdeFilter;
00072 }
00076 static QString qtFilter(const QStringList& _filters)
00077 {
00078 QString converted;
00079 QStringList filters = _filters;
00080
00081 foreach (const QString& current, filters) {
00082 QString new_f;
00083 QString new_name;
00084 int p = current.indexOf('|');
00085 if (p==-1) {
00086 new_f = current;
00087 new_name = current;
00088 }
00089 else {
00090 new_f = current.left(p);
00091 new_name = current.mid(p+1);
00092 }
00093
00094 new_name = new_name.replace('(', '[').replace(')',']').trimmed();
00095
00096
00097 QStringList allfiltersUnique;
00098 const QStringList origList( new_f.split(' ', QString::SkipEmptyParts) );
00099 foreach (const QString& origFilter, origList) {
00100 if (!allfiltersUnique.contains(origFilter, Qt::CaseInsensitive))
00101 allfiltersUnique += origFilter.toLower();
00102 }
00103
00104 if (!converted.isEmpty())
00105 converted += ";;";
00106
00107 converted += (new_name + " (" + allfiltersUnique.join(" ") + QLatin1Char(')'));
00108 }
00109
00110
00111 converted.replace("\\/","/");
00112
00113 return converted;
00114 }
00115
00119 static QString qtFilter(const QString& filter)
00120 {
00121
00122
00123 QStringList filters;
00124 if (filter.isEmpty())
00125 filters += i18n("*|All files");
00126 else {
00127
00128 int pos = filter.indexOf('/');
00129 if (pos > 0 && filter[pos - 1] != '\\')
00130 filters = mime2KdeFilter(filter.split(QLatin1Char(' '), QString::SkipEmptyParts));
00131 else
00132 filters = filter.split('\n', QString::SkipEmptyParts);
00133 }
00134 return qtFilter(filters);
00135 }
00136
00137 static KAbstractFileModule* s_module = 0;
00138 static KAbstractFileModule* fileModule()
00139 {
00140 if (!s_module) {
00141
00142 KPluginLoader loader("libkfilemodule");
00143 KPluginFactory *factory = loader.factory();
00144 if (!factory) {
00145 kWarning() << "KFileDialog wasn't able to find libkfilemodule: " << loader.errorString();
00146 } else {
00147 s_module = factory->create<KAbstractFileModule>();
00148 if (!s_module) {
00149 kWarning() << "An error occurred while loading libkfilemodule";
00150 }
00151 }
00152 }
00153 return s_module;
00154 }
00155
00156 class KFileDialogPrivate
00157 {
00158 public:
00160 class Native {
00161 public:
00162 Native()
00163 : mode(KFile::File),
00164 operationMode(KAbstractFileWidget::Opening)
00165 {
00166 }
00169 KUrl startDir() const
00170 {
00171 if (!s_startDir.isEmpty())
00172 return s_startDir;
00173 if (!selectedUrls.isEmpty())
00174 return selectedUrls.first();
00175 return KUrl();
00176 }
00179 static KUrl staticStartDir( const KUrl& defaultDir )
00180 {
00181 if ( s_startDir.isEmpty() )
00182 return defaultDir;
00183 return s_startDir;
00184 }
00185 static KUrl s_startDir;
00186 static bool s_allowNative;
00187 QString filter;
00188 QStringList mimeTypes;
00189 KUrl::List selectedUrls;
00190 KFile::Modes mode;
00191 KAbstractFileWidget::OperationMode operationMode;
00192 };
00193
00194 KFileDialogPrivate()
00195 : native(0),
00196 w(0),
00197 cfgGroup(KGlobal::config(), ConfigGroup)
00198 {
00199 if (cfgGroup.readEntry("Native", NATIVE_FILEDIALOGS_BY_DEFAULT) &&
00200 KFileDialogPrivate::Native::s_allowNative)
00201 native = new Native;
00202 }
00203
00204 static bool isNative()
00205 {
00206 if(!KFileDialogPrivate::Native::s_allowNative)
00207 return false;
00208 KConfigGroup cfgGroup(KGlobal::config(), ConfigGroup);
00209 return cfgGroup.readEntry("Native", NATIVE_FILEDIALOGS_BY_DEFAULT);
00210 }
00211
00212 ~KFileDialogPrivate()
00213 {
00214 delete native;
00215 }
00216
00217 Native* native;
00218 KAbstractFileWidget* w;
00219 KConfigGroup cfgGroup;
00220 };
00221
00222 KUrl KFileDialogPrivate::Native::s_startDir;
00223 bool KFileDialogPrivate::Native::s_allowNative = true;
00224
00225 KFileDialog::KFileDialog( const KUrl& startDir, const QString& filter,
00226 QWidget *parent, QWidget* customWidget)
00227 #ifdef Q_WS_WIN
00228 : KDialog( parent , Qt::WindowMinMaxButtonsHint),
00229 #else
00230 : KDialog( parent ),
00231 #endif
00232 d( new KFileDialogPrivate )
00233
00234 {
00235
00236
00237
00238 QWidget* fileQWidget = fileModule()->createFileWidget(startDir, this);
00239 d->w = ::qobject_cast<KAbstractFileWidget *>(fileQWidget);
00240
00241 if (d->native) {
00242 KFileDialogPrivate::Native::s_startDir = startDir;
00243
00244 int pos = filter.indexOf('/');
00245 if (pos > 0 && filter[pos - 1] != '\\')
00246 setMimeFilter(filter.split(QLatin1Char(' '), QString::SkipEmptyParts));
00247 else
00248 setFilter(filter);
00249 return;
00250 }
00251
00252 setButtons( KDialog::None );
00253 restoreDialogSize(d->cfgGroup);
00254
00255
00256 d->w->setFilter(filter);
00257 setMainWidget(fileQWidget);
00258
00259 d->w->okButton()->show();
00260 connect(d->w->okButton(), SIGNAL(clicked()), SLOT(slotOk()));
00261 d->w->cancelButton()->show();
00262 connect(d->w->cancelButton(), SIGNAL( clicked() ), SLOT( slotCancel() ));
00263
00264
00265
00266
00267
00268
00269 kDebug (kfile_area) << "KFileDialog connecting signals";
00270 connect(fileQWidget, SIGNAL(fileSelected(const QString&)),
00271 SIGNAL(fileSelected(const QString&)));
00272 connect(fileQWidget, SIGNAL(fileHighlighted(const QString&)),
00273 SIGNAL(fileHighlighted(const QString&)));
00274 connect(fileQWidget, SIGNAL(selectionChanged()),
00275 SIGNAL(selectionChanged()));
00276 connect(fileQWidget, SIGNAL(filterChanged(const QString&)),
00277 SIGNAL(filterChanged(const QString&)));
00278
00279 connect(fileQWidget, SIGNAL(accepted()), SLOT(accept()));
00280
00281
00282 if (customWidget)
00283 d->w->setCustomWidget(QString(), customWidget);
00284 }
00285
00286
00287 KFileDialog::~KFileDialog()
00288 {
00289 delete d;
00290 }
00291
00292 void KFileDialog::setLocationLabel(const QString& text)
00293 {
00294 if (d->native)
00295 return;
00296 d->w->setLocationLabel(text);
00297 }
00298
00299 void KFileDialog::setFilter(const QString& filter)
00300 {
00301 if (d->native) {
00302 d->native->filter = filter;
00303 return;
00304 }
00305 d->w->setFilter(filter);
00306 }
00307
00308 QString KFileDialog::currentFilter() const
00309 {
00310 if (d->native)
00311 return QString();
00312 return d->w->currentFilter();
00313 }
00314
00315 void KFileDialog::setMimeFilter( const QStringList& mimeTypes,
00316 const QString& defaultType )
00317 {
00318 d->w->setMimeFilter(mimeTypes, defaultType);
00319
00320 if (d->native) {
00321 QString allExtensions;
00322 QStringList filters = mime2KdeFilter(mimeTypes, &allExtensions);
00323 if (defaultType.isEmpty() && (mimeTypes.count() > 1)) {
00324 filters.prepend(allExtensions + QLatin1Char('|') + i18n("All Supported Files"));
00325 }
00326 d->native->filter = filters.join(QLatin1String("\n"));
00327 }
00328 }
00329
00330 void KFileDialog::clearFilter()
00331 {
00332 if (d->native) {
00333 d->native->filter.clear();
00334 return;
00335 }
00336 d->w->clearFilter();
00337 }
00338
00339 QString KFileDialog::currentMimeFilter() const
00340 {
00341 return d->w->currentMimeFilter();
00342 }
00343
00344 KMimeType::Ptr KFileDialog::currentFilterMimeType()
00345 {
00346 return KMimeType::mimeType( currentMimeFilter() );
00347 }
00348
00349 void KFileDialog::setPreviewWidget(KPreviewWidgetBase *w)
00350 {
00351 if (d->native)
00352 return;
00353 d->w->setPreviewWidget(w);
00354 }
00355
00356 void KFileDialog::setInlinePreviewShown(bool show)
00357 {
00358 if (d->native) {
00359 return;
00360 }
00361 d->w->setInlinePreviewShown(show);
00362 }
00363
00364 QSize KFileDialog::sizeHint() const
00365 {
00366 return QSize(700, 450);
00367 }
00368
00369
00370 void KFileDialog::slotOk()
00371 {
00372 if (d->native)
00373 return;
00374 d->w->slotOk();
00375 }
00376
00377
00378 void KFileDialog::accept()
00379 {
00380 if (d->native)
00381 return;
00382 setResult( QDialog::Accepted );
00383 d->w->accept();
00384 KConfigGroup cfgGroup(KGlobal::config(), ConfigGroup);
00385 KDialog::accept();
00386 emit okClicked();
00387 }
00388
00389
00390 void KFileDialog::slotCancel()
00391 {
00392 if (d->native)
00393 return;
00394 d->w->slotCancel();
00395 reject();
00396 }
00397
00398 void KFileDialog::setUrl(const KUrl& url, bool clearforward)
00399 {
00400 if (d->native) {
00401 d->native->selectedUrls.clear();
00402 d->native->selectedUrls.append(url);
00403 return;
00404 }
00405 d->w->setUrl(url, clearforward);
00406 }
00407
00408 void KFileDialog::setSelection(const QString& name)
00409 {
00410 if (d->native) {
00411 d->native->selectedUrls.clear();
00412 d->native->selectedUrls.append( KUrl(name) );
00413 return;
00414 }
00415 d->w->setSelection(name);
00416 }
00417
00418 QString KFileDialog::getOpenFileName(const KUrl& startDir,
00419 const QString& filter,
00420 QWidget *parent, const QString& caption)
00421 {
00422 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00423 return QFileDialog::getOpenFileName(
00424 parent,
00425 caption.isEmpty() ? i18n("Open") : caption,
00426 KFileDialogPrivate::Native::staticStartDir( startDir ).toLocalFile(),
00427 qtFilter(filter) );
00428
00429 }
00430 KFileDialog dlg(startDir, filter, parent);
00431 dlg.setOperationMode( Opening );
00432
00433 dlg.setMode( KFile::File | KFile::LocalOnly | KFile::ExistingOnly );
00434 dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00435
00436
00437 dlg.exec();
00438
00439 return dlg.selectedFile();
00440 }
00441
00442 QString KFileDialog::getOpenFileNameWId(const KUrl& startDir,
00443 const QString& filter,
00444 WId parent_id, const QString& caption)
00445 {
00446 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile()))
00447 return KFileDialog::getOpenFileName(startDir, filter, 0, caption);
00448 QWidget* parent = QWidget::find( parent_id );
00449 KFileDialogPrivate::Native::s_allowNative = false;
00450 KFileDialog dlg(startDir, filter, parent);
00451 if( parent == NULL && parent_id != 0 )
00452 KWindowSystem::setMainWindow( &dlg, parent_id );
00453
00454 dlg.setOperationMode( KFileDialog::Opening );
00455
00456 dlg.setMode( KFile::File | KFile::LocalOnly | KFile::ExistingOnly );
00457 dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00458
00459
00460 dlg.exec();
00461
00462 return dlg.selectedFile();
00463 }
00464
00465 QStringList KFileDialog::getOpenFileNames(const KUrl& startDir,
00466 const QString& filter,
00467 QWidget *parent,
00468 const QString& caption)
00469 {
00470 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00471 return QFileDialog::getOpenFileNames(
00472 parent,
00473 caption.isEmpty() ? i18n("Open") : caption,
00474 KFileDialogPrivate::Native::staticStartDir( startDir ).toLocalFile(),
00475 qtFilter( filter ) );
00476
00477 }
00478 KFileDialogPrivate::Native::s_allowNative = false;
00479 KFileDialog dlg(startDir, filter, parent);
00480 dlg.setOperationMode( Opening );
00481
00482 dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00483 dlg.setMode(KFile::Files | KFile::LocalOnly | KFile::ExistingOnly);
00484
00485 dlg.exec();
00486
00487 return dlg.selectedFiles();
00488 }
00489
00490 KUrl KFileDialog::getOpenUrl(const KUrl& startDir, const QString& filter,
00491 QWidget *parent, const QString& caption)
00492 {
00493 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00494 const QString fileName( KFileDialog::getOpenFileName(
00495 startDir, filter, parent, caption) );
00496 return fileName.isEmpty() ? KUrl() : KUrl::fromPath(fileName);
00497 }
00498 KFileDialogPrivate::Native::s_allowNative = false;
00499 KFileDialog dlg(startDir, filter, parent);
00500 dlg.setOperationMode( Opening );
00501
00502 dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00503 dlg.setMode( KFile::File | KFile::ExistingOnly );
00504
00505 dlg.exec();
00506
00507 return dlg.selectedUrl();
00508 }
00509
00510 KUrl::List KFileDialog::getOpenUrls(const KUrl& startDir,
00511 const QString& filter,
00512 QWidget *parent,
00513 const QString& caption)
00514 {
00515 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00516 const QStringList fileNames( KFileDialog::getOpenFileNames(
00517 startDir, filter, parent, caption) );
00518 return KUrl::List(fileNames);
00519 }
00520 KFileDialogPrivate::Native::s_allowNative = false;
00521 KFileDialog dlg(startDir, filter, parent);
00522 dlg.setOperationMode( Opening );
00523
00524 dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00525 dlg.setMode(KFile::Files | KFile::ExistingOnly);
00526
00527 dlg.exec();
00528
00529 return dlg.selectedUrls();
00530 }
00531
00532 void KFileDialog::setConfirmOverwrite(bool enable)
00533 {
00534 if (operationMode() == KFileDialog::Saving) {
00535 d->w->setConfirmOverwrite(enable);
00536 }
00537 }
00538
00539 KUrl KFileDialog::getExistingDirectoryUrl(const KUrl& startDir,
00540 QWidget *parent,
00541 const QString& caption)
00542 {
00543 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00544 QString result( QFileDialog::getExistingDirectory(parent, caption,
00545 KFileDialogPrivate::Native::staticStartDir( startDir ).toLocalFile(),
00546 QFileDialog::ShowDirsOnly) );
00547 return result.isEmpty() ? KUrl() : KUrl::fromPath(result);
00548 }
00549 return fileModule()->selectDirectory(startDir, false, parent, caption);
00550 }
00551
00552 QString KFileDialog::getExistingDirectory(const KUrl& startDir,
00553 QWidget *parent,
00554 const QString& caption)
00555 {
00556 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00557 return QFileDialog::getExistingDirectory(parent, caption,
00558 KFileDialogPrivate::Native::staticStartDir( startDir ).toLocalFile(),
00559 QFileDialog::ShowDirsOnly);
00560 }
00561 KUrl url = fileModule()->selectDirectory(startDir, true, parent, caption);
00562 if ( url.isValid() )
00563 return url.path();
00564 return QString();
00565 }
00566
00567 KUrl KFileDialog::getImageOpenUrl( const KUrl& startDir, QWidget *parent,
00568 const QString& caption)
00569 {
00570 if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00571 const QStringList mimetypes( KImageIO::mimeTypes( KImageIO::Reading ) );
00572 return KFileDialog::getOpenUrl(startDir, mimetypes.join(" "), parent, caption);
00573 }
00574 QStringList mimetypes = KImageIO::mimeTypes( KImageIO::Reading );
00575 KFileDialogPrivate::Native::s_allowNative = false;
00576 KFileDialog dlg(startDir,
00577 mimetypes.join(" "),
00578 parent);
00579 dlg.setOperationMode( Opening );
00580 dlg.setCaption( caption.isEmpty() ? i18n("Open") : caption );
00581 dlg.setMode( KFile::File );
00582 dlg.setInlinePreviewShown( true );
00583
00584 dlg.exec();
00585
00586 return dlg.selectedUrl();
00587 }
00588
00589 KUrl KFileDialog::selectedUrl() const
00590 {
00591 if (d->native)
00592 return d->native->selectedUrls.isEmpty() ? KUrl() : d->native->selectedUrls.first();
00593 return d->w->selectedUrl();
00594 }
00595
00596 KUrl::List KFileDialog::selectedUrls() const
00597 {
00598 if (d->native)
00599 return d->native->selectedUrls;
00600 return d->w->selectedUrls();
00601 }
00602
00603 QString KFileDialog::selectedFile() const
00604 {
00605 if (d->native)
00606 return selectedUrl().toLocalFile();
00607 return d->w->selectedFile();
00608 }
00609
00610 QStringList KFileDialog::selectedFiles() const
00611 {
00612 if (d->native)
00613 return selectedUrls().toStringList();
00614 return d->w->selectedFiles();
00615 }
00616
00617 KUrl KFileDialog::baseUrl() const
00618 {
00619 if (d->native)
00620 return selectedUrl().isEmpty() ? KUrl() : KUrl::fromPath(selectedUrl().path());
00621 return d->w->baseUrl();
00622 }
00623
00624 QString KFileDialog::getSaveFileName(const KUrl& dir, const QString& filter,
00625 QWidget *parent,
00626 const QString& caption)
00627 {
00628 if (KFileDialogPrivate::isNative()) {
00629 bool defaultDir = dir.isEmpty();
00630 bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00631 KUrl startDir;
00632 QString recentDirClass;
00633 if (specialDir) {
00634 startDir = KFileDialog::getStartUrl(dir, recentDirClass);
00635 }
00636 else if ( !specialDir && !defaultDir ) {
00637 if (!dir.isLocalFile())
00638 kWarning() << "non-local start dir " << dir;
00639 startDir = dir;
00640 }
00641
00642 const QString result = QFileDialog::getSaveFileName(
00643 parent,
00644 caption.isEmpty() ? i18n("Save As") : caption,
00645 KFileDialogPrivate::Native::staticStartDir( startDir ).toLocalFile(),
00646 qtFilter(filter) );
00647
00648 if (!result.isEmpty()) {
00649 if (!recentDirClass.isEmpty())
00650 KRecentDirs::add(recentDirClass, KUrl::fromPath(result).url());
00651 KRecentDocument::add(result);
00652 }
00653 return result;
00654 }
00655 bool defaultDir = dir.isEmpty();
00656 bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00657 KFileDialog dlg( specialDir ? dir : KUrl(), filter, parent);
00658 if ( !specialDir && !defaultDir ) {
00659 if (!dir.isLocalFile())
00660 kWarning() << "KFileDialog::getSaveFileName called with non-local start dir " << dir;
00661 dlg.setSelection( dir.toLocalFile() );
00662 }
00663
00664 dlg.setOperationMode( Saving );
00665 dlg.setMode( KFile::File );
00666 dlg.setCaption(caption.isEmpty() ? i18n("Save As") : caption);
00667
00668 dlg.exec();
00669
00670 QString filename = dlg.selectedFile();
00671 if (!filename.isEmpty())
00672 KRecentDocument::add(filename);
00673
00674 return filename;
00675 }
00676
00677 QString KFileDialog::getSaveFileNameWId(const KUrl& dir, const QString& filter,
00678 WId parent_id,
00679 const QString& caption)
00680 {
00681 if (KFileDialogPrivate::isNative()) {
00682 return KFileDialog::getSaveFileName(dir, filter, 0, caption);
00683 }
00684 bool defaultDir = dir.isEmpty();
00685 bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00686 QWidget* parent = QWidget::find( parent_id );
00687 KFileDialog dlg( specialDir ? dir : KUrl(), filter, parent);
00688 if( parent == NULL && parent_id != 0 )
00689 KWindowSystem::setMainWindow( &dlg, parent_id);
00690
00691 if ( !specialDir && !defaultDir ) {
00692 if (!dir.isLocalFile())
00693 kWarning() << "KFileDialog::getSaveFileNameWId called with non-local start dir " << dir;
00694 dlg.setSelection( dir.toLocalFile() );
00695 }
00696
00697 dlg.setOperationMode( Saving );
00698 dlg.setMode( KFile::File );
00699 dlg.setCaption(caption.isEmpty() ? i18n("Save As") : caption);
00700
00701 dlg.exec();
00702
00703 QString filename = dlg.selectedFile();
00704 if (!filename.isEmpty())
00705 KRecentDocument::add(filename);
00706
00707 return filename;
00708 }
00709
00710 KUrl KFileDialog::getSaveUrl(const KUrl& dir, const QString& filter,
00711 QWidget *parent, const QString& caption)
00712 {
00713 if (KFileDialogPrivate::isNative() && (!dir.isValid() || dir.isLocalFile())) {
00714 const QString fileName( KFileDialog::getSaveFileName(
00715 dir, filter, parent, caption) );
00716 return fileName.isEmpty() ? KUrl() : KUrl::fromPath(fileName);
00717 }
00718 bool defaultDir = dir.isEmpty();
00719 bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00720 KFileDialogPrivate::Native::s_allowNative = false;
00721 KFileDialog dlg(specialDir ? dir : KUrl(), filter, parent);
00722 if ( !specialDir && !defaultDir )
00723 dlg.setSelection( dir.url() );
00724
00725 dlg.setCaption(caption.isEmpty() ? i18n("Save As") : caption);
00726 dlg.setOperationMode( Saving );
00727 dlg.setMode( KFile::File );
00728
00729 dlg.exec();
00730
00731 KUrl url = dlg.selectedUrl();
00732 if (url.isValid())
00733 KRecentDocument::add( url );
00734
00735 return url;
00736 }
00737
00738 void KFileDialog::setMode( KFile::Modes m )
00739 {
00740 if (d->native)
00741 d->native->mode = m;
00742 else
00743 d->w->setMode(m);
00744 }
00745
00746 KFile::Modes KFileDialog::mode() const
00747 {
00748 if (d->native)
00749 return d->native->mode;
00750 return d->w->mode();
00751 }
00752
00753 KPushButton * KFileDialog::okButton() const
00754 {
00755 return d->w->okButton();
00756 }
00757
00758 KPushButton * KFileDialog::cancelButton() const
00759 {
00760 return d->w->cancelButton();
00761 }
00762
00763 KUrlComboBox* KFileDialog::locationEdit() const
00764 {
00765 return d->w->locationEdit();
00766 }
00767
00768 KFileFilterCombo* KFileDialog::filterWidget() const
00769 {
00770 return d->w->filterWidget();
00771 }
00772
00773 KActionCollection * KFileDialog::actionCollection() const
00774 {
00775 return d->w->actionCollection();
00776 }
00777
00778 void KFileDialog::setKeepLocation( bool keep )
00779 {
00780 if (d->native)
00781 return;
00782 d->w->setKeepLocation(keep);
00783 }
00784
00785 bool KFileDialog::keepsLocation() const
00786 {
00787 if (d->native)
00788 return false;
00789 return d->w->keepsLocation();
00790 }
00791
00792 void KFileDialog::setOperationMode( OperationMode mode )
00793 {
00794 if (d->native)
00795 d->native->operationMode = static_cast<KAbstractFileWidget::OperationMode>(mode);
00796 else
00797 d->w->setOperationMode(static_cast<KAbstractFileWidget::OperationMode>(mode));
00798 }
00799
00800 KFileDialog::OperationMode KFileDialog::operationMode() const
00801 {
00802 if (d->native)
00803 return static_cast<KFileDialog::OperationMode>(d->native->operationMode);
00804 return static_cast<KFileDialog::OperationMode>(d->w->operationMode());
00805 }
00806
00807 void KFileDialog::keyPressEvent( QKeyEvent *e )
00808 {
00809 if (d->native)
00810 return;
00811
00812 if ( e->key() == Qt::Key_Escape )
00813 {
00814 e->accept();
00815 d->w->cancelButton()->animateClick();
00816 }
00817 else
00818 KDialog::keyPressEvent( e );
00819 }
00820
00821 void KFileDialog::hideEvent( QHideEvent *e )
00822 {
00823 if (d->native)
00824 return;
00825
00826 saveDialogSize(d->cfgGroup, KConfigBase::Persistent);
00827
00828 KDialog::hideEvent( e );
00829 }
00830
00831
00832 KUrl KFileDialog::getStartUrl( const KUrl& startDir,
00833 QString& recentDirClass )
00834 {
00835 return fileModule()->getStartUrl(startDir, recentDirClass);
00836 }
00837
00838 void KFileDialog::setStartDir( const KUrl& directory )
00839 {
00840 if (KFileDialogPrivate::isNative())
00841 KFileDialogPrivate::Native::s_startDir = directory;
00842 fileModule()->setStartDir(directory);
00843 }
00844
00845 KToolBar * KFileDialog::toolBar() const
00846 {
00847 return d->w->toolBar();
00848 }
00849
00850 KAbstractFileWidget* KFileDialog::fileWidget()
00851 {
00852 return d->w;
00853 }
00854
00855 #ifdef Q_WS_WIN
00856 int KFileDialog::exec()
00857 {
00858 if (!d->native || !KFileDialogPrivate::Native::s_allowNative) {
00859 KFileDialogPrivate::Native::s_allowNative = true;
00860 return KDialog::exec();
00861 }
00862
00863
00864
00865 switch (d->native->operationMode) {
00866 case KAbstractFileWidget::Opening:
00867 case KAbstractFileWidget::Other:
00868 if (d->native->mode & KFile::File) {
00869 KUrl url( KFileDialog::getOpenUrl(
00870 d->native->startDir(), d->native->filter, parentWidget(), windowTitle()) );
00871 if (url.isEmpty() || !url.isValid())
00872 return QDialog::Rejected;
00873 d->native->selectedUrls.clear();
00874 d->native->selectedUrls.append(url);
00875 return QDialog::Accepted;
00876 }
00877 else if (d->native->mode & KFile::Files) {
00878 KUrl::List urls( KFileDialog::getOpenUrls(
00879 d->native->startDir(), d->native->filter, parentWidget(), windowTitle()) );
00880 if (urls.isEmpty())
00881 return QDialog::Rejected;
00882 d->native->selectedUrls = urls;
00883 return QDialog::Accepted;
00884 }
00885 else if (d->native->mode & KFile::Directory) {
00886 KUrl url( KFileDialog::getExistingDirectoryUrl(
00887 d->native->startDir(), parentWidget(), windowTitle()) );
00888 if (url.isEmpty() || !url.isValid())
00889 return QDialog::Rejected;
00890 d->native->selectedUrls.clear();
00891 d->native->selectedUrls.append(url);
00892 return QDialog::Accepted;
00893 }
00894 break;
00895 case KAbstractFileWidget::Saving:
00896 if (d->native->mode & KFile::File) {
00897 KUrl url( KFileDialog::getSaveUrl(
00898 d->native->startDir(), d->native->filter, parentWidget(), windowTitle()) );
00899 if (url.isEmpty() || !url.isValid())
00900 return QDialog::Rejected;
00901 d->native->selectedUrls.clear();
00902 d->native->selectedUrls.append(url);
00903 return QDialog::Accepted;
00904 }
00905 else if (d->native->mode & KFile::Directory) {
00906 KUrl url( KFileDialog::getExistingDirectoryUrl(
00907 d->native->startDir(), parentWidget(), windowTitle()) );
00908 if (url.isEmpty() || !url.isValid())
00909 return QDialog::Rejected;
00910 d->native->selectedUrls.clear();
00911 d->native->selectedUrls.append(url);
00912 return QDialog::Accepted;
00913 }
00914 break;
00915 default:;
00916 }
00917 return QDialog::Rejected;
00918 }
00919 #endif // Q_WS_WIN
00920
00921 #ifdef Q_WS_WIN
00922 #define KF_EXTERN extern __declspec(dllimport)
00923 #else
00924 #define KF_EXTERN extern
00925 #endif
00926
00927 typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption,
00928 const QString &dir,
00929 QFileDialog::Options options);
00930 KF_EXTERN _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook;
00931
00932 typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption,
00933 const QString &dir, const QString &filter,
00934 QString *selectedFilter,
00935 QFileDialog::Options options);
00936 KF_EXTERN _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook;
00937
00938 typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption,
00939 const QString &dir, const QString &filter,
00940 QString *selectedFilter,
00941 QFileDialog::Options options);
00942 KF_EXTERN _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook;
00943
00944 typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption,
00945 const QString &dir, const QString &filter,
00946 QString *selectedFilter,
00947 QFileDialog::Options options);
00948 KF_EXTERN _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook;
00949
00950
00951
00952
00953
00954
00955 class KFileDialogQtOverride
00956 {
00957 public:
00958 KFileDialogQtOverride()
00959 {
00960 if(!qt_filedialog_existing_directory_hook)
00961 qt_filedialog_existing_directory_hook=&getExistingDirectory;
00962 if(!qt_filedialog_open_filename_hook)
00963 qt_filedialog_open_filename_hook=&getOpenFileName;
00964 if(!qt_filedialog_open_filenames_hook)
00965 qt_filedialog_open_filenames_hook=&getOpenFileNames;
00966 if(!qt_filedialog_save_filename_hook)
00967 qt_filedialog_save_filename_hook=&getSaveFileName;
00968 }
00969
00970 ~KFileDialogQtOverride() {
00971 if(qt_filedialog_existing_directory_hook == &getExistingDirectory)
00972 qt_filedialog_existing_directory_hook = 0;
00973 if(qt_filedialog_open_filename_hook == &getOpenFileName)
00974 qt_filedialog_open_filename_hook = 0;
00975 if(qt_filedialog_open_filenames_hook == &getOpenFileNames)
00976 qt_filedialog_open_filenames_hook=0;
00977 if(qt_filedialog_save_filename_hook == &getSaveFileName)
00978 qt_filedialog_save_filename_hook=0;
00979 }
00980
00981
00982
00983
00984 static QString qt2KdeFilter(const QString &f)
00985 {
00986 QString filter;
00987 QTextStream str(&filter, QIODevice::WriteOnly);
00988 QStringList list(f.split(";;").replaceInStrings("/", "\\/"));
00989 QStringList::const_iterator it(list.begin()),
00990 end(list.end());
00991 bool first=true;
00992
00993 for(; it!=end; ++it)
00994 {
00995 int ob=(*it).lastIndexOf('('),
00996 cb=(*it).lastIndexOf(')');
00997
00998 if(-1!=cb && ob<cb)
00999 {
01000 if(first)
01001 first=false;
01002 else
01003 str << '\n';
01004 str << (*it).mid(ob+1, (cb-ob)-1) << '|' << (*it).mid(0, ob);
01005 }
01006 }
01007
01008 return filter;
01009 }
01010
01011
01012
01013
01014 static void kde2QtFilter(const QString &orig, const QString &kde, QString *sel)
01015 {
01016 if(sel)
01017 {
01018 QStringList list(orig.split(";;"));
01019 QStringList::const_iterator it(list.begin()),
01020 end(list.end());
01021 int pos;
01022
01023 for(; it!=end; ++it)
01024 if(-1!=(pos=(*it).indexOf(kde)) && pos>0 &&
01025 ('('==(*it)[pos-1] || ' '==(*it)[pos-1]) &&
01026 (*it).length()>=kde.length()+pos &&
01027 (')'==(*it)[pos+kde.length()] || ' '==(*it)[pos+kde.length()]))
01028 {
01029 *sel=*it;
01030 return;
01031 }
01032 }
01033 }
01034
01035 static QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir,
01036 QFileDialog::Options options)
01037 {
01038 if (KFileDialogPrivate::isNative()) {
01039 if(qt_filedialog_existing_directory_hook)
01040 qt_filedialog_existing_directory_hook=0;
01041 return QFileDialog::getExistingDirectory(parent, caption, dir, options);
01042 }
01043
01044 KUrl url(KFileDialog::getExistingDirectory(KUrl(dir), parent, caption));
01045
01046 if(url.isLocalFile())
01047 return url.pathOrUrl();
01048 else
01049 return QString();
01050 }
01051
01052 static QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir,
01053 const QString &filter, QString *selectedFilter,
01054 QFileDialog::Options options)
01055 {
01056 if (KFileDialogPrivate::isNative()) {
01057 if(qt_filedialog_open_filename_hook)
01058 qt_filedialog_open_filename_hook=0;
01059 return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
01060 }
01061
01062 KFileDialog dlg(KUrl(dir), qt2KdeFilter(filter), parent);
01063
01064 dlg.setOperationMode(KFileDialog::Opening);
01065 dlg.setMode(KFile::File|KFile::LocalOnly);
01066 dlg.setCaption(caption);
01067 dlg.exec();
01068
01069 QString rv(dlg.selectedFile());
01070
01071 if(!rv.isEmpty())
01072 kde2QtFilter(filter, dlg.currentFilter(), selectedFilter);
01073
01074 return rv;
01075 }
01076
01077 static QStringList getOpenFileNames(QWidget *parent, const QString &caption, const QString &dir,
01078 const QString &filter, QString *selectedFilter,
01079 QFileDialog::Options options)
01080 {
01081 if (KFileDialogPrivate::isNative()) {
01082 if(qt_filedialog_open_filenames_hook)
01083 qt_filedialog_open_filenames_hook=0;
01084 return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
01085 }
01086
01087 KFileDialog dlg(KUrl(dir), qt2KdeFilter(filter), parent);
01088
01089 dlg.setOperationMode(KFileDialog::Opening);
01090 dlg.setMode(KFile::Files|KFile::LocalOnly);
01091 dlg.setCaption(caption);
01092 dlg.exec();
01093
01094 QStringList rv(dlg.selectedFiles());
01095
01096 if(rv.count())
01097 kde2QtFilter(filter, dlg.currentFilter(), selectedFilter);
01098
01099 return rv;
01100 }
01101
01102 static QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir,
01103 const QString &filter, QString *selectedFilter,
01104 QFileDialog::Options options)
01105 {
01106 if (KFileDialogPrivate::isNative()) {
01107 if(qt_filedialog_save_filename_hook)
01108 qt_filedialog_save_filename_hook=0;
01109 return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options);
01110 }
01111
01112 KFileDialog dlg(KUrl(dir), qt2KdeFilter(filter), parent);
01113
01114 dlg.setOperationMode(KFileDialog::Saving);
01115 dlg.setMode(KFile::File|KFile::LocalOnly);
01116 dlg.setCaption(caption);
01117 dlg.setConfirmOverwrite(!(options & QFileDialog::DontConfirmOverwrite));
01118 dlg.exec();
01119
01120 QString rv(dlg.selectedFile());
01121
01122 if(!rv.isEmpty())
01123 kde2QtFilter(filter, dlg.currentFilter(), selectedFilter);
01124
01125 return rv;
01126 }
01127
01128 };
01129
01130 static KFileDialogQtOverride qtOverride;
01131
01132 #include "kfiledialog.moc"