File indexing completed on 2025-01-05 04:55:48

0001 /* -*- mode: c++; c-basic-offset:4 -*-
0002     ui/filenamerequester.cpp
0003 
0004     This file is part of Kleopatra, the KDE keymanager
0005     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include <config-libkleo.h>
0011 
0012 #include "filenamerequester.h"
0013 
0014 #include <KLocalizedString>
0015 
0016 #include <QCompleter>
0017 #include <QEvent>
0018 #include <QFileDialog>
0019 #include <QFileSystemModel>
0020 #include <QHBoxLayout>
0021 #include <QLineEdit>
0022 #include <QString>
0023 #include <QToolButton>
0024 
0025 using namespace Kleo;
0026 
0027 class Q_DECL_HIDDEN FileNameRequester::FileNameRequesterPrivate
0028 {
0029     friend class ::Kleo::FileNameRequester;
0030     FileNameRequester *const q;
0031 
0032 public:
0033     explicit FileNameRequesterPrivate(FileNameRequester *qq);
0034     ~FileNameRequesterPrivate();
0035 
0036 private:
0037     void slotButtonClicked();
0038 
0039 private:
0040 #ifndef QT_NO_DIRMODEL
0041     QFileSystemModel dirmodel;
0042     QCompleter completer;
0043 #else
0044     QDir::Filters filter;
0045 #endif
0046 
0047     QLineEdit lineedit;
0048     QToolButton button;
0049     QHBoxLayout hlay;
0050 
0051     QString nameFilter;
0052     bool existingOnly;
0053 };
0054 
0055 FileNameRequester::FileNameRequesterPrivate::FileNameRequesterPrivate(FileNameRequester *qq)
0056     : q(qq)
0057     ,
0058 #ifndef QT_NO_DIRMODEL
0059     dirmodel()
0060     , completer(&dirmodel)
0061     ,
0062 #else
0063     filter()
0064     ,
0065 #endif
0066     lineedit(q)
0067     , button(q)
0068     , hlay(q)
0069     , nameFilter()
0070     , existingOnly(true)
0071 {
0072 #ifndef QT_NO_DIRMODEL
0073     dirmodel.setObjectName(QLatin1StringView("dirmodel"));
0074     completer.setObjectName(QLatin1StringView("completer"));
0075 #endif
0076     lineedit.setObjectName(QLatin1StringView("lineedit"));
0077     button.setObjectName(QLatin1StringView("button"));
0078     hlay.setObjectName(QLatin1StringView("hlay"));
0079 
0080     button.setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
0081     button.setToolTip(i18n("Open file dialog"));
0082     button.setAccessibleName(i18n("Open file dialog"));
0083 #ifndef QT_NO_DIRMODEL
0084     lineedit.setCompleter(&completer);
0085 #endif
0086     lineedit.setClearButtonEnabled(true);
0087     hlay.setContentsMargins(0, 0, 0, 0);
0088     hlay.addWidget(&lineedit);
0089     hlay.addWidget(&button);
0090     q->setFocusPolicy(lineedit.focusPolicy());
0091     q->setFocusProxy(&lineedit);
0092 
0093     connect(&button, &QToolButton::clicked, q, [this]() {
0094         slotButtonClicked();
0095     });
0096     connect(&lineedit, &QLineEdit::textChanged, q, &FileNameRequester::fileNameChanged);
0097 }
0098 
0099 FileNameRequester::FileNameRequesterPrivate::~FileNameRequesterPrivate()
0100 {
0101 }
0102 
0103 FileNameRequester::FileNameRequester(QWidget *p)
0104     : QWidget(p)
0105     , d(new FileNameRequesterPrivate(this))
0106 {
0107 }
0108 
0109 FileNameRequester::FileNameRequester(QDir::Filters f, QWidget *p)
0110     : QWidget(p)
0111     , d(new FileNameRequesterPrivate(this))
0112 {
0113 #ifndef QT_NO_DIRMODEL
0114     d->dirmodel.setFilter(f);
0115 #else
0116     d->filter = f;
0117 #endif
0118 }
0119 
0120 FileNameRequester::~FileNameRequester() = default;
0121 
0122 void FileNameRequester::setFileName(const QString &file)
0123 {
0124     d->lineedit.setText(file);
0125 }
0126 
0127 QString FileNameRequester::fileName() const
0128 {
0129     return d->lineedit.text();
0130 }
0131 
0132 void FileNameRequester::setExistingOnly(bool on)
0133 {
0134     d->existingOnly = on;
0135 }
0136 
0137 bool FileNameRequester::existingOnly() const
0138 {
0139     return d->existingOnly;
0140 }
0141 
0142 void FileNameRequester::setFilter(QDir::Filters f)
0143 {
0144 #ifndef QT_NO_DIRMODEL
0145     d->dirmodel.setFilter(f);
0146 #else
0147     d->filter = f;
0148 #endif
0149 }
0150 
0151 QDir::Filters FileNameRequester::filter() const
0152 {
0153 #ifndef QT_NO_DIRMODEL
0154     return d->dirmodel.filter();
0155 #else
0156     return d->filter;
0157 #endif
0158 }
0159 
0160 void FileNameRequester::setNameFilter(const QString &nameFilter)
0161 {
0162     d->nameFilter = nameFilter;
0163 }
0164 
0165 QString FileNameRequester::nameFilter() const
0166 {
0167     return d->nameFilter;
0168 }
0169 
0170 void FileNameRequester::setAccessibleNameOfLineEdit(const QString &name)
0171 {
0172     d->lineedit.setAccessibleName(name);
0173 }
0174 
0175 void FileNameRequester::FileNameRequesterPrivate::slotButtonClicked()
0176 {
0177     const QString fileName = q->requestFileName();
0178     if (!fileName.isEmpty()) {
0179         q->setFileName(fileName);
0180     }
0181 }
0182 
0183 bool FileNameRequester::event(QEvent *e)
0184 {
0185     if (e->type() == QEvent::ToolTipChange) {
0186         d->lineedit.setToolTip(toolTip());
0187     }
0188     return QWidget::event(e);
0189 }
0190 
0191 QString FileNameRequester::requestFileName()
0192 {
0193 #ifndef QT_NO_FILEDIALOG
0194     const QDir::Filters filters = filter();
0195     if ((filters & QDir::Dirs) && !(filters & QDir::Files)) {
0196         return QFileDialog::getExistingDirectory(this);
0197     } else if (d->existingOnly) {
0198         return QFileDialog::getOpenFileName(this, QString(), QString(), d->nameFilter);
0199     } else {
0200         return QFileDialog::getSaveFileName(this, QString(), fileName(), d->nameFilter);
0201     }
0202 #else
0203     return QString();
0204 #endif
0205 }
0206 
0207 #include "moc_filenamerequester.cpp"