File indexing completed on 2024-05-12 16:40:55

0001 /* This file is part of the KDE project
0002    Copyright (C) 2003-2018 Jarosław Staniek <staniek@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "KexiFileWidgetInterface.h"
0021 #include <kexiutils/utils.h>
0022 #include "KexiFileRequester.h"
0023 
0024 #include <KLocalizedString>
0025 #include <KMessageBox>
0026 
0027 #ifdef KEXI_USE_KFILEWIDGET
0028 #include "KexiFileWidget.h"
0029 
0030 #include <KConfigGroup>
0031 #include <KSharedConfig>
0032 #endif
0033 
0034 #include <QDir>
0035 
0036 //! @internal
0037 class Q_DECL_HIDDEN KexiFileWidgetInterface::Private
0038 {
0039 public:
0040     Private()
0041     {
0042     }
0043 
0044     QUrl startUrl;
0045     KexiFileFilters filters;
0046     QString defaultExtension;
0047     bool confirmOverwrites = true;
0048     bool filtersUpdated = false;
0049     QString highlightedName;
0050     QString recentDirClass;
0051 };
0052 
0053 //------------------
0054 
0055 KexiFileWidgetInterface::KexiFileWidgetInterface(const QUrl &startDirOrVariable,
0056                                                  const QString &fileName)
0057     : d(new Private)
0058 {
0059     if (startDirOrVariable.scheme() == "kfiledialog") {
0060         d->startUrl = KexiUtils::getStartUrl(startDirOrVariable, &d->recentDirClass, fileName);
0061     } else if (fileName.isEmpty()) {
0062         d->startUrl = startDirOrVariable;
0063     } else {
0064         d->startUrl = startDirOrVariable;
0065         d->startUrl.setPath(startDirOrVariable.path() + '/' + fileName);
0066     }
0067 }
0068 
0069 KexiFileWidgetInterface::~KexiFileWidgetInterface()
0070 {
0071     delete d;
0072 }
0073 
0074 QUrl KexiFileWidgetInterface::startUrl() const
0075 {
0076     return d->startUrl;
0077 }
0078 
0079 void KexiFileWidgetInterface::addRecentDir(const QString &name)
0080 {
0081     if (!d->recentDirClass.isEmpty() && QDir(name).exists()) {
0082         KexiUtils::addRecentDir(d->recentDirClass, name);
0083     }
0084 }
0085 
0086 void KexiFileWidgetInterface::done()
0087 {
0088     qDebug() << d->recentDirClass;
0089     if (!d->recentDirClass.isEmpty()) {
0090         QString f = selectedFile();
0091         QString dir;
0092         if (f.isEmpty()) {
0093             dir = currentDir();
0094         }
0095         else {
0096             QFileInfo fi(f);
0097             QString dirStr = fi.isDir() ? fi.absoluteFilePath() : fi.dir().absolutePath();
0098             dir = dirStr;
0099         }
0100         qDebug() << dir;
0101         qDebug() << selectedFile();
0102         addRecentDir(dir);
0103     }
0104 }
0105 
0106 // static
0107 KexiFileWidgetInterface *KexiFileWidgetInterface::createWidget(const QUrl &startDirOrVariable,
0108                                                                KexiFileFilters::Mode mode,
0109                                                                const QString &fileName,
0110                                                                QWidget *parent)
0111 {
0112 #ifdef KEXI_USE_KFILEWIDGET
0113     bool useKFileWidget;
0114     KConfigGroup group =  KSharedConfig::openConfig()->group("File Dialogs");
0115     if (group.hasKey("UseKFileWidget")) { // allow to override
0116         useKFileWidget = group.readEntry("UseKFileWidget", false);
0117     } else {
0118         useKFileWidget = KexiUtils::isKDEDesktopSession();
0119     }
0120     if (useKFileWidget) {
0121         return new KexiFileWidget(startDirOrVariable, mode, fileName, parent);
0122     }
0123 #endif
0124     return new KexiFileRequester(startDirOrVariable, mode, fileName, parent);
0125 }
0126 
0127 // static
0128 KexiFileWidgetInterface *KexiFileWidgetInterface::createWidget(const QUrl &startDirOrVariable,
0129                                                                KexiFileFilters::Mode mode,
0130                                                                QWidget *parent)
0131 {
0132     return KexiFileWidgetInterface::createWidget(startDirOrVariable, mode, QString(), parent);
0133 }
0134 
0135 KexiFileFilters::Mode KexiFileWidgetInterface::mode() const
0136 {
0137     return d->filters.mode();
0138 }
0139 
0140 void KexiFileWidgetInterface::setMode(KexiFileFilters::Mode mode)
0141 {
0142     //delayed
0143     d->filters.setMode(mode);
0144     d->filtersUpdated = false;
0145     updateFilters();
0146 }
0147 
0148 QStringList KexiFileWidgetInterface::additionalMimeTypes() const
0149 {
0150     return d->filters.additionalMimeTypes();
0151 }
0152 
0153 void KexiFileWidgetInterface::setAdditionalMimeTypes(const QStringList &mimeTypes)
0154 {
0155     d->filters.setAdditionalMimeTypes(mimeTypes);
0156     d->filtersUpdated = false;
0157 }
0158 
0159 QStringList KexiFileWidgetInterface::excludedMimeTypes() const
0160 {
0161     return d->filters.excludedMimeTypes();
0162 }
0163 
0164 void KexiFileWidgetInterface::setExcludedMimeTypes(const QStringList &mimeTypes)
0165 {
0166     d->filters.setExcludedMimeTypes(mimeTypes);
0167     d->filtersUpdated = false;
0168 }
0169 
0170 QString KexiFileWidgetInterface::defaultExtension() const
0171 {
0172     return d->defaultExtension;
0173 }
0174 
0175 void KexiFileWidgetInterface::setDefaultExtension(const QString& ext)
0176 {
0177     d->defaultExtension = ext;
0178 }
0179 
0180 bool KexiFileWidgetInterface::confirmOverwrites() const
0181 {
0182     return d->confirmOverwrites;
0183 }
0184 
0185 void KexiFileWidgetInterface::setConfirmOverwrites(bool set)
0186 {
0187     d->confirmOverwrites = set;
0188 }
0189 
0190 QString KexiFileWidgetInterface::currentDir() const
0191 {
0192     qFatal("Implement it");
0193     return QString();
0194 }
0195 
0196 void KexiFileWidgetInterface::setFiltersUpdated(bool set)
0197 {
0198     d->filtersUpdated = set;
0199 }
0200 
0201 bool KexiFileWidgetInterface::filtersUpdated() const
0202 {
0203     return d->filtersUpdated;
0204 }
0205 
0206 KexiFileFilters* KexiFileWidgetInterface::filters()
0207 {
0208     return &d->filters;
0209 }
0210 
0211 const KexiFileFilters* KexiFileWidgetInterface::filters() const
0212 {
0213     return &d->filters;
0214 }
0215 
0216 void KexiFileWidgetInterface::connectFileHighlightedSignal(QObject *receiver, const char *slot)
0217 {
0218     QObject::connect(widget(), SIGNAL(fileHighlighted(QString)), receiver, slot);
0219 }
0220 
0221 void KexiFileWidgetInterface::connectFileSelectedSignal(QObject *receiver, const char *slot)
0222 {
0223     QObject::connect(widget(), SIGNAL(fileSelected(QString)), receiver, slot);
0224 }
0225 
0226 bool KexiFileWidgetInterface::checkSelectedFile()
0227 {
0228     qDebug() << "selectedFile:" << selectedFile();
0229 
0230     applyEnteredFileName();
0231 
0232     qDebug() << "selectedFile after applyEnteredFileName():" << selectedFile();
0233     
0234     if (selectedFile().isEmpty()) {
0235         KMessageBox::error(widget(), xi18n("Enter a filename."));
0236         return false;
0237     }
0238 
0239     if (filters()->mode() == KexiFileFilters::SavingFileBasedDB || filters()->mode() == KexiFileFilters::CustomSavingFileBasedDB) {
0240         const QStringList currentFilters(this->currentFilters());
0241         if (!currentFilters.isEmpty()) {
0242             QString path = selectedFile();
0243             qDebug()<< "filter:" << currentFilters << "path:" << path;
0244             QString ext(QFileInfo(path).suffix());
0245             bool hasExtension = false;
0246             for (const QString &filter : currentFilters) {
0247                 const QString f(filter.trimmed());
0248                 hasExtension = !f.midRef(2).isEmpty() && ext == f.midRef(2);
0249                 if (hasExtension) {
0250                     break;
0251                 }
0252             }
0253             if (!hasExtension) {
0254                 //no extension: add one
0255                 QString ext(defaultExtension());
0256                 if (ext.isEmpty()) {
0257                     ext = currentFilters.first().trimmed().mid(2); //first one
0258                 }
0259                 path += (QLatin1String(".") + ext);
0260                 qDebug() << "appended extension:" << path;
0261                 setSelectedFile(path);
0262             }
0263             qDebug() << "selectedFile after applying extension:" << selectedFile();
0264         }
0265     }
0266 
0267     if (filters()->isExistingFileRequired()) {
0268         QFileInfo fi(selectedFile());
0269         if (!fi.exists()) {
0270             KMessageBox::error(widget(),
0271                                xi18nc("@info", "The file <filename>%1</filename> does not exist.",
0272                                       QDir::toNativeSeparators(fi.absoluteFilePath())));
0273             return false;
0274         }
0275         if (!fi.isFile()) {
0276             KMessageBox::error(widget(), xi18nc("@info", "Enter a filename."));
0277             return false;
0278         }
0279         if (!fi.isReadable()) {
0280             KMessageBox::error(widget(),
0281                                xi18nc("@info", "The file <filename>%1</filename> is not readable.",
0282                                       QDir::toNativeSeparators(fi.absoluteFilePath())));
0283             return false;
0284         }
0285     } else if (confirmOverwrites() && !KexiUtils::askForFileOverwriting(selectedFile(), widget())) {
0286         return false;
0287     }
0288     return true;
0289 }