• 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 "kabstractfilewidget.h"
00042 #include "kabstractfilemodule.h"
00043 #include "krecentdirs.h"
00044 
00045 #ifdef Q_WS_X11
00046 #include <qx11info_x11.h>
00047 #include <X11/Xlib.h>
00048 #include <fixx11h.h>
00049 #endif
00050 
00052 #ifdef Q_WS_WIN
00053 const bool NATIVE_FILEDIALOGS_BY_DEFAULT = true;
00054 #else
00055 const bool NATIVE_FILEDIALOGS_BY_DEFAULT = false;
00056 #endif
00057 
00061 static QString qtFilter(const QStringList& filters)
00062 {
00063     QString converted;
00064     foreach (const QString& current, filters) {
00065         QString new_f; //filter part
00066         QString new_name; //filter name part
00067         int p = current.indexOf('|');
00068         if (p==-1) {
00069             new_f = current;
00070             new_name = current; // nothing better found
00071         }
00072         else {
00073             new_f = current.left(p);
00074             new_name = current.mid(p+1);
00075         }
00076         // remove (.....) from name
00077         p = new_name.indexOf('(');
00078         int p2 = new_name.lastIndexOf(')');
00079         QString new_name1, new_name2;
00080         if (p!=-1)
00081             new_name1 = new_name.left(p);
00082         if (p2!=-1)
00083             new_name2 = new_name.mid(p2+1);
00084         if (!new_name1.isEmpty() || !new_name2.isEmpty())
00085             new_name = new_name1.trimmed() + QLatin1Char(' ') + new_name2.trimmed();
00086         new_name.remove('(');
00087         new_name.remove(')');
00088         new_name = new_name.trimmed();
00089 
00090         // make filters unique: remove uppercase extensions (case doesn't matter on win32, BTW)
00091         QStringList allfiltersUnique;
00092         const QStringList origList( new_f.split(' ', QString::SkipEmptyParts) );
00093         foreach (const QString& origFilter, origList) {
00094             if (origFilter == origFilter.toLower())
00095                 allfiltersUnique += origFilter;
00096         }
00097 
00098         if (!converted.isEmpty())
00099             converted += ";;";
00100 
00101         converted += (new_name + " (" + allfiltersUnique.join(" ") + QLatin1Char(')'));
00102     } // foreach
00103 
00104     // Strip escape characters from escaped '/' characters.
00105     for (int pos = 0; (pos = converted.indexOf("\\/", pos)) != -1; ++pos)
00106       converted.remove(pos, 1);
00107 
00108     return converted;
00109 }
00110 
00114 static QString qtFilter(const QString& filter)
00115 {
00116     // Qt format: "some text (*.first *.second)" or "All files (*)" separated by ;;
00117     // KDE format: "*.first *.second|Description" or "*|Description", separated by \n (Description is optional)
00118     QStringList filters;
00119     if (filter.isEmpty())
00120         filters += i18n("*|All files");
00121     else
00122         filters = filter.split('\n', QString::SkipEmptyParts);
00123     return qtFilter(filters);
00124 }
00125 
00126 static KAbstractFileModule* s_module = 0;
00127 static KAbstractFileModule* fileModule()
00128 {
00129     if (!s_module) {
00130         // TODO fix memleak -- qApp post routine for deleting the module ?
00131         KPluginLoader loader("libkfilemodule");
00132         KPluginFactory *factory = loader.factory();
00133         if (!factory) {
00134             kWarning() << "KFileDialog wasn't able to find libkfilemodule: " << loader.errorString();
00135         } else {
00136             s_module = factory->create<KAbstractFileModule>();
00137             if (!s_module) {
00138                 kWarning() << "An error occurred while loading libkfilemodule";
00139             }
00140         }
00141     }
00142     return s_module;
00143 }
00144 
00145 class KFileDialogPrivate
00146 {
00147 public:
00149     class Native {
00150     public:
00151         Native()
00152           : mode(KFile::File),
00153             operationMode(KAbstractFileWidget::Opening)
00154         {
00155         }
00158         KUrl startDir() const
00159         {
00160             if (!s_startDir.isEmpty())
00161                 return s_startDir;
00162             if (!selectedUrls.isEmpty())
00163                 return selectedUrls.first();
00164             return KUrl();
00165         }
00168         static KUrl staticStartDir( const KUrl& defaultDir )
00169         {
00170             if ( s_startDir.isEmpty() )
00171               return defaultDir;
00172             return s_startDir;
00173         }
00174         static KUrl s_startDir;
00175         QString filter;
00176         QStringList mimeTypes;
00177         KUrl::List selectedUrls;
00178         KFile::Modes mode;
00179         KAbstractFileWidget::OperationMode operationMode;
00180     };
00181 
00182     KFileDialogPrivate()
00183       : native(0),
00184         w(0),
00185         cfgGroup(KGlobal::config(), ConfigGroup)
00186     {
00187         if (cfgGroup.readEntry("Native", NATIVE_FILEDIALOGS_BY_DEFAULT))
00188             native = new Native;
00189     }
00190 
00191     static bool isNative()
00192     {
00193         KConfigGroup cfgGroup(KGlobal::config(), ConfigGroup);
00194         return cfgGroup.readEntry("Native", NATIVE_FILEDIALOGS_BY_DEFAULT);
00195     }
00196 
00197     ~KFileDialogPrivate()
00198     {
00199         delete native;
00200     }
00201 
00202     Native* native;
00203     KAbstractFileWidget* w;
00204     KConfigGroup cfgGroup;
00205 };
00206 
00207 KUrl KFileDialogPrivate::Native::s_startDir;
00208 
00209 KFileDialog::KFileDialog( const KUrl& startDir, const QString& filter,
00210                           QWidget *parent, QWidget* customWidget)
00211 #ifdef Q_WS_WIN
00212     : KDialog( parent , Qt::WindowMinMaxButtonsHint),
00213 #else
00214     : KDialog( parent ),
00215 #endif
00216       d( new KFileDialogPrivate )
00217 
00218 {
00219     if (!d->native) {
00220         setButtons( KDialog::None );
00221         restoreDialogSize(d->cfgGroup); // call this before the fileQWidget is set as the main widget.
00222                                         // otherwise the sizes for the components are not obeyed (ereslibre)
00223     }
00224 
00225     // Dlopen the file widget from libkfilemodule
00226     QWidget* fileQWidget = fileModule()->createFileWidget(startDir, this);
00227     d->w = ::qobject_cast<KAbstractFileWidget *>(fileQWidget);
00228 
00229     if (d->native) {
00230         d->native->filter = 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 = 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         QString kdeFilter;
00300         foreach( const QString& mimeType, mimeTypes ) {
00301             KMimeType::Ptr mime( KMimeType::mimeType(mimeType) );
00302             if (mime)
00303                kdeFilter += (mime->patterns().join(" ") + QLatin1Char('|') + mime->comment());
00304         }
00305         d->native->filter = kdeFilter;
00306     }
00307 }
00308 
00309 void KFileDialog::clearFilter()
00310 {
00311     if (d->native) {
00312         d->native->filter.clear();
00313         return;
00314     }
00315     d->w->clearFilter();
00316 }
00317 
00318 QString KFileDialog::currentMimeFilter() const
00319 {
00320     return d->w->currentMimeFilter();
00321 }
00322 
00323 KMimeType::Ptr KFileDialog::currentFilterMimeType()
00324 {
00325     return KMimeType::mimeType( currentMimeFilter() );
00326 }
00327 
00328 void KFileDialog::setPreviewWidget(KPreviewWidgetBase *w)
00329 {
00330     if (d->native)
00331       return;
00332     d->w->setPreviewWidget(w);
00333 }
00334 
00335 QSize KFileDialog::sizeHint() const
00336 {
00337     return QSize(640, 400);
00338 }
00339 
00340 // This slot still exists mostly for compat purposes; for subclasses which reimplement slotOk
00341 void KFileDialog::slotOk()
00342 {
00343     if (d->native)
00344         return;
00345     d->w->slotOk();
00346 }
00347 
00348 // This slot still exists mostly for compat purposes; for subclasses which reimplement accept
00349 void KFileDialog::accept()
00350 {
00351     if (d->native)
00352         return;
00353     setResult( QDialog::Accepted ); // keep old behavior; probably not needed though
00354     d->w->accept();
00355     KConfigGroup cfgGroup(KGlobal::config(), ConfigGroup);
00356     KDialog::accept();
00357     emit okClicked();
00358 }
00359 
00360 // This slot still exists mostly for compat purposes; for subclasses which reimplement slotCancel
00361 void KFileDialog::slotCancel()
00362 {
00363     if (d->native)
00364         return;
00365     d->w->slotCancel();
00366     reject();
00367 }
00368 
00369 void KFileDialog::setUrl(const KUrl& url, bool clearforward)
00370 {
00371     if (d->native) {
00372          d->native->selectedUrls.clear();
00373          d->native->selectedUrls.append(url);
00374         return;
00375     }
00376     d->w->setUrl(url, clearforward);
00377 }
00378 
00379 void KFileDialog::setSelection(const QString& name)
00380 {
00381     if (d->native) {
00382          d->native->selectedUrls.clear();
00383          d->native->selectedUrls.append( KUrl::fromPath(name) );
00384          return;
00385     }
00386     d->w->setSelection(name);
00387 }
00388 
00389 QString KFileDialog::getOpenFileName(const KUrl& startDir,
00390                                      const QString& filter,
00391                                      QWidget *parent, const QString& caption)
00392 {
00393     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00394         return QFileDialog::getOpenFileName( 
00395             parent,
00396             caption.isEmpty() ? i18n("Open") : caption,
00397             KFileDialogPrivate::Native::staticStartDir( startDir ).path(),
00398             qtFilter(filter) );
00399 // TODO use extra args?     QString * selectedFilter = 0, Options options = 0
00400     }
00401     KFileDialog dlg(startDir, filter, parent);
00402     dlg.setOperationMode( Opening );
00403 
00404     dlg.setMode( KFile::File | KFile::LocalOnly );
00405     dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00406 
00407     //dlg.d->ops->clearHistory();
00408     dlg.exec();
00409 
00410     return dlg.selectedFile();
00411 }
00412 
00413 QString KFileDialog::getOpenFileNameWId(const KUrl& startDir,
00414                                         const QString& filter,
00415                                         WId parent_id, const QString& caption)
00416 {
00417     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile()))
00418         return KFileDialog::getOpenFileName(startDir, filter, 0, caption); // everything we can do...
00419     QWidget* parent = QWidget::find( parent_id );
00420     KFileDialog dlg(startDir, filter, parent);
00421 #ifdef Q_WS_X11
00422     if( parent == NULL && parent_id != 0 )
00423         XSetTransientForHint( QX11Info::display(), dlg.winId(), parent_id );
00424 #else
00425     // TODO
00426 #endif
00427 
00428     dlg.setOperationMode( KFileDialog::Opening );
00429 
00430     dlg.setMode( KFile::File | KFile::LocalOnly );
00431     dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00432 
00433     //dlg.d->ops->clearHistory();
00434     dlg.exec();
00435 
00436     return dlg.selectedFile();
00437 }
00438 
00439 QStringList KFileDialog::getOpenFileNames(const KUrl& startDir,
00440                                           const QString& filter,
00441                                           QWidget *parent,
00442                                           const QString& caption)
00443 {
00444     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00445         return QFileDialog::getOpenFileNames(
00446             parent,
00447             caption.isEmpty() ? i18n("Open") : caption,
00448             KFileDialogPrivate::Native::staticStartDir( startDir ).path(),
00449             qtFilter(filter) );
00450 // TODO use extra args?  QString * selectedFilter = 0, Options options = 0
00451     }
00452     KFileDialog dlg(startDir, filter, parent);
00453     dlg.setOperationMode( Opening );
00454 
00455     dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00456     dlg.setMode(KFile::Files | KFile::LocalOnly);
00457     //dlg.d->ops->clearHistory();
00458     dlg.exec();
00459 
00460     return dlg.selectedFiles();
00461 }
00462 
00463 KUrl KFileDialog::getOpenUrl(const KUrl& startDir, const QString& filter,
00464                                 QWidget *parent, const QString& caption)
00465 {
00466     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00467         const QString fileName( KFileDialog::getOpenFileName(
00468             startDir, filter, parent, caption) );
00469         return fileName.isEmpty() ? KUrl() : KUrl::fromPath(fileName);
00470     }
00471     KFileDialog dlg(startDir, filter, parent);
00472     dlg.setOperationMode( Opening );
00473 
00474     dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00475     dlg.setMode( KFile::File );
00476     //dlg.d->ops->clearHistory();
00477     dlg.exec();
00478 
00479     return dlg.selectedUrl();
00480 }
00481 
00482 KUrl::List KFileDialog::getOpenUrls(const KUrl& startDir,
00483                                           const QString& filter,
00484                                           QWidget *parent,
00485                                           const QString& caption)
00486 {
00487     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00488         const QStringList fileNames( KFileDialog::getOpenFileNames(
00489             startDir, filter, parent, caption) );
00490         return KUrl::List(fileNames);
00491     }
00492     KFileDialog dlg(startDir, filter, parent);
00493     dlg.setOperationMode( Opening );
00494 
00495     dlg.setCaption(caption.isEmpty() ? i18n("Open") : caption);
00496     dlg.setMode(KFile::Files);
00497     //dlg.d->ops->clearHistory();
00498     dlg.exec();
00499 
00500     return dlg.selectedUrls();
00501 }
00502 
00503 KUrl KFileDialog::getExistingDirectoryUrl(const KUrl& startDir,
00504                                           QWidget *parent,
00505                                           const QString& caption)
00506 {
00507     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00508         QString result( QFileDialog::getExistingDirectory(parent, caption,
00509             KFileDialogPrivate::Native::staticStartDir( startDir ).path(),
00510             QFileDialog::ShowDirsOnly) );
00511         return result.isEmpty() ? KUrl() : KUrl::fromPath(result);
00512     }
00513     return fileModule()->selectDirectory(startDir, false, parent, caption);
00514 }
00515 
00516 QString KFileDialog::getExistingDirectory(const KUrl& startDir,
00517                                           QWidget *parent,
00518                                           const QString& caption)
00519 {
00520     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) {
00521         return QFileDialog::getExistingDirectory(parent, caption,
00522             KFileDialogPrivate::Native::staticStartDir( startDir ).path(),
00523             QFileDialog::ShowDirsOnly);
00524     }
00525     KUrl url = fileModule()->selectDirectory(startDir, true, parent, caption);
00526     if ( url.isValid() )
00527         return url.path();
00528     return QString();
00529 }
00530 
00531 KUrl KFileDialog::getImageOpenUrl( const KUrl& startDir, QWidget *parent,
00532                                    const QString& caption)
00533 {
00534     if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) { // everything we can do...
00535         const QStringList mimetypes( KImageIO::mimeTypes( KImageIO::Reading ) );
00536         return KFileDialog::getOpenUrl(startDir, mimetypes.join(" "), parent, caption);
00537     }
00538     QStringList mimetypes = KImageIO::mimeTypes( KImageIO::Reading );
00539     KFileDialog dlg(startDir,
00540                     mimetypes.join(" "),
00541                     parent);
00542     dlg.setOperationMode( Opening );
00543     dlg.setCaption( caption.isEmpty() ? i18n("Open") : caption );
00544     dlg.setMode( KFile::File );
00545 
00546     KImageFilePreview *ip = new KImageFilePreview( &dlg );
00547     dlg.setPreviewWidget( ip );
00548     dlg.exec();
00549 
00550     return dlg.selectedUrl();
00551 }
00552 
00553 KUrl KFileDialog::selectedUrl() const
00554 {
00555     if (d->native)
00556         return d->native->selectedUrls.isEmpty() ? KUrl() : d->native->selectedUrls.first();
00557     return d->w->selectedUrl();
00558 }
00559 
00560 KUrl::List KFileDialog::selectedUrls() const
00561 {
00562     if (d->native)
00563         return d->native->selectedUrls;
00564     return d->w->selectedUrls();
00565 }
00566 
00567 QString KFileDialog::selectedFile() const
00568 {
00569     if (d->native)
00570         return selectedUrl().path();
00571     return d->w->selectedFile();
00572 }
00573 
00574 QStringList KFileDialog::selectedFiles() const
00575 {
00576     if (d->native)
00577         return selectedUrls().toStringList();
00578     return d->w->selectedFiles();
00579 }
00580 
00581 KUrl KFileDialog::baseUrl() const
00582 {
00583     if (d->native)
00584         return selectedUrl().isEmpty() ? KUrl() : KUrl::fromPath(selectedUrl().path());
00585     return d->w->baseUrl();
00586 }
00587 
00588 QString KFileDialog::getSaveFileName(const KUrl& dir, const QString& filter,
00589                                      QWidget *parent,
00590                                      const QString& caption)
00591 {
00592     if (KFileDialogPrivate::isNative()) {
00593         bool defaultDir = dir.isEmpty();
00594         bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00595         KUrl startDir;
00596         QString recentDirClass;
00597         if (specialDir) {
00598           startDir = KFileDialog::getStartUrl(dir, recentDirClass);
00599         }
00600         else if ( !specialDir && !defaultDir ) {
00601           if (!dir.isLocalFile())
00602               kWarning() << "non-local start dir " << dir;
00603           startDir = dir;
00604         }
00605 
00606         const QString result = QFileDialog::getSaveFileName(
00607             parent,
00608             caption.isEmpty() ? i18n("Save As") : caption,
00609             KFileDialogPrivate::Native::staticStartDir( startDir ).path(),
00610             qtFilter(filter) );
00611 // TODO use extra args?     QString * selectedFilter = 0, Options options = 0
00612         if (!result.isEmpty()) {
00613             if (!recentDirClass.isEmpty())
00614                 KRecentDirs::add(recentDirClass, KUrl::fromPath(result).url());
00615             KRecentDocument::add(result);
00616         }
00617         return result;
00618     }
00619     bool defaultDir = dir.isEmpty();
00620     bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00621     KFileDialog dlg( specialDir ? dir : KUrl(), filter, parent);
00622     if ( !specialDir && !defaultDir ) {
00623         if (!dir.isLocalFile())
00624             kWarning() << "KFileDialog::getSaveFileName called with non-local start dir " << dir;
00625         dlg.setSelection( dir.path() ); // may also be a filename
00626     }
00627 
00628     dlg.setOperationMode( Saving );
00629     dlg.setMode( KFile::File );
00630     dlg.setCaption(caption.isEmpty() ? i18n("Save As") : caption);
00631 
00632     dlg.exec();
00633 
00634     QString filename = dlg.selectedFile();
00635     if (!filename.isEmpty())
00636         KRecentDocument::add(filename);
00637 
00638     return filename;
00639 }
00640 
00641 QString KFileDialog::getSaveFileNameWId(const KUrl& dir, const QString& filter,
00642                                      WId parent_id,
00643                                      const QString& caption)
00644 {
00645     if (KFileDialogPrivate::isNative()) {
00646         return KFileDialog::getSaveFileName(dir, filter, 0, caption); // everything we can do...
00647     }
00648     bool defaultDir = dir.isEmpty();
00649     bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00650     QWidget* parent = QWidget::find( parent_id );
00651     KFileDialog dlg( specialDir ? dir : KUrl(), filter, parent);
00652 #ifdef Q_WS_X11
00653     if( parent == NULL && parent_id != 0 )
00654         XSetTransientForHint(QX11Info::display(), dlg.winId(), parent_id);
00655 #else
00656     // TODO
00657 #endif
00658 
00659     if ( !specialDir && !defaultDir ) {
00660         if (!dir.isLocalFile())
00661             kWarning() << "KFileDialog::getSaveFileNameWId called with non-local start dir " << dir;
00662         dlg.setSelection( dir.path() ); // may also be a filename
00663     }
00664 
00665     dlg.setOperationMode( Saving );
00666     dlg.setMode( KFile::File );
00667     dlg.setCaption(caption.isEmpty() ? i18n("Save As") : caption);
00668 
00669     dlg.exec();
00670 
00671     QString filename = dlg.selectedFile();
00672     if (!filename.isEmpty())
00673         KRecentDocument::add(filename);
00674 
00675     return filename;
00676 }
00677 
00678 KUrl KFileDialog::getSaveUrl(const KUrl& dir, const QString& filter,
00679                              QWidget *parent, const QString& caption)
00680 {
00681     if (KFileDialogPrivate::isNative() && (!dir.isValid() || dir.isLocalFile())) {
00682         const QString fileName( KFileDialog::getSaveFileName(
00683             dir.path(), filter, parent, caption) );
00684         return fileName.isEmpty() ? KUrl() : KUrl::fromPath(fileName);
00685     }
00686     bool defaultDir = dir.isEmpty();
00687     bool specialDir = !defaultDir && dir.protocol() == "kfiledialog";
00688     KFileDialog dlg(specialDir ? dir : KUrl(), filter, parent);
00689     if ( !specialDir )
00690         dlg.setSelection( dir.url() ); // may also be a filename
00691 
00692     dlg.setCaption(caption.isEmpty() ? i18n("Save As") : caption);
00693     dlg.setOperationMode( Saving );
00694     dlg.setMode( KFile::File );
00695 
00696     dlg.exec();
00697 
00698     KUrl url = dlg.selectedUrl();
00699     if (url.isValid())
00700         KRecentDocument::add( url );
00701 
00702     return url;
00703 }
00704 
00705 void KFileDialog::setMode( KFile::Modes m )
00706 {
00707     if (d->native)
00708         d->native->mode = m;
00709     else
00710         d->w->setMode(m);
00711 }
00712 
00713 KFile::Modes KFileDialog::mode() const
00714 {
00715     if (d->native)
00716         return d->native->mode;
00717     return d->w->mode();
00718 }
00719 
00720 KPushButton * KFileDialog::okButton() const
00721 {
00722     return d->w->okButton();
00723 }
00724 
00725 KPushButton * KFileDialog::cancelButton() const
00726 {
00727     return d->w->cancelButton();
00728 }
00729 
00730 KUrlComboBox* KFileDialog::locationEdit() const
00731 {
00732     return d->w->locationEdit();
00733 }
00734 
00735 KFileFilterCombo* KFileDialog::filterWidget() const
00736 {
00737     return d->w->filterWidget();
00738 }
00739 
00740 KActionCollection * KFileDialog::actionCollection() const
00741 {
00742     return d->w->actionCollection();
00743 }
00744 
00745 void KFileDialog::setKeepLocation( bool keep )
00746 {
00747     if (d->native)
00748         return;
00749     d->w->setKeepLocation(keep);
00750 }
00751 
00752 bool KFileDialog::keepsLocation() const
00753 {
00754     if (d->native)
00755         return false;
00756     return d->w->keepsLocation();
00757 }
00758 
00759 void KFileDialog::setOperationMode( OperationMode mode )
00760 {
00761     if (d->native)
00762         d->native->operationMode = static_cast<KAbstractFileWidget::OperationMode>(mode);
00763     else
00764         d->w->setOperationMode(static_cast<KAbstractFileWidget::OperationMode>(mode));
00765 }
00766 
00767 KFileDialog::OperationMode KFileDialog::operationMode() const
00768 {
00769     if (d->native)
00770         return static_cast<KFileDialog::OperationMode>(d->native->operationMode);
00771     return static_cast<KFileDialog::OperationMode>(d->w->operationMode());
00772 }
00773 
00774 void KFileDialog::keyPressEvent( QKeyEvent *e )
00775 {
00776     if (d->native)
00777         return;
00778 
00779     if ( e->key() == Qt::Key_Escape )
00780     {
00781         e->accept();
00782         d->w->cancelButton()->animateClick();
00783     }
00784     else
00785         KDialog::keyPressEvent( e );
00786 }
00787 
00788 void KFileDialog::hideEvent( QHideEvent *e )
00789 {
00790     if (d->native)
00791         return;
00792 
00793     saveDialogSize(d->cfgGroup, KConfigBase::Persistent);
00794 
00795     KDialog::hideEvent( e );
00796 }
00797 
00798 // static
00799 KUrl KFileDialog::getStartUrl( const KUrl& startDir,
00800                                QString& recentDirClass )
00801 {
00802     return fileModule()->getStartUrl(startDir, recentDirClass);
00803 }
00804 
00805 void KFileDialog::setStartDir( const KUrl& directory )
00806 {
00807     if (KFileDialogPrivate::isNative())
00808         KFileDialogPrivate::Native::s_startDir = directory;
00809     fileModule()->setStartDir(directory);
00810 }
00811 
00812 KToolBar * KFileDialog::toolBar() const
00813 {
00814     return d->w->toolBar();
00815 }
00816 
00817 KAbstractFileWidget* KFileDialog::fileWidget()
00818 {
00819     return d->w;
00820 }
00821 
00822 #ifdef Q_WS_WIN
00823 int KFileDialog::exec()
00824 {
00825     if (!d->native)
00826       return QDialog::exec();
00827 
00828 //    d->native->selectedUrls.clear();
00829     switch (d->native->operationMode) {
00830     case KAbstractFileWidget::Opening:
00831     case KAbstractFileWidget::Other:
00832         if (d->native->mode & KFile::File) {
00833             KUrl url( KFileDialog::getOpenUrl(
00834                d->native->startDir(), d->native->filter, parentWidget(), windowTitle()) );
00835             if (url.isEmpty() || !url.isValid())
00836                 return QDialog::Rejected;
00837             d->native->selectedUrls.append(url);
00838             return QDialog::Accepted;
00839         }
00840         else if (d->native->mode & KFile::Files) {
00841             KUrl::List urls( KFileDialog::getOpenUrls(
00842                 d->native->startDir(), d->native->filter, parentWidget(), windowTitle()) );
00843             if (urls.isEmpty())
00844                 return QDialog::Rejected;
00845             d->native->selectedUrls = urls;
00846             return QDialog::Accepted;
00847         }
00848         else if (d->native->mode & KFile::Directory) {
00849             KUrl url( KFileDialog::getExistingDirectoryUrl(
00850                 d->native->startDir(), parentWidget(), windowTitle()) );
00851             if (url.isEmpty() || !url.isValid())
00852                 return QDialog::Rejected;
00853             d->native->selectedUrls.append(url);
00854             return QDialog::Accepted;
00855         }
00856         break;
00857     case KAbstractFileWidget::Saving:
00858         if (d->native->mode & KFile::File) {
00859             KUrl url( KFileDialog::getSaveUrl(
00860                 d->native->startDir(), d->native->filter, parentWidget(), windowTitle()) );
00861             if (url.isEmpty() || !url.isValid())
00862                 return QDialog::Rejected;
00863             d->native->selectedUrls.append(url);
00864             return QDialog::Accepted;
00865         }
00866         else if (d->native->mode & KFile::Directory) {
00867             KUrl url( KFileDialog::getExistingDirectoryUrl(
00868                 d->native->startDir(), parentWidget(), windowTitle()) );
00869             if (url.isEmpty() || !url.isValid())
00870                 return QDialog::Rejected;
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.4
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