File indexing completed on 2024-05-12 15:27:48
0001 /*************************************************************************** 0002 File : ImportDialog.cc 0003 Project : LabPlot 0004 Description : import file data dialog 0005 -------------------------------------------------------------------- 0006 Copyright : (C) 2008-2019 Alexander Semke (alexander.semke@web.de) 0007 Copyright : (C) 2008-2015 by Stefan Gerlach (stefan.gerlach@uni.kn) 0008 0009 ***************************************************************************/ 0010 0011 /*************************************************************************** 0012 * * 0013 * This program is free software; you can redistribute it and/or modify * 0014 * it under the terms of the GNU General Public License as published by * 0015 * the Free Software Foundation; either version 2 of the License, or * 0016 * (at your option) any later version. * 0017 * * 0018 * This program is distributed in the hope that it will be useful, * 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0021 * GNU General Public License for more details. * 0022 * * 0023 * You should have received a copy of the GNU General Public License * 0024 * along with this program; if not, write to the Free Software * 0025 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0026 * Boston, MA 02110-1301 USA * 0027 * * 0028 ***************************************************************************/ 0029 0030 #include "ImportFileDialog.h" 0031 #include "ImportFileWidget.h" 0032 #include "backend/core/AspectTreeModel.h" 0033 #include "backend/datasources/filters/AbstractFileFilter.h" 0034 #include "backend/datasources/filters/filters.h" 0035 #include "backend/spreadsheet/Spreadsheet.h" 0036 #include "backend/matrix/Matrix.h" 0037 #include "backend/core/Workbook.h" 0038 #include "commonfrontend/widgets/TreeViewComboBox.h" 0039 #include "kdefrontend/MainWin.h" 0040 0041 #ifdef HAVE_MQTT 0042 #include "backend/datasources/MQTTClient.h" 0043 #endif 0044 0045 #include <KLocalizedString> 0046 #include <KMessageBox> 0047 #include <KMessageWidget> 0048 #include <KSharedConfig> 0049 #include <KWindowConfig> 0050 0051 #include <QDialogButtonBox> 0052 #include <QElapsedTimer> 0053 #include <QProgressBar> 0054 #include <QTcpSocket> 0055 #include <QLocalSocket> 0056 #include <QUdpSocket> 0057 #include <QStatusBar> 0058 #include <QDir> 0059 #include <QInputDialog> 0060 #include <QMenu> 0061 #include <QWindow> 0062 0063 /*! 0064 \class ImportFileDialog 0065 \brief Dialog for importing data from a file. Embeds \c ImportFileWidget and provides the standard buttons. 0066 0067 \ingroup kdefrontend 0068 */ 0069 0070 ImportFileDialog::ImportFileDialog(MainWin* parent, bool liveDataSource, const QString& fileName) : ImportDialog(parent), 0071 m_importFileWidget(new ImportFileWidget(this, liveDataSource, fileName)) { 0072 0073 vLayout->addWidget(m_importFileWidget); 0074 0075 //dialog buttons 0076 auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Reset |QDialogButtonBox::Cancel); 0077 okButton = buttonBox->button(QDialogButtonBox::Ok); 0078 m_optionsButton = buttonBox->button(QDialogButtonBox::Reset); //we highjack the default "Reset" button and use if for showing/hiding the options 0079 okButton->setEnabled(false); //ok is only available if a valid container was selected 0080 vLayout->addWidget(buttonBox); 0081 0082 //hide the data-source related widgets 0083 if (!liveDataSource) 0084 setModel(); 0085 0086 //Signals/Slots 0087 connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); 0088 connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); 0089 0090 if (!liveDataSource) 0091 setWindowTitle(i18nc("@title:window", "Import Data to Spreadsheet or Matrix")); 0092 else 0093 setWindowTitle(i18nc("@title:window", "Add New Live Data Source")); 0094 0095 setWindowIcon(QIcon::fromTheme("document-import-database")); 0096 0097 //restore saved settings if available 0098 create(); // ensure there's a window created 0099 0100 QApplication::processEvents(QEventLoop::AllEvents, 0); 0101 m_importFileWidget->loadSettings(); 0102 0103 KConfigGroup conf(KSharedConfig::openConfig(), "ImportFileDialog"); 0104 if (conf.exists()) { 0105 m_showOptions = conf.readEntry("ShowOptions", false); 0106 0107 KWindowConfig::restoreWindowSize(windowHandle(), conf); 0108 resize(windowHandle()->size()); // workaround for QTBUG-40584 0109 } else 0110 resize(QSize(0, 0).expandedTo(minimumSize())); 0111 0112 m_importFileWidget->showOptions(m_showOptions); 0113 //do the signal-slot connections after all settings were loaded in import file widget and check the OK button after this 0114 connect(m_importFileWidget, &ImportFileWidget::checkedFitsTableToMatrix, this, &ImportFileDialog::checkOnFitsTableToMatrix); 0115 connect(m_importFileWidget, static_cast<void (ImportFileWidget::*)()>(&ImportFileWidget::fileNameChanged), this, &ImportFileDialog::checkOkButton); 0116 connect(m_importFileWidget, static_cast<void (ImportFileWidget::*)()>(&ImportFileWidget::sourceTypeChanged), this, &ImportFileDialog::checkOkButton); 0117 connect(m_importFileWidget, &ImportFileWidget::hostChanged, this, &ImportFileDialog::checkOkButton); 0118 connect(m_importFileWidget, &ImportFileWidget::portChanged, this, &ImportFileDialog::checkOkButton); 0119 connect(m_importFileWidget, &ImportFileWidget::error, this, &ImportFileDialog::showErrorMessage); 0120 #ifdef HAVE_MQTT 0121 connect(m_importFileWidget, &ImportFileWidget::subscriptionsChanged, this, &ImportFileDialog::checkOkButton); 0122 connect(m_importFileWidget, &ImportFileWidget::checkFileType, this, &ImportFileDialog::checkOkButton); 0123 #endif 0124 0125 m_showOptions ? m_optionsButton->setText(i18n("Hide Options")) : m_optionsButton->setText(i18n("Show Options")); 0126 connect(m_optionsButton, &QPushButton::clicked, this, &ImportFileDialog::toggleOptions); 0127 0128 ImportFileDialog::checkOkButton(); 0129 } 0130 0131 ImportFileDialog::~ImportFileDialog() { 0132 //save current settings 0133 KConfigGroup conf(KSharedConfig::openConfig(), "ImportFileDialog"); 0134 conf.writeEntry("ShowOptions", m_showOptions); 0135 if (cbPosition) 0136 conf.writeEntry("Position", cbPosition->currentIndex()); 0137 0138 KWindowConfig::saveWindowSize(windowHandle(), conf); 0139 } 0140 0141 LiveDataSource::SourceType ImportFileDialog::sourceType() const { 0142 return m_importFileWidget->currentSourceType(); 0143 } 0144 0145 /*! 0146 triggers data import to the live data source \c source 0147 */ 0148 void ImportFileDialog::importToLiveDataSource(LiveDataSource* source, QStatusBar* statusBar) const { 0149 DEBUG("ImportFileDialog::importToLiveDataSource()"); 0150 m_importFileWidget->saveSettings(source); 0151 0152 //show a progress bar in the status bar 0153 auto* progressBar = new QProgressBar(); 0154 progressBar->setRange(0, 100); 0155 connect(source->filter(), &AbstractFileFilter::completed, progressBar, &QProgressBar::setValue); 0156 0157 statusBar->clearMessage(); 0158 statusBar->addWidget(progressBar, 1); 0159 WAIT_CURSOR; 0160 0161 QElapsedTimer timer; 0162 timer.start(); 0163 DEBUG(" Initial read()"); 0164 source->read(); 0165 statusBar->showMessage( i18n("Live data source created in %1 seconds.", (float)timer.elapsed()/1000) ); 0166 0167 RESET_CURSOR; 0168 statusBar->removeWidget(progressBar); 0169 } 0170 0171 #ifdef HAVE_MQTT 0172 /*! 0173 triggers data import to the MQTTClient \c client 0174 */ 0175 void ImportFileDialog::importToMQTT(MQTTClient* client) const{ 0176 m_importFileWidget->saveMQTTSettings(client); 0177 client->read(); 0178 client->ready(); 0179 } 0180 #endif 0181 0182 /*! 0183 triggers data import to the currently selected data container 0184 */ 0185 void ImportFileDialog::importTo(QStatusBar* statusBar) const { 0186 DEBUG("ImportFileDialog::importTo()"); 0187 QDEBUG(" cbAddTo->currentModelIndex() =" << cbAddTo->currentModelIndex()); 0188 AbstractAspect* aspect = static_cast<AbstractAspect*>(cbAddTo->currentModelIndex().internalPointer()); 0189 if (!aspect) { 0190 DEBUG("ERROR in importTo(): No aspect available"); 0191 DEBUG(" cbAddTo->currentModelIndex().isValid() = " << cbAddTo->currentModelIndex().isValid()); 0192 DEBUG(" cbAddTo->currentModelIndex() row/column = " << cbAddTo->currentModelIndex().row() << ' ' << cbAddTo->currentModelIndex().column()); 0193 return; 0194 } 0195 0196 if (m_importFileWidget->isFileEmpty()) { 0197 KMessageBox::information(nullptr, i18n("No data to import."), i18n("No Data")); 0198 return; 0199 } 0200 0201 QString fileName = m_importFileWidget->fileName(); 0202 auto filter = m_importFileWidget->currentFileFilter(); 0203 auto mode = AbstractFileFilter::ImportMode(cbPosition->currentIndex()); 0204 0205 //show a progress bar in the status bar 0206 auto* progressBar = new QProgressBar(); 0207 progressBar->setRange(0, 100); 0208 connect(filter, &AbstractFileFilter::completed, progressBar, &QProgressBar::setValue); 0209 0210 statusBar->clearMessage(); 0211 statusBar->addWidget(progressBar, 1); 0212 0213 WAIT_CURSOR; 0214 QApplication::processEvents(QEventLoop::AllEvents, 100); 0215 0216 QElapsedTimer timer; 0217 timer.start(); 0218 0219 if (aspect->inherits(AspectType::Matrix)) { 0220 DEBUG("ImportFileDialog::importTo(): to Matrix"); 0221 auto* matrix = qobject_cast<Matrix*>(aspect); 0222 filter->readDataFromFile(fileName, matrix, mode); 0223 } else if (aspect->inherits(AspectType::Spreadsheet)) { 0224 DEBUG("ImportFileDialog::importTo(): to Spreadsheet"); 0225 auto* spreadsheet = qobject_cast<Spreadsheet*>(aspect); 0226 DEBUG(" Calling filter->readDataFromFile() with spreadsheet " << spreadsheet); 0227 filter->readDataFromFile(fileName, spreadsheet, mode); 0228 } else if (aspect->inherits(AspectType::Workbook)) { 0229 DEBUG("ImportFileDialog::importTo(): to Workbook"); 0230 auto* workbook = static_cast<Workbook*>(aspect); 0231 workbook->setUndoAware(false); 0232 auto sheets = workbook->children<AbstractAspect>(); 0233 0234 AbstractFileFilter::FileType fileType = m_importFileWidget->currentFileType(); 0235 // multiple data sets/variables for HDF5, NetCDF and ROOT 0236 if (fileType == AbstractFileFilter::FileType::HDF5 || fileType == AbstractFileFilter::FileType::NETCDF || 0237 fileType == AbstractFileFilter::FileType::ROOT) { 0238 QStringList names; 0239 if (fileType == AbstractFileFilter::FileType::HDF5) 0240 names = m_importFileWidget->selectedHDF5Names(); 0241 else if (fileType == AbstractFileFilter::FileType::NETCDF) 0242 names = m_importFileWidget->selectedNetCDFNames(); 0243 else 0244 names = m_importFileWidget->selectedROOTNames(); 0245 0246 int nrNames = names.size(), offset = sheets.size(); 0247 0248 //TODO: think about importing multiple sets into one sheet 0249 0250 int start = 0; // add nrNames sheets (0 to nrNames) 0251 0252 //in replace mode add only missing sheets (from offset to nrNames) 0253 //and rename the already available sheets 0254 if (mode == AbstractFileFilter::ImportMode::Replace) { 0255 start = offset; 0256 0257 // if there are more available spreadsheets, than needed, 0258 // delete the unneeded spreadsheets 0259 if (offset > nrNames) { 0260 for (int i = nrNames; i < offset; i++) 0261 sheets[i]->remove(); 0262 offset = nrNames; 0263 } 0264 0265 //rename the available sheets 0266 for (int i = 0; i < offset; ++i) { 0267 //HDF5 variable names contain the whole path, remove it and keep the name only 0268 QString sheetName = names.at(i); 0269 if (fileType == AbstractFileFilter::FileType::HDF5) 0270 sheetName = names[i].mid(names[i].lastIndexOf("/") + 1); 0271 0272 auto* sheet = sheets.at(i); 0273 sheet->setUndoAware(false); 0274 sheet->setName(sheetName); 0275 sheet->setUndoAware(true); 0276 } 0277 } 0278 0279 // add additional spreadsheets 0280 for (int i = start; i < nrNames; ++i) { 0281 //HDF5 variable names contain the whole path, remove it and keep the name only 0282 QString sheetName = names.at(i); 0283 if (fileType == AbstractFileFilter::FileType::HDF5) 0284 sheetName = names[i].mid(names[i].lastIndexOf("/") + 1); 0285 0286 auto* spreadsheet = new Spreadsheet(sheetName); 0287 if (mode == AbstractFileFilter::ImportMode::Prepend && !sheets.isEmpty()) 0288 workbook->insertChildBefore(spreadsheet, sheets[0]); 0289 else 0290 workbook->addChildFast(spreadsheet); 0291 } 0292 0293 // start at offset for append, else at 0 0294 if (mode != AbstractFileFilter::ImportMode::Append) 0295 offset = 0; 0296 0297 // import all sets to a different sheet 0298 sheets = workbook->children<AbstractAspect>(); 0299 for (int i = 0; i < nrNames; ++i) { 0300 if (fileType == AbstractFileFilter::FileType::HDF5) 0301 static_cast<HDF5Filter*>(filter)->setCurrentDataSetName(names[i]); 0302 else if (fileType == AbstractFileFilter::FileType::NETCDF) 0303 static_cast<NetCDFFilter*>(filter)->setCurrentVarName(names[i]); 0304 else 0305 static_cast<ROOTFilter*>(filter)->setCurrentObject(names[i]); 0306 0307 int index = i + offset; 0308 filter->readDataFromFile(fileName, qobject_cast<Spreadsheet*>(sheets[index])); 0309 } 0310 0311 workbook->setUndoAware(true); 0312 } else { // single import file types 0313 // use active spreadsheet/matrix if present, else new spreadsheet 0314 auto* sheet = workbook->currentSpreadsheet(); 0315 if (sheet) 0316 filter->readDataFromFile(fileName, sheet, mode); 0317 else { 0318 workbook->setUndoAware(true); 0319 auto* spreadsheet = new Spreadsheet(fileName); 0320 workbook->addChild(spreadsheet); 0321 workbook->setUndoAware(false); 0322 filter->readDataFromFile(fileName, spreadsheet, mode); 0323 } 0324 } 0325 } 0326 statusBar->showMessage(i18n("File %1 imported in %2 seconds.", fileName, (float)timer.elapsed()/1000)); 0327 0328 RESET_CURSOR; 0329 statusBar->removeWidget(progressBar); 0330 } 0331 0332 void ImportFileDialog::toggleOptions() { 0333 m_importFileWidget->showOptions(!m_showOptions); 0334 m_showOptions = !m_showOptions; 0335 m_showOptions ? m_optionsButton->setText(i18n("Hide Options")) : m_optionsButton->setText(i18n("Show Options")); 0336 0337 //resize the dialog 0338 layout()->activate(); 0339 resize( QSize(this->width(), 0).expandedTo(minimumSize()) ); 0340 } 0341 0342 void ImportFileDialog::checkOnFitsTableToMatrix(const bool enable) { 0343 if (cbAddTo) { 0344 QDEBUG("cbAddTo->currentModelIndex() = " << cbAddTo->currentModelIndex()); 0345 AbstractAspect* aspect = static_cast<AbstractAspect*>(cbAddTo->currentModelIndex().internalPointer()); 0346 if (!aspect) { 0347 DEBUG("ERROR: no aspect available."); 0348 return; 0349 } 0350 0351 if (aspect->inherits(AspectType::Matrix)) { 0352 okButton->setEnabled(enable); 0353 if (enable) 0354 okButton->setToolTip(i18n("Close the dialog and import the data.")); 0355 else 0356 okButton->setToolTip(i18n("Cannot import into a matrix since the data contains non-numerical data.")); 0357 } 0358 } 0359 } 0360 0361 void ImportFileDialog::checkOkButton() { 0362 DEBUG("ImportFileDialog::checkOkButton()"); 0363 if (cbAddTo) { //only check for the target container when no file data source is being added 0364 QDEBUG(" cbAddTo->currentModelIndex() = " << cbAddTo->currentModelIndex()); 0365 AbstractAspect* aspect = static_cast<AbstractAspect*>(cbAddTo->currentModelIndex().internalPointer()); 0366 if (!aspect) { 0367 okButton->setEnabled(false); 0368 okButton->setToolTip(i18n("Select a data container where the data has to be imported into.")); 0369 lPosition->setEnabled(false); 0370 cbPosition->setEnabled(false); 0371 cbAddTo->setFocus(); //set the focus to make the user aware about the fact that a data container needs to be provided 0372 return; 0373 } else { 0374 lPosition->setEnabled(true); 0375 cbPosition->setEnabled(true); 0376 0377 //when doing ASCII import to a matrix, hide the options for using the file header (first line) 0378 //to name the columns since the column names are fixed in a matrix 0379 const auto* matrix = dynamic_cast<const Matrix*>(aspect); 0380 m_importFileWidget->showAsciiHeaderOptions(matrix == nullptr); 0381 } 0382 } 0383 0384 QString fileName = m_importFileWidget->fileName(); 0385 #ifdef HAVE_WINDOWS 0386 if (!fileName.isEmpty() && fileName.at(1) != QLatin1String(":")) 0387 #else 0388 if (!fileName.isEmpty() && fileName.at(0) != QLatin1String("/")) 0389 #endif 0390 fileName = QDir::homePath() + QLatin1String("/") + fileName; 0391 0392 DEBUG("Data Source Type: " << ENUM_TO_STRING(LiveDataSource, SourceType, m_importFileWidget->currentSourceType())); 0393 switch (m_importFileWidget->currentSourceType()) { 0394 case LiveDataSource::SourceType::FileOrPipe: { 0395 DEBUG(" fileName = " << fileName.toUtf8().constData()); 0396 const bool enable = QFile::exists(fileName); 0397 okButton->setEnabled(enable); 0398 if (enable) { 0399 okButton->setToolTip(i18n("Close the dialog and import the data.")); 0400 showErrorMessage(QString()); 0401 } else { 0402 QString msg = i18n("The provided file doesn't exist."); 0403 okButton->setToolTip(msg); 0404 0405 //suppress the error widget when the dialog is opened the first time. 0406 //show only the error widget if the file was really a non-existing file was provided. 0407 if (!fileName.isEmpty()) 0408 showErrorMessage(msg); 0409 } 0410 0411 break; 0412 } 0413 case LiveDataSource::SourceType::LocalSocket: { 0414 const bool enable = QFile::exists(fileName); 0415 if (enable) { 0416 QLocalSocket lsocket{this}; 0417 DEBUG("CONNECT"); 0418 lsocket.connectToServer(fileName, QLocalSocket::ReadOnly); 0419 if (lsocket.waitForConnected()) { 0420 0421 // this is required for server that send data as soon as connected 0422 lsocket.waitForReadyRead(); 0423 0424 DEBUG("DISCONNECT"); 0425 lsocket.disconnectFromServer(); 0426 // read-only socket is disconnected immediately (no waitForDisconnected()) 0427 okButton->setEnabled(true); 0428 okButton->setToolTip(i18n("Close the dialog and import the data.")); 0429 showErrorMessage(QString()); 0430 } else { 0431 okButton->setEnabled(false); 0432 QString msg = i18n("Could not connect to the provided local socket. Error: %1.", lsocket.errorString()); 0433 okButton->setToolTip(msg); 0434 showErrorMessage(msg); 0435 } 0436 } else { 0437 okButton->setEnabled(false); 0438 QString msg = i18n("Could not connect to the provided local socket. The socket does not exist."); 0439 okButton->setToolTip(msg); 0440 if (!fileName.isEmpty()) 0441 showErrorMessage(msg); 0442 } 0443 0444 break; 0445 } 0446 case LiveDataSource::SourceType::NetworkTcpSocket: { 0447 const bool enable = !m_importFileWidget->host().isEmpty() && !m_importFileWidget->port().isEmpty(); 0448 if (enable) { 0449 QTcpSocket socket(this); 0450 socket.connectToHost(m_importFileWidget->host(), m_importFileWidget->port().toUShort(), QTcpSocket::ReadOnly); 0451 if (socket.waitForConnected()) { 0452 okButton->setEnabled(true); 0453 okButton->setToolTip(i18n("Close the dialog and import the data.")); 0454 showErrorMessage(QString()); 0455 socket.disconnectFromHost(); 0456 } else { 0457 okButton->setEnabled(false); 0458 QString msg = i18n("Could not connect to the provided TCP socket. Error: %1.", socket.errorString()); 0459 okButton->setToolTip(msg); 0460 showErrorMessage(msg); 0461 } 0462 } else { 0463 okButton->setEnabled(false); 0464 QString msg = i18n("Either the host name or the port number is missing."); 0465 okButton->setToolTip(msg); 0466 showErrorMessage(msg); 0467 } 0468 break; 0469 } 0470 case LiveDataSource::SourceType::NetworkUdpSocket: { 0471 const bool enable = !m_importFileWidget->host().isEmpty() && !m_importFileWidget->port().isEmpty(); 0472 if (enable) { 0473 QUdpSocket socket(this); 0474 socket.bind(QHostAddress(m_importFileWidget->host()), m_importFileWidget->port().toUShort()); 0475 socket.connectToHost(m_importFileWidget->host(), 0, QUdpSocket::ReadOnly); 0476 if (socket.waitForConnected()) { 0477 okButton->setEnabled(true); 0478 okButton->setToolTip(i18n("Close the dialog and import the data.")); 0479 showErrorMessage(QString()); 0480 socket.disconnectFromHost(); 0481 // read-only socket is disconnected immediately (no waitForDisconnected()) 0482 } else { 0483 okButton->setEnabled(false); 0484 QString msg = i18n("Could not connect to the provided UDP socket. Error: %1.", socket.errorString()); 0485 okButton->setToolTip(msg); 0486 showErrorMessage(msg); 0487 } 0488 } else { 0489 okButton->setEnabled(false); 0490 okButton->setToolTip(i18n("Either the host name or the port number is missing.")); 0491 } 0492 0493 break; 0494 } 0495 case LiveDataSource::SourceType::SerialPort: { 0496 #ifdef HAVE_QTSERIALPORT 0497 const QString sPort = m_importFileWidget->serialPort(); 0498 const int baudRate = m_importFileWidget->baudRate(); 0499 0500 if (!sPort.isEmpty()) { 0501 QSerialPort serialPort{this}; 0502 0503 DEBUG(" Port: " << STDSTRING(sPort) << ", Settings: " << baudRate << ',' << serialPort.dataBits() 0504 << ',' << serialPort.parity() << ',' << serialPort.stopBits()); 0505 serialPort.setPortName(sPort); 0506 serialPort.setBaudRate(baudRate); 0507 0508 const bool serialPortOpened = serialPort.open(QIODevice::ReadOnly); 0509 okButton->setEnabled(serialPortOpened); 0510 if (serialPortOpened) { 0511 okButton->setToolTip(i18n("Close the dialog and import the data.")); 0512 showErrorMessage(QString()); 0513 serialPort.close(); 0514 } else { 0515 QString msg = i18n("Could not connect to the provided serial port."); 0516 okButton->setToolTip(msg); 0517 showErrorMessage(msg); 0518 } 0519 } else { 0520 okButton->setEnabled(false); 0521 QString msg = i18n("Serial port number is missing."); 0522 okButton->setToolTip(msg); 0523 showErrorMessage(msg); 0524 } 0525 #endif 0526 break; 0527 } 0528 case LiveDataSource::SourceType::MQTT: { 0529 #ifdef HAVE_MQTT 0530 const bool enable = m_importFileWidget->isMqttValid(); 0531 showErrorMessage(QString()); 0532 if (enable) { 0533 okButton->setEnabled(true); 0534 okButton->setToolTip(i18n("Close the dialog and import the data.")); 0535 } 0536 else { 0537 okButton->setEnabled(false); 0538 okButton->setToolTip(i18n("Either there is no connection, or no subscriptions were made, or the file filter is not ASCII.")); 0539 } 0540 #endif 0541 break; 0542 } 0543 } 0544 } 0545 0546 QString ImportFileDialog::selectedObject() const { 0547 return m_importFileWidget->selectedObject(); 0548 } 0549 0550 void ImportFileDialog::showErrorMessage(const QString& message) { 0551 if (message.isEmpty()) { 0552 if (m_messageWidget && m_messageWidget->isVisible()) 0553 m_messageWidget->close(); 0554 } else { 0555 if (!m_messageWidget) { 0556 m_messageWidget = new KMessageWidget(this); 0557 m_messageWidget->setMessageType(KMessageWidget::Error); 0558 vLayout->insertWidget(vLayout->count() - 1, m_messageWidget); 0559 } 0560 m_messageWidget->setText(message); 0561 m_messageWidget->animatedShow(); 0562 } 0563 }