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