• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KIO

kfiledialog.cpp

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 /* This file is part of the KDE libraries
00003     Copyright (C) 1997, 1998 Richard Moore <rich@kde.org>
00004                   1998 Stephan Kulow <coolo@kde.org>
00005                   1998 Daniel Grana <grana@ie.iwi.unibe.ch>
00006                   1999,2000,2001,2002,2003 Carsten Pfeiffer <pfeiffer@kde.org>
00007                   2003 Clarence Dang <dang@kde.org>
00008                   2008 Jarosław Staniek <staniek@kde.org>
00009 
00010     This library is free software; you can redistribute it and/or
00011     modify it under the terms of the GNU Library General Public
00012     License as published by the Free Software Foundation; either
00013     version 2 of the License, or (at your option) any later version.
00014 
00015     This library is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018     Library General Public License for more details.
00019 
00020     You should have received a copy of the GNU Library General Public License
00021     along with this library; see the file COPYING.LIB.  If not, write to
00022     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00023     Boston, MA 02110-1301, USA.
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 <kcompletion.h>
00043 #include <kurlcombobox.h>
00044 #include "kabstractfilewidget.h"
00045 #include "kabstractfilemodule.h"
00046 #include "krecentdirs.h"
00047 
00049 #ifdef Q_WS_WIN
00050 const bool NATIVE_FILEDIALOGS_BY_DEFAULT = true;
00051 #else
00052 const bool NATIVE_FILEDIALOGS_BY_DEFAULT = false;
00053 #endif
00054 
00055 static QStringList mime2KdeFilter( const QStringList &mimeTypes )
00056 {
00057   const KUrl emptyUrl;
00058   QStringList kdeFilter;
00059   foreach( const QString& mimeType, mimeTypes ) {
00060     KMimeType::Ptr mime( KMimeType::mimeType(mimeType) );
00061     if (mime)
00062       kdeFilter.append(mime->patterns().join(QLatin1String(" ")) +
00063                        QLatin1Char('|') +
00064                        mime->comment(emptyUrl));
00065   }
00066   return kdeFilter;
00067 }
00071 static QString qtFilter(const QStringList& _filters)
00072 {
00073     QString converted;
00074     QStringList filters = _filters;
00075     qSort( filters );
00076     foreach (const QString& current, filters) {
00077         QString new_f; //filter part
00078         QString new_name; //filter name part
00079         int p = current.indexOf('|');
00080         if (p==-1) {
00081             new_f = current;
00082             new_name = current; // nothing better found
00083         }
00084         else {
00085             new_f = current.left(p);
00086             new_name = current.mid(p+1);
00087         }
00088         // remove (.....) from name
00089         p = new_name.indexOf('(');
00090         int p2 = new_name.lastIndexOf(')');
00091         QString new_name1, new_name2;
00092         if (p!=-1)
00093             new_name1 = new_name.left(p);
00094         if (p2!=-1)
00095             new_name2 = new_name.mid(p2+1);
00096         if (!new_name1.isEmpty() || !new_name2.isEmpty())
00097             new_name = new_name1.trimmed() + QLatin1Char(' ') + new_name2.trimmed();
00098         new_name.remove('(');
00099         new_name.remove(')');
00100         new_name = new_name.trimmed();
00101 
00102         // make filters unique: remove uppercase extensions (case doesn't matter on win32, BTW)
00103         QStringList allfiltersUnique;
00104         const QStringList origList( new_f.split(' ', QString::SkipEmptyParts) );
00105         foreach (const QString& origFilter, origList) {
00106             if (origFilter == origFilter.toLower())
00107                 allfiltersUnique += origFilter;
00108         }
00109 
00110         if (!converted.isEmpty())
00111             converted += ";;";
00112 
00113         converted += (new_name + " (" + allfiltersUnique.join(" ") + QLatin1Char(')'));
00114     } // foreach
00115 
00116     // Strip escape characters from escaped '/' characters.
00117     for (int pos = 0; (pos = converted.indexOf("\\/", pos)) != -1; ++pos)
00118       converted.remove(pos, 1);
00119 
00120     return converted;
00121 }
00122 
00126 static QString qtFilter(const QString& filter)
00127 {
00128     // Qt format: "some text (*.first *.second)" or "All files (*)" separated by ;;
00129     // KDE format: "*.first *.second|Description" or "*|Description", separated by \n (Description is optional)
00130     QStringList filters;
00131     if (filter.isEmpty())
00132         filters += i18n("*|All files");
00133     else {
00134       // check if it's a mimefilter
00135       int pos = filter.indexOf('/');
00136       if (pos > 0 && filter[pos - 1] != '\\')
00137           filters = mime2KdeFilter(filter.split(QLatin1Char(' '), QString::SkipEmptyParts));
00138       else
00139           filters = filter.split('\n', QString::SkipEmptyParts);
00140     }
00141     return qtFilter(filters);
00142 }
00143 
00144 static KAbstractFileModule* s_module = 0;
00145 static KAbstractFileModule* fileModule()
00146 {
00147     if (!s_module) {
00148         // TODO fix memleak -- qApp post routine for deleting the module ?
00149         KPluginLoader loader("libkfilemodule");
00150         KPluginFactory *factory = loader.factory();
00151         if (!factory) {
00152             kWarning() << "KFileDialog wasn't able to find libkfilemodule: " << loader.errorString();
00153         } else {
00154             s_module = factory->create<KAbstractFileModule>();
00155             if (!s_module) {
00156                 kWarning() << "An error occurred while loading libkfilemodule";
00157             }
00158         }
00159     }
00160     return s_module;
00161 }
00162 
00163 class KFileDialogPrivate
00164 {
00165 public:
00167     class Native {
00168     public:
00169         Native()
00170           : mode(KFile::File),
00171             operationMode(KAbstractFileWidget::Opening)
00172         {
00173         }
00176         KUrl startDir() const
00177         {
00178             if (!s_startDir.isEmpty())
00179                 return s_startDir;
00180             if (!selectedUrls.isEmpty())
00181                 return selectedUrls.first();
00182             return KUrl();
00183         }
00186         static KUrl staticStartDir( const KUrl& defaultDir )
00187         {
00188             if ( s_startDir.isEmpty() )
00189               return defaultDir;
00190             return s_startDir;
00191         }
00192         static KUrl s_startDir;
00193         QString filter;
00194         QStringList mimeTypes;
00195         KUrl::List selectedUrls;
00196         KFile::Modes mode;
00197         KAbstractFileWidget::OperationMode operationMode;
00198     };
00199 
00200     KFileDialogPrivate()
00201       : native(0),
00202         w(0),
00203         cfgGroup(KGlobal::config(), ConfigGroup)
00204     {
00205         if (cfgGroup.readEntry("Native", NATIVE_FILEDIALOGS_BY_DEFAULT))
00206             native = new Native;
00207     }
00208 
00209     static bool isNative()
00210     {
00211         KConfigGroup cfgGroup(KGlobal::config(), ConfigGroup);
00212         return cfgGroup.readEntry("Native", NATIVE_FILEDIALOGS_BY_DEFAULT);
00213     }
00214 
00215     ~KFileDialogPrivate()
00216     {
00217         delete native;
00218     }
00219 
00220     Native* native;
00221     KAbstractFileWidget* w;
00222     KConfigGroup cfgGroup;
00223 };
00224 
00225 KUrl KFileDialogPrivate::Native::s_startDir;
00226 
00227 KFileDialog::KFileDialog( const KUrl& startDir, const QString& filter,
00228                           QWidget *parent, QWidget* customWidget)
00229 #ifdef Q_WS_WIN
00230     : KDialog( parent , Qt::WindowMinMaxButtonsHint),
00231 #else
00232     : KDialog( parent ),
00233 #endif
00234       d( new KFileDialogPrivate )
00235 
00236 {
00237     if (!d->native) {
00238         setButtons( KDialog::None );
00239         restoreDialogSize(d->cfgGroup); // call this before the fileQWidget is set as the main widget.
00240                                         // otherwise the sizes for the components are not obeyed (ereslibre)
00241     }
00242 
00243     // Dlopen the file widget from libkfilemodule
00244     QWidget* fileQWidget = fileModule()->createFileWidget(startDir, this);
00245     d->w = ::qobject_cast<KAbstractFileWidget *>(fileQWidget);
00246 
00247     if (d->native) {
00248         // check if it's a mimefilter
00249         int pos = filter.indexOf('/');
00250         if (pos > 0 && filter[pos - 1] != '\\')
00251           setMimeFilter(filter.split(QLatin1Char(' '), QString::SkipEmptyParts));
00252         else
00253           setFilter(filter);
00254         return;
00255     }
00256 
00257     d->w->setFilter(filter);
00258     setMainWidget(fileQWidget);
00259 
00260     d->w->okButton()->show();
00261     connect(d->w->okButton(), SIGNAL(clicked()), SLOT(slotOk()));
00262     d->w->cancelButton()->show();
00263     connect(d->w->cancelButton(), SIGNAL( clicked() ), SLOT( slotCancel() ));
00264 
00265     // Publish signals
00266     // TODO: Move the relevant signal declarations from KFileWidget to the
00267     //       KAbstractFileWidget interface?
00268     //
00269     //       Else, all of these connects (including "accepted") are not typesafe.
00270     kDebug (kfile_area) << "KFileDialog connecting signals";
00271     connect(fileQWidget, SIGNAL(fileSelected(const QString&)),
00272                          SIGNAL(fileSelected(const QString&)));
00273     connect(fileQWidget, SIGNAL(fileHighlighted(const QString&)),
00274                          SIGNAL(fileHighlighted(const QString&)));
00275     connect(fileQWidget, SIGNAL(selectionChanged()),
00276                          SIGNAL(selectionChanged()));
00277     connect(fileQWidget, SIGNAL(filterChanged(const QString&)),
00278                          SIGNAL(filterChanged(const QString&)));
00279 
00280     connect(fileQWidget, SIGNAL(accepted()), SLOT(accept()));
00281     //connect(fileQWidget, SIGNAL(canceled()), SLOT(slotCancel()));
00282 
00283     if (customWidget)
00284      d->w->setCustomWidget(QString(), customWidget);
00285 
00286     if (!d->native) {
00287      KCompletion* comp = d->w->locationEdit()->completionObject();
00288      comp->setIgnoreCase(true);
00289     }
00290 }
00291 
00292 
00293 KFileDialog::~KFileDialog()
00294 {
00295     delete d;
00296 }
00297 
00298 void KFileDialog::setLocationLabel(const QString& text)
00299 {
00300     if (d->native)
00301         return; // not available
00302     d->w->setLocationLabel(text);
00303 }
00304 
00305 void KFileDialog::setFilter(const QString& filter)
00306 {
00307     if (d->native) {
00308         d->native->filter = filter;
00309         return;
00310     }
00311     d->w->setFilter(filter);
00312 }
00313 
00314 QString KFileDialog::currentFilter() const
00315 {
00316     if (d->native)
00317         return QString(); // not available
00318     return d->w->currentFilter();
00319 }
00320 
00321 void KFileDialog::setMimeFilter( const QStringList& mimeTypes,
00322                                  const QString& defaultType )
00323 {
00324     d->w->setMimeFilter(mimeTypes, defaultType);
00325 
00326     if (d->native)
00327         d->native->filter = mime2KdeFilter( mimeTypes ).join(QLatin1String("\n"));
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 // This slot still exists mostly for compat purposes; for subclasses which reimplement slotOk
00370 void KFileDialog::slotOk()
00371 {
00372     if (d->native)
00373         return;
00374     d->w->slotOk();
00375 }
00376 
00377 // This slot still exists mostly for compat purposes; for subclasses which reimplement accept
00378 void KFileDialog::accept()
00379 {
00380     if (d->native)
00381         return;
00382     setResult( QDialog::Accepted ); // keep old behavior; probably not needed though
00383     d->w->accept();
00384     KConfigGroup cfgGroup(KGlobal::config(), ConfigGroup);
00385     KDialog::accept();
00386     emit okClicked();
00387 }
00388 
00389 // This slot still exists mostly for compat purposes; for subclasses which reimplement slotCancel
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 ).path(),
00427             qtFilter(filter) );
00428 // TODO use extra args?     QString * selectedFilter = 0, Options options = 0
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     //dlg.d->ops->clearHistory();
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); // everything we can do...
00448     QWidget* parent = QWidget::find( parent_id );
00449     KFileDialog dlg(startDir, filter, parent);
00450     if( parent == NULL && parent_id != 0 )
00451         KWindowSystem::setMainWindow( &dlg, parent_id );
00452 
00453     dlg.setOperationMode( KFileDialog::Opening );
00454 
00455     dlg.setMode( KFile::File | KFile::LocalOnly | KFile::ExistingOnly );
00456     dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00457 
00458     //dlg.d->ops->clearHistory();
00459     dlg.exec();
00460 
00461     return dlg.selectedFile();
00462 }
00463 
00464 QStringList KFileDialog::getOpenFileNames(const KUrl& startDir,
00465                                           const QString& filter,
00466                                           QWidget *parent,
00467                                           const QString& caption)
00468 {
00469     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00470         return QFileDialog::getOpenFileNames(
00471             parent,
00472             caption.isEmpty() ? i18n("Open") : caption,
00473             KFileDialogPrivate::Native::staticStartDir( startDir ).path(),
00474             qtFilter( filter ) );
00475 // TODO use extra args?  QString * selectedFilter = 0, Options options = 0
00476     }
00477     KFileDialog dlg(startDir, filter, parent);
00478     dlg.setOperationMode( Opening );
00479 
00480     dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00481     dlg.setMode(KFile::Files | KFile::LocalOnly | KFile::ExistingOnly);
00482     //dlg.d->ops->clearHistory();
00483     dlg.exec();
00484 
00485     return dlg.selectedFiles();
00486 }
00487 
00488 KUrl KFileDialog::getOpenUrl(const KUrl& startDir, const QString& filter,
00489                                 QWidget *parent, const QString& caption)
00490 {
00491     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00492         const QString fileName( KFileDialog::getOpenFileName(
00493             startDir, filter, parent, caption) );
00494         return fileName.isEmpty() ? KUrl() : KUrl::fromPath(fileName);
00495     }
00496     KFileDialog dlg(startDir, filter, parent);
00497     dlg.setOperationMode( Opening );
00498 
00499     dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00500     dlg.setMode( KFile::File | KFile::ExistingOnly );
00501     //dlg.d->ops->clearHistory();
00502     dlg.exec();
00503 
00504     return dlg.selectedUrl();
00505 }
00506 
00507 KUrl::List KFileDialog::getOpenUrls(const KUrl& startDir,
00508                                           const QString& filter,
00509                                           QWidget *parent,
00510                                           const QString& caption)
00511 {
00512     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00513         const QStringList fileNames( KFileDialog::getOpenFileNames(
00514             startDir, filter, parent, caption) );
00515         return KUrl::List(fileNames);
00516     }
00517     KFileDialog dlg(startDir, filter, parent);
00518     dlg.setOperationMode( Opening );
00519 
00520     dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00521     dlg.setMode(KFile::Files | KFile::ExistingOnly);
00522     //dlg.d->ops->clearHistory();
00523     dlg.exec();
00524 
00525     return dlg.selectedUrls();
00526 }
00527 
00528 void KFileDialog::setConfirmOverwrite(bool enable)
00529 {
00530     if (operationMode() == KFileDialog::Saving) {
00531         d->w->setConfirmOverwrite(enable);
00532     }
00533 }
00534 
00535 KUrl KFileDialog::getExistingDirectoryUrl(const KUrl& startDir,
00536                                           QWidget *parent,
00537                                           const QString& caption)
00538 {
00539     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00540         QString result( QFileDialog::getExistingDirectory(parent, caption,
00541             KFileDialogPrivate::Native::staticStartDir( startDir ).path(),
00542             QFileDialog::ShowDirsOnly) );
00543         return result.isEmpty() ? KUrl() : KUrl::fromPath(result);
00544     }
00545     return fileModule()->selectDirectory(startDir, false, parent, caption);
00546 }
00547 
00548 QString KFileDialog::getExistingDirectory(const KUrl& startDir,
00549                                           QWidget *parent,
00550                                           const QString& caption)
00551 {
00552     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00553         return QFileDialog::getExistingDirectory(parent, caption,
00554             KFileDialogPrivate::Native::staticStartDir( startDir ).path(),
00555             QFileDialog::ShowDirsOnly);
00556     }
00557     KUrl url = fileModule()->selectDirectory(startDir, true, parent, caption);
00558     if ( url.isValid() )
00559         return url.path();
00560     return QString();
00561 }
00562 
00563 KUrl KFileDialog::getImageOpenUrl( const KUrl& startDir, QWidget *parent,
00564                                    const QString& caption)
00565 {
00566     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) { // everything we can do...
00567         const QStringList mimetypes( KImageIO::mimeTypes( KImageIO::Reading ) );
00568         return KFileDialog::getOpenUrl(startDir, mimetypes.join(" "), parent, caption);
00569     }
00570     QStringList mimetypes = KImageIO::mimeTypes( KImageIO::Reading );
00571     KFileDialog dlg(startDir,
00572                     mimetypes.join(" "),
00573                     parent);
00574     dlg.setOperationMode( Opening );
00575     dlg.setCaption( caption.isEmpty() ? i18n("Open") : caption );
00576     dlg.setMode( KFile::File );
00577     dlg.setInlinePreviewShown( true );
00578 
00579     dlg.exec();
00580 
00581     return dlg.selectedUrl();
00582 }
00583 
00584 KUrl KFileDialog::selectedUrl() const
00585 {
00586     if (d->native)
00587         return d->native->selectedUrls.isEmpty() ? KUrl() : d->native->selectedUrls.first();
00588     return d->w->selectedUrl();
00589 }
00590 
00591 KUrl::List KFileDialog::selectedUrls() const
00592 {
00593     if (d->native)
00594         return d->native->selectedUrls;
00595     return d->w->selectedUrls();
00596 }
00597 
00598 QString KFileDialog::selectedFile() const
00599 {
00600     if (d->native)
00601         return selectedUrl().path();
00602     return d->w->selectedFile();
00603 }
00604 
00605 QStringList KFileDialog::selectedFiles() const
00606 {
00607     if (d->native)
00608         return selectedUrls().toStringList();
00609     return d->w->selectedFiles();
00610 }
00611 
00612 KUrl KFileDialog::baseUrl() const
00613 {
00614     if (d->native)
00615         return selectedUrl().isEmpty() ? KUrl() : KUrl::fromPath(selectedUrl().path());
00616     return d->w->baseUrl();
00617 }
00618 
00619 QString KFileDialog::getSaveFileName(const KUrl& dir, const QString& filter,
00620                                      QWidget *parent,
00621                                      const QString& caption)
00622 {
00623     if (KFileDialogPrivate::isNative()) {
00624         bool defaultDir = dir.isEmpty();
00625         bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00626         KUrl startDir;
00627         QString recentDirClass;
00628         if (specialDir) {
00629           startDir = KFileDialog::getStartUrl(dir, recentDirClass);
00630         }
00631         else if ( !specialDir && !defaultDir ) {
00632           if (!dir.isLocalFile())
00633               kWarning() << "non-local start dir " << dir;
00634           startDir = dir;
00635         }
00636 
00637         const QString result = QFileDialog::getSaveFileName(
00638             parent,
00639             caption.isEmpty() ? i18n("Save As") : caption,
00640             KFileDialogPrivate::Native::staticStartDir( startDir ).path(),
00641             qtFilter(filter) );
00642 // TODO use extra args?     QString * selectedFilter = 0, Options options = 0
00643         if (!result.isEmpty()) {
00644             if (!recentDirClass.isEmpty())
00645                 KRecentDirs::add(recentDirClass, KUrl::fromPath(result).url());
00646             KRecentDocument::add(result);
00647         }
00648         return result;
00649     }
00650     bool defaultDir = dir.isEmpty();
00651     bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00652     KFileDialog dlg( specialDir ? dir : KUrl(), filter, parent);
00653     if ( !specialDir && !defaultDir ) {
00654         if (!dir.isLocalFile())
00655             kWarning() << "KFileDialog::getSaveFileName called with non-local start dir " << dir;
00656         dlg.setSelection( dir.path() ); // may also be a filename
00657     }
00658 
00659     dlg.setOperationMode( Saving );
00660     dlg.setMode( KFile::File );
00661     dlg.setCaption(caption.isEmpty() ? i18n("Save As") : caption);
00662 
00663     dlg.exec();
00664 
00665     QString filename = dlg.selectedFile();
00666     if (!filename.isEmpty())
00667         KRecentDocument::add(filename);
00668 
00669     return filename;
00670 }
00671 
00672 QString KFileDialog::getSaveFileNameWId(const KUrl& dir, const QString& filter,
00673                                      WId parent_id,
00674                                      const QString& caption)
00675 {
00676     if (KFileDialogPrivate::isNative()) {
00677         return KFileDialog::getSaveFileName(dir, filter, 0, caption); // everything we can do...
00678     }
00679     bool defaultDir = dir.isEmpty();
00680     bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00681     QWidget* parent = QWidget::find( parent_id );
00682     KFileDialog dlg( specialDir ? dir : KUrl(), filter, parent);
00683     if( parent == NULL && parent_id != 0 )
00684         KWindowSystem::setMainWindow( &dlg, parent_id);
00685 
00686     if ( !specialDir && !defaultDir ) {
00687         if (!dir.isLocalFile())
00688             kWarning() << "KFileDialog::getSaveFileNameWId called with non-local start dir " << dir;
00689         dlg.setSelection( dir.path() ); // may also be a filename
00690     }
00691 
00692     dlg.setOperationMode( Saving );
00693     dlg.setMode( KFile::File );
00694     dlg.setCaption(caption.isEmpty() ? i18n("Save As") : caption);
00695 
00696     dlg.exec();
00697 
00698     QString filename = dlg.selectedFile();
00699     if (!filename.isEmpty())
00700         KRecentDocument::add(filename);
00701 
00702     return filename;
00703 }
00704 
00705 KUrl KFileDialog::getSaveUrl(const KUrl& dir, const QString& filter,
00706                              QWidget *parent, const QString& caption)
00707 {
00708     if (KFileDialogPrivate::isNative() && (!dir.isValid() || dir.isLocalFile())) {
00709         const QString fileName( KFileDialog::getSaveFileName(
00710             dir.path(), filter, parent, caption) );
00711         return fileName.isEmpty() ? KUrl() : KUrl::fromPath(fileName);
00712     }
00713     bool defaultDir = dir.isEmpty();
00714     bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00715     KFileDialog dlg(specialDir ? dir : KUrl(), filter, parent);
00716     if ( !specialDir )
00717         dlg.setSelection( dir.url() ); // may also be a filename
00718 
00719     dlg.setCaption(caption.isEmpty() ? i18n("Save As") : caption);
00720     dlg.setOperationMode( Saving );
00721     dlg.setMode( KFile::File );
00722 
00723     dlg.exec();
00724 
00725     KUrl url = dlg.selectedUrl();
00726     if (url.isValid())
00727         KRecentDocument::add( url );
00728 
00729     return url;
00730 }
00731 
00732 void KFileDialog::setMode( KFile::Modes m )
00733 {
00734     if (d->native)
00735         d->native->mode = m;
00736     else
00737         d->w->setMode(m);
00738 }
00739 
00740 KFile::Modes KFileDialog::mode() const
00741 {
00742     if (d->native)
00743         return d->native->mode;
00744     return d->w->mode();
00745 }
00746 
00747 KPushButton * KFileDialog::okButton() const
00748 {
00749     return d->w->okButton();
00750 }
00751 
00752 KPushButton * KFileDialog::cancelButton() const
00753 {
00754     return d->w->cancelButton();
00755 }
00756 
00757 KUrlComboBox* KFileDialog::locationEdit() const
00758 {
00759     return d->w->locationEdit();
00760 }
00761 
00762 KFileFilterCombo* KFileDialog::filterWidget() const
00763 {
00764     return d->w->filterWidget();
00765 }
00766 
00767 KActionCollection * KFileDialog::actionCollection() const
00768 {
00769     return d->w->actionCollection();
00770 }
00771 
00772 void KFileDialog::setKeepLocation( bool keep )
00773 {
00774     if (d->native)
00775         return;
00776     d->w->setKeepLocation(keep);
00777 }
00778 
00779 bool KFileDialog::keepsLocation() const
00780 {
00781     if (d->native)
00782         return false;
00783     return d->w->keepsLocation();
00784 }
00785 
00786 void KFileDialog::setOperationMode( OperationMode mode )
00787 {
00788     if (d->native)
00789         d->native->operationMode = static_cast<KAbstractFileWidget::OperationMode>(mode);
00790     else
00791         d->w->setOperationMode(static_cast<KAbstractFileWidget::OperationMode>(mode));
00792 }
00793 
00794 KFileDialog::OperationMode KFileDialog::operationMode() const
00795 {
00796     if (d->native)
00797         return static_cast<KFileDialog::OperationMode>(d->native->operationMode);
00798     return static_cast<KFileDialog::OperationMode>(d->w->operationMode());
00799 }
00800 
00801 void KFileDialog::keyPressEvent( QKeyEvent *e )
00802 {
00803     if (d->native)
00804         return;
00805 
00806     if ( e->key() == Qt::Key_Escape )
00807     {
00808         e->accept();
00809         d->w->cancelButton()->animateClick();
00810     }
00811     else
00812         KDialog::keyPressEvent( e );
00813 }
00814 
00815 void KFileDialog::hideEvent( QHideEvent *e )
00816 {
00817     if (d->native)
00818         return;
00819 
00820     saveDialogSize(d->cfgGroup, KConfigBase::Persistent);
00821 
00822     KDialog::hideEvent( e );
00823 }
00824 
00825 // static
00826 KUrl KFileDialog::getStartUrl( const KUrl& startDir,
00827                                QString& recentDirClass )
00828 {
00829     return fileModule()->getStartUrl(startDir, recentDirClass);
00830 }
00831 
00832 void KFileDialog::setStartDir( const KUrl& directory )
00833 {
00834     if (KFileDialogPrivate::isNative())
00835         KFileDialogPrivate::Native::s_startDir = directory;
00836     fileModule()->setStartDir(directory);
00837 }
00838 
00839 KToolBar * KFileDialog::toolBar() const
00840 {
00841     return d->w->toolBar();
00842 }
00843 
00844 KAbstractFileWidget* KFileDialog::fileWidget()
00845 {
00846     return d->w;
00847 }
00848 
00849 #ifdef Q_WS_WIN
00850 int KFileDialog::exec()
00851 {
00852     if (!d->native)
00853       return KDialog::exec();
00854 
00855 // not clear here to let KFileDialogPrivate::Native::startDir() return a useful value
00856 // d->native->selectedUrls.clear();
00857     switch (d->native->operationMode) {
00858     case KAbstractFileWidget::Opening:
00859     case KAbstractFileWidget::Other:
00860         if (d->native->mode & KFile::File) {
00861             KUrl url( KFileDialog::getOpenUrl(
00862                d->native->startDir(), d->native->filter, parentWidget(), windowTitle()) );
00863             if (url.isEmpty() || !url.isValid())
00864                 return QDialog::Rejected;
00865             d->native->selectedUrls.clear();
00866             d->native->selectedUrls.append(url);
00867             return QDialog::Accepted;
00868         }
00869         else if (d->native->mode & KFile::Files) {
00870             KUrl::List urls( KFileDialog::getOpenUrls(
00871                 d->native->startDir(), d->native->filter, parentWidget(), windowTitle()) );
00872             if (urls.isEmpty())
00873                 return QDialog::Rejected;
00874             d->native->selectedUrls = urls;
00875             return QDialog::Accepted;
00876         }
00877         else if (d->native->mode & KFile::Directory) {
00878             KUrl url( KFileDialog::getExistingDirectoryUrl(
00879                 d->native->startDir(), parentWidget(), windowTitle()) );
00880             if (url.isEmpty() || !url.isValid())
00881                 return QDialog::Rejected;
00882             d->native->selectedUrls.clear();
00883             d->native->selectedUrls.append(url);
00884             return QDialog::Accepted;
00885         }
00886         break;
00887     case KAbstractFileWidget::Saving:
00888         if (d->native->mode & KFile::File) {
00889             KUrl url( KFileDialog::getSaveUrl(
00890                 d->native->startDir(), d->native->filter, parentWidget(), windowTitle()) );
00891             if (url.isEmpty() || !url.isValid())
00892                 return QDialog::Rejected;
00893             d->native->selectedUrls.clear();
00894             d->native->selectedUrls.append(url);
00895             return QDialog::Accepted;
00896         }
00897         else if (d->native->mode & KFile::Directory) {
00898             KUrl url( KFileDialog::getExistingDirectoryUrl(
00899                 d->native->startDir(), parentWidget(), windowTitle()) );
00900             if (url.isEmpty() || !url.isValid())
00901                 return QDialog::Rejected;
00902             d->native->selectedUrls.clear();
00903             d->native->selectedUrls.append(url);
00904             return QDialog::Accepted;
00905         }
00906         break;
00907     default:;
00908     }
00909     return QDialog::Rejected;
00910 }
00911 #endif // Q_WS_WIN
00912 
00913 #ifdef Q_WS_WIN
00914 #define KF_EXTERN extern __declspec(dllimport)
00915 #else
00916 #define KF_EXTERN extern
00917 #endif
00918 
00919 typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption,
00920                                                           const QString &dir,
00921                                                           QFileDialog::Options options);
00922 KF_EXTERN _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook;
00923 
00924 typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption,
00925                                                      const QString &dir, const QString &filter,
00926                                                      QString *selectedFilter,
00927                                                      QFileDialog::Options options);
00928 KF_EXTERN _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook;
00929 
00930 typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption,
00931                                                           const QString &dir, const QString &filter,
00932                                                           QString *selectedFilter,
00933                                                           QFileDialog::Options options);
00934 KF_EXTERN _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook;
00935 
00936 typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption,
00937                                                      const QString &dir, const QString &filter,
00938                                                      QString *selectedFilter,
00939                                                      QFileDialog::Options options);
00940 KF_EXTERN _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook;
00941 
00942 /*
00943  * This class is used to override Qt's QFileDialog calls with KFileDialog ones.
00944  * This is necessary because QPrintDialog calls QFileDialog::getSaveFileName() for
00945  * the print to file function.
00946  */
00947 class KFileDialogQtOverride
00948 {
00949 public:
00950     KFileDialogQtOverride()
00951     {
00952         if(!qt_filedialog_existing_directory_hook)
00953             qt_filedialog_existing_directory_hook=&getExistingDirectory;
00954         if(!qt_filedialog_open_filename_hook)
00955             qt_filedialog_open_filename_hook=&getOpenFileName;
00956         if(!qt_filedialog_open_filenames_hook)
00957             qt_filedialog_open_filenames_hook=&getOpenFileNames;
00958         if(!qt_filedialog_save_filename_hook)
00959             qt_filedialog_save_filename_hook=&getSaveFileName;
00960     }
00961 
00962     ~KFileDialogQtOverride() {
00963         if(qt_filedialog_existing_directory_hook == &getExistingDirectory)
00964             qt_filedialog_existing_directory_hook = 0;
00965         if(qt_filedialog_open_filename_hook == &getOpenFileName)
00966             qt_filedialog_open_filename_hook = 0;
00967         if(qt_filedialog_open_filenames_hook == &getOpenFileNames)
00968             qt_filedialog_open_filenames_hook=0;
00969         if(qt_filedialog_save_filename_hook == &getSaveFileName)
00970             qt_filedialog_save_filename_hook=0;
00971     }
00972 
00973     /*
00974      * Map a Qt filter string into a KDE one.
00975      */
00976     static QString qt2KdeFilter(const QString &f)
00977     {
00978         QString               filter;
00979         QTextStream           str(&filter, QIODevice::WriteOnly);
00980         QStringList           list(f.split(";;"));
00981         QStringList::const_iterator it(list.begin()),
00982                               end(list.end());
00983         bool                  first=true;
00984 
00985         for(; it!=end; ++it)
00986         {
00987             int ob=(*it).lastIndexOf('('),
00988                 cb=(*it).lastIndexOf(')');
00989 
00990             if(-1!=cb && ob<cb)
00991             {
00992                 if(first)
00993                     first=false;
00994                 else
00995                     str << '\n';
00996                 str << (*it).mid(ob+1, (cb-ob)-1) << '|' << (*it).mid(0, ob);
00997             }
00998         }
00999 
01000         return filter;
01001     }
01002 
01003     /*
01004      * Map a KDE filter string into a Qt one.
01005      */
01006     static void kde2QtFilter(const QString &orig, const QString &kde, QString *sel)
01007     {
01008         if(sel)
01009         {
01010             QStringList           list(orig.split(";;"));
01011             QStringList::const_iterator it(list.begin()),
01012                                   end(list.end());
01013             int                   pos;
01014 
01015             for(; it!=end; ++it)
01016                 if(-1!=(pos=(*it).indexOf(kde)) && pos>0 &&
01017                    ('('==(*it)[pos-1] || ' '==(*it)[pos-1]) &&
01018                    (*it).length()>=kde.length()+pos &&
01019                    (')'==(*it)[pos+kde.length()] || ' '==(*it)[pos+kde.length()]))
01020                 {
01021                     *sel=*it;
01022                     return;
01023                 }
01024         }
01025     }
01026 
01027     static QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir,
01028                                         QFileDialog::Options options)
01029     {
01030         if (KFileDialogPrivate::isNative()) {
01031             if(qt_filedialog_existing_directory_hook)
01032                 qt_filedialog_existing_directory_hook=0; // do not override
01033             return QFileDialog::getExistingDirectory(parent, caption, dir, options);
01034         }
01035 
01036         KUrl url(KFileDialog::getExistingDirectory(KUrl(dir), parent, caption));
01037 
01038         if(url.isLocalFile())
01039             return url.pathOrUrl();
01040         else
01041             return QString();
01042     }
01043 
01044     static QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir,
01045                                    const QString &filter, QString *selectedFilter,
01046                                    QFileDialog::Options options)
01047     {
01048         if (KFileDialogPrivate::isNative()) {
01049             if(qt_filedialog_open_filename_hook)
01050                 qt_filedialog_open_filename_hook=0; // do not override
01051             return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
01052         }
01053 
01054         KFileDialog dlg(KUrl(dir), qt2KdeFilter(filter), parent);
01055 
01056         dlg.setOperationMode(KFileDialog::Opening);
01057         dlg.setMode(KFile::File|KFile::LocalOnly);
01058         dlg.setCaption(caption);
01059         dlg.exec();
01060 
01061         QString rv(dlg.selectedFile());
01062 
01063         if(!rv.isEmpty())
01064             kde2QtFilter(filter, dlg.currentFilter(), selectedFilter);
01065 
01066         return rv;
01067     }
01068 
01069     static QStringList getOpenFileNames(QWidget *parent, const QString &caption, const QString &dir,
01070                                         const QString &filter, QString *selectedFilter,
01071                                         QFileDialog::Options options)
01072     {
01073         if (KFileDialogPrivate::isNative()) {
01074             if(qt_filedialog_open_filenames_hook)
01075                 qt_filedialog_open_filenames_hook=0; // do not override
01076             return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
01077         }
01078 
01079         KFileDialog dlg(KUrl(dir), qt2KdeFilter(filter), parent);
01080 
01081         dlg.setOperationMode(KFileDialog::Opening);
01082         dlg.setMode(KFile::Files|KFile::LocalOnly);
01083         dlg.setCaption(caption);
01084         dlg.exec();
01085 
01086         QStringList rv(dlg.selectedFiles());
01087 
01088         if(rv.count())
01089             kde2QtFilter(filter, dlg.currentFilter(), selectedFilter);
01090 
01091         return rv;
01092     }
01093 
01094     static QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir,
01095                                    const QString &filter, QString *selectedFilter,
01096                                    QFileDialog::Options options)
01097     {
01098         if (KFileDialogPrivate::isNative()) {
01099             if(qt_filedialog_save_filename_hook)
01100                 qt_filedialog_save_filename_hook=0; // do not override
01101             return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options);
01102         }
01103 
01104         KFileDialog dlg(KUrl(dir), qt2KdeFilter(filter), parent);
01105 
01106         dlg.setOperationMode(KFileDialog::Saving);
01107         dlg.setMode(KFile::File|KFile::LocalOnly);
01108         dlg.setCaption(caption);
01109         dlg.exec();
01110 
01111         QString rv(dlg.selectedFile());
01112 
01113         if(!rv.isEmpty())
01114             kde2QtFilter(filter, dlg.currentFilter(), selectedFilter);
01115 
01116         return rv;
01117     }
01118 
01119 };
01120 
01121 static KFileDialogQtOverride qtOverride;
01122 
01123 #include "kfiledialog.moc"

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal