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