diff --git a/src/kio/kfiledialog.cpp b/src/kio/kfiledialog.cpp index 9b5f4fa4..6ade38fd 100644 --- a/src/kio/kfiledialog.cpp +++ b/src/kio/kfiledialog.cpp @@ -1,1067 +1,1077 @@ // -*- c++ -*- /* This file is part of the KDE libraries Copyright (C) 1997, 1998 Richard Moore 1998 Stephan Kulow 1998 Daniel Grana 1999,2000,2001,2002,2003 Carsten Pfeiffer 2003 Clarence Dang 2008 JarosÅ‚aw Staniek 2009 David Jarvie This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kfiledialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kfilewidget.h" #include "krecentdirs.h" #include "kservice.h" #include #include //From defaults-kfile.h in KIOFileWidgets #define ConfigGroup QLatin1String("KFileDialog Settings") /** File dialogs are native by default on Windows. */ #if defined(Q_OS_WIN) const bool NATIVE_FILEDIALOGS_BY_DEFAULT = true; #else const bool NATIVE_FILEDIALOGS_BY_DEFAULT = false; #endif static QStringList mime2KdeFilter(const QStringList &mimeTypes, QString *allExtensions = nullptr) { QMimeDatabase db; QStringList kdeFilter; QStringList allExt; foreach (const QString &mimeType, mimeTypes) { QMimeType mime(db.mimeTypeForName(mimeType)); if (mime.isValid()) { allExt += mime.globPatterns(); kdeFilter.append(mime.globPatterns().join(QLatin1String(" ")) + QLatin1Char('|') + mime.comment()); } } if (allExtensions) { allExt.sort(); *allExtensions = allExt.join(QLatin1String(" ")); } return kdeFilter; } /** @return File dialog filter in Qt format for @a filters * or "All files (*)" for empty list. */ static QString qtFilter(const QStringList &_filters) { QString converted; const QStringList filters = _filters; foreach (const QString ¤t, filters) { QString new_f; //filter part QString new_name; //filter name part int p = current.indexOf('|'); if (p == -1) { new_f = current; new_name = current; // nothing better found } else { new_f = current.left(p); new_name = current.mid(p + 1); } //Qt filters assume anything in () is the file extension list new_name = new_name.replace('(', '[').replace(')', ']').trimmed(); //convert everything to lower case and remove dupes (doesn't matter on win32) QStringList allfiltersUnique; const QStringList origList(new_f.split(' ', QString::SkipEmptyParts)); foreach (const QString &origFilter, origList) { if (!allfiltersUnique.contains(origFilter, Qt::CaseInsensitive)) { allfiltersUnique += origFilter.toLower(); } } if (!converted.isEmpty()) { converted += ";;"; } converted += (new_name + " (" + allfiltersUnique.join(" ") + QLatin1Char(')')); } // Strip escape characters from escaped '/' characters. converted.replace("\\/", "/"); return converted; } /** @return File dialog filter in Qt format for @a filter in KDE format * or "All files (*)" for empty filter. */ static QString qtFilter(const QString &filter) { // Qt format: "some text (*.first *.second)" or "All files (*)" separated by ;; // KDE format: "*.first *.second|Description" or "*|Description", separated by \n (Description is optional) QStringList filters; if (filter.isEmpty()) { filters += i18n("*|All files"); } else { // check if it's a mimefilter int pos = filter.indexOf('/'); if (pos > 0 && filter[pos - 1] != '\\') { filters = mime2KdeFilter(filter.split(QLatin1Char(' '), QString::SkipEmptyParts)); } else { filters = filter.split('\n', QString::SkipEmptyParts); } } return qtFilter(filters); } class KFileDialogPrivate { public: /** Data used for native mode. */ class Native { public: Native() : mode(KFile::File), operationMode(KFileWidget::Opening) { } /** @return previously set (global) start dir or the first url selected using setSelection() or setUrl() if the start dir is empty. */ QUrl startDir() const { if (!s_startDir.isEmpty()) { return s_startDir; } if (!selectedUrls.isEmpty()) { return selectedUrls.first(); } return QUrl(); } /** @return previously set (global) start dir or @p defaultDir if the start dir is empty. */ static QUrl staticStartDir(const QUrl &defaultDir) { if (s_startDir.isEmpty()) { return defaultDir; } return s_startDir; } static QUrl s_startDir; static bool s_allowNative; // as fallback when we can't use native dialog QString filter; QString selectedFilter; QStringList mimeTypes; QList selectedUrls; KFile::Modes mode; KFileWidget::OperationMode operationMode; }; KFileDialogPrivate() : native(nullptr), w(nullptr), cfgGroup(KSharedConfig::openConfig(), ConfigGroup) { if (cfgGroup.readEntry("Native", NATIVE_FILEDIALOGS_BY_DEFAULT) && KFileDialogPrivate::Native::s_allowNative) { native = new Native; } } static bool isNative() { if (!KFileDialogPrivate::Native::s_allowNative) { return false; } KConfigGroup cfgGroup(KSharedConfig::openConfig(), ConfigGroup); return cfgGroup.readEntry("Native", NATIVE_FILEDIALOGS_BY_DEFAULT); } static QString getOpenFileName(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption, QString *selectedFilter); static QUrl getOpenUrl(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption, QString *selectedFilter); static QStringList getOpenFileNames(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption, QString *selectedFilter); static QList getOpenUrls(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption, QString *selectedFilter); static QString getSaveFileName(const QUrl &dir, const QString &filter, QWidget *parent, const QString &caption, KFileDialog::Options options, QString *selectedFilter); static QUrl getSaveUrl(const QUrl &dir, const QString &filter, QWidget *parent, const QString &caption, KFileDialog::Options options, QString *selectedFilter); ~KFileDialogPrivate() { delete native; } Native *native; KFileWidget *w; KConfigGroup cfgGroup; }; QUrl KFileDialogPrivate::Native::s_startDir; bool KFileDialogPrivate::Native::s_allowNative = true; KFileDialog::KFileDialog(const QUrl &startDir, const QString &filter, QWidget *parent, QWidget *customWidget) #ifdef Q_OS_WIN : QDialog(parent, Qt::WindowMinMaxButtonsHint), #else : QDialog(parent), #endif d(new KFileDialogPrivate) { if (d->native) { KFileDialogPrivate::Native::s_startDir = startDir; // check if it's a mimefilter int pos = filter.indexOf('/'); if (pos > 0 && filter[pos - 1] != '\\') { setMimeFilter(filter.split(QLatin1Char(' '), QString::SkipEmptyParts)); } else { setFilter(filter); } return; } d->w = new KFileWidget(startDir, this); KFileWidget *fileQWidget = d->w; KWindowConfig::restoreWindowSize(windowHandle(), d->cfgGroup); // call this before the fileQWidget is set as the main widget. // otherwise the sizes for the components are not obeyed (ereslibre) d->w->setFilter(filter); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(fileQWidget); setLayout(layout); d->w->okButton()->show(); connect(d->w->okButton(), SIGNAL(clicked()), SLOT(slotOk())); d->w->cancelButton()->show(); connect(d->w->cancelButton(), SIGNAL(clicked()), SLOT(slotCancel())); // Publish signals connect(fileQWidget, SIGNAL(fileSelected(QUrl)), SIGNAL(fileSelected(QUrl))); connect(fileQWidget, SIGNAL(fileHighlighted(QUrl)), SIGNAL(fileHighlighted(QUrl))); connect(fileQWidget, SIGNAL(selectionChanged()), SIGNAL(selectionChanged())); connect(fileQWidget, SIGNAL(filterChanged(QString)), SIGNAL(filterChanged(QString))); connect(fileQWidget, SIGNAL(accepted()), SLOT(accept())); //connect(fileQWidget, SIGNAL(canceled()), SLOT(slotCancel())); if (customWidget) { d->w->setCustomWidget(QString(), customWidget); } } KFileDialog::~KFileDialog() { delete d; } void KFileDialog::setLocationLabel(const QString &text) { - if (d->native) { - return; // not available + if (d->w) { + d->w->setLocationLabel(text); } - d->w->setLocationLabel(text); } void KFileDialog::setFilter(const QString &filter) { if (d->native) { d->native->filter = filter; return; } d->w->setFilter(filter); } QString KFileDialog::currentFilter() const { - if (d->native) { - return QString(); // not available + if (d->w) { + return d->w->currentFilter(); } - return d->w->currentFilter(); + return QString(); // not available } void KFileDialog::setMimeFilter(const QStringList &mimeTypes, const QString &defaultType) { - d->w->setMimeFilter(mimeTypes, defaultType); - if (d->native) { QString allExtensions; QStringList filters = mime2KdeFilter(mimeTypes, &allExtensions); if (defaultType.isEmpty() && (mimeTypes.count() > 1)) { filters.prepend(allExtensions + QLatin1Char('|') + i18n("All Supported Files")); } d->native->filter = filters.join(QLatin1String("\n")); + return; } + d->w->setMimeFilter(mimeTypes, defaultType); } void KFileDialog::clearFilter() { if (d->native) { d->native->filter.clear(); return; } d->w->clearFilter(); } QString KFileDialog::currentMimeFilter() const { if (d->native) { // adapted from qt2KdeFilter QString filter = d->native->selectedFilter.split(";;").replaceInStrings("/", "\\/")[0]; filter = filter.mid(filter.indexOf('(') + 1, filter.indexOf(')') - filter.indexOf('(') - 1); QMimeDatabase db; QString mimetype = db.mimeTypeForFile("test" + filter.mid(1).split(' ')[0], QMimeDatabase::MatchExtension).name(); return mimetype; } return d->w->currentMimeFilter(); } QMimeType KFileDialog::currentFilterMimeType() { QMimeDatabase db; return db.mimeTypeForName(currentMimeFilter()); } void KFileDialog::setPreviewWidget(KPreviewWidgetBase *w) { - if (d->native) { - return; + if (d->w) { + d->w->setPreviewWidget(w); } - d->w->setPreviewWidget(w); } void KFileDialog::setInlinePreviewShown(bool show) { - if (d->native) { - return; + if (d->w) { + d->w->setInlinePreviewShown(show); } - d->w->setInlinePreviewShown(show); } // This is only used for the initial size when no configuration has been saved QSize KFileDialog::sizeHint() const { - return d->w->dialogSizeHint(); + if (d->w) { + return d->w->dialogSizeHint(); + } + return QSize(); } // This slot still exists mostly for compat purposes; for subclasses which reimplement slotOk void KFileDialog::slotOk() { - if (d->native) { - return; + if (d->w) { + d->w->slotOk(); } - d->w->slotOk(); } // This slot still exists mostly for compat purposes; for subclasses which reimplement accept void KFileDialog::accept() { - if (d->native) { - return; + if (d->w) { + setResult(QDialog::Accepted); // keep old behavior; probably not needed though + d->w->accept(); + KConfigGroup cfgGroup(KSharedConfig::openConfig(), ConfigGroup); + QDialog::accept(); } - setResult(QDialog::Accepted); // keep old behavior; probably not needed though - d->w->accept(); - KConfigGroup cfgGroup(KSharedConfig::openConfig(), ConfigGroup); - QDialog::accept(); } // This slot still exists mostly for compat purposes; for subclasses which reimplement slotCancel void KFileDialog::slotCancel() { - if (d->native) { - return; + if (d->w) { + d->w->slotCancel(); + reject(); } - d->w->slotCancel(); - reject(); } void KFileDialog::setUrl(const QUrl &url, bool clearforward) { if (d->native) { d->native->selectedUrls.clear(); d->native->selectedUrls.append(url); return; } d->w->setUrl(url, clearforward); } void KFileDialog::setSelection(const QString &name) { if (d->native) { d->native->selectedUrls.clear(); d->native->selectedUrls.append(QUrl(name)); // could be relative return; } d->w->setSelection(name); } QString KFileDialog::getOpenFileName(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption) { return KFileDialogPrivate::getOpenFileName(startDir, filter, parent, caption, nullptr); } QString KFileDialogPrivate::getOpenFileName(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption, QString *selectedFilter) { if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) { return QFileDialog::getOpenFileName( parent, caption.isEmpty() ? i18n("Open") : caption, KFileDialogPrivate::Native::staticStartDir(startDir).toLocalFile(), qtFilter(filter), selectedFilter); // TODO use extra args? QString * selectedFilter = 0, Options options = 0 } KFileDialog dlg(startDir, filter, parent); dlg.setOperationMode(KFileDialog::Opening); dlg.setMode(KFile::File | KFile::LocalOnly | KFile::ExistingOnly); dlg.setWindowTitle(caption.isEmpty() ? i18n("Open") : caption); dlg.exec(); if (selectedFilter) { *selectedFilter = dlg.currentMimeFilter(); } return dlg.selectedFile(); } QString KFileDialog::getOpenFileNameWId(const QUrl &startDir, const QString &filter, WId parent_id, const QString &caption) { if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) { return KFileDialog::getOpenFileName(startDir, filter, nullptr, caption); // everything we can do... } QWidget *parent = QWidget::find(parent_id); KFileDialogPrivate::Native::s_allowNative = false; KFileDialog dlg(startDir, filter, parent); if (parent == nullptr && parent_id != 0) { KWindowSystem::setMainWindow(&dlg, parent_id); } dlg.setOperationMode(KFileDialog::Opening); dlg.setMode(KFile::File | KFile::LocalOnly | KFile::ExistingOnly); dlg.setWindowTitle(caption.isEmpty() ? i18n("Open") : caption); dlg.exec(); return dlg.selectedFile(); } QStringList KFileDialog::getOpenFileNames(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption) { return KFileDialogPrivate::getOpenFileNames(startDir, filter, parent, caption, nullptr); } QStringList KFileDialogPrivate::getOpenFileNames(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption, QString *selectedFilter) { if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) { return QFileDialog::getOpenFileNames( parent, caption.isEmpty() ? i18n("Open") : caption, KFileDialogPrivate::Native::staticStartDir(startDir).toLocalFile(), qtFilter(filter), selectedFilter); // TODO use extra args? QString * selectedFilter = 0, Options options = 0 } KFileDialogPrivate::Native::s_allowNative = false; KFileDialog dlg(startDir, filter, parent); dlg.setOperationMode(KFileDialog::Opening); dlg.setMode(KFile::Files | KFile::LocalOnly | KFile::ExistingOnly); dlg.setWindowTitle(caption.isEmpty() ? i18n("Open") : caption); dlg.exec(); if (selectedFilter) { *selectedFilter = dlg.currentMimeFilter(); } return dlg.selectedFiles(); } QUrl KFileDialog::getOpenUrl(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption) { return KFileDialogPrivate::getOpenUrl(startDir, filter, parent, caption, nullptr); } QUrl KFileDialogPrivate::getOpenUrl(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption, QString *selectedFilter) { if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) { const QString fileName(KFileDialogPrivate::getOpenFileName( startDir, filter, parent, caption, selectedFilter)); return fileName.isEmpty() ? QUrl() : QUrl::fromLocalFile(fileName); } KFileDialogPrivate::Native::s_allowNative = false; KFileDialog dlg(startDir, filter, parent); dlg.setOperationMode(KFileDialog::Opening); dlg.setMode(KFile::File | KFile::ExistingOnly); dlg.setWindowTitle(caption.isEmpty() ? i18n("Open") : caption); dlg.exec(); if (selectedFilter) { *selectedFilter = dlg.currentMimeFilter(); } return dlg.selectedUrl(); } QList KFileDialog::getOpenUrls(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption) { return KFileDialogPrivate::getOpenUrls(startDir, filter, parent, caption, nullptr); } QList KFileDialogPrivate::getOpenUrls(const QUrl &startDir, const QString &filter, QWidget *parent, const QString &caption, QString *selectedFilter) { if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) { const QStringList fileNames(KFileDialogPrivate::getOpenFileNames( startDir, filter, parent, caption, selectedFilter)); QList urls; Q_FOREACH (const QString &file, fileNames) { urls.append(QUrl::fromLocalFile(file)); } return urls; } KFileDialogPrivate::Native::s_allowNative = false; KFileDialog dlg(startDir, filter, parent); dlg.setOperationMode(KFileDialog::Opening); dlg.setMode(KFile::Files | KFile::ExistingOnly); dlg.setWindowTitle(caption.isEmpty() ? i18n("Open") : caption); dlg.exec(); if (selectedFilter) { *selectedFilter = dlg.currentMimeFilter(); } return dlg.selectedUrls(); } void KFileDialog::setConfirmOverwrite(bool enable) { - if (operationMode() == KFileDialog::Saving) { + if (d->w && operationMode() == KFileDialog::Saving) { d->w->setConfirmOverwrite(enable); } } QUrl KFileDialog::getExistingDirectoryUrl(const QUrl &startDir, QWidget *parent, const QString &caption) { return QFileDialog::getExistingDirectoryUrl(parent, caption, KFileDialogPrivate::Native::staticStartDir(startDir)); } QString KFileDialog::getExistingDirectory(const QUrl &startDir, QWidget *parent, const QString &caption) { if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) { return QFileDialog::getExistingDirectory(parent, caption, KFileDialogPrivate::Native::staticStartDir(startDir).toLocalFile(), QFileDialog::ShowDirsOnly); } QUrl url = KFileDialog::getExistingDirectoryUrl(startDir, parent, caption); if (url.isValid()) { return url.toLocalFile(); } return QString(); } QUrl KFileDialog::getImageOpenUrl(const QUrl &startDir, QWidget *parent, const QString &caption) { if (KFileDialogPrivate::isNative() && (!startDir.isValid() || startDir.isLocalFile())) { // everything we can do... const QStringList mimetypes(KImageIO::mimeTypes(KImageIO::Reading)); return KFileDialog::getOpenUrl(startDir, mimetypes.join(" "), parent, caption); } const QStringList mimetypes = KImageIO::mimeTypes(KImageIO::Reading); KFileDialogPrivate::Native::s_allowNative = false; KFileDialog dlg(startDir, mimetypes.join(" "), parent); dlg.setOperationMode(KFileDialog::Opening); dlg.setMode(KFile::File | KFile::ExistingOnly); dlg.setWindowTitle(caption.isEmpty() ? i18n("Open") : caption); dlg.setInlinePreviewShown(true); dlg.exec(); return dlg.selectedUrl(); } QUrl KFileDialog::selectedUrl() const { if (d->native) { return d->native->selectedUrls.isEmpty() ? QUrl() : d->native->selectedUrls.first(); } return d->w->selectedUrl(); } QList KFileDialog::selectedUrls() const { if (d->native) { return d->native->selectedUrls; } return d->w->selectedUrls(); } QString KFileDialog::selectedFile() const { if (d->native) { return selectedUrl().toLocalFile(); } return d->w->selectedFile(); } QStringList KFileDialog::selectedFiles() const { if (d->native) { QStringList lst; Q_FOREACH (const QUrl &u, selectedUrls()) { if (u.isLocalFile()) { lst.append(u.toLocalFile()); } } return lst; } return d->w->selectedFiles(); } QUrl KFileDialog::baseUrl() const { if (d->native) { return selectedUrl().isEmpty() ? QUrl() : QUrl::fromLocalFile(selectedUrl().path()); /* shouldn't that be .directory()? */ } return d->w->baseUrl(); } QString KFileDialog::getSaveFileName(const QUrl &dir, const QString &filter, QWidget *parent, const QString &caption) { //TODO KDE5: replace this method by the method below (with default parameter values in declaration) // Set no confirm-overwrite mode for backwards compatibility return KFileDialogPrivate::getSaveFileName(dir, filter, parent, caption, Options(nullptr), nullptr); } QString KFileDialog::getSaveFileName(const QUrl &dir, const QString &filter, QWidget *parent, const QString &caption, Options options) { return KFileDialogPrivate::getSaveFileName(dir, filter, parent, caption, options, nullptr); } QString KFileDialogPrivate::getSaveFileName(const QUrl &dir, const QString &filter, QWidget *parent, const QString &caption, KFileDialog::Options options, QString *selectedFilter) { if (KFileDialogPrivate::isNative()) { bool defaultDir = dir.isEmpty(); bool specialDir = !defaultDir && dir.scheme() == "kfiledialog"; QUrl startDir; QString recentDirClass; if (specialDir) { startDir = KFileDialog::getStartUrl(dir, recentDirClass); } else if (!specialDir && !defaultDir) { if (!dir.isLocalFile()) { qWarning() << "non-local start dir " << dir; } startDir = dir; } QFileDialog::Options opts = (options & KFileDialog::ConfirmOverwrite) ? QFileDialog::Options(nullptr) : QFileDialog::DontConfirmOverwrite; const QString result = QFileDialog::getSaveFileName( parent, caption.isEmpty() ? i18n("Save As") : caption, KFileDialogPrivate::Native::staticStartDir(startDir).toLocalFile(), qtFilter(filter), // TODO use extra args? QString * selectedFilter = 0, Options opts = 0 selectedFilter, opts); if (!result.isEmpty()) { if (!recentDirClass.isEmpty()) { KRecentDirs::add(recentDirClass, QUrl::fromLocalFile(result).toString()); } KRecentDocument::add(result); } return result; } KFileDialog dlg(dir, filter, parent); dlg.setOperationMode(KFileDialog::Saving); dlg.setMode(KFile::File | KFile::LocalOnly); dlg.setConfirmOverwrite(options & KFileDialog::ConfirmOverwrite); dlg.setInlinePreviewShown(options & KFileDialog::ShowInlinePreview); dlg.setWindowTitle(caption.isEmpty() ? i18n("Save As") : caption); dlg.exec(); QString filename = dlg.selectedFile(); if (!filename.isEmpty()) { KRecentDocument::add(filename); } return filename; } QString KFileDialog::getSaveFileNameWId(const QUrl &dir, const QString &filter, WId parent_id, const QString &caption) { //TODO KDE5: replace this method by the method below (with default parameter values in declaration) // Set no confirm-overwrite mode for backwards compatibility return getSaveFileNameWId(dir, filter, parent_id, caption, Options(nullptr)); } QString KFileDialog::getSaveFileNameWId(const QUrl &dir, const QString &filter, WId parent_id, const QString &caption, Options options) { if (KFileDialogPrivate::isNative()) { return KFileDialog::getSaveFileName(dir, filter, nullptr, caption, options); // everything we can do... } QWidget *parent = QWidget::find(parent_id); KFileDialog dlg(dir, filter, parent); if (parent == nullptr && parent_id != 0) { KWindowSystem::setMainWindow(&dlg, parent_id); } dlg.setOperationMode(KFileDialog::Saving); dlg.setMode(KFile::File | KFile::LocalOnly); dlg.setConfirmOverwrite(options & ConfirmOverwrite); dlg.setInlinePreviewShown(options & ShowInlinePreview); dlg.setWindowTitle(caption.isEmpty() ? i18n("Save As") : caption); dlg.exec(); QString filename = dlg.selectedFile(); if (!filename.isEmpty()) { KRecentDocument::add(filename); } return filename; } QUrl KFileDialog::getSaveUrl(const QUrl &dir, const QString &filter, QWidget *parent, const QString &caption) { //TODO KDE5: replace this method by the method below (with default parameter values in declaration) // Set no confirm-overwrite mode for backwards compatibility return KFileDialogPrivate::getSaveUrl(dir, filter, parent, caption, Options(nullptr), nullptr); } QUrl KFileDialog::getSaveUrl(const QUrl &dir, const QString &filter, QWidget *parent, const QString &caption, Options options) { return KFileDialogPrivate::getSaveUrl(dir, filter, parent, caption, options, nullptr); } QUrl KFileDialogPrivate::getSaveUrl(const QUrl &dir, const QString &filter, QWidget *parent, const QString &caption, KFileDialog::Options options, QString *selectedFilter) { if (KFileDialogPrivate::isNative() && (!dir.isValid() || dir.isLocalFile())) { const QString fileName(KFileDialogPrivate::getSaveFileName( dir, filter, parent, caption, options, selectedFilter)); return fileName.isEmpty() ? QUrl() : QUrl::fromLocalFile(fileName); } KFileDialogPrivate::Native::s_allowNative = false; KFileDialog dlg(dir, filter, parent); dlg.setOperationMode(KFileDialog::Saving); dlg.setMode(KFile::File); dlg.setConfirmOverwrite(options & KFileDialog::ConfirmOverwrite); dlg.setInlinePreviewShown(options & KFileDialog::ShowInlinePreview); dlg.setWindowTitle(caption.isEmpty() ? i18n("Save As") : caption); dlg.exec(); if (selectedFilter) { *selectedFilter = dlg.currentMimeFilter(); } QUrl url = dlg.selectedUrl(); if (url.isValid()) { KRecentDocument::add(url); } return url; } void KFileDialog::setMode(KFile::Modes m) { if (d->native) { d->native->mode = m; } else { d->w->setMode(m); } } KFile::Modes KFileDialog::mode() const { if (d->native) { return d->native->mode; } return d->w->mode(); } QPushButton *KFileDialog::okButton() const { - return d->w->okButton(); + if (d->w) { + return d->w->okButton(); + } + return nullptr; } QPushButton *KFileDialog::cancelButton() const { - return d->w->cancelButton(); + if (d->w) { + return d->w->cancelButton(); + } + return nullptr; } KUrlComboBox *KFileDialog::locationEdit() const { - return d->w->locationEdit(); + if (d->w) { + return d->w->locationEdit(); + } + return nullptr; } KFileFilterCombo *KFileDialog::filterWidget() const { - return d->w->filterWidget(); + if (d->w) { + return d->w->filterWidget(); + } + return nullptr; } KActionCollection *KFileDialog::actionCollection() const { - return d->w->actionCollection(); + if (d->w) { + return d->w->actionCollection(); + } + return nullptr; } void KFileDialog::setKeepLocation(bool keep) { - if (d->native) { - return; + if (d->w) { + d->w->setKeepLocation(keep); } - d->w->setKeepLocation(keep); } bool KFileDialog::keepsLocation() const { - if (d->native) { - return false; + if (d->w) { + return d->w->keepsLocation(); } - return d->w->keepsLocation(); + return false; } void KFileDialog::setOperationMode(OperationMode mode) { if (d->native) { d->native->operationMode = static_cast(mode); } else { d->w->setOperationMode(static_cast(mode)); } } KFileDialog::OperationMode KFileDialog::operationMode() const { if (d->native) { return static_cast(d->native->operationMode); } return static_cast(d->w->operationMode()); } void KFileDialog::keyPressEvent(QKeyEvent *e) { - if (d->native) { - return; - } - - if (e->key() == Qt::Key_Escape) { - e->accept(); - d->w->cancelButton()->animateClick(); - } else { - QDialog::keyPressEvent(e); + if (d->w) { + if (e->key() == Qt::Key_Escape) { + e->accept(); + d->w->cancelButton()->animateClick(); + } else { + QDialog::keyPressEvent(e); + } } } void KFileDialog::hideEvent(QHideEvent *e) { - if (d->native) { - return; - } - - KWindowConfig::saveWindowSize(windowHandle(), d->cfgGroup, KConfigBase::Persistent); + if (d->w) { + KWindowConfig::saveWindowSize(windowHandle(), d->cfgGroup, KConfigBase::Persistent); - QDialog::hideEvent(e); + QDialog::hideEvent(e); + } } // static QUrl KFileDialog::getStartUrl(const QUrl &startDir, QString &recentDirClass) { return KFileWidget::getStartUrl(startDir, recentDirClass); } void KFileDialog::setStartDir(const QUrl &directory) { if (KFileDialogPrivate::isNative()) { KFileDialogPrivate::Native::s_startDir = directory; } KFileWidget::setStartDir(directory); } KToolBar *KFileDialog::toolBar() const { - return d->w->toolBar(); + if (d->w) { + return d->w->toolBar(); + } + return nullptr; } KFileWidget *KFileDialog::fileWidget() { return d->w; } #ifdef Q_OS_WIN int KFileDialog::exec() { if (!d->native || !KFileDialogPrivate::Native::s_allowNative) { KFileDialogPrivate::Native::s_allowNative = true; return QDialog::exec(); } // not clear here to let KFileDialogPrivate::Native::startDir() return a useful value // d->native->selectedUrls.clear(); int res = QDialog::Rejected; switch (d->native->operationMode) { case KFileWidget::Opening: case KFileWidget::Other: if (d->native->mode & KFile::File) { QUrl url(KFileDialogPrivate::getOpenUrl( d->native->startDir(), d->native->filter, parentWidget(), windowTitle(), &d->native->selectedFilter)); if (url.isEmpty() || !url.isValid()) { res = QDialog::Rejected; break; } d->native->selectedUrls.clear(); d->native->selectedUrls.append(url); res = QDialog::Accepted; break; } else if (d->native->mode & KFile::Files) { QList urls(KFileDialogPrivate::getOpenUrls( d->native->startDir(), d->native->filter, parentWidget(), windowTitle(), &d->native->selectedFilter)); if (urls.isEmpty()) { res = QDialog::Rejected; break; } d->native->selectedUrls = urls; res = QDialog::Accepted; break; } else if (d->native->mode & KFile::Directory) { QUrl url(KFileDialog::getExistingDirectoryUrl( d->native->startDir(), parentWidget(), windowTitle())); if (url.isEmpty() || !url.isValid()) { res = QDialog::Rejected; break; } d->native->selectedUrls.clear(); d->native->selectedUrls.append(url); res = QDialog::Accepted; break; } break; case KFileWidget::Saving: if (d->native->mode & KFile::File) { QUrl url(KFileDialogPrivate::getSaveUrl( d->native->startDir(), d->native->filter, parentWidget(), windowTitle(), Options(0), &d->native->selectedFilter)); if (url.isEmpty() || !url.isValid()) { res = QDialog::Rejected; break; } d->native->selectedUrls.clear(); d->native->selectedUrls.append(url); res = QDialog::Accepted; break; } else if (d->native->mode & KFile::Directory) { QUrl url(KFileDialog::getExistingDirectoryUrl( d->native->startDir(), parentWidget(), windowTitle())); if (url.isEmpty() || !url.isValid()) { res = QDialog::Rejected; break; } d->native->selectedUrls.clear(); d->native->selectedUrls.append(url); res = QDialog::Accepted; break; } break; default:; } setResult(res); emit finished(res); if (res == QDialog::Accepted) { emit accepted(); } else { emit rejected(); } return res; } #endif // Q_OS_WIN #include "moc_kfiledialog.cpp"