File indexing completed on 2024-05-19 12:55:40
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 "KexiFileWidget.h" 0021 #include <kexi_global.h> 0022 #include <core/kexi.h> 0023 #include <core/KexiMainWindowIface.h> 0024 #include <core/KexiMigrateManagerInterface.h> 0025 #include <kexiutils/utils.h> 0026 0027 #include <KDbDriver> 0028 #include <KDbUtils> 0029 0030 #include <KActionCollection> 0031 #include <KDirOperator> 0032 #include <KFile> 0033 #include <KFileFilterCombo> 0034 #include <KLocalizedString> 0035 #include <KMessageBox> 0036 #include <KUrlComboBox> 0037 0038 #include <QAction> 0039 #include <QApplication> 0040 #include <QDebug> 0041 #include <QEvent> 0042 #include <QFileDialog> 0043 #include <QKeyEvent> 0044 #include <QLineEdit> 0045 #include <QLocale> 0046 #include <QMimeDatabase> 0047 #include <QMimeType> 0048 #include <QPushButton> 0049 0050 //! @internal 0051 class Q_DECL_HIDDEN KexiFileWidget::Private 0052 { 0053 public: 0054 Private() 0055 { 0056 } 0057 QUrl selectedUrl; 0058 }; 0059 0060 //------------------ 0061 0062 static QUrl startDirWithFileName(const QUrl &startDirOrVariable, const QString &fileName) 0063 { 0064 QUrl result = startDirOrVariable; 0065 if (!fileName.isEmpty()) { 0066 result.setPath(result.path() + '/' + fileName); 0067 } 0068 return result; 0069 } 0070 0071 KexiFileWidget::KexiFileWidget(const QUrl &startDirOrVariable, KexiFileFilters::Mode mode, 0072 const QString &fileName, QWidget *parent) 0073 : KFileWidget(startDirWithFileName(startDirOrVariable, fileName), parent) 0074 , KexiFileWidgetInterface(startDirOrVariable, fileName) 0075 , d(new Private) 0076 { 0077 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); 0078 QAction *previewAction = dirOperator()->actionCollection()->action("preview"); 0079 if (previewAction) { 0080 previewAction->setChecked(false); 0081 } 0082 setFocusProxy(locationEdit()); 0083 connect(this, &KFileWidget::fileHighlighted, this, &KexiFileWidget::slotFileHighlighted); 0084 setMode(mode); 0085 } 0086 0087 KexiFileWidget::KexiFileWidget(const QUrl &startDirOrVariable, KexiFileFilters::Mode mode, 0088 QWidget *parent) 0089 : KexiFileWidget(startDirOrVariable, mode, QString(), parent) 0090 { 0091 } 0092 0093 KexiFileWidget::~KexiFileWidget() 0094 { 0095 done(); 0096 #if 0 0097 qDebug() << d->recentDirClass; 0098 if (!d->recentDirClass.isEmpty()) { 0099 QString hf = highlightedFile(); 0100 QUrl dir; 0101 if (hf.isEmpty()) { 0102 dir = baseUrl(); 0103 } 0104 else { 0105 QFileInfo fi(hf); 0106 QString dirStr = fi.isDir() ? fi.absoluteFilePath() : fi.dir().absolutePath(); 0107 dir = QUrl::fromLocalFile(dirStr); 0108 } 0109 //qDebug() << dir; 0110 //qDebug() << highlightedFile(); 0111 if (!dir.isEmpty()) 0112 KRecentDirs::add(d->recentDirClass, dir.path()); 0113 } 0114 #endif 0115 delete d; 0116 } 0117 0118 void KexiFileWidget::slotFileHighlighted(const QUrl& url) 0119 { 0120 //qDebug() << url; 0121 d->selectedUrl = url; 0122 emit fileSelected(selectedFile()); 0123 } 0124 0125 void KexiFileWidget::slotFileSelected(const QUrl& url) 0126 { 0127 Q_UNUSED(url) 0128 //qDebug() << url; 0129 emit fileSelected(selectedFile()); 0130 } 0131 0132 void KexiFileWidget::setMode(KexiFileFilters::Mode mode) 0133 { 0134 KexiFileWidgetInterface::setMode(mode); 0135 } 0136 0137 void KexiFileWidget::updateFilters() 0138 { 0139 if (filtersUpdated()) 0140 return; 0141 setFiltersUpdated(true); 0142 clearFilter(); 0143 filters()->setDefaultFilter(filterWidget()->defaultFilter()); 0144 KexiFileFiltersFormat format; 0145 format.type = KexiFileFiltersFormat::Type::KDE; 0146 setFilter(filters()->toString(format)); 0147 0148 if (filters()->mode() == KexiFileFilters::Opening || filters()->mode() == KexiFileFilters::CustomOpening) { 0149 KFileWidget::setMode(KFile::ExistingOnly | KFile::LocalOnly | KFile::File); 0150 setOperationMode(KFileWidget::Opening); 0151 } else { 0152 KFileWidget::setMode(KFile::LocalOnly | KFile::File); 0153 setOperationMode(KFileWidget::Saving); 0154 } 0155 } 0156 0157 void KexiFileWidget::showEvent(QShowEvent * event) 0158 { 0159 setFiltersUpdated(false); 0160 updateFilters(); 0161 KFileWidget::showEvent(event); 0162 } 0163 0164 /*TODO 0165 QString KexiFileWidget::selectedFile() const 0166 { 0167 #ifdef Q_OS_WIN 0168 // QString path = selectedFile(); 0169 //js @todo 0170 // qDebug() << "selectedFile() ==" << path << "'" << url().fileName() << "'" << m_lineEdit->text(); 0171 QString path = dir()->absolutePath(); 0172 if (!path.endsWith('/') && !path.endsWith("\\")) 0173 path.append("/"); 0174 path += m_lineEdit->text(); 0175 // QString path = QFileInfo(selectedFile()).dirPath(true) + "/" + m_lineEdit->text(); 0176 #else 0177 // QString path = locationEdit->currentText().trimmed(); //url.path().trimmed(); that does not work, if the full path is not in the location edit !!!!! 0178 QString path( KFileWidget::selectedFile() ); 0179 qDebug() << "prev selectedFile() ==" << path; 0180 qDebug() << "locationEdit ==" << locationEdit()->currentText().trimmed(); 0181 //make sure user-entered path is acceped: 0182 //! @todo KEXI3 setSelection( locationEdit()->currentText().trimmed() ); 0183 // path = KFileWidget::selectedFile(); 0184 path = locationEdit()->currentText().trimmed(); 0185 qDebug() << "selectedFile() ==" << path; 0186 0187 #endif 0188 0189 if (!currentFilter().isEmpty()) { 0190 if (d->mode & SavingFileBasedDB) { 0191 const QStringList filters( currentFilter().split(' ') ); 0192 qDebug()<< "filter ==" << filters; 0193 QString ext( QFileInfo(path).suffix() ); 0194 bool hasExtension = false; 0195 foreach (const QString& filter, filters) { 0196 const QString f( filter.trimmed() ); 0197 hasExtension = !f.mid(2).isEmpty() && ext==f.mid(2); 0198 if (hasExtension) 0199 break; 0200 } 0201 if (!hasExtension) { 0202 //no extension: add one 0203 QString defaultExtension( d->defaultExtension ); 0204 if (defaultExtension.isEmpty()) 0205 defaultExtension = filters.first().trimmed().mid(2); //first one 0206 path += (QString(".")+defaultExtension); 0207 qDebug() << "KexiFileWidget::checkURL(): append extension," << path; 0208 } 0209 } 0210 } 0211 qDebug() << "KexiFileWidget::currentFileName() ==" << path; 0212 return path; 0213 } 0214 */ 0215 0216 QString KexiFileWidget::selectedFile() const 0217 { 0218 return d->selectedUrl.toLocalFile(); 0219 } 0220 0221 QString KexiFileWidget::highlightedFile() const 0222 { 0223 return d->selectedUrl.toLocalFile(); 0224 } 0225 0226 void KexiFileWidget::setSelectedFile(const QString &name) 0227 { 0228 d->selectedUrl = QUrl::fromLocalFile(name); 0229 } 0230 0231 QString KexiFileWidget::currentDir() const 0232 { 0233 return KFileWidget::baseUrl().toLocalFile(); 0234 } 0235 0236 void KexiFileWidget::applyEnteredFileName() 0237 { 0238 const QString enteredFileName(locationEdit()->lineEdit()->text()); 0239 if (enteredFileName.isEmpty()) { 0240 return; 0241 } 0242 //qDebug() << enteredFileName; 0243 //qDebug() << locationEdit()->urls(); 0244 //qDebug() << currentDir(); 0245 0246 setSelectedFile(currentDir()); 0247 // FIXME: find first... 0248 if (QDir::isAbsolutePath(enteredFileName)) { 0249 setSelectedFile(enteredFileName); 0250 } else { 0251 setSelectedFile(currentDir() + enteredFileName); 0252 } 0253 } 0254 0255 QStringList KexiFileWidget::currentFilters() const 0256 { 0257 return currentFilter().split(QLatin1Char(' ')); 0258 } 0259 0260 void KexiFileWidget::accept() 0261 { 0262 //qDebug(); 0263 KFileWidget::accept(); 0264 // qDebug() << selectedFile(); 0265 0266 // locationEdit->setFocus(); 0267 // QKeyEvent ev(QEvent::KeyPress, Qt::Key_Enter, '\n', 0); 0268 // QApplication::sendEvent(locationEdit, &ev); 0269 // QApplication::postEvent(locationEdit, &ev); 0270 0271 // qDebug() << "KexiFileWidget::accept() m_lastUrl ==" << m_lastUrl.path(); 0272 // if (m_lastUrl.path()==currentURL().path()) {//(js) to prevent more multiple kjob signals (I do not know why this is) 0273 /* 0274 if (d->lastFileName==selectedFile()) {//(js) to prevent more multiple kjob signals (I do not know why this is) 0275 // m_lastUrl=QUrl(); 0276 d->lastFileName.clear(); 0277 qDebug() << "d->lastFileName==selectedFile()"; 0278 #ifdef Q_OS_WIN 0279 return; 0280 #endif 0281 } 0282 qDebug() << "KexiFileWidget::accept(): path =" << selectedFile(); 0283 if ( checkSelectedFile() ) { 0284 emit accepted(); 0285 } 0286 d->lastFileName = selectedFile(); 0287 0288 #ifdef Q_OS_WIN 0289 saveLastVisitedPath(d->lastFileName); 0290 #endif*/ 0291 } 0292 0293 void KexiFileWidget::reject() 0294 { 0295 //qDebug(); 0296 emit rejected(); 0297 } 0298 0299 #if 0 // TODO? 0300 void KexiFileWidget::setLocationText(const QString& text) 0301 { 0302 locationEdit()->setUrl(QUrl(text)); 0303 /* 0304 #ifdef Q_OS_WIN 0305 //js @todo 0306 setSelection(fn); 0307 #else 0308 setSelection(fn); 0309 // locationEdit->setCurrentText(fn); 0310 // locationEdit->lineEdit()->setEdited( true ); 0311 // setSelection(fn); 0312 #endif*/ 0313 } 0314 #endif 0315 0316 void KexiFileWidget::focusInEvent(QFocusEvent *event) 0317 { 0318 Q_UNUSED(event) 0319 locationEdit()->setFocus(); 0320 } 0321 0322 /*bool KexiFileWidget::eventFilter ( QObject * watched, QEvent * e ) 0323 { 0324 //filter-out ESC key 0325 if (e->type()==QEvent::KeyPress && static_cast<QKeyEvent*>(e)->key()==Qt::Key_Escape 0326 && static_cast<QKeyEvent*>(e)->state()==Qt::NoButton) { 0327 static_cast<QKeyEvent*>(e)->accept(); 0328 emit rejected(); 0329 return true; 0330 } 0331 return KexiFileWidgetBase::eventFilter(watched,e); 0332 } */ 0333 0334 void KexiFileWidget::setWidgetFrame(bool set) 0335 { 0336 Q_UNUSED(set) 0337 }