[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [labplot/gsoc2018_mqtt] src/kdefrontend: reorganised, commented, improved naming in ImportFileWidget
From: Ferencz Kovacs <null () kde ! org>
Date: 2018-07-17 15:45:53
Message-ID: E1ffSAj-0000em-P3 () code ! kde ! org
[Download RAW message or body]
Git commit ff73cc90ee3d507572c459d4f2efb8f949393402 by Ferencz Kovacs.
Committed on 17/07/2018 at 15:44.
Pushed by ferenczkovacs into branch 'gsoc2018_mqtt'.
reorganised, commented, improved naming in ImportFileWidget
added comments in ImportFileDialog
added comments in MainWin
M +2 -1 src/kdefrontend/MainWin.cpp
M +4 -1 src/kdefrontend/datasources/ImportFileDialog.cpp
M +1711 -1514 src/kdefrontend/datasources/ImportFileWidget.cpp
M +5 -5 src/kdefrontend/datasources/ImportFileWidget.h
https://commits.kde.org/labplot/ff73cc90ee3d507572c459d4f2efb8f949393402
diff --git a/src/kdefrontend/MainWin.cpp b/src/kdefrontend/MainWin.cpp
index 0bcd87cf..77c1a777 100644
--- a/src/kdefrontend/MainWin.cpp
+++ b/src/kdefrontend/MainWin.cpp
@@ -1835,6 +1835,7 @@ void MainWin::newLiveDataSourceActionTriggered() {
mqttClient->setName(mqttClient->clientHostName());
QVector<const MQTTClient*> existingClients = m_project->children<const \
MQTTClient>(AbstractAspect::Recursive);
+ //doesn't make sense to have more MQTTClients connected to the same broker
bool found = false;
for(int i = 0; i < existingClients.size(); ++i) {
if(existingClients[i]->clientHostName() == mqttClient->clientHostName()) {
@@ -1865,7 +1866,7 @@ void MainWin::addAspectToProject(AbstractAspect* aspect) {
if (index.isValid()) {
AbstractAspect* parent = static_cast<AbstractAspect*>(index.internalPointer());
#ifdef HAVE_MQTT
-
+ //doesn't make sense to add a new MQTTClient to an existing MQTTClient or to any \
of its successors QString className = parent->metaObject()->className();
MQTTClient* clientAncestor = parent->ancestor<MQTTClient>();
if(className == "MQTTClient")
diff --git a/src/kdefrontend/datasources/ImportFileDialog.cpp \
b/src/kdefrontend/datasources/ImportFileDialog.cpp index be65578e..f706a7f6 100644
--- a/src/kdefrontend/datasources/ImportFileDialog.cpp
+++ b/src/kdefrontend/datasources/ImportFileDialog.cpp
@@ -90,7 +90,7 @@ ImportFileDialog::ImportFileDialog(MainWin* parent, bool \
liveDataSource, const Q
//Signals/Slots
#ifdef HAVE_MQTT
- connect(m_importFileWidget, &ImportFileWidget::subscriptionMade, this, \
&ImportFileDialog::checkOkButton); + connect(m_importFileWidget, \
&ImportFileWidget::subscriptionsChanged, this, &ImportFileDialog::checkOkButton); \
connect(m_importFileWidget, &ImportFileWidget::checkFileType, this, \
&ImportFileDialog::checkOkButton); #endif
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
@@ -173,6 +173,9 @@ void ImportFileDialog::importToLiveDataSource(LiveDataSource* \
source, QStatusBar }
#ifdef HAVE_MQTT
+/*!
+ triggers data import to the MQTTClient \c client
+*/
void ImportFileDialog::importToMQTT(MQTTClient* client) const{
m_importFileWidget->saveMQTTSettings(client);
client->read();
diff --git a/src/kdefrontend/datasources/ImportFileWidget.cpp \
b/src/kdefrontend/datasources/ImportFileWidget.cpp index 405b0468..89958d2b 100644
--- a/src/kdefrontend/datasources/ImportFileWidget.cpp
+++ b/src/kdefrontend/datasources/ImportFileWidget.cpp
@@ -6,6 +6,7 @@ Description : import file data widget
Copyright : (C) 2009-2018 Stefan Gerlach (stefan.gerlach@uni.kn)
Copyright : (C) 2009-2017 Alexander Semke (alexander.semke@web.de)
Copyright : (C) 2017-2018 Fabian Kristof (fkristofszabolcs@gmail.com)
+Copyright : (C) 2018 Kovacs Ferencz (kferike98@gmail.com)
***************************************************************************/
@@ -97,19 +98,20 @@ Copyright : (C) 2017-2018 Fabian Kristof \
(fkristofszabolcs@gmail.com) ImportFileWidget::ImportFileWidget(QWidget* parent, \
const QString& fileName) : QWidget(parent), m_fileName(fileName),
m_fileEmpty(false),
- m_liveDataSource(true),
-#ifdef HAVE_MQTT
+ m_liveDataSource(true),
+ #ifdef HAVE_MQTT
m_mqttReadyForPreview (false),
m_searching(false),
-#endif
+ m_searchTimer(new QTimer(this)),
+ m_connectTimeoutTimer(new QTimer(this)),
+ m_client(new QMqttClient(this)),
+ #endif
m_suppressRefresh(false) {
ui.setupUi(this);
#ifdef HAVE_MQTT
- m_searchTimer = new QTimer(this);
m_searchTimer->setInterval(10000);
- m_timeoutTimer = new QTimer(this);
- m_timeoutTimer->setInterval(5000);
+ m_connectTimeoutTimer->setInterval(5000);
#endif
QCompleter* completer = new QCompleter(this);
@@ -210,9 +212,6 @@ ImportFileWidget::ImportFileWidget(QWidget* parent, const \
QString& fileName) : Q ui.bManageFilters->setIcon( QIcon::fromTheme("configure") );
ui.bSaveFilter->setIcon( QIcon::fromTheme("document-save") );
ui.bRefreshPreview->setIcon( QIcon::fromTheme("view-refresh") );
-#ifdef HAVE_MQTT
- m_client = new QMqttClient(this);
-#endif
connect( ui.leFileName, SIGNAL(textChanged(QString)), \
SLOT(fileNameChanged(QString)) ); connect( ui.bOpen, SIGNAL(clicked()), this, SLOT \
(selectFile()) ); @@ -224,6 +223,7 @@ ImportFileWidget::ImportFileWidget(QWidget* \
parent, const QString& fileName) : Q connect( ui.cbReadingType, \
SIGNAL(currentIndexChanged(int)), this, SLOT(readingTypeChanged(int))); connect( \
ui.cbFilter, SIGNAL(activated(int)), SLOT(filterChanged(int)) ); connect( \
ui.bRefreshPreview, SIGNAL(clicked()), SLOT(refreshPreview()) ); +
#ifdef HAVE_MQTT
connect(ui.chbID, SIGNAL(stateChanged(int)), this, SLOT(idChecked(int)));
connect(ui.chbAuthentication, SIGNAL(stateChanged(int)), this, \
SLOT(authenticationChecked(int))); @@ -235,16 +235,14 @@ \
ImportFileWidget::ImportFileWidget(QWidget* parent, const QString& fileName) : Q \
connect(this, &ImportFileWidget::newTopic, this, &ImportFileWidget::setCompleter); \
connect(m_searchTimer, &QTimer::timeout, this, &ImportFileWidget::topicTimeout); \
connect(m_client, &QMqttClient::disconnected, this, \
&ImportFileWidget::onMqttDisconnect);
- connect(m_timeoutTimer, &QTimer::timeout, this, &ImportFileWidget::mqttTimeout);
-
+ connect(m_connectTimeoutTimer, &QTimer::timeout, this, \
&ImportFileWidget::mqttConnectTimeout); connect(ui.chbWill, \
&QCheckBox::stateChanged, this, &ImportFileWidget::useWillMessage); \
connect(ui.cbWillMessageType, static_cast<void (QComboBox::*) \
(int)>(&QComboBox::currentIndexChanged), this, \
&ImportFileWidget::willMessageTypeChanged);
- connect(ui.cbWillUpdate, static_cast<void (QComboBox::*) \
(int)>(&QComboBox::currentIndexChanged), this, &ImportFileWidget::willUpdateChanged); \
+ connect(ui.cbWillUpdate, static_cast<void (QComboBox::*) \
(int)>(&QComboBox::currentIndexChanged), this, \
&ImportFileWidget::willUpdateTypeChanged); connect(this, \
&ImportFileWidget::newTopicForWill, this, &ImportFileWidget::updateWillTopics); \
connect(m_client, &QMqttClient::errorChanged, this, \
&ImportFileWidget::mqttErrorChanged); connect(ui.cbFileType, static_cast<void \
(QComboBox::*) (int)>(&QComboBox::currentIndexChanged), [this]() {emit \
checkFileType();});
- connect(ui.leTopics, &QLineEdit::textChanged, this, \
&ImportFileWidget::searchTreeItem);
-
+ connect(ui.leTopics, &QLineEdit::textChanged, this, \
&ImportFileWidget::scrollToTreeItem); connect(ui.chbAuthentication, \
&QCheckBox::stateChanged, this, &ImportFileWidget::checkConnectEnable); \
connect(ui.chbID, &QCheckBox::stateChanged, this, \
&ImportFileWidget::checkConnectEnable); connect(ui.leHost, &QLineEdit::textChanged, \
this, &ImportFileWidget::checkConnectEnable); @@ -312,7 +310,9 @@ void \
ImportFileWidget::loadSettings() { ui.lePort->setText(conf.readEntry("Port",""));
ui.sbSampleSize->setValue(conf.readEntry("SampleSize").toInt());
ui.sbUpdateInterval->setValue(conf.readEntry("UpdateInterval").toInt());
+
#ifdef HAVE_MQTT
+ //MQTT related settings
ui.chbID->setChecked(conf.readEntry("mqttUseId").toInt());
ui.chbAuthentication->setChecked(conf.readEntry("mqttUseAuthentication").toInt());
ui.chbRetain->setChecked(conf.readEntry("mqttUseRetain").toInt());
@@ -332,12 +332,14 @@ void ImportFileWidget::loadSettings() {
}
ui.cbWillMessageType->setCurrentIndex(conf.readEntry("mqttWillMessageType").toInt());
ui.chbWill->setChecked(conf.readEntry("mqttWillUse").toInt());
+
//chbWill is unchecked by deafult, so if false is loaded it doesn't emit state \
changed signal, we have to force it if(!ui.chbWill->isChecked()) {
ui.chbWill->setChecked(true);
ui.chbWill->setChecked(false);
}
#endif
+
m_suppressRefresh = false;
refreshPreview();
}
@@ -367,7 +369,9 @@ ImportFileWidget::~ImportFileWidget() {
conf.writeEntry("Host", ui.leHost->text());
conf.writeEntry("Port", ui.lePort->text());
conf.writeEntry("UpdateInterval", ui.sbUpdateInterval->value());
+
#ifdef HAVE_MQTT
+ //MQTT related settings
conf.writeEntry("mqttUsername", ui.leUsername->text());
conf.writeEntry("mqttPassword", ui.lePassword->text());
conf.writeEntry("mqttId", ui.leID->text());
@@ -558,8 +562,10 @@ void ImportFileWidget::saveSettings(LiveDataSource* source) \
const { }
#ifdef HAVE_MQTT
+/*!
+ saves the settings to the MQTTClient \c client.
+*/
void ImportFileWidget::saveMQTTSettings(MQTTClient* client) const {
- qDebug()<<"Saving to MQTT Client";
MQTTClient::UpdateType updateType = \
static_cast<MQTTClient::UpdateType>(ui.cbUpdateType->currentIndex()); \
MQTTClient::ReadingType readingType = \
static_cast<MQTTClient::ReadingType>(ui.cbReadingType->currentIndex());
@@ -578,7 +584,6 @@ void ImportFileWidget::saveMQTTSettings(MQTTClient* client) const \
{ if (readingType != MQTTClient::ReadingType::TillEnd)
client->setSampleRate(ui.sbSampleSize->value());
- qDebug()<<"Saving mqtt";
client->setMqttClientHostPort(m_client->hostname(), m_client->port());
client->setMQTTUseAuthentication(ui.chbAuthentication->isChecked());
@@ -592,6 +597,7 @@ void ImportFileWidget::saveMQTTSettings(MQTTClient* client) const \
{ for(int i=0; i<m_mqttSubscriptions.count(); ++i) {
client->addMqttSubscriptions(m_mqttSubscriptions[i]->topic(), \
m_mqttSubscriptions[i]->qos()); }
+
client->setMqttRetain(ui.chbRetain->isChecked());
client->setWillMessageType(static_cast<MQTTClient::WillMessageType>(ui.cbWillMessageType->currentIndex()) \
); client->setWillOwnMessage(ui.leWillOwnMessage->text());
@@ -601,6 +607,7 @@ void ImportFileWidget::saveMQTTSettings(MQTTClient* client) const \
{ client->setWillTopic(ui.cbWillTopic->currentText());
client->setWillUpdateType(static_cast<MQTTClient::WillUpdateType>(ui.cbWillUpdate->currentIndex()) \
); client->setMqttWillUse(ui.chbWill->isChecked());
+
for(int i = 0; i < ui.lwWillStatistics->count(); ++i) {
QListWidgetItem* item = ui.lwWillStatistics->item(i);
if (item->checkState() == Qt::Checked)
@@ -629,108 +636,108 @@ AbstractFileFilter* ImportFileWidget::currentFileFilter() \
const {
switch (fileType) {
case AbstractFileFilter::Ascii: {
- DEBUG(" ASCII");
-//TODO std::unique_ptr<AsciiFilter> filter(new AsciiFilter());
- AsciiFilter* filter = new AsciiFilter();
-
- if (ui.cbFilter->currentIndex() == 0) //"automatic"
- filter->setAutoModeEnabled(true);
- else if (ui.cbFilter->currentIndex() == 1) { //"custom"
- filter->setAutoModeEnabled(false);
- m_asciiOptionsWidget->applyFilterSettings(filter);
- } else
- filter->loadFilterSettings( ui.cbFilter->currentText() );
-
- //save the data portion to import
- filter->setStartRow( ui.sbStartRow->value());
- filter->setEndRow( ui.sbEndRow->value() );
- filter->setStartColumn( ui.sbStartColumn->value());
- filter->setEndColumn( ui.sbEndColumn->value());
-
- return filter;
- }
+ DEBUG(" ASCII");
+ //TODO std::unique_ptr<AsciiFilter> filter(new AsciiFilter());
+ AsciiFilter* filter = new AsciiFilter();
+
+ if (ui.cbFilter->currentIndex() == 0) //"automatic"
+ filter->setAutoModeEnabled(true);
+ else if (ui.cbFilter->currentIndex() == 1) { //"custom"
+ filter->setAutoModeEnabled(false);
+ m_asciiOptionsWidget->applyFilterSettings(filter);
+ } else
+ filter->loadFilterSettings( ui.cbFilter->currentText() );
+
+ //save the data portion to import
+ filter->setStartRow( ui.sbStartRow->value());
+ filter->setEndRow( ui.sbEndRow->value() );
+ filter->setStartColumn( ui.sbStartColumn->value());
+ filter->setEndColumn( ui.sbEndColumn->value());
+
+ return filter;
+ }
case AbstractFileFilter::Binary: {
- BinaryFilter* filter = new BinaryFilter();
- if ( ui.cbFilter->currentIndex() == 0 ) //"automatic"
- filter->setAutoModeEnabled(true);
- else if ( ui.cbFilter->currentIndex() == 1 ) { //"custom"
- filter->setAutoModeEnabled(false);
- m_binaryOptionsWidget->applyFilterSettings(filter);
- } else {
- //TODO: load filter settings
-// filter->setFilterName( ui.cbFilter->currentText() );
- }
+ BinaryFilter* filter = new BinaryFilter();
+ if ( ui.cbFilter->currentIndex() == 0 ) //"automatic"
+ filter->setAutoModeEnabled(true);
+ else if ( ui.cbFilter->currentIndex() == 1 ) { //"custom"
+ filter->setAutoModeEnabled(false);
+ m_binaryOptionsWidget->applyFilterSettings(filter);
+ } else {
+ //TODO: load filter settings
+ // filter->setFilterName( ui.cbFilter->currentText() );
+ }
- filter->setStartRow( ui.sbStartRow->value() );
- filter->setEndRow( ui.sbEndRow->value() );
+ filter->setStartRow( ui.sbStartRow->value() );
+ filter->setEndRow( ui.sbEndRow->value() );
- return filter;
- }
+ return filter;
+ }
case AbstractFileFilter::Image: {
- ImageFilter* filter = new ImageFilter();
+ ImageFilter* filter = new ImageFilter();
- filter->setImportFormat(m_imageOptionsWidget->currentFormat());
- filter->setStartRow( ui.sbStartRow->value() );
- filter->setEndRow( ui.sbEndRow->value() );
- filter->setStartColumn( ui.sbStartColumn->value() );
- filter->setEndColumn( ui.sbEndColumn->value() );
+ filter->setImportFormat(m_imageOptionsWidget->currentFormat());
+ filter->setStartRow( ui.sbStartRow->value() );
+ filter->setEndRow( ui.sbEndRow->value() );
+ filter->setStartColumn( ui.sbStartColumn->value() );
+ filter->setEndColumn( ui.sbEndColumn->value() );
- return filter;
- }
+ return filter;
+ }
case AbstractFileFilter::HDF5: {
- HDF5Filter* filter = new HDF5Filter();
- QStringList names = selectedHDF5Names();
- if (!names.isEmpty())
- filter->setCurrentDataSetName(names[0]);
- filter->setStartRow( ui.sbStartRow->value() );
- filter->setEndRow( ui.sbEndRow->value() );
- filter->setStartColumn( ui.sbStartColumn->value() );
- filter->setEndColumn( ui.sbEndColumn->value() );
-
- return filter;
- }
+ HDF5Filter* filter = new HDF5Filter();
+ QStringList names = selectedHDF5Names();
+ if (!names.isEmpty())
+ filter->setCurrentDataSetName(names[0]);
+ filter->setStartRow( ui.sbStartRow->value() );
+ filter->setEndRow( ui.sbEndRow->value() );
+ filter->setStartColumn( ui.sbStartColumn->value() );
+ filter->setEndColumn( ui.sbEndColumn->value() );
+
+ return filter;
+ }
case AbstractFileFilter::NETCDF: {
- NetCDFFilter* filter = new NetCDFFilter();
+ NetCDFFilter* filter = new NetCDFFilter();
- if (!selectedNetCDFNames().isEmpty())
- filter->setCurrentVarName(selectedNetCDFNames()[0]);
- filter->setStartRow( ui.sbStartRow->value() );
- filter->setEndRow( ui.sbEndRow->value() );
- filter->setStartColumn( ui.sbStartColumn->value() );
- filter->setEndColumn( ui.sbEndColumn->value() );
+ if (!selectedNetCDFNames().isEmpty())
+ filter->setCurrentVarName(selectedNetCDFNames()[0]);
+ filter->setStartRow( ui.sbStartRow->value() );
+ filter->setEndRow( ui.sbEndRow->value() );
+ filter->setStartColumn( ui.sbStartColumn->value() );
+ filter->setEndColumn( ui.sbEndColumn->value() );
- return filter;
- }
+ return filter;
+ }
case AbstractFileFilter::FITS: {
- FITSFilter* filter = new FITSFilter();
- filter->setStartRow( ui.sbStartRow->value());
- filter->setEndRow( ui.sbEndRow->value() );
- filter->setStartColumn( ui.sbStartColumn->value());
- filter->setEndColumn( ui.sbEndColumn->value());
- return filter;
- }
+ FITSFilter* filter = new FITSFilter();
+ filter->setStartRow( ui.sbStartRow->value());
+ filter->setEndRow( ui.sbEndRow->value() );
+ filter->setStartColumn( ui.sbStartColumn->value());
+ filter->setEndColumn( ui.sbEndColumn->value());
+ return filter;
+ }
case AbstractFileFilter::Json: {
- JsonFilter* filter = new JsonFilter();
- m_jsonOptionsWidget->applyFilterSettings(filter, ui.tvJson->currentIndex());
-
- filter->setStartRow( ui.sbStartRow->value() );
- filter->setEndRow( ui.sbEndRow->value() );
- filter->setStartColumn( ui.sbStartColumn->value());
- filter->setEndColumn( ui.sbEndColumn->value());
- return filter;
- }
+ JsonFilter* filter = new JsonFilter();
+ m_jsonOptionsWidget->applyFilterSettings(filter, ui.tvJson->currentIndex());
+
+ filter->setStartRow( ui.sbStartRow->value() );
+ filter->setEndRow( ui.sbEndRow->value() );
+ filter->setStartColumn( ui.sbStartColumn->value());
+ filter->setEndColumn( ui.sbEndColumn->value());
+ return filter;
+ }
case AbstractFileFilter::ROOT: {
- ROOTFilter* filter = new ROOTFilter();
- QStringList names = selectedROOTNames();
- if (!names.isEmpty())
- filter->setCurrentHistogram(names.first());
+ ROOTFilter* filter = new ROOTFilter();
+ QStringList names = selectedROOTNames();
+ if (!names.isEmpty())
+ filter->setCurrentHistogram(names.first());
- filter->setStartBin( m_rootOptionsWidget->startBin() );
- filter->setEndBin( m_rootOptionsWidget->endBin() );
- filter->setColumns( m_rootOptionsWidget->columns() );
+ filter->setStartBin( m_rootOptionsWidget->startBin() );
+ filter->setEndBin( m_rootOptionsWidget->endBin() );
+ filter->setColumns( m_rootOptionsWidget->columns() );
- return filter;
- }
+ return filter;
+ }
case AbstractFileFilter::NgspiceRawAscii: {
NgspiceRawAsciiFilter* filter = new NgspiceRawAsciiFilter();
filter->setStartRow( ui.sbStartRow->value() );
@@ -768,708 +775,1239 @@ void ImportFileWidget::selectFile() {
ui.leFileName->setText(path);
//TODO: decide whether the selection of several files should be possible
-// QStringList filelist = QFileDialog::getOpenFileNames(this,i18n("Select one or \
more files to open"));
-// if (! filelist.isEmpty() )
-// ui.leFileName->setText(filelist.join(";"));
+ // QStringList filelist = QFileDialog::getOpenFileNames(this,i18n("Select one or \
more files to open")); + // if (! filelist.isEmpty() )
+ // ui.leFileName->setText(filelist.join(";"));
}
-/************** SLOTS \
**************************************************************/
-
/*!
- called on file name changes.
- Determines the file format (ASCII, binary etc.), if the file exists,
- and activates the corresponding options.
+ hides the MQTT related items of the widget
*/
-void ImportFileWidget::fileNameChanged(const QString& name) {
- QString fileName = name;
-#ifndef HAVE_WINDOWS
- // make relative path
- if ( !fileName.isEmpty() && fileName.at(0) != QDir::separator())
- fileName = QDir::homePath() + QDir::separator() + fileName;
-#endif
-
- bool fileExists = QFile::exists(fileName);
- if (fileExists)
- ui.leFileName->setStyleSheet("");
- else
- ui.leFileName->setStyleSheet("QLineEdit{background:red;}");
-
- ui.gbOptions->setEnabled(fileExists);
- ui.bManageFilters->setEnabled(fileExists);
- ui.cbFilter->setEnabled(fileExists);
- ui.cbFileType->setEnabled(fileExists);
- ui.bFileInfo->setEnabled(fileExists);
- ui.gbUpdateOptions->setEnabled(fileExists);
- if (!fileExists) {
- //file doesn't exist -> delete the content preview that is still potentially
- //available from the previously selected file
- ui.tePreview->clear();
- m_twPreview->clear();
- m_hdf5OptionsWidget->clear();
- m_netcdfOptionsWidget->clear();
- m_fitsOptionsWidget->clear();
- m_jsonOptionsWidget->clearModel();
- m_rootOptionsWidget->clear();
-
- emit fileNameChanged();
- return;
- }
-
- if (currentSourceType() == LiveDataSource::FileOrPipe) {
- const AbstractFileFilter::FileType fileType = \
AbstractFileFilter::fileType(fileName);
- switch(fileType) {
- case AbstractFileFilter::Ascii:
- ui.cbFileType->setCurrentIndex(AbstractFileFilter::Ascii);
- break;
- case AbstractFileFilter::Binary:
- ui.cbFileType->setCurrentIndex(AbstractFileFilter::Binary);
- break;
- case AbstractFileFilter::Image:
- ui.cbFileType->setCurrentIndex(AbstractFileFilter::Image);
- break;
- case AbstractFileFilter::HDF5:
- ui.cbFileType->setCurrentIndex(AbstractFileFilter::HDF5);
- m_hdf5OptionsWidget->updateContent((HDF5Filter*)this->currentFileFilter(), \
fileName);
- break;
- case AbstractFileFilter::NETCDF:
- ui.cbFileType->setCurrentIndex(AbstractFileFilter::NETCDF);
- m_netcdfOptionsWidget->updateContent((NetCDFFilter*)this->currentFileFilter(), \
fileName);
- break;
- case AbstractFileFilter::FITS:
-#ifdef HAVE_FITS
- ui.cbFileType->setCurrentIndex(AbstractFileFilter::FITS);
- m_fitsOptionsWidget->updateContent((FITSFilter*)this->currentFileFilter(), \
fileName);
-#endif
- break;
- case AbstractFileFilter::Json:
- ui.cbFileType->setCurrentIndex(AbstractFileFilter::Json);
- m_jsonOptionsWidget->loadDocument(fileName);
- break;
- case AbstractFileFilter::ROOT:
- ui.cbFileType->setCurrentIndex(AbstractFileFilter::ROOT);
- m_rootOptionsWidget->updateContent((ROOTFilter*)this->currentFileFilter(), \
fileName);
- break;
- case AbstractFileFilter::NgspiceRawAscii:
- ui.cbFileType->setCurrentIndex(AbstractFileFilter::NgspiceRawAscii);
- break;
- case AbstractFileFilter::NgspiceRawBinary:
- ui.cbFileType->setCurrentIndex(AbstractFileFilter::NgspiceRawBinary);
- break;
- }
- }
-
- refreshPreview();
- emit fileNameChanged();
+void ImportFileWidget::hideMQTT() {
+ ui.leID->hide();
+ ui.lMqttID->hide();
+ ui.lePassword->hide();
+ ui.lPassword->hide();
+ ui.leUsername->hide();
+ ui.lUsername->hide();
+ ui.cbQos->hide();
+ ui.lQos->hide();
+ ui.twTopics->hide();
+ ui.lTopicSearch->hide();
+ ui.leTopics->hide();
+ ui.twSubscriptions->hide();
+ ui.chbAuthentication->hide();
+ ui.chbID->hide();
+ ui.bSubscribe->hide();
+ ui.bUnsubscribe->hide();
+ ui.bConnect->hide();
+ ui.gbMqttWill->hide();
+ ui.chbWill->hide();
+ ui.chbWillRetain->hide();
+ ui.cbWillQoS->hide();
+ ui.cbWillMessageType->hide();
+ ui.cbWillTopic->hide();
+ ui.cbWillUpdate->hide();
+ ui.leWillOwnMessage->hide();
+ ui.leWillUpdateInterval->setValidator(new QIntValidator(2, 1000000) );
+ ui.leWillUpdateInterval->hide();
+ ui.lWillMessageType->hide();
+ ui.lWillOwnMessage->hide();
+ ui.lWillQos->hide();
+ ui.lWillTopic->hide();
+ ui.lWillUpdate->hide();
+ ui.lWillUpdateInterval->hide();
+ ui.lwWillStatistics->hide();
+ ui.lWillStatistics->hide();
}
+#ifdef HAVE_MQTT
/*!
- saves the current filter settings
-*/
-void ImportFileWidget::saveFilter() {
- bool ok;
- QString text = QInputDialog::getText(this, i18n("Save Filter Settings as"),
- i18n("Filter name:"), QLineEdit::Normal, \
i18n("new filter"), &ok);
- if (ok && !text.isEmpty()) {
- //TODO
- //AsciiFilter::saveFilter()
- }
+ * returns \c true if there is a valid connection to an MQTT broker and the user has \
subscribed to at least 1 topic, + * returns \c false otherwise.
+ */
+bool ImportFileWidget::isMqttValid(){
+ bool connected = (m_client->state() == QMqttClient::ClientState::Connected);
+ bool subscribed = (ui.twSubscriptions->topLevelItemCount() > 0);
+ bool fileTypeOk = false;
+ if(this->currentFileType() == AbstractFileFilter::FileType::Ascii)
+ fileTypeOk = true;
+ return connected && subscribed && fileTypeOk;
}
/*!
- opens a dialog for managing all available predefined filters.
-*/
-void ImportFileWidget::manageFilters() {
- //TODO
+ *\brief Checks if a topic contains another one
+ *
+ * \param superior the name of a topic
+ * \param inferior the name of a topic
+ * \return true if superior is equal to or contains(if superior contains wildcards) \
inferior, + * false otherwise
+ */
+bool ImportFileWidget::checkTopicContains(const QString& superior, const QString& \
inferior) { + if (superior == inferior)
+ return true;
+ else {
+ if(superior.contains("/")) {
+ QStringList superiorList = superior.split('/', QString::SkipEmptyParts);
+ QStringList inferiorList = inferior.split('/', QString::SkipEmptyParts);
+
+ //a longer topic can't contain a shorter one
+ if(superiorList.size() > inferiorList.size())
+ return false;
+
+ bool ok = true;
+ for(int i = 0; i < superiorList.size(); ++i) {
+ if(superiorList.at(i) != inferiorList.at(i)) {
+ if((superiorList.at(i) != "+") &&
+ !(superiorList.at(i) == "#" && i == superiorList.size() - 1)) {
+ qDebug() <<superiorList.at(i)<<" "<<inferiorList.at(i);
+ ok = false;
+ break;
+ }
+ }
+ }
+ return ok;
+ }
+ return false;
+ }
}
/*!
- Depending on the selected file type, activates the corresponding options in the \
data portion tab
- and populates the combobox with the available pre-defined fllter settings for the \
selected type.
-*/
-void ImportFileWidget::fileTypeChanged(int fileType) {
- ui.swOptions->setCurrentIndex(fileType);
+ *\brief Returns the "+" wildcard containing topic name, which includes the given \
topic names + *
+ * \param first the name of a topic
+ * \param second the name of a topic
+ * \return The name of the common topic, if it exists, otherwise ""
+ */
+QString ImportFileWidget::checkCommonLevel(const QString& first, const QString& \
second) { + qDebug()<<first<<" "<<second;
+ QStringList firstList = first.split('/', QString::SkipEmptyParts);
+ QStringList secondtList = second.split('/', QString::SkipEmptyParts);
+ QString commonTopic = "";
- //default
- ui.lFilter->show();
- ui.cbFilter->show();
+ if(!firstList.isEmpty()) {
+ //the two topics have to be the same size and can't be identic
+ if(firstList.size() == secondtList.size() && (first != second)) {
- //different file types show different number of tabs in ui.tabWidget.
- //when switching from the previous file type we re-set the tab widget to its \
original state
- //and remove/add the required tabs further below
- for (int i = 0; i<ui.tabWidget->count(); ++i)
- ui.tabWidget->count();
+ //the index where they differ
+ int differIndex = -1;
+ for(int i = 0; i < firstList.size(); ++i) {
+ if(firstList.at(i) != secondtList.at(i)) {
+ differIndex = i;
+ break;
+ }
+ }
- ui.tabWidget->addTab(ui.tabDataFormat, i18n("Data format"));
- ui.tabWidget->addTab(ui.tabDataPreview, i18n("Preview"));
- ui.tabWidget->addTab(ui.tabDataPortion, i18n("Data portion to read"));
-
- ui.lPreviewLines->show();
- ui.sbPreviewLines->show();
- ui.lStartColumn->show();
- ui.sbStartColumn->show();
- ui.lEndColumn->show();
- ui.sbEndColumn->show();
+ //they can differ at only one level
+ bool differ = false;
+ if(differIndex > 0) {
+ for(int j = differIndex + 1; j < firstList.size(); ++j) {
+ if(firstList.at(j) != secondtList.at(j)) {
+ differ = true;
+ break;
+ }
+ }
+ }
+ else
+ differ = true;
- showJsonModel(false);
+ if(!differ)
+ {
+ for(int i = 0; i < firstList.size(); ++i) {
+ if(i != differIndex) {
+ commonTopic.append(firstList.at(i));
+ } else {
+ //we put "+" wildcard at the level where they differ
+ commonTopic.append("+");
+ }
- switch (fileType) {
- case AbstractFileFilter::Ascii:
- break;
- case AbstractFileFilter::Binary:
- ui.lStartColumn->hide();
- ui.sbStartColumn->hide();
- ui.lEndColumn->hide();
- ui.sbEndColumn->hide();
- break;
- case AbstractFileFilter::ROOT:
- ui.tabWidget->removeTab(1);
- // falls through
- case AbstractFileFilter::HDF5:
- case AbstractFileFilter::NETCDF:
- case AbstractFileFilter::FITS:
- ui.lFilter->hide();
- ui.cbFilter->hide();
- // hide global preview tab. we have our own
- ui.tabWidget->setTabText(0, i18n("Data format && preview"));
- ui.tabWidget->removeTab(1);
- ui.tabWidget->setCurrentIndex(0);
- break;
- case AbstractFileFilter::Image:
- ui.lPreviewLines->hide();
- ui.sbPreviewLines->hide();
- ui.lFilter->hide();
- ui.cbFilter->hide();
- break;
- case AbstractFileFilter::NgspiceRawAscii:
- case AbstractFileFilter::NgspiceRawBinary:
- ui.lStartColumn->hide();
- ui.sbStartColumn->hide();
- ui.lEndColumn->hide();
- ui.sbEndColumn->hide();
- ui.tabWidget->removeTab(0);
- ui.tabWidget->setCurrentIndex(0);
- break;
- case AbstractFileFilter::Json:
- ui.lFilter->hide();
- ui.cbFilter->hide();
- showJsonModel(true);
- break;
- default:
- DEBUG("unknown file type");
+ if(i != firstList.size() - 1)
+ commonTopic.append("/");
+ }
+ }
+ }
}
- m_hdf5OptionsWidget->clear();
- m_netcdfOptionsWidget->clear();
- m_rootOptionsWidget->clear();
-
- int lastUsedFilterIndex = ui.cbFilter->currentIndex();
- ui.cbFilter->clear();
- ui.cbFilter->addItem( i18n("Automatic") );
- ui.cbFilter->addItem( i18n("Custom") );
-
- //TODO: populate the combobox with the available pre-defined filter settings for \
the selected type
- ui.cbFilter->setCurrentIndex(lastUsedFilterIndex);
- filterChanged(lastUsedFilterIndex);
-
- refreshPreview();
+ qDebug() << "Common topic: "<<commonTopic;
+ return commonTopic;
}
+/*!
+ *\brief Returns the index of level where the two topic names differ, if there is a \
common topic for them + *
+ * \param first the name of a topic
+ * \param second the name of a topic
+ * \return The index of the unequal level, if there is a common topic, otherwise -1
+ */
+int ImportFileWidget::commonLevelIndex(const QString& first, const QString& second) \
{ + qDebug()<<first<<" "<<second;
+ QStringList firstList = first.split('/', QString::SkipEmptyParts);
+ QStringList secondtList = second.split('/', QString::SkipEmptyParts);
+ QString commonTopic = "";
+ int differIndex = -1;
-const QStringList ImportFileWidget::selectedHDF5Names() const {
- return m_hdf5OptionsWidget->selectedHDF5Names();
-}
-
-const QStringList ImportFileWidget::selectedNetCDFNames() const {
- return m_netcdfOptionsWidget->selectedNetCDFNames();
-}
+ if(!firstList.isEmpty()) {
+ //the two topics have to be the same size and can't be identic
+ if(firstList.size() == secondtList.size() && (first != second)) {
-const QStringList ImportFileWidget::selectedFITSExtensions() const {
- return m_fitsOptionsWidget->selectedFITSExtensions();
-}
+ //the index where they differ
+ for(int i = 0; i < firstList.size(); ++i) {
+ if(firstList.at(i) != secondtList.at(i)) {
+ differIndex = i;
+ break;
+ }
+ }
-const QStringList ImportFileWidget::selectedROOTNames() const {
- return m_rootOptionsWidget->selectedROOTNames();
-}
+ //they can differ at only one level
+ bool differ = false;
+ if(differIndex > 0) {
+ for(int j = differIndex + 1; j < firstList.size(); ++j) {
+ if(firstList.at(j) != secondtList.at(j)) {
+ differ = true;
+ break;
+ }
+ }
+ }
+ else
+ differ = true;
-/*!
- shows the dialog with the information about the file(s) to be imported.
-*/
-void ImportFileWidget::fileInfoDialog() {
- QStringList files = ui.leFileName->text().split(';');
- FileInfoDialog* dlg = new FileInfoDialog(this);
- dlg->setFiles(files);
- dlg->exec();
-}
+ if(!differ)
+ {
+ for(int i = 0; i < firstList.size(); ++i) {
+ if(i != differIndex)
+ commonTopic.append(firstList.at(i));
+ else
+ commonTopic.append("+");
-/*!
- enables the options if the filter "custom" was chosen. Disables the options \
otherwise.
-*/
-void ImportFileWidget::filterChanged(int index) {
- // ignore filter for these formats
- if (ui.cbFileType->currentIndex() == AbstractFileFilter::HDF5 ||
- ui.cbFileType->currentIndex() == AbstractFileFilter::NETCDF ||
- ui.cbFileType->currentIndex() == AbstractFileFilter::Image ||
- ui.cbFileType->currentIndex() == AbstractFileFilter::FITS ||
- ui.cbFileType->currentIndex() == AbstractFileFilter::Json ||
- ui.cbFileType->currentIndex() == AbstractFileFilter::ROOT) {
- ui.swOptions->setEnabled(true);
- return;
+ if(i != firstList.size() - 1)
+ commonTopic.append("/");
+ }
+ }
+ }
}
- if (index == 0) { // "automatic"
- ui.swOptions->setEnabled(false);
- ui.bSaveFilter->setEnabled(false);
- } else if (index == 1) { //custom
- ui.swOptions->setEnabled(true);
- ui.bSaveFilter->setEnabled(true);
- } else {
- // predefined filter settings were selected.
- //load and show them in the GUI.
- //TODO
- }
+ qDebug() << "Common topic: "<<commonTopic;
+ qDebug() << "differ Index: "<<differIndex;
+ //if there is a common topic we return the differIndex
+ if(!commonTopic.isEmpty())
+ return differIndex;
+ else
+ return -1;
}
-void ImportFileWidget::refreshPreview() {
- if (m_suppressRefresh)
- return;
+/*!
+ *\brief Unsubscribes from the given topic, and removes any data connected to it
+ *
+ * \param topicName the name of a topic we want to unsubscribe from
+ */
+void ImportFileWidget::unsubscribeFromTopic(const QString& topicName) {
+ if(!topicName.isEmpty()) {
+ QMqttTopicFilter filter{topicName};
+ m_client->unsubscribe(filter);
- WAIT_CURSOR;
+ qDebug()<<"unsubscribe occured";
- QString fileName = ui.leFileName->text();
-#ifndef HAVE_WINDOWS
- if (!fileName.isEmpty() && fileName.at(0) != QDir::separator())
- fileName = QDir::homePath() + QDir::separator() + fileName;
-#endif
- DEBUG("refreshPreview(): file name = " << fileName.toStdString());
+ for(int i = 0; i< m_mqttSubscriptions.count(); ++i)
+ if(m_mqttSubscriptions[i]->topic().filter() == topicName) {
+ m_mqttSubscriptions.remove(i);
+ break;
+ }
- QVector<QStringList> importedStrings;
- AbstractFileFilter::FileType fileType = \
(AbstractFileFilter::FileType)ui.cbFileType->currentIndex(); + m_mqttReadyForPreview \
= false;
- // generic table widget
- if (fileType == AbstractFileFilter::Ascii || fileType == AbstractFileFilter::Binary
- || fileType == AbstractFileFilter::Json || fileType == \
AbstractFileFilter::NgspiceRawAscii
- || fileType == AbstractFileFilter::NgspiceRawBinary)
- m_twPreview->show();
- else
- m_twPreview->hide();
+ QMapIterator<QMqttTopicName, bool> i(m_messageArrived);
+ while(i.hasNext()) {
+ i.next();
+ if(checkTopicContains(topicName, i.key().name())) {
+ m_messageArrived.remove(i.key());
+ }
+ }
- int lines = ui.sbPreviewLines->value();
+ QMapIterator<QMqttTopicName, QMqttMessage> j(m_lastMessage);
+ while(j.hasNext()) {
+ j.next();
+ if(checkTopicContains(topicName, j.key().name())) {
+ m_lastMessage.remove(j.key());
+ }
+ }
- bool ok = true;
- QTableWidget* tmpTableWidget{nullptr};
- QStringList vectorNameList;
- QVector<AbstractColumn::ColumnMode> columnModes;
- DEBUG("Data File Type: " << ENUM_TO_STRING(AbstractFileFilter, FileType, \
fileType));
- switch (fileType) {
- case AbstractFileFilter::Ascii: {
- ui.tePreview->clear();
+ for(int row = 0; row<ui.twSubscriptions->topLevelItemCount(); row++) {
+ if(ui.twSubscriptions->topLevelItem(row)->text(0) == topicName) {
+ ui.twSubscriptions->topLevelItem(row)->takeChildren();
+ ui.twSubscriptions->takeTopLevelItem(row);
+ }
+ }
- AsciiFilter* filter = static_cast<AsciiFilter*>(this->currentFileFilter());
+ for(int i = 0; i < m_subscribedTopicNames.size(); ++i) {
+ if(checkTopicContains(topicName, m_subscribedTopicNames[i])) {
+ m_subscribedTopicNames.remove(i);
+ i--;
+ }
+ }
- DEBUG("Data Source Type: " << ENUM_TO_STRING(LiveDataSource, SourceType, \
currentSourceType()));
- switch (currentSourceType()) {
- case LiveDataSource::SourceType::FileOrPipe: {
- importedStrings = filter->preview(fileName, lines);
- break;
- }
- case LiveDataSource::SourceType::LocalSocket: {
- QLocalSocket lsocket{this};
- DEBUG("Local socket: CONNECT PREVIEW");
- lsocket.connectToServer(fileName, QLocalSocket::ReadOnly);
- if (lsocket.waitForConnected()) {
- DEBUG("connected to local socket " << fileName.toStdString());
- if (lsocket.waitForReadyRead())
- importedStrings = filter->preview(lsocket);
- DEBUG("Local socket: DISCONNECT PREVIEW");
- lsocket.disconnectFromServer();
- // read-only socket is disconnected immediately (no waitForDisconnected())
- } else {
- DEBUG("failed connect to local socket " << fileName.toStdString() << " - " << \
lsocket.errorString().toStdString());
- }
+ for(int item = 0; item < ui.cbWillTopic->count(); ++item) {
+ if(checkTopicContains(topicName, ui.cbWillTopic->itemText(item))) {
+ ui.cbWillTopic->removeItem(item);
+ item--;
+ }
+ }
- break;
- }
- case LiveDataSource::SourceType::NetworkTcpSocket: {
- QTcpSocket tcpSocket{this};
- tcpSocket.connectToHost(host(), port().toInt(), QTcpSocket::ReadOnly);
- if (tcpSocket.waitForConnected()) {
- DEBUG("connected to TCP socket");
- if ( tcpSocket.waitForReadyRead() )
- importedStrings = filter->preview(tcpSocket);
-
- tcpSocket.disconnectFromHost();
- } else {
- DEBUG("failed to connect to TCP socket " << " - " << \
tcpSocket.errorString().toStdString());
- }
+ //signals that there was a change among the subscribed topics
+ emit subscriptionsChanged();
+ refreshPreview();
+ }
+}
- break;
- }
- case LiveDataSource::SourceType::NetworkUdpSocket: {
- QUdpSocket udpSocket{this};
- DEBUG("UDP Socket: CONNECT PREVIEW, state = " << udpSocket.state());
- udpSocket.bind(QHostAddress(host()), port().toInt());
- udpSocket.connectToHost(host(), 0, QUdpSocket::ReadOnly);
- if (udpSocket.waitForConnected()) {
- DEBUG(" connected to UDP socket " << host().toStdString() << ':' << \
port().toInt());
- if (!udpSocket.waitForReadyRead(2000) )
- DEBUG(" ERROR: not ready for read after 2 sec");
- if (udpSocket.hasPendingDatagrams()) {
- DEBUG(" has pending data");
- } else {
- DEBUG(" has no pending data");
- }
- importedStrings = filter->preview(udpSocket);
-
- DEBUG("UDP Socket: DISCONNECT PREVIEW, state = " << udpSocket.state());
- udpSocket.disconnectFromHost();
- } else {
- DEBUG("failed to connect to UDP socket " << " - " << \
udpSocket.errorString().toStdString());
- }
-
- break;
- }
- case LiveDataSource::SourceType::SerialPort: {
- QSerialPort sPort{this};
- DEBUG(" Port name: " << serialPort().toStdString());
- DEBUG(" Settings: " << baudRate() << ',' << sPort.dataBits() << ',' << \
sPort.parity()
- << ',' << sPort.stopBits());
- sPort.setPortName(serialPort());
- sPort.setBaudRate(baudRate());
-
- if (sPort.open(QIODevice::ReadOnly)) {
- if (sPort.waitForReadyRead(2000))
- importedStrings = filter->preview(sPort);
- else {
- DEBUG(" ERROR: not ready for read after 2 sec");
- }
-
- sPort.close();
- } else {
- DEBUG(" ERROR: failed to open serial port. error: " << sPort.error());
- }
- break;
+/*!
+ *\brief Adds to a # wildcard containing topic, every topic present in twTopics that \
the former topic contains + *
+ * \param topic pointer to the TreeWidgetItem which was selected before subscribing
+ * \param subscription pointer to the TreeWidgetItem which represents the new \
subscirption, + * we add all of the children to this item
+ */
+void ImportFileWidget::addSubscriptionChildren(QTreeWidgetItem * topic, \
QTreeWidgetItem * subscription) { + //if the topic doesn't have any children we don't \
do anything + if(topic->childCount() > 0) {
+ for(int i = 0; i < topic->childCount(); ++i) {
+ QTreeWidgetItem* temp = topic->child(i);
+ QString name;
+ //if it has children, then we add it as a # wildcrad containing topic
+ if(topic->child(i)->childCount() > 0) {
+ name.append(temp->text(0) + "/#");
+ while(temp->parent() != nullptr) {
+ temp = temp->parent();
+ name.prepend(temp->text(0) + "/");
}
- case LiveDataSource::SourceType::MQTT: {
-#ifdef HAVE_MQTT
- qDebug()<<"preview mqtt, is it ready:"<<m_mqttReadyForPreview;
- if(m_mqttReadyForPreview)
- {
- filter->vectorNames().clear();
- QMapIterator<QMqttTopicName, QMqttMessage> i(m_lastMessage);
- while(i.hasNext()) {
- i.next();
- qDebug()<<"calling ascii mqtt preview"<< importedStrings << " \
"<<QString(i.value().payload().data())
- << " "<< i.key().name();
- filter->mqttPreview(importedStrings, QString(i.value().payload().data()), \
i.key().name() );
- if(importedStrings.isEmpty())
- break;
- }
- QMapIterator<QMqttTopicName, bool> j(m_messageArrived);
- while(j.hasNext()) {
- j.next();
- qDebug()<<"Set false after preview: "<<j.key().name();
- m_messageArrived[j.key()] = false;
- }
- m_mqttReadyForPreview = false;
- }
-#endif
- break;
}
+ //if not then we simply add the topic itself
+ else {
+ name.append(temp->text(0));
+ while(temp->parent() != nullptr) {
+ temp = temp->parent();
+ name.prepend(temp->text(0) + "/");
+ }
}
-
- tmpTableWidget = m_twPreview;
- vectorNameList = filter->vectorNames();
- columnModes = filter->columnModes();
- break;
- }
- case AbstractFileFilter::Binary: {
- ui.tePreview->clear();
- BinaryFilter *filter = (BinaryFilter *)this->currentFileFilter();
- importedStrings = filter->preview(fileName, lines);
- tmpTableWidget = m_twPreview;
- break;
- }
- case AbstractFileFilter::Image: {
- ui.tePreview->clear();
-
- QImage image(fileName);
- QTextCursor cursor = ui.tePreview->textCursor();
- cursor.insertImage(image);
- RESET_CURSOR;
- return;
- }
- case AbstractFileFilter::HDF5: {
- HDF5Filter *filter = (HDF5Filter *)this->currentFileFilter();
- lines = m_hdf5OptionsWidget->lines();
- importedStrings = filter->readCurrentDataSet(fileName, NULL, ok, \
AbstractFileFilter::Replace, lines);
- tmpTableWidget = m_hdf5OptionsWidget->previewWidget();
- break;
- }
- case AbstractFileFilter::NETCDF: {
- NetCDFFilter *filter = (NetCDFFilter *)this->currentFileFilter();
- lines = m_netcdfOptionsWidget->lines();
- importedStrings = filter->readCurrentVar(fileName, NULL, \
AbstractFileFilter::Replace, lines);
- tmpTableWidget = m_netcdfOptionsWidget->previewWidget();
- break;
+ QStringList nameList;
+ nameList.append(name);
+ QTreeWidgetItem* childItem = new QTreeWidgetItem(nameList);
+ subscription->addChild(childItem);
+ //we use the function recursively on the given item
+ addSubscriptionChildren(topic->child(i), childItem);
}
- case AbstractFileFilter::FITS: {
- FITSFilter* filter = (FITSFilter*)this->currentFileFilter();
- lines = m_fitsOptionsWidget->lines();
-
- // update file name (may be any file type)
- m_fitsOptionsWidget->updateContent(filter, fileName);
- QString extensionName = m_fitsOptionsWidget->extensionName(&ok);
- if (!extensionName.isEmpty()) {
- DEBUG(" extension name = " << extensionName.toStdString());
- fileName = extensionName;
- }
- DEBUG(" file name = " << fileName.toStdString());
-
- bool readFitsTableToMatrix;
- importedStrings = filter->readChdu(fileName, &readFitsTableToMatrix, lines);
- emit checkedFitsTableToMatrix(readFitsTableToMatrix);
+ }
+}
- tmpTableWidget = m_fitsOptionsWidget->previewWidget();
- break;
- }
- case AbstractFileFilter::Json: {
- ui.tePreview->clear();
- m_jsonOptionsWidget->loadDocument(fileName);
- JsonFilter *filter = (JsonFilter*)this->currentFileFilter();
- m_jsonOptionsWidget->applyFilterSettings(filter, ui.tvJson->currentIndex());
- importedStrings = filter->preview(fileName);
- tmpTableWidget = m_twPreview;
- columnModes = filter->columnModes();
- break;
- }
- case AbstractFileFilter::ROOT: {
- ROOTFilter *filter = (ROOTFilter *)this->currentFileFilter();
- lines = m_rootOptionsWidget->lines();
- m_rootOptionsWidget->setNBins(filter->binsInCurrentHistogram(fileName));
- importedStrings = filter->previewCurrentHistogram(
- fileName,
- m_rootOptionsWidget->startBin(),
- qMin(m_rootOptionsWidget->startBin() + m_rootOptionsWidget->lines() - 1,
- m_rootOptionsWidget->endBin())
- );
- tmpTableWidget = m_rootOptionsWidget->previewWidget();
- // the last vector element contains the column names
- vectorNameList = importedStrings.last();
- importedStrings.removeLast();
- columnModes = QVector<AbstractColumn::ColumnMode>(vectorNameList.size(), \
AbstractColumn::Numeric);
- break;
- }
- case AbstractFileFilter::NgspiceRawAscii: {
- ui.tePreview->clear();
- NgspiceRawAsciiFilter* filter = \
(NgspiceRawAsciiFilter*)this->currentFileFilter();
- importedStrings = filter->preview(fileName, lines);
- tmpTableWidget = m_twPreview;
- vectorNameList = filter->vectorNames();
- columnModes = filter->columnModes();
- break;
- }
- case AbstractFileFilter::NgspiceRawBinary: {
- ui.tePreview->clear();
- NgspiceRawBinaryFilter* filter = \
(NgspiceRawBinaryFilter*)this->currentFileFilter();
- importedStrings = filter->preview(fileName, lines);
- tmpTableWidget = m_twPreview;
- vectorNameList = filter->vectorNames();
- columnModes = filter->columnModes();
- break;
+/*!
+ *\brief Fills the children vector, with the root item's (twSubscriptions) leaf \
children (meaning no wildcard containing topics) + *
+ * \param children vector of TreeWidgetItem pointers
+ * \param root pointer to a TreeWidgetItem of twSubscriptions
+ */
+void ImportFileWidget::findSubscriptionLeafChildren(QVector<QTreeWidgetItem *>& \
children, QTreeWidgetItem* root) { + if(root->childCount() == 0) {
+ children.push_back(root);
+ } else {
+ for(int i = 0; i < root->childCount(); ++i) {
+ findSubscriptionLeafChildren(children, root->child(i));
}
}
+}
- // fill the table widget
- tmpTableWidget->setRowCount(0);
- tmpTableWidget->setColumnCount(0);
- if( !importedStrings.isEmpty() ) {
- //QDEBUG("importedStrings =" << importedStrings);
- if (!ok) {
- // show imported strings as error message
- tmpTableWidget->setRowCount(1);
- tmpTableWidget->setColumnCount(1);
- QTableWidgetItem* item = new QTableWidgetItem();
- item->setText(importedStrings[0][0]);
- tmpTableWidget->setItem(0, 0, item);
+/*!
+ *\brief Returns the amount of topics that the "+" wildcard will replace in the \
level position + *
+ * \param levelIdx the level currently being investigated
+ * \param level the level where the new + wildcard will be placed
+ * \param commonList the topic name split into levels
+ * \param currentItem pointer to a TreeWidgetItem which represents the parent of the \
level + * represented by levelIdx
+ * \return returns the childCount, or -1 if some topics already represented by + \
wildcard have different + * amount of children
+ */
+int ImportFileWidget::checkCommonChildCount(int levelIdx, int level, QStringList& \
commonList, QTreeWidgetItem* currentItem) { + //we recursively check the number of \
children, until we get to level-1 + if(levelIdx < level - 1) {
+ if(commonList[levelIdx] != "+") {
+ for(int j = 0; j < currentItem->childCount(); ++j) {
+ if(currentItem->child(j)->text(0) == commonList[levelIdx]) {
+ //if the level isn't represented by + wildcard we simply return the amount of \
children of the corresponding item, recursively + return \
checkCommonChildCount(levelIdx + 1, level, commonList, currentItem->child(j)); + }
+ }
} else {
- //TODO: maxrows not used
- const int rows = qMax(importedStrings.size(), 1);
- const int maxColumns = 300;
- tmpTableWidget->setRowCount(rows);
-
- for (int i = 0; i < rows; ++i) {
-// QDEBUG("imported string " << importedStrings[i]);
-
- int cols = importedStrings[i].size() > maxColumns ? maxColumns : \
importedStrings[i].size(); // new
- if (cols > tmpTableWidget->columnCount())
- tmpTableWidget->setColumnCount(cols);
+ int childCount = -1;
+ bool ok = true;
- for (int j = 0; j < cols; ++j) {
- QTableWidgetItem* item = new QTableWidgetItem(importedStrings[i][j]);
- tmpTableWidget->setItem(i, j, item);
+ //otherwise we check if every + wildcard represented topic has the same number of \
children, recursively + for(int j = 0; j < currentItem->childCount(); ++j) {
+ int temp = checkCommonChildCount(levelIdx + 1, level, commonList, \
currentItem->child(j)); + if((j > 0) && (temp != childCount)) {
+ ok = false;
+ break;
}
+ childCount = temp;
}
- // set header if columnMode available
- for (int i = 0; i < qMin(tmpTableWidget->columnCount(), columnModes.size()); ++i) \
{
- QString columnName = QString::number(i+1);
- if (i < vectorNameList.size())
- columnName = vectorNameList[i];
- auto* item = new QTableWidgetItem(columnName + QLatin1String(" {") + \
ENUM_TO_STRING(AbstractColumn, ColumnMode, columnModes[i]) + \
QLatin1String("}"));
- item->setTextAlignment(Qt::AlignLeft);
- item->setIcon(AbstractColumn::iconForMode(columnModes[i]));
+ //if yes we return this number, otherwise -1
+ if(ok)
+ return childCount;
+ else
+ return -1;
+ }
+ } else if (levelIdx == level - 1) {
+ if(commonList[levelIdx] != "+") {
+ for(int j = 0; j < currentItem->childCount(); ++j) {
+ if(currentItem->child(j)->text(0) == commonList[levelIdx]) {
+ //if the level isn't represented by + wildcard we simply return the amount of \
children of the corresponding item + return currentItem->child(j)->childCount();
+ }
+ }
+ } else {
+ int childCount = -1;
+ bool ok = true;
- tmpTableWidget->setHorizontalHeaderItem(i, item);
+ //otherwise we check if every + wildcard represented topic has the same number of \
children + for(int j = 0; j < currentItem->childCount(); ++j) {
+ if((j > 0) && (currentItem->child(j)->childCount() != childCount)) {
+ ok = false;
+ break;
+ }
+ childCount = currentItem->child(j)->childCount();
}
+
+ //if yes we return this number, otherwise -1
+ if(ok)
+ return childCount;
+ else
+ return -1;
}
- tmpTableWidget->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
- m_fileEmpty = false;
- } else {
- m_fileEmpty = true;
+ } else if (level == 1 && levelIdx == 1) {
+ return currentItem->childCount();
}
- emit previewRefreshed();
-
- RESET_CURSOR;
+ return -1;
}
-void ImportFileWidget::updateTypeChanged(int idx) {
- LiveDataSource::UpdateType type = static_cast<LiveDataSource::UpdateType>(idx);
+/*!
+ *\brief We search in twSubscriptions for topics that can be represented using + \
wildcards, then merge them. + * We do this until there are no topics to merge
+ */
+void ImportFileWidget::manageCommonLevelSubscriptions() {
+ bool foundEqual = false;
- switch (type) {
- case LiveDataSource::UpdateType::TimeInterval:
- ui.lUpdateInterval->show();
- ui.sbUpdateInterval->show();
- break;
- case LiveDataSource::UpdateType::NewData:
- ui.lUpdateInterval->hide();
- ui.sbUpdateInterval->hide();
- }
-}
+ do{
+ foundEqual = false;
+ QMap<QString, QVector<QString>> equalTopicsMap;
+ QVector<QString> equalTopics;
-void ImportFileWidget::readingTypeChanged(int idx) {
- LiveDataSource::ReadingType type = static_cast<LiveDataSource::ReadingType>(idx);
+ //compare the subscriptions present in the TreeWidget
+ for(int i = 0; i < ui.twSubscriptions->topLevelItemCount() - 1; ++i) {
+ for(int j = i + 1; j < ui.twSubscriptions->topLevelItemCount(); ++j) {
+ qDebug()<<ui.twSubscriptions->topLevelItem(i)->text(0)<<" \
"<<ui.twSubscriptions->topLevelItem(j)->text(0); + QString commonTopic = \
checkCommonLevel(ui.twSubscriptions->topLevelItem(i)->text(0), \
ui.twSubscriptions->topLevelItem(j)->text(0));
- if (type == LiveDataSource::ReadingType::TillEnd || type == \
LiveDataSource::ReadingType::WholeFile) {
- ui.lSampleSize->hide();
- ui.sbSampleSize->hide();
- } else {
- ui.lSampleSize->show();
- ui.sbSampleSize->show();
- }
+ //if there is a common topic for the 2 compared topics, we add them to the map \
(using the common topic as key) + if(!commonTopic.isEmpty()) {
+ if(!equalTopicsMap[commonTopic].contains(ui.twSubscriptions->topLevelItem(i)->text(0))) \
{ + equalTopicsMap[commonTopic].push_back(ui.twSubscriptions->topLevelItem(i)->text(0));
+ }
- if (type == LiveDataSource::ReadingType::WholeFile) {
- ui.lKeepLastValues->hide();
- ui.sbKeepNValues->hide();
- } else {
- ui.lKeepLastValues->show();
- ui.sbKeepNValues->show();
- }
-}
+ if(!equalTopicsMap[commonTopic].contains(ui.twSubscriptions->topLevelItem(j)->text(0))) \
{ + qDebug()<<commonTopic<<": "<<ui.twSubscriptions->topLevelItem(i)->text(0);
+ equalTopicsMap[commonTopic].push_back(ui.twSubscriptions->topLevelItem(j)->text(0));
+ }
+ }
+ }
+ }
-void ImportFileWidget::sourceTypeChanged(int idx) {
- LiveDataSource::SourceType type = static_cast<LiveDataSource::SourceType>(idx);
+ if(!equalTopicsMap.isEmpty()) {
+ qDebug()<<"Equal topics not empty";
- switch (type) {
- case LiveDataSource::SourceType::FileOrPipe:
- ui.lFileName->show();
- ui.leFileName->show();
- ui.bFileInfo->show();
- ui.bOpen->show();
- ui.chbLinkFile->show();
-
- ui.cbBaudRate->hide();
- ui.lBaudRate->hide();
- ui.lHost->hide();
- ui.leHost->hide();
- ui.lPort->hide();
- ui.lePort->hide();
- ui.cbSerialPort->hide();
- ui.lSerialPort->hide();
-
- fileNameChanged(ui.leFileName->text());
- break;
- case LiveDataSource::SourceType::LocalSocket:
- ui.lFileName->show();
- ui.leFileName->show();
- ui.bOpen->show();
-
- ui.bFileInfo->hide();
- ui.cbBaudRate->hide();
- ui.lBaudRate->hide();
- ui.lHost->hide();
- ui.leHost->hide();
- ui.lPort->hide();
- ui.lePort->hide();
- ui.cbSerialPort->hide();
- ui.lSerialPort->hide();
- ui.chbLinkFile->hide();
-
- ui.gbOptions->setEnabled(true);
- ui.bManageFilters->setEnabled(true);
- ui.cbFilter->setEnabled(true);
- ui.cbFileType->setEnabled(true);
- break;
- case LiveDataSource::SourceType::NetworkTcpSocket:
- case LiveDataSource::SourceType::NetworkUdpSocket:
- ui.lHost->show();
- ui.leHost->show();
- ui.lePort->show();
- ui.lPort->show();
-
- ui.lBaudRate->hide();
- ui.cbBaudRate->hide();
- ui.lSerialPort->hide();
- ui.cbSerialPort->hide();
-
- ui.lFileName->hide();
- ui.leFileName->hide();
- ui.bFileInfo->hide();
- ui.bOpen->hide();
- ui.chbLinkFile->hide();
-
- ui.gbOptions->setEnabled(true);
- ui.bManageFilters->setEnabled(true);
- ui.cbFilter->setEnabled(true);
- ui.cbFileType->setEnabled(true);
- break;
- case LiveDataSource::SourceType::SerialPort:
- ui.lBaudRate->show();
- ui.cbBaudRate->show();
- ui.lSerialPort->show();
- ui.cbSerialPort->show();
-
- ui.lHost->hide();
- ui.leHost->hide();
- ui.lePort->hide();
- ui.lPort->hide();
- ui.lFileName->hide();
- ui.leFileName->hide();
- ui.bFileInfo->hide();
- ui.bOpen->hide();
- ui.chbLinkFile->hide();
- ui.cbFileType->setEnabled(true);
-
- ui.gbOptions->setEnabled(true);
- ui.bManageFilters->setEnabled(true);
- ui.cbFilter->setEnabled(true);
- break;
+ QVector<QString> commonTopics;
+ QMapIterator<QString, QVector<QString>> topics(equalTopicsMap);
- case LiveDataSource::SourceType::MQTT:
-#ifdef HAVE_MQTT
+ //check for every map entry, if the found topics can be merged or not
+ while(topics.hasNext()) {
+ topics.next();
- ui.lBaudRate->hide();
- ui.cbBaudRate->hide();
- ui.lSerialPort->hide();
- ui.cbSerialPort->hide();
+ int level = commonLevelIndex(topics.value().last(), topics.value().first());
+ QStringList commonList = topics.value().first().split('/', \
QString::SkipEmptyParts); + QTreeWidgetItem* currentItem;
+ //search the corresponding item to the common topics first level(root)
+ for(int i = 0; i < ui.twTopics->topLevelItemCount(); ++i) {
+ if(ui.twTopics->topLevelItem(i)->text(0) == commonList.first()) {
+ currentItem = ui.twTopics->topLevelItem(i);
+ break;
+ }
+ }
- ui.lHost->show();
- ui.leHost->show();
- ui.lePort->show();
- ui.lPort->show();
- ui.lFileName->hide();
+ //calculate the number of topics the new + wildcard could replace
+ int childCount = checkCommonChildCount(1, level, commonList, currentItem);
+ if(childCount > 0) {
+ //if the number of topics found and the calculated number of topics is equal, \
the topics can be merged + if(topics.value().size() == childCount) {
+ foundEqual = true;
+ commonTopics.push_back(topics.key());
+ }
+ }
+ }
+
+ if(foundEqual) {
+ //if there are more common topics, the topics of which can be merged, we choose \
the one which has the lowest level new "+" wildcard + int lowestLevel = INT_MAX;
+ int topicIdx = -1;
+ for(int i = 0; i < commonTopics.size(); ++i) {
+ int level = commonLevelIndex(equalTopicsMap[commonTopics[i]].first(), \
commonTopics[i]); + if(level < lowestLevel) {
+ topicIdx = i;
+ lowestLevel = level;
+ }
+ }
+
+ equalTopics.append(equalTopicsMap[commonTopics[topicIdx]]);
+
+ qDebug()<<"Adding common topic";
+ //Add the common topic ("merging")
+ QString commonTopic;
+ commonTopic = checkCommonLevel(equalTopics.first(), equalTopics.last());
+ QStringList nameList;
+ nameList.append(commonTopic);
+ QTreeWidgetItem* newTopic = new QTreeWidgetItem(nameList);
+ ui.twSubscriptions->addTopLevelItem(newTopic);
+ QMqttTopicFilter filter {commonTopic};
+ QMqttSubscription *temp_subscription = m_client->subscribe(filter, \
static_cast<quint8> (ui.cbQos->currentText().toUInt()) ); +
+ if(temp_subscription) {
+ m_mqttSubscriptions.push_back(temp_subscription);
+ connect(temp_subscription, &QMqttSubscription::messageReceived, this, \
&ImportFileWidget::mqttSubscriptionMessageReceived); + emit \
subscriptionsChanged(); + }
+
+ //remove the "merged" topics
+ qDebug()<<"unsubscribe from equal topics";
+ for(int i = 0; i < equalTopics.size(); ++i) {
+ for(int j = 0; j < ui.twSubscriptions->topLevelItemCount(); ++j){
+ if(ui.twSubscriptions->topLevelItem(j)->text(0) == equalTopics[i]) {
+ newTopic->addChild(ui.twSubscriptions->takeTopLevelItem(j));
+ unsubscribeFromTopic(equalTopics[i]);
+ break;
+ }
+ }
+ }
+
+ //remove any subscription that the new subscription contains
+ for(int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
+ if(checkTopicContains(commonTopic, \
ui.twSubscriptions->topLevelItem(i)->text(0)) && + commonTopic != \
ui.twSubscriptions->topLevelItem(i)->text(0) ) { \
+ unsubscribeFromTopic(ui.twSubscriptions->topLevelItem(i)->text(0)); \
+ i--; + }
+ }
+ }
+ }
+ } while(foundEqual);
+}
+#endif
+
+/************** SLOTS \
**************************************************************/ +
+/*!
+ called on file name changes.
+ Determines the file format (ASCII, binary etc.), if the file exists,
+ and activates the corresponding options.
+*/
+void ImportFileWidget::fileNameChanged(const QString& name) {
+ QString fileName = name;
+#ifndef HAVE_WINDOWS
+ // make relative path
+ if ( !fileName.isEmpty() && fileName.at(0) != QDir::separator())
+ fileName = QDir::homePath() + QDir::separator() + fileName;
+#endif
+
+ bool fileExists = QFile::exists(fileName);
+ if (fileExists)
+ ui.leFileName->setStyleSheet("");
+ else
+ ui.leFileName->setStyleSheet("QLineEdit{background:red;}");
+
+ ui.gbOptions->setEnabled(fileExists);
+ ui.bManageFilters->setEnabled(fileExists);
+ ui.cbFilter->setEnabled(fileExists);
+ ui.cbFileType->setEnabled(fileExists);
+ ui.bFileInfo->setEnabled(fileExists);
+ ui.gbUpdateOptions->setEnabled(fileExists);
+ if (!fileExists) {
+ //file doesn't exist -> delete the content preview that is still potentially
+ //available from the previously selected file
+ ui.tePreview->clear();
+ m_twPreview->clear();
+ m_hdf5OptionsWidget->clear();
+ m_netcdfOptionsWidget->clear();
+ m_fitsOptionsWidget->clear();
+ m_jsonOptionsWidget->clearModel();
+ m_rootOptionsWidget->clear();
+
+ emit fileNameChanged();
+ return;
+ }
+
+ if (currentSourceType() == LiveDataSource::FileOrPipe) {
+ const AbstractFileFilter::FileType fileType = \
AbstractFileFilter::fileType(fileName); + switch(fileType) {
+ case AbstractFileFilter::Ascii:
+ ui.cbFileType->setCurrentIndex(AbstractFileFilter::Ascii);
+ break;
+ case AbstractFileFilter::Binary:
+ ui.cbFileType->setCurrentIndex(AbstractFileFilter::Binary);
+ break;
+ case AbstractFileFilter::Image:
+ ui.cbFileType->setCurrentIndex(AbstractFileFilter::Image);
+ break;
+ case AbstractFileFilter::HDF5:
+ ui.cbFileType->setCurrentIndex(AbstractFileFilter::HDF5);
+ m_hdf5OptionsWidget->updateContent((HDF5Filter*)this->currentFileFilter(), \
fileName); + break;
+ case AbstractFileFilter::NETCDF:
+ ui.cbFileType->setCurrentIndex(AbstractFileFilter::NETCDF);
+ m_netcdfOptionsWidget->updateContent((NetCDFFilter*)this->currentFileFilter(), \
fileName); + break;
+ case AbstractFileFilter::FITS:
+#ifdef HAVE_FITS
+ ui.cbFileType->setCurrentIndex(AbstractFileFilter::FITS);
+ m_fitsOptionsWidget->updateContent((FITSFilter*)this->currentFileFilter(), \
fileName); +#endif
+ break;
+ case AbstractFileFilter::Json:
+ ui.cbFileType->setCurrentIndex(AbstractFileFilter::Json);
+ m_jsonOptionsWidget->loadDocument(fileName);
+ break;
+ case AbstractFileFilter::ROOT:
+ ui.cbFileType->setCurrentIndex(AbstractFileFilter::ROOT);
+ m_rootOptionsWidget->updateContent((ROOTFilter*)this->currentFileFilter(), \
fileName); + break;
+ case AbstractFileFilter::NgspiceRawAscii:
+ ui.cbFileType->setCurrentIndex(AbstractFileFilter::NgspiceRawAscii);
+ break;
+ case AbstractFileFilter::NgspiceRawBinary:
+ ui.cbFileType->setCurrentIndex(AbstractFileFilter::NgspiceRawBinary);
+ break;
+ }
+ }
+
+ refreshPreview();
+ emit fileNameChanged();
+}
+
+/*!
+ saves the current filter settings
+*/
+void ImportFileWidget::saveFilter() {
+ bool ok;
+ QString text = QInputDialog::getText(this, i18n("Save Filter Settings as"),
+ i18n("Filter name:"), QLineEdit::Normal, i18n("new filter"), &ok);
+ if (ok && !text.isEmpty()) {
+ //TODO
+ //AsciiFilter::saveFilter()
+ }
+}
+
+/*!
+ opens a dialog for managing all available predefined filters.
+*/
+void ImportFileWidget::manageFilters() {
+ //TODO
+}
+
+/*!
+ Depending on the selected file type, activates the corresponding options in the \
data portion tab + and populates the combobox with the available pre-defined fllter \
settings for the selected type. +*/
+void ImportFileWidget::fileTypeChanged(int fileType) {
+ ui.swOptions->setCurrentIndex(fileType);
+
+ //default
+ ui.lFilter->show();
+ ui.cbFilter->show();
+
+ //different file types show different number of tabs in ui.tabWidget.
+ //when switching from the previous file type we re-set the tab widget to its \
original state + //and remove/add the required tabs further below
+ for (int i = 0; i<ui.tabWidget->count(); ++i)
+ ui.tabWidget->count();
+
+ ui.tabWidget->addTab(ui.tabDataFormat, i18n("Data format"));
+ ui.tabWidget->addTab(ui.tabDataPreview, i18n("Preview"));
+ ui.tabWidget->addTab(ui.tabDataPortion, i18n("Data portion to read"));
+
+ ui.lPreviewLines->show();
+ ui.sbPreviewLines->show();
+ ui.lStartColumn->show();
+ ui.sbStartColumn->show();
+ ui.lEndColumn->show();
+ ui.sbEndColumn->show();
+
+ showJsonModel(false);
+
+ switch (fileType) {
+ case AbstractFileFilter::Ascii:
+ break;
+ case AbstractFileFilter::Binary:
+ ui.lStartColumn->hide();
+ ui.sbStartColumn->hide();
+ ui.lEndColumn->hide();
+ ui.sbEndColumn->hide();
+ break;
+ case AbstractFileFilter::ROOT:
+ ui.tabWidget->removeTab(1);
+ // falls through
+ case AbstractFileFilter::HDF5:
+ case AbstractFileFilter::NETCDF:
+ case AbstractFileFilter::FITS:
+ ui.lFilter->hide();
+ ui.cbFilter->hide();
+ // hide global preview tab. we have our own
+ ui.tabWidget->setTabText(0, i18n("Data format && preview"));
+ ui.tabWidget->removeTab(1);
+ ui.tabWidget->setCurrentIndex(0);
+ break;
+ case AbstractFileFilter::Image:
+ ui.lPreviewLines->hide();
+ ui.sbPreviewLines->hide();
+ ui.lFilter->hide();
+ ui.cbFilter->hide();
+ break;
+ case AbstractFileFilter::NgspiceRawAscii:
+ case AbstractFileFilter::NgspiceRawBinary:
+ ui.lStartColumn->hide();
+ ui.sbStartColumn->hide();
+ ui.lEndColumn->hide();
+ ui.sbEndColumn->hide();
+ ui.tabWidget->removeTab(0);
+ ui.tabWidget->setCurrentIndex(0);
+ break;
+ case AbstractFileFilter::Json:
+ ui.lFilter->hide();
+ ui.cbFilter->hide();
+ showJsonModel(true);
+ break;
+ default:
+ DEBUG("unknown file type");
+ }
+
+ m_hdf5OptionsWidget->clear();
+ m_netcdfOptionsWidget->clear();
+ m_rootOptionsWidget->clear();
+
+ int lastUsedFilterIndex = ui.cbFilter->currentIndex();
+ ui.cbFilter->clear();
+ ui.cbFilter->addItem( i18n("Automatic") );
+ ui.cbFilter->addItem( i18n("Custom") );
+
+ //TODO: populate the combobox with the available pre-defined filter settings for \
the selected type + ui.cbFilter->setCurrentIndex(lastUsedFilterIndex);
+ filterChanged(lastUsedFilterIndex);
+
+ refreshPreview();
+}
+
+
+const QStringList ImportFileWidget::selectedHDF5Names() const {
+ return m_hdf5OptionsWidget->selectedHDF5Names();
+}
+
+const QStringList ImportFileWidget::selectedNetCDFNames() const {
+ return m_netcdfOptionsWidget->selectedNetCDFNames();
+}
+
+const QStringList ImportFileWidget::selectedFITSExtensions() const {
+ return m_fitsOptionsWidget->selectedFITSExtensions();
+}
+
+const QStringList ImportFileWidget::selectedROOTNames() const {
+ return m_rootOptionsWidget->selectedROOTNames();
+}
+
+/*!
+ shows the dialog with the information about the file(s) to be imported.
+*/
+void ImportFileWidget::fileInfoDialog() {
+ QStringList files = ui.leFileName->text().split(';');
+ FileInfoDialog* dlg = new FileInfoDialog(this);
+ dlg->setFiles(files);
+ dlg->exec();
+}
+
+/*!
+ enables the options if the filter "custom" was chosen. Disables the options \
otherwise. +*/
+void ImportFileWidget::filterChanged(int index) {
+ // ignore filter for these formats
+ if (ui.cbFileType->currentIndex() == AbstractFileFilter::HDF5 ||
+ ui.cbFileType->currentIndex() == AbstractFileFilter::NETCDF ||
+ ui.cbFileType->currentIndex() == AbstractFileFilter::Image ||
+ ui.cbFileType->currentIndex() == AbstractFileFilter::FITS ||
+ ui.cbFileType->currentIndex() == AbstractFileFilter::Json ||
+ ui.cbFileType->currentIndex() == AbstractFileFilter::ROOT) {
+ ui.swOptions->setEnabled(true);
+ return;
+ }
+
+ if (index == 0) { // "automatic"
+ ui.swOptions->setEnabled(false);
+ ui.bSaveFilter->setEnabled(false);
+ } else if (index == 1) { //custom
+ ui.swOptions->setEnabled(true);
+ ui.bSaveFilter->setEnabled(true);
+ } else {
+ // predefined filter settings were selected.
+ //load and show them in the GUI.
+ //TODO
+ }
+}
+
+void ImportFileWidget::refreshPreview() {
+ if (m_suppressRefresh)
+ return;
+
+ WAIT_CURSOR;
+
+ QString fileName = ui.leFileName->text();
+#ifndef HAVE_WINDOWS
+ if (!fileName.isEmpty() && fileName.at(0) != QDir::separator())
+ fileName = QDir::homePath() + QDir::separator() + fileName;
+#endif
+ DEBUG("refreshPreview(): file name = " << fileName.toStdString());
+
+ QVector<QStringList> importedStrings;
+ AbstractFileFilter::FileType fileType = \
(AbstractFileFilter::FileType)ui.cbFileType->currentIndex(); +
+ // generic table widget
+ if (fileType == AbstractFileFilter::Ascii || fileType == AbstractFileFilter::Binary
+ || fileType == AbstractFileFilter::Json || fileType == \
AbstractFileFilter::NgspiceRawAscii + || fileType == \
AbstractFileFilter::NgspiceRawBinary) + m_twPreview->show();
+ else
+ m_twPreview->hide();
+
+ int lines = ui.sbPreviewLines->value();
+
+ bool ok = true;
+ QTableWidget* tmpTableWidget{nullptr};
+ QStringList vectorNameList;
+ QVector<AbstractColumn::ColumnMode> columnModes;
+ DEBUG("Data File Type: " << ENUM_TO_STRING(AbstractFileFilter, FileType, \
fileType)); + switch (fileType) {
+ case AbstractFileFilter::Ascii: {
+ ui.tePreview->clear();
+
+ AsciiFilter* filter = static_cast<AsciiFilter*>(this->currentFileFilter());
+
+ DEBUG("Data Source Type: " << ENUM_TO_STRING(LiveDataSource, SourceType, \
currentSourceType())); + switch (currentSourceType()) {
+ case LiveDataSource::SourceType::FileOrPipe: {
+ importedStrings = filter->preview(fileName, lines);
+ break;
+ }
+ case LiveDataSource::SourceType::LocalSocket: {
+ QLocalSocket lsocket{this};
+ DEBUG("Local socket: CONNECT PREVIEW");
+ lsocket.connectToServer(fileName, QLocalSocket::ReadOnly);
+ if (lsocket.waitForConnected()) {
+ DEBUG("connected to local socket " << fileName.toStdString());
+ if (lsocket.waitForReadyRead())
+ importedStrings = filter->preview(lsocket);
+ DEBUG("Local socket: DISCONNECT PREVIEW");
+ lsocket.disconnectFromServer();
+ // read-only socket is disconnected immediately (no waitForDisconnected())
+ } else {
+ DEBUG("failed connect to local socket " << fileName.toStdString() << " - " << \
lsocket.errorString().toStdString()); + }
+
+ break;
+ }
+ case LiveDataSource::SourceType::NetworkTcpSocket: {
+ QTcpSocket tcpSocket{this};
+ tcpSocket.connectToHost(host(), port().toInt(), QTcpSocket::ReadOnly);
+ if (tcpSocket.waitForConnected()) {
+ DEBUG("connected to TCP socket");
+ if ( tcpSocket.waitForReadyRead() )
+ importedStrings = filter->preview(tcpSocket);
+
+ tcpSocket.disconnectFromHost();
+ } else {
+ DEBUG("failed to connect to TCP socket " << " - " << \
tcpSocket.errorString().toStdString()); + }
+
+ break;
+ }
+ case LiveDataSource::SourceType::NetworkUdpSocket: {
+ QUdpSocket udpSocket{this};
+ DEBUG("UDP Socket: CONNECT PREVIEW, state = " << udpSocket.state());
+ udpSocket.bind(QHostAddress(host()), port().toInt());
+ udpSocket.connectToHost(host(), 0, QUdpSocket::ReadOnly);
+ if (udpSocket.waitForConnected()) {
+ DEBUG(" connected to UDP socket " << host().toStdString() << ':' << \
port().toInt()); + if (!udpSocket.waitForReadyRead(2000) )
+ DEBUG(" ERROR: not ready for read after 2 sec");
+ if (udpSocket.hasPendingDatagrams()) {
+ DEBUG(" has pending data");
+ } else {
+ DEBUG(" has no pending data");
+ }
+ importedStrings = filter->preview(udpSocket);
+
+ DEBUG("UDP Socket: DISCONNECT PREVIEW, state = " << udpSocket.state());
+ udpSocket.disconnectFromHost();
+ } else {
+ DEBUG("failed to connect to UDP socket " << " - " << \
udpSocket.errorString().toStdString()); + }
+
+ break;
+ }
+ case LiveDataSource::SourceType::SerialPort: {
+ QSerialPort sPort{this};
+ DEBUG(" Port name: " << serialPort().toStdString());
+ DEBUG(" Settings: " << baudRate() << ',' << sPort.dataBits() << ',' << \
sPort.parity() + << ',' << sPort.stopBits());
+ sPort.setPortName(serialPort());
+ sPort.setBaudRate(baudRate());
+
+ if (sPort.open(QIODevice::ReadOnly)) {
+ if (sPort.waitForReadyRead(2000))
+ importedStrings = filter->preview(sPort);
+ else {
+ DEBUG(" ERROR: not ready for read after 2 sec");
+ }
+
+ sPort.close();
+ } else {
+ DEBUG(" ERROR: failed to open serial port. error: " << sPort.error());
+ }
+ break;
+ }
+ case LiveDataSource::SourceType::MQTT: {
+#ifdef HAVE_MQTT
+ qDebug()<<"preview mqtt, is it ready:"<<m_mqttReadyForPreview;
+ if(m_mqttReadyForPreview)
+ {
+ filter->vectorNames().clear();
+ QMapIterator<QMqttTopicName, QMqttMessage> i(m_lastMessage);
+ while(i.hasNext()) {
+ i.next();
+ qDebug()<<"calling ascii mqtt preview"<< importedStrings << " \
"<<QString(i.value().payload().data()) + << " "<< i.key().name();
+ filter->mqttPreview(importedStrings, QString(i.value().payload().data()), \
i.key().name() ); + if(importedStrings.isEmpty())
+ break;
+ }
+
+ QMapIterator<QMqttTopicName, bool> j(m_messageArrived);
+ while(j.hasNext()) {
+ j.next();
+ qDebug()<<"Set false after preview: "<<j.key().name();
+ m_messageArrived[j.key()] = false;
+ }
+ m_mqttReadyForPreview = false;
+ }
+#endif
+ break;
+ }
+ }
+
+ tmpTableWidget = m_twPreview;
+ vectorNameList = filter->vectorNames();
+ columnModes = filter->columnModes();
+ break;
+ }
+ case AbstractFileFilter::Binary: {
+ ui.tePreview->clear();
+ BinaryFilter *filter = (BinaryFilter *)this->currentFileFilter();
+ importedStrings = filter->preview(fileName, lines);
+ tmpTableWidget = m_twPreview;
+ break;
+ }
+ case AbstractFileFilter::Image: {
+ ui.tePreview->clear();
+
+ QImage image(fileName);
+ QTextCursor cursor = ui.tePreview->textCursor();
+ cursor.insertImage(image);
+ RESET_CURSOR;
+ return;
+ }
+ case AbstractFileFilter::HDF5: {
+ HDF5Filter *filter = (HDF5Filter *)this->currentFileFilter();
+ lines = m_hdf5OptionsWidget->lines();
+ importedStrings = filter->readCurrentDataSet(fileName, NULL, ok, \
AbstractFileFilter::Replace, lines); + tmpTableWidget = \
m_hdf5OptionsWidget->previewWidget(); + break;
+ }
+ case AbstractFileFilter::NETCDF: {
+ NetCDFFilter *filter = (NetCDFFilter *)this->currentFileFilter();
+ lines = m_netcdfOptionsWidget->lines();
+ importedStrings = filter->readCurrentVar(fileName, NULL, \
AbstractFileFilter::Replace, lines); + tmpTableWidget = \
m_netcdfOptionsWidget->previewWidget(); + break;
+ }
+ case AbstractFileFilter::FITS: {
+ FITSFilter* filter = (FITSFilter*)this->currentFileFilter();
+ lines = m_fitsOptionsWidget->lines();
+
+ // update file name (may be any file type)
+ m_fitsOptionsWidget->updateContent(filter, fileName);
+ QString extensionName = m_fitsOptionsWidget->extensionName(&ok);
+ if (!extensionName.isEmpty()) {
+ DEBUG(" extension name = " << extensionName.toStdString());
+ fileName = extensionName;
+ }
+ DEBUG(" file name = " << fileName.toStdString());
+
+ bool readFitsTableToMatrix;
+ importedStrings = filter->readChdu(fileName, &readFitsTableToMatrix, lines);
+ emit checkedFitsTableToMatrix(readFitsTableToMatrix);
+
+ tmpTableWidget = m_fitsOptionsWidget->previewWidget();
+ break;
+ }
+ case AbstractFileFilter::Json: {
+ ui.tePreview->clear();
+ m_jsonOptionsWidget->loadDocument(fileName);
+ JsonFilter *filter = (JsonFilter*)this->currentFileFilter();
+ m_jsonOptionsWidget->applyFilterSettings(filter, ui.tvJson->currentIndex());
+ importedStrings = filter->preview(fileName);
+ tmpTableWidget = m_twPreview;
+ columnModes = filter->columnModes();
+ break;
+ }
+ case AbstractFileFilter::ROOT: {
+ ROOTFilter *filter = (ROOTFilter *)this->currentFileFilter();
+ lines = m_rootOptionsWidget->lines();
+ m_rootOptionsWidget->setNBins(filter->binsInCurrentHistogram(fileName));
+ importedStrings = filter->previewCurrentHistogram(
+ fileName,
+ m_rootOptionsWidget->startBin(),
+ qMin(m_rootOptionsWidget->startBin() + m_rootOptionsWidget->lines() - 1,
+ m_rootOptionsWidget->endBin())
+ );
+ tmpTableWidget = m_rootOptionsWidget->previewWidget();
+ // the last vector element contains the column names
+ vectorNameList = importedStrings.last();
+ importedStrings.removeLast();
+ columnModes = QVector<AbstractColumn::ColumnMode>(vectorNameList.size(), \
AbstractColumn::Numeric); + break;
+ }
+ case AbstractFileFilter::NgspiceRawAscii: {
+ ui.tePreview->clear();
+ NgspiceRawAsciiFilter* filter = (NgspiceRawAsciiFilter*)this->currentFileFilter();
+ importedStrings = filter->preview(fileName, lines);
+ tmpTableWidget = m_twPreview;
+ vectorNameList = filter->vectorNames();
+ columnModes = filter->columnModes();
+ break;
+ }
+ case AbstractFileFilter::NgspiceRawBinary: {
+ ui.tePreview->clear();
+ NgspiceRawBinaryFilter* filter = \
(NgspiceRawBinaryFilter*)this->currentFileFilter(); + importedStrings = \
filter->preview(fileName, lines); + tmpTableWidget = m_twPreview;
+ vectorNameList = filter->vectorNames();
+ columnModes = filter->columnModes();
+ break;
+ }
+ }
+
+ // fill the table widget
+ tmpTableWidget->setRowCount(0);
+ tmpTableWidget->setColumnCount(0);
+ if( !importedStrings.isEmpty() ) {
+ //QDEBUG("importedStrings =" << importedStrings);
+ if (!ok) {
+ // show imported strings as error message
+ tmpTableWidget->setRowCount(1);
+ tmpTableWidget->setColumnCount(1);
+ QTableWidgetItem* item = new QTableWidgetItem();
+ item->setText(importedStrings[0][0]);
+ tmpTableWidget->setItem(0, 0, item);
+ } else {
+ //TODO: maxrows not used
+ const int rows = qMax(importedStrings.size(), 1);
+ const int maxColumns = 300;
+ tmpTableWidget->setRowCount(rows);
+
+ for (int i = 0; i < rows; ++i) {
+ // QDEBUG("imported string " << importedStrings[i]);
+
+ int cols = importedStrings[i].size() > maxColumns ? maxColumns : \
importedStrings[i].size(); // new + if (cols > tmpTableWidget->columnCount())
+ tmpTableWidget->setColumnCount(cols);
+
+ for (int j = 0; j < cols; ++j) {
+ QTableWidgetItem* item = new QTableWidgetItem(importedStrings[i][j]);
+ tmpTableWidget->setItem(i, j, item);
+ }
+ }
+
+ // set header if columnMode available
+ for (int i = 0; i < qMin(tmpTableWidget->columnCount(), columnModes.size()); ++i) \
{ + QString columnName = QString::number(i+1);
+ if (i < vectorNameList.size())
+ columnName = vectorNameList[i];
+ auto* item = new QTableWidgetItem(columnName + QLatin1String(" {") + \
ENUM_TO_STRING(AbstractColumn, ColumnMode, columnModes[i]) + QLatin1String("}")); \
+ item->setTextAlignment(Qt::AlignLeft); \
+ item->setIcon(AbstractColumn::iconForMode(columnModes[i])); +
+ tmpTableWidget->setHorizontalHeaderItem(i, item);
+ }
+ }
+
+ tmpTableWidget->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
+ m_fileEmpty = false;
+ } else {
+ m_fileEmpty = true;
+ }
+
+ emit previewRefreshed();
+
+ RESET_CURSOR;
+}
+
+void ImportFileWidget::updateTypeChanged(int idx) {
+ LiveDataSource::UpdateType type = static_cast<LiveDataSource::UpdateType>(idx);
+
+ switch (type) {
+ case LiveDataSource::UpdateType::TimeInterval:
+ ui.lUpdateInterval->show();
+ ui.sbUpdateInterval->show();
+ break;
+ case LiveDataSource::UpdateType::NewData:
+ ui.lUpdateInterval->hide();
+ ui.sbUpdateInterval->hide();
+ }
+}
+
+void ImportFileWidget::readingTypeChanged(int idx) {
+ LiveDataSource::ReadingType type = static_cast<LiveDataSource::ReadingType>(idx);
+
+ if (type == LiveDataSource::ReadingType::TillEnd || type == \
LiveDataSource::ReadingType::WholeFile) { + ui.lSampleSize->hide();
+ ui.sbSampleSize->hide();
+ } else {
+ ui.lSampleSize->show();
+ ui.sbSampleSize->show();
+ }
+
+ if (type == LiveDataSource::ReadingType::WholeFile) {
+ ui.lKeepLastValues->hide();
+ ui.sbKeepNValues->hide();
+ } else {
+ ui.lKeepLastValues->show();
+ ui.sbKeepNValues->show();
+ }
+}
+
+void ImportFileWidget::sourceTypeChanged(int idx) {
+ LiveDataSource::SourceType type = static_cast<LiveDataSource::SourceType>(idx);
+
+ switch (type) {
+ case LiveDataSource::SourceType::FileOrPipe:
+ ui.lFileName->show();
+ ui.leFileName->show();
+ ui.bFileInfo->show();
+ ui.bOpen->show();
+ ui.chbLinkFile->show();
+
+ ui.cbBaudRate->hide();
+ ui.lBaudRate->hide();
+ ui.lHost->hide();
+ ui.leHost->hide();
+ ui.lPort->hide();
+ ui.lePort->hide();
+ ui.cbSerialPort->hide();
+ ui.lSerialPort->hide();
+
+ fileNameChanged(ui.leFileName->text());
+ break;
+ case LiveDataSource::SourceType::LocalSocket:
+ ui.lFileName->show();
+ ui.leFileName->show();
+ ui.bOpen->show();
+
+ ui.bFileInfo->hide();
+ ui.cbBaudRate->hide();
+ ui.lBaudRate->hide();
+ ui.lHost->hide();
+ ui.leHost->hide();
+ ui.lPort->hide();
+ ui.lePort->hide();
+ ui.cbSerialPort->hide();
+ ui.lSerialPort->hide();
+ ui.chbLinkFile->hide();
+
+ ui.gbOptions->setEnabled(true);
+ ui.bManageFilters->setEnabled(true);
+ ui.cbFilter->setEnabled(true);
+ ui.cbFileType->setEnabled(true);
+ break;
+ case LiveDataSource::SourceType::NetworkTcpSocket:
+ case LiveDataSource::SourceType::NetworkUdpSocket:
+ ui.lHost->show();
+ ui.leHost->show();
+ ui.lePort->show();
+ ui.lPort->show();
+
+ ui.lBaudRate->hide();
+ ui.cbBaudRate->hide();
+ ui.lSerialPort->hide();
+ ui.cbSerialPort->hide();
+
+ ui.lFileName->hide();
+ ui.leFileName->hide();
+ ui.bFileInfo->hide();
+ ui.bOpen->hide();
+ ui.chbLinkFile->hide();
+
+ ui.gbOptions->setEnabled(true);
+ ui.bManageFilters->setEnabled(true);
+ ui.cbFilter->setEnabled(true);
+ ui.cbFileType->setEnabled(true);
+ break;
+ case LiveDataSource::SourceType::SerialPort:
+ ui.lBaudRate->show();
+ ui.cbBaudRate->show();
+ ui.lSerialPort->show();
+ ui.cbSerialPort->show();
+
+ ui.lHost->hide();
+ ui.leHost->hide();
+ ui.lePort->hide();
+ ui.lPort->hide();
+ ui.lFileName->hide();
+ ui.leFileName->hide();
+ ui.bFileInfo->hide();
+ ui.bOpen->hide();
+ ui.chbLinkFile->hide();
+ ui.cbFileType->setEnabled(true);
+
+ ui.gbOptions->setEnabled(true);
+ ui.bManageFilters->setEnabled(true);
+ ui.cbFilter->setEnabled(true);
+ break;
+
+ case LiveDataSource::SourceType::MQTT:
+#ifdef HAVE_MQTT
+
+ ui.lBaudRate->hide();
+ ui.cbBaudRate->hide();
+ ui.lSerialPort->hide();
+ ui.cbSerialPort->hide();
+
+ ui.lHost->show();
+ ui.leHost->show();
+ ui.lePort->show();
+ ui.lPort->show();
+ ui.lFileName->hide();
ui.leFileName->hide();
ui.bFileInfo->hide();
ui.bOpen->hide();
@@ -1485,11 +2023,9 @@ void ImportFileWidget::sourceTypeChanged(int idx) {
ui.cbQos->show();
ui.lQos->show();
ui.twTopics->show();
- //ui.lTopicTree->show();
ui.lTopicSearch->show();
ui.leTopics->show();
ui.twSubscriptions->show();
- //ui.lSubscriptions->show();
ui.chbAuthentication->show();
ui.chbID->show();
ui.bSubscribe->show();
@@ -1601,31 +2137,34 @@ void ImportFileWidget::initializeAndFillPortsAndBaudRates() {
}
#ifdef HAVE_MQTT
-void ImportFileWidget::idChecked(int state)
-{
- if (state == 2)
- {
+
+/*!
+ *\brief called when ID checkbox's state is changed, if checked a lineEdit is shown \
so the user can set the ID + * \param state the state of the checbox
+ */
+void ImportFileWidget::idChecked(int state) {
+ if (state == 2) {
ui.leID->show();
ui.lMqttID->show();
- }
- else if (state == 0)
- {
+ } else if (state == 0) {
ui.leID->hide();
ui.lMqttID->hide();
}
}
-void ImportFileWidget::authenticationChecked(int state)
-{
- if(state == 2)
- {
+/*!
+ *\brief called when authentication checkbox's state is changed,
+ * if checked two lineEdits are shown so the user can set the username and \
password + *
+ * \param state the state of the checbox
+ */
+void ImportFileWidget::authenticationChecked(int state) {
+ if(state == 2) {
ui.leUsername->show();
ui.lePassword->show();
ui.lPassword->show();
ui.lUsername->show();
- }
- else if (state == 0)
- {
+ } else if (state == 0) {
ui.leUsername->hide();
ui.lePassword->hide();
ui.lUsername->hide();
@@ -1633,9 +2172,14 @@ void ImportFileWidget::authenticationChecked(int state)
}
}
-void ImportFileWidget::mqttConnection()
-{
+/*!
+ *\brief called when the connect/disconnect button is pressed
+ * makes the connection to the given MQTT broker, with the given options
+ * or disconnects from the broker
+ */
+void ImportFileWidget::mqttConnection() {
if(m_client->state() == QMqttClient::ClientState::Disconnected) {
+ //Check whether the set options are valid and a connection can be made, or not
const bool hostSet = !ui.leHost->text().isEmpty();
const bool portSet = !ui.lePort->text().isEmpty();
const bool idUsed = ui.chbID->isChecked();
@@ -1649,16 +2193,19 @@ void ImportFileWidget::mqttConnection()
if (valid) {
m_client->setHostname(ui.leHost->text().simplified());
m_client->setPort(ui.lePort->text().toUInt());
+
if(ui.chbID->isChecked())
m_client->setClientId(ui.leID->text().simplified());
+
if(ui.chbAuthentication->isChecked()) {
m_client->setUsername(ui.leUsername->text().simplified());
m_client->setPassword(ui.lePassword->text().simplified());
}
+
qDebug()<< ui.leHost->text() << " " << m_client->hostname() << " " << \
m_client->port(); qDebug()<<"Trying to connect";
m_client->connectToHost();
- m_timeoutTimer->start();
+ m_connectTimeoutTimer->start();
}
}
else if (m_client->state() == QMqttClient::ClientState::Connected) {
@@ -1667,9 +2214,13 @@ void ImportFileWidget::mqttConnection()
}
}
+/*!
+ *\brief called when the client connects to the broker succesfully, it subscribes to \
every topic (# wildcard) + * in order to later list every available topic
+ */
void ImportFileWidget::onMqttConnect() {
if(m_client->error() == QMqttClient::NoError) {
- m_timeoutTimer->stop();
+ m_connectTimeoutTimer->stop();
ui.gbManageSubscriptions->setEnabled(true);
ui.bConnect->setText("Disconnect");
ui.leHost->setEnabled(false);
@@ -1677,270 +2228,24 @@ void ImportFileWidget::onMqttConnect() {
ui.lePassword->setEnabled(false);
ui.leUsername->setEnabled(false);
ui.leID->setEnabled(false);
- ui.cbSourceType->setEnabled(false);
- ui.chbAuthentication->setEnabled(false);
- ui.chbID->setEnabled(false);
- ui.chbRetain->setEnabled(false);
- QMessageBox::information(this, "Connection successful", "Connection established");
- QMqttTopicFilter globalFilter{"#"};
- m_mainSubscription = m_client->subscribe(globalFilter, 1);
- if(!m_mainSubscription)
- QMessageBox::information(this, "Couldn't subscribe", "Something went wrong");
- }
-}
-
-void ImportFileWidget::mqttSubscribe() {
- QString name;
- QTreeWidgetItem *item = ui.twTopics->currentItem();
- if(item != nullptr) {
- QTreeWidgetItem *tempItem = item;
- name.prepend(item->text(0));
- if(item->childCount() != 0)
- name.append("/#");
-
- while(tempItem->parent() != nullptr) {
- tempItem = tempItem->parent();
- name.prepend(tempItem->text(0) + "/");
- }
-
- QList<QTreeWidgetItem *> topLevelList = ui.twSubscriptions->findItems(name, \
Qt::MatchExactly);
-
- if(topLevelList.isEmpty() || topLevelList.first()->parent() != nullptr) {
-
- qDebug() << name;
- bool foundSuperior = false;
-
- for(int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
- qDebug()<<i<<" "<<ui.twSubscriptions->topLevelItemCount();
- if(checkTopicContains(name, ui.twSubscriptions->topLevelItem(i)->text(0))
- && name != ui.twSubscriptions->topLevelItem(i)->text(0)) {
- qDebug()<<"1"<<name<<" "<< ui.twSubscriptions->topLevelItem(i)->text(0);
- unsubscribeFromTopic(ui.twSubscriptions->topLevelItem(i)->text(0));
- qDebug()<<"After Delete";
- i--;
- continue;
- }
- qDebug()<<"checked inferior";
-
- if(checkTopicContains(ui.twSubscriptions->topLevelItem(i)->text(0), name)
- && name != ui.twSubscriptions->topLevelItem(i)->text(0)) {
- foundSuperior = true;
- qDebug()<<"2"<<name<<" "<< ui.twSubscriptions->topLevelItem(i)->text(0);
- break;
- }
- qDebug()<<"checked superior";
- }
-
- if(!foundSuperior) {
- qDebug()<<"Adding new topic";
- QStringList toplevelName;
- toplevelName.push_back(name);
- QTreeWidgetItem* newTopLevelItem = new QTreeWidgetItem(toplevelName);
- ui.twSubscriptions->addTopLevelItem(newTopLevelItem);
-
- QMqttTopicFilter filter {name};
- QMqttSubscription *temp_subscription = m_client->subscribe(filter, \
static_cast<quint8> (ui.cbQos->currentText().toUInt()) );
-
- if(temp_subscription) {
- m_mqttSubscriptions.push_back(temp_subscription);
- connect(temp_subscription, &QMqttSubscription::messageReceived, this, \
&ImportFileWidget::mqttSubscriptionMessageReceived);
- emit subscriptionMade();
- }
-
- if(name.endsWith("#")) {
- addSubscriptionChildren(item, newTopLevelItem);
- }
- }
-
- if(name.endsWith("#") && !foundSuperior) {
- QStringList nameList = name.split('/', QString::SkipEmptyParts);
- QString root = nameList.first();
- QVector<QTreeWidgetItem*> children;
- for(int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
- if(ui.twSubscriptions->topLevelItem(i)->text(0).startsWith(root)
- && name != ui.twSubscriptions->topLevelItem(i)->text(0)) {
- children.clear();
- findSubscriptionLeafChildren(children, ui.twSubscriptions->topLevelItem(i));
- for(int j = 0; j < children.size(); ++j) {
- if(checkTopicContains(name, children[j]->text(0))) {
- ui.twSubscriptions->setCurrentItem(children[j]);
- mqttUnsubscribe();
- }
- }
- }
- }
- }
-
- if(!foundSuperior)
- manageCommonLevelSubscriptions();
-
- if(foundSuperior) {
- QMessageBox::warning(this, "Warning", "You already subscribed to a topic \
containing this one");
- }
- }
- else
- QMessageBox::warning(this, "Warning", "You already subscribed to this topic");
- }
- else
- QMessageBox::warning(this, "Warning", "You didn't select any item from the Tree \
Widget");
-}
-
-void ImportFileWidget::mqttUnsubscribe() {
- QTreeWidgetItem* unsubscribeItem = ui.twSubscriptions->currentItem();
-
- if(unsubscribeItem != nullptr) {
- if(unsubscribeItem->parent() == nullptr)
- unsubscribeFromTopic(unsubscribeItem->text(0));
- else{
- while(unsubscribeItem->parent() != nullptr) {
- for(int i = 0; i < unsubscribeItem->parent()->childCount(); ++i) {
- if(unsubscribeItem->text(0) != unsubscribeItem->parent()->child(i)->text(0)) {
- QMqttTopicFilter filter {unsubscribeItem->parent()->child(i)->text(0)};
- QMqttSubscription *temp_subscription = m_client->subscribe(filter, \
static_cast<quint8> (ui.cbQos->currentText().toUInt()) );
-
- ui.twSubscriptions->addTopLevelItem(unsubscribeItem->parent()->takeChild(i));
-
- if(temp_subscription) {
- m_mqttSubscriptions.push_back(temp_subscription);
- connect(temp_subscription, &QMqttSubscription::messageReceived, this, \
&ImportFileWidget::mqttSubscriptionMessageReceived);
- emit subscriptionMade();
- }
- i--;
- }
- }
- unsubscribeItem = unsubscribeItem->parent();
- }
- unsubscribeFromTopic(unsubscribeItem->text(0));
-
- manageCommonLevelSubscriptions();
- }
- }
- else
- QMessageBox::warning(this, "Warning", "You didn't select any item from the Tree \
Widget");
-}
-
-void ImportFileWidget::mqttMessageReceived(const QByteArray &message , const \
QMqttTopicName &topic) {
- if(!m_addedTopics.contains(topic.name())) {
- m_addedTopics.push_back(topic.name());
- QStringList name;
- QChar sep = '/';
- QString rootName;
- if(topic.name().contains(sep)) {
- QStringList list = topic.name().split(sep, QString::SkipEmptyParts);
-
- rootName = list.at(0);
- name.append(list.at(0));
- QTreeWidgetItem* currentItem;
- int topItemIdx = -1;
- for(int i = 0; i < ui.twTopics->topLevelItemCount(); ++i) {
- if(ui.twTopics->topLevelItem(i)->text(0) == list.at(0)) {
- topItemIdx = i;
- break;
- }
- }
- if( topItemIdx < 0) {
- currentItem = new QTreeWidgetItem(name);
- ui.twTopics->addTopLevelItem(currentItem);
- for(int i = 1; i < list.size(); ++i) {
- name.clear();
- name.append(list.at(i));
- currentItem->addChild(new QTreeWidgetItem(name));
- currentItem = currentItem->child(0);
- }
- } else {
- currentItem = ui.twTopics->topLevelItem(topItemIdx);
- int listIdx = 1;
- for(; listIdx < list.size(); ++listIdx) {
- QTreeWidgetItem* childItem = nullptr;
- bool found = false;
- for(int j = 0; j < currentItem->childCount(); ++j) {
- childItem = currentItem->child(j);
- if(childItem->text(0) == list.at(listIdx)) {
- found = true;
- currentItem = childItem;
- break;
- }
- }
- if(!found)
- break;
- }
-
- for(; listIdx < list.size(); ++listIdx) {
- name.clear();
- name.append(list.at(listIdx));
- currentItem->addChild(new QTreeWidgetItem(name));
- currentItem = currentItem->child(currentItem->childCount() - 1);
- }
- }
- }
- else {
- rootName = topic.name();
- name.append(topic.name());
- ui.twTopics->addTopLevelItem(new QTreeWidgetItem(name));
- }
- emit newTopic(rootName);
- }
-}
-
-void ImportFileWidget::setCompleter(const QString& topic) {
- if(!m_searching) {
- if(!m_topicList.contains(topic)) {
- m_topicList.append(topic);
- m_completer = new QCompleter(m_topicList, this);
- m_completer->setCompletionMode(QCompleter::PopupCompletion);
- m_completer->setCaseSensitivity(Qt::CaseSensitive);
- ui.leTopics->setCompleter(m_completer);
- }
- }
-}
-
-void ImportFileWidget::topicTimeout() {
- qDebug()<<"lejart ido";
- m_searching = false;
- m_searchTimer->stop();
-}
-
-bool ImportFileWidget::isMqttValid(){
- bool connected = (m_client->state() == QMqttClient::ClientState::Connected);
- bool subscribed = (ui.twSubscriptions->topLevelItemCount() > 0);
- bool fileTypeOk = false;
- if(this->currentFileType() == AbstractFileFilter::FileType::Ascii)
- fileTypeOk = true;
- return connected && subscribed && fileTypeOk;
-}
-
-void ImportFileWidget::mqttSubscriptionMessageReceived(const QMqttMessage &msg) {
- qDebug()<<"message received from: "<<msg.topic().name();
- if(!m_subscribedTopicNames.contains(msg.topic().name())) {
- m_messageArrived[msg.topic()] = true;
- qDebug()<<msg.topic().name()<<"set true";
- m_subscribedTopicNames.push_back(msg.topic().name());
- emit newTopicForWill();
- }
-
- if(m_messageArrived[msg.topic()] == false) {
- qDebug()<<msg.topic().name()<<"set true";
- m_messageArrived[msg.topic()] = true;
- }
-
- m_lastMessage[msg.topic()]= msg;
- bool check = true;
- QMapIterator<QMqttTopicName, bool> i(m_messageArrived);
- while(i.hasNext()) {
- i.next();
- if(i.value() == false ) {
- qDebug()<<"Found false: "<<i.key().name();
- check = false;
- break;
- }
- }
+ ui.cbSourceType->setEnabled(false);
+ ui.chbAuthentication->setEnabled(false);
+ ui.chbID->setEnabled(false);
+ ui.chbRetain->setEnabled(false);
+ QMessageBox::information(this, "Connection successful", "Connection established");
- if (check == true) {
- m_mqttReadyForPreview = true;
- refreshPreview();
+ //subscribing to every topic (# wildcard) in order to later list every available \
topic + QMqttTopicFilter globalFilter{"#"};
+ m_mainSubscription = m_client->subscribe(globalFilter, 1);
+ if(!m_mainSubscription)
+ QMessageBox::information(this, "Couldn't subscribe", "Something went wrong");
}
}
+/*!
+ *\brief called when the client disconnects from the broker succesfully
+ * removes every information about the former connection
+ */
void ImportFileWidget::onMqttDisconnect() {
ui.gbManageSubscriptions->setEnabled(false);
ui.bConnect->setText("Connect");
@@ -1980,397 +2285,457 @@ void ImportFileWidget::onMqttDisconnect() {
m_lastMessage.clear();
}
-void ImportFileWidget::useWillMessage(int state) {
- if(state == Qt::Checked) {
- ui.chbWillRetain->show();
- ui.cbWillQoS->show();
- ui.cbWillMessageType->show();
- ui.cbWillTopic->show();
- ui.cbWillUpdate->show();
- ui.lWillMessageType->show();
- ui.lWillQos->show();
- ui.lWillTopic->show();
- ui.lWillUpdate->show();
-
- if (ui.cbWillMessageType->currentIndex() == \
static_cast<int>(MQTTClient::WillMessageType::OwnMessage) ) {
- ui.leWillOwnMessage->show();
- ui.lWillOwnMessage->show();
- }
- else if(ui.cbWillMessageType->currentIndex() == \
static_cast<int>(MQTTClient::WillMessageType::Statistics) ){
- qDebug()<<"will use checked show statistics";
- ui.lWillStatistics->show();
- ui.lwWillStatistics->show();
- }
-
+/*!
+ *\brief called when the subscribe button is pressed
+ * subscribes to the topic represented by the current item of twTopics
+ */
+void ImportFileWidget::mqttSubscribe() {
+ QString name;
+ QTreeWidgetItem *item = ui.twTopics->currentItem();
+ if(item != nullptr) {
+ QTreeWidgetItem *tempItem = item;
- if(ui.cbWillUpdate->currentIndex() == 0) {
- ui.leWillUpdateInterval->show();
- ui.lWillUpdateInterval->show();
+ //produce the topic name that the current item represents
+ name.prepend(item->text(0));
+ if(item->childCount() != 0)
+ name.append("/#");
+ while(tempItem->parent() != nullptr) {
+ tempItem = tempItem->parent();
+ name.prepend(tempItem->text(0) + "/");
}
- }
- else if (state == Qt::Unchecked) {
- qDebug()<<"will use unchecked";
- ui.chbWillRetain->hide();
- ui.cbWillQoS->hide();
- ui.cbWillMessageType->hide();
- ui.cbWillTopic->hide();
- ui.cbWillUpdate->hide();
- ui.leWillOwnMessage->hide();
- ui.leWillUpdateInterval->hide();
- ui.lWillMessageType->hide();
- ui.lWillOwnMessage->hide();
- ui.lWillQos->hide();
- ui.lWillTopic->hide();
- ui.lWillUpdate->hide();
- ui.lWillUpdateInterval->hide();
- ui.lWillStatistics->hide();
- ui.lwWillStatistics->hide();
- }
-}
+ QList<QTreeWidgetItem *> topLevelList = ui.twSubscriptions->findItems(name, \
Qt::MatchExactly);
-void ImportFileWidget::willMessageTypeChanged(int type) {
- if(static_cast<MQTTClient::WillMessageType> (type) == \
MQTTClient::WillMessageType::OwnMessage) {
- ui.leWillOwnMessage->show();
- ui.lWillOwnMessage->show();
- ui.lWillStatistics->hide();
- ui.lwWillStatistics->hide();
- }
- else if(static_cast<MQTTClient::WillMessageType> (type) == \
MQTTClient::WillMessageType::LastMessage) {
- ui.leWillOwnMessage->hide();
- ui.lWillOwnMessage->hide();
- ui.lWillStatistics->hide();
- ui.lwWillStatistics->hide();
- }
- else if(static_cast<MQTTClient::WillMessageType> (type) == \
MQTTClient::WillMessageType::Statistics) {
- qDebug()<<"will message type changed show statistics";
- ui.lWillStatistics->show();
- ui.lwWillStatistics->show();
- ui.leWillOwnMessage->hide();
- ui.lWillOwnMessage->hide();
- }
-}
+ //check if the subscription already exists
+ if(topLevelList.isEmpty() || topLevelList.first()->parent() != nullptr) {
+ qDebug() << name;
+ bool foundSuperior = false;
-void ImportFileWidget::updateWillTopics() {
- ui.cbWillTopic->clear();
- for(int i = 0; i < m_subscribedTopicNames.size(); ++i) {
- ui.cbWillTopic->addItem(m_subscribedTopicNames[i]);
- }
-}
+ for(int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
+ qDebug()<<i<<" "<<ui.twSubscriptions->topLevelItemCount();
-void ImportFileWidget::willUpdateChanged(int updateType) {
- if(static_cast<MQTTClient::WillUpdateType>(updateType) == \
MQTTClient::WillUpdateType::TimePeriod) {
- ui.leWillUpdateInterval->show();
- ui.lWillUpdateInterval->show();
- }
- else if (static_cast<MQTTClient::WillUpdateType>(updateType) == \
MQTTClient::WillUpdateType::OnClick) {
- ui.leWillUpdateInterval->hide();
- ui.lWillUpdateInterval->hide();
- }
-}
-#endif
+ //if the new subscirptions contains an already existing one, we remove the \
inferior one + if(checkTopicContains(name, \
ui.twSubscriptions->topLevelItem(i)->text(0)) + && name != \
ui.twSubscriptions->topLevelItem(i)->text(0)) { + qDebug()<<"1"<<name<<" "<< \
ui.twSubscriptions->topLevelItem(i)->text(0); \
+ unsubscribeFromTopic(ui.twSubscriptions->topLevelItem(i)->text(0)); + i--;
+ continue;
+ }
+ qDebug()<<"checked inferior";
-void ImportFileWidget::hideMQTT() {
- ui.leID->hide();
- ui.lMqttID->hide();
- ui.lePassword->hide();
- ui.lPassword->hide();
- ui.leUsername->hide();
- ui.lUsername->hide();
- ui.cbQos->hide();
- ui.lQos->hide();
- ui.twTopics->hide();
- //ui.lTopicTree->hide();
- ui.lTopicSearch->hide();
- ui.leTopics->hide();
- ui.twSubscriptions->hide();
- //ui.lSubscriptions->hide();
- ui.chbAuthentication->hide();
- ui.chbID->hide();
- ui.bSubscribe->hide();
- ui.bUnsubscribe->hide();
- ui.bConnect->hide();
+ //if there is a subscription containing the new one we set foundSuperior true
+ if(checkTopicContains(ui.twSubscriptions->topLevelItem(i)->text(0), name)
+ && name != ui.twSubscriptions->topLevelItem(i)->text(0)) {
+ foundSuperior = true;
+ qDebug()<<"2"<<name<<" "<< ui.twSubscriptions->topLevelItem(i)->text(0);
+ break;
+ }
+ qDebug()<<"checked superior";
+ }
- ui.gbMqttWill->hide();
- ui.chbWill->hide();
- ui.chbWillRetain->hide();
- ui.cbWillQoS->hide();
- ui.cbWillMessageType->hide();
- ui.cbWillTopic->hide();
- ui.cbWillUpdate->hide();
- ui.leWillOwnMessage->hide();
- ui.leWillUpdateInterval->setValidator(new QIntValidator(2, 1000000) );
- ui.leWillUpdateInterval->hide();
- ui.lWillMessageType->hide();
- ui.lWillOwnMessage->hide();
- ui.lWillQos->hide();
- ui.lWillTopic->hide();
- ui.lWillUpdate->hide();
- ui.lWillUpdateInterval->hide();
- ui.lwWillStatistics->hide();
- ui.lWillStatistics->hide();
-}
+ //if there wasn't a superior subscription we can subscribe to the new topic
+ if(!foundSuperior) {
+ qDebug()<<"Adding new topic";
+ QStringList toplevelName;
+ toplevelName.push_back(name);
+ QTreeWidgetItem* newTopLevelItem = new QTreeWidgetItem(toplevelName);
+ ui.twSubscriptions->addTopLevelItem(newTopLevelItem);
-#ifdef HAVE_MQTT
-void ImportFileWidget::mqttErrorChanged(QMqttClient::ClientError clientError) {
- switch (clientError) {
- case QMqttClient::BadUsernameOrPassword:
- QMessageBox::warning(this, "Couldn't connect", "Bad username or password");
- break;
- case QMqttClient::IdRejected:
- QMessageBox::warning(this, "Couldn't connect", "The client ID wasn't accepted");
- break;
- case QMqttClient::ServerUnavailable:
- QMessageBox::warning(this, "Server unavailable", "The network connection has been \
established, but the service is unavailable on the broker side.");
- break;
- case QMqttClient::NotAuthorized:
- QMessageBox::warning(this, "Couldn't connect", "The client is not authorized to \
connect.");
- break;
- case QMqttClient::UnknownError:
- QMessageBox::warning(this, "Unknown MQTT error", "An unknown error occurred.");
- break;
- default:
- break;
- }
-}
+ QMqttTopicFilter filter {name};
+ QMqttSubscription *temp_subscription = m_client->subscribe(filter, \
static_cast<quint8> (ui.cbQos->currentText().toUInt()) );
-bool ImportFileWidget::checkTopicContains(const QString& superior, const QString& \
inferior) {
- if (superior == inferior)
- return true;
- else {
- if(superior.contains("/")) {
- QStringList superiorList = superior.split('/', QString::SkipEmptyParts);
- QStringList inferiorList = inferior.split('/', QString::SkipEmptyParts);
+ if(temp_subscription) {
+ m_mqttSubscriptions.push_back(temp_subscription);
+ connect(temp_subscription, &QMqttSubscription::messageReceived, this, \
&ImportFileWidget::mqttSubscriptionMessageReceived); + emit \
subscriptionsChanged(); + }
- if(superiorList.size() > inferiorList.size())
- return false;
+ if(name.endsWith("#")) {
+ //adding every topic that the subscription contains
+ addSubscriptionChildren(item, newTopLevelItem);
- bool ok = true;
- for(int i = 0; i < superiorList.size(); ++i) {
- if(superiorList.at(i) != inferiorList.at(i)) {
- if((superiorList.at(i) != "+") &&
- !(superiorList.at(i) == "#" && i == superiorList.size() - 1)) {
- qDebug() <<superiorList.at(i)<<" "<<inferiorList.at(i);
- ok = false;
- break;
+ //if an already existing subscription contains a topic that the new \
subscription also contains + //we decompose the already existing subscription
+ //by unsubscribing from its topics, that are present in the new subscription as \
well + QStringList nameList = name.split('/', QString::SkipEmptyParts);
+ QString root = nameList.first();
+ QVector<QTreeWidgetItem*> children;
+ for(int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
+ if(ui.twSubscriptions->topLevelItem(i)->text(0).startsWith(root)
+ && name != ui.twSubscriptions->topLevelItem(i)->text(0)) {
+ children.clear();
+ //get the "leaf" children of the inspected subscription
+ findSubscriptionLeafChildren(children, ui.twSubscriptions->topLevelItem(i));
+ for(int j = 0; j < children.size(); ++j) {
+ if(checkTopicContains(name, children[j]->text(0))) {
+ //if the new subscription contains a topic, we unsubscribe from it
+ ui.twSubscriptions->setCurrentItem(children[j]);
+ mqttUnsubscribe();
+ }
+ }
+ }
}
}
+
+ manageCommonLevelSubscriptions();
+ } else {
+ QMessageBox::warning(this, "Warning", "You already subscribed to a topic \
containing this one"); }
- return ok;
}
-
- return false;
+ else
+ QMessageBox::warning(this, "Warning", "You already subscribed to this topic");
}
+ else
+ QMessageBox::warning(this, "Warning", "You didn't select any item from the Tree \
Widget"); }
-QString ImportFileWidget::checkCommonLevel(const QString& first, const QString& \
second) {
- qDebug()<<first<<" "<<second;
- QStringList firstList = first.split('/', QString::SkipEmptyParts);
- QStringList secondtList = second.split('/', QString::SkipEmptyParts);
- QString commonTopic = "";
+/*!
+ *\brief called when the unsubscribe button is pressed
+ * unsubscribes from the topic represented by the current item of twSubscription
+ */
+void ImportFileWidget::mqttUnsubscribe() {
+ QTreeWidgetItem* unsubscribeItem = ui.twSubscriptions->currentItem();
- if(!firstList.isEmpty()) {
- if(firstList.size() == secondtList.size() && (first != second)) {
- int matchIndex = -1;
- for(int i = 0; i < firstList.size(); ++i) {
- if(firstList.at(i) != secondtList.at(i)) {
- matchIndex = i;
- break;
- }
- }
- bool differ = false;
- if(matchIndex > 0) {
- for(int j = matchIndex +1; j < firstList.size(); ++j) {
- if(firstList.at(j) != secondtList.at(j)) {
- differ = true;
- break;
- }
- }
- }
- else
- differ = true;
+ if(unsubscribeItem != nullptr) {
+ //if it is a top level item, meaning a topic that we really subscribed to(not one \
that belongs to a subscription) + //we can simply unsubscribe from it
+ if(unsubscribeItem->parent() == nullptr)
+ unsubscribeFromTopic(unsubscribeItem->text(0));
+ else{
+ //otherwise we remove the selected item, but subscribe to every other topic, that \
was contained by + //the selected item's parent subscription(top level item of \
twSubscripitons) + while(unsubscribeItem->parent() != nullptr) {
+ for(int i = 0; i < unsubscribeItem->parent()->childCount(); ++i) {
+ if(unsubscribeItem->text(0) != unsubscribeItem->parent()->child(i)->text(0)) {
+ QMqttTopicFilter filter {unsubscribeItem->parent()->child(i)->text(0)};
+ QMqttSubscription *temp_subscription = m_client->subscribe(filter, \
static_cast<quint8> (ui.cbQos->currentText().toUInt()) );
- if(!differ)
- {
- for(int i = 0; i < firstList.size(); ++i) {
- if(i != matchIndex)
- commonTopic.append(firstList.at(i));
- else
- commonTopic.append("+");
+ ui.twSubscriptions->addTopLevelItem(unsubscribeItem->parent()->takeChild(i));
- if(i != firstList.size() - 1)
- commonTopic.append("/");
+ if(temp_subscription) {
+ m_mqttSubscriptions.push_back(temp_subscription);
+ connect(temp_subscription, &QMqttSubscription::messageReceived, this, \
&ImportFileWidget::mqttSubscriptionMessageReceived); + emit \
subscriptionsChanged(); + }
+ i--;
+ }
}
+ unsubscribeItem = unsubscribeItem->parent();
}
+ unsubscribeFromTopic(unsubscribeItem->text(0));
+
+ //check if any common topics were subscribed, if possible merge them
+ manageCommonLevelSubscriptions();
}
}
- qDebug() << "Common topic: "<<commonTopic;
- return commonTopic;
+ else
+ QMessageBox::warning(this, "Warning", "You didn't select any item from the Tree \
Widget"); }
-int ImportFileWidget::commonLevelIndex(const QString& first, const QString& second) \
{
- qDebug()<<first<<" "<<second;
- QStringList firstList = first.split('/', QString::SkipEmptyParts);
- QStringList secondtList = second.split('/', QString::SkipEmptyParts);
- QString commonTopic = "";
- int matchIndex = -1;
+/*!
+ *\brief called when the client receives a message
+ * if the message arrived from a new topic, the topic is put in twTopics
+ */
+void ImportFileWidget::mqttMessageReceived(const QByteArray &message , const \
QMqttTopicName &topic) { + if(!m_addedTopics.contains(topic.name())) {
+ m_addedTopics.push_back(topic.name());
+ QStringList name;
+ QChar sep = '/';
+ QString rootName;
+ if(topic.name().contains(sep)) {
+ QStringList list = topic.name().split(sep, QString::SkipEmptyParts);
- if(!firstList.isEmpty()) {
- if(firstList.size() == secondtList.size() && (first != second)) {
- for(int i = 0; i < firstList.size(); ++i) {
- if(firstList.at(i) != secondtList.at(i)) {
- matchIndex = i;
+ rootName = list.at(0);
+ name.append(list.at(0));
+ QTreeWidgetItem* currentItem;
+ int topItemIdx = -1;
+ //check whether the first level of the topic can be found in twTopics
+ for(int i = 0; i < ui.twTopics->topLevelItemCount(); ++i) {
+ if(ui.twTopics->topLevelItem(i)->text(0) == list.at(0)) {
+ topItemIdx = i;
break;
}
}
- bool differ = false;
- if(matchIndex > 0) {
- for(int j = matchIndex +1; j < firstList.size(); ++j) {
- if(firstList.at(j) != secondtList.at(j)) {
- differ = true;
+ //if not we simply add every level of the topic to the tree
+ if( topItemIdx < 0) {
+ currentItem = new QTreeWidgetItem(name);
+ ui.twTopics->addTopLevelItem(currentItem);
+ for(int i = 1; i < list.size(); ++i) {
+ name.clear();
+ name.append(list.at(i));
+ currentItem->addChild(new QTreeWidgetItem(name));
+ currentItem = currentItem->child(0);
+ }
+ }
+ //otherwise we search for the first level that isn't part of the tree,
+ //then add every level of the topic to the tree from that certain level
+ else {
+ currentItem = ui.twTopics->topLevelItem(topItemIdx);
+ int listIdx = 1;
+ for(; listIdx < list.size(); ++listIdx) {
+ QTreeWidgetItem* childItem = nullptr;
+ bool found = false;
+ for(int j = 0; j < currentItem->childCount(); ++j) {
+ childItem = currentItem->child(j);
+ if(childItem->text(0) == list.at(listIdx)) {
+ found = true;
+ currentItem = childItem;
+ break;
+ }
+ }
+ if(!found) {
+ //this is the level that isn't present in the tree
break;
}
}
- }
- else
- differ = true;
-
- if(!differ)
- {
- for(int i = 0; i < firstList.size(); ++i) {
- if(i != matchIndex)
- commonTopic.append(firstList.at(i));
- else
- commonTopic.append("+");
- if(i != firstList.size() - 1)
- commonTopic.append("/");
+ //add every level to the tree starting with the first level that isn't part of \
the tree + for(; listIdx < list.size(); ++listIdx) {
+ name.clear();
+ name.append(list.at(listIdx));
+ currentItem->addChild(new QTreeWidgetItem(name));
+ currentItem = currentItem->child(currentItem->childCount() - 1);
}
}
}
+ else {
+ rootName = topic.name();
+ name.append(topic.name());
+ ui.twTopics->addTopLevelItem(new QTreeWidgetItem(name));
+ }
+ //signals that a newTopic was added, in order to fill the completer of leTopics
+ emit newTopic(rootName);
}
-
- qDebug() << "Common topic: "<<commonTopic;
- qDebug() << "match index: "<<matchIndex;
- if(!commonTopic.isEmpty())
- return matchIndex;
- else
- return -1;
}
-void ImportFileWidget::searchTreeItem(const QString& rootName) {
- m_searching = true;
- m_searchTimer->start();
-
- qDebug()<<rootName;
- int topItemIdx = -1;
- for(int i = 0; i< ui.twTopics->topLevelItemCount(); ++i)
- if(ui.twTopics->topLevelItem(i)->text(0) == rootName) {
- topItemIdx = i;
- break;
+/*!
+ *\brief called when a new topic is added to the tree(twTopics)
+ * appends the topic's root to the topicList if it isn't in the list already
+ * then sets the completer for leTopics
+ */
+void ImportFileWidget::setCompleter(const QString& topic) {
+ if(!m_searching) {
+ if(!m_topicList.contains(topic)) {
+ m_topicList.append(topic);
+ m_completer = new QCompleter(m_topicList, this);
+ m_completer->setCompletionMode(QCompleter::PopupCompletion);
+ m_completer->setCaseSensitivity(Qt::CaseSensitive);
+ ui.leTopics->setCompleter(m_completer);
}
-
- if(topItemIdx >= 0) {
- qDebug() << "Scroll";
- ui.twTopics->scrollToItem(ui.twTopics->topLevelItem(topItemIdx), \
QAbstractItemView::ScrollHint::PositionAtTop); }
}
-void ImportFileWidget::unsubscribeFromTopic(const QString& topicName) {
- if(!topicName.isEmpty()) {
- QMqttTopicFilter filter{topicName};
- m_client->unsubscribe(filter);
+/*!
+ *\brief called when too much time passed since trying to connect to the broker
+ */
+void ImportFileWidget::topicTimeout() {
+ qDebug()<<"lejart ido";
+ m_searching = false;
+ m_searchTimer->stop();
+}
- qDebug()<<"unsubscribe occured";
+/*!
+ *\brief called when the client receives a message from a subscribed topic (that \
isn't the "#" wildcard) + */
+void ImportFileWidget::mqttSubscriptionMessageReceived(const QMqttMessage &msg) {
+ qDebug()<<"message received from: "<<msg.topic().name();
+ if(!m_subscribedTopicNames.contains(msg.topic().name())) {
+ m_messageArrived[msg.topic()] = true;
+ qDebug()<<msg.topic().name()<<"set true";
+ m_subscribedTopicNames.push_back(msg.topic().name());
- for(int i = 0; i< m_mqttSubscriptions.count(); ++i)
- if(m_mqttSubscriptions[i]->topic().filter() == topicName) {
- qDebug()<<"1 subscription found at "<<i <<"and removed";
- m_mqttSubscriptions.remove(i);
- break;
- }
+ //signals that there is a new topic that can be set as will topic
+ emit newTopicForWill();
+ }
- m_mqttReadyForPreview = false;
+ if(m_messageArrived[msg.topic()] == false) {
+ qDebug()<<msg.topic().name()<<"set true";
+ m_messageArrived[msg.topic()] = true;
+ }
- QMapIterator<QMqttTopicName, bool> i(m_messageArrived);
- while(i.hasNext()) {
- i.next();
- if(checkTopicContains(topicName, i.key().name())) {
- m_messageArrived.remove(i.key());
- qDebug()<<"2 subscription found at "<<i.key() <<"and removed";
- }
- }
+ //updates the last message of the topic
+ m_lastMessage[msg.topic()]= msg;
- QMapIterator<QMqttTopicName, QMqttMessage> j(m_lastMessage);
- while(j.hasNext()) {
- j.next();
- if(checkTopicContains(topicName, j.key().name())) {
- m_lastMessage.remove(j.key());
- qDebug()<<"3 subscription found at "<<j.key() <<"and removed";
- }
+ //check if the client received a message from every subscribed topic, since the \
last time the preview was refreshed + bool check = true;
+ QMapIterator<QMqttTopicName, bool> i(m_messageArrived);
+ while(i.hasNext()) {
+ i.next();
+ if(i.value() == false ) {
+ qDebug()<<"Found false: "<<i.key().name();
+ check = false;
+ break;
}
+ }
- for(int row = 0; row<ui.twSubscriptions->topLevelItemCount(); row++) {
- if(ui.twSubscriptions->topLevelItem(row)->text(0) == topicName) {
- qDebug()<<"4 subscription found at \
"<<ui.twSubscriptions->topLevelItem(row)->text(0) <<"and removed";
- ui.twSubscriptions->topLevelItem(row)->takeChildren();
- ui.twSubscriptions->takeTopLevelItem(row);
- }
- }
+ //if there is a message from every subscribed topic, we refresh the preview
+ if (check == true) {
+ m_mqttReadyForPreview = true;
+ refreshPreview();
+ }
+}
- for(int i = 0; i < m_subscribedTopicNames.size(); ++i) {
- if(checkTopicContains(topicName, m_subscribedTopicNames[i])) {
- m_subscribedTopicNames.remove(i);
- i--;
- }
+/*!
+ *\brief called when use will message checkbox's state is changed,
+ * if state is checked it shows the options regarding the will message
+ *
+ * \param state the state of the checbox
+ */
+void ImportFileWidget::useWillMessage(int state) {
+ if(state == Qt::Checked) {
+ ui.chbWillRetain->show();
+ ui.cbWillQoS->show();
+ ui.cbWillMessageType->show();
+ ui.cbWillTopic->show();
+ ui.cbWillUpdate->show();
+ ui.lWillMessageType->show();
+ ui.lWillQos->show();
+ ui.lWillTopic->show();
+ ui.lWillUpdate->show();
+
+ if (ui.cbWillMessageType->currentIndex() == \
static_cast<int>(MQTTClient::WillMessageType::OwnMessage) ) { \
+ ui.leWillOwnMessage->show(); + ui.lWillOwnMessage->show();
+ } else if(ui.cbWillMessageType->currentIndex() == \
static_cast<int>(MQTTClient::WillMessageType::Statistics) ) { \
+ ui.lWillStatistics->show(); + ui.lwWillStatistics->show();
}
- for(int item = 0; item < ui.cbWillTopic->count(); ++item) {
- if(checkTopicContains(topicName, ui.cbWillTopic->itemText(item))) {
- ui.cbWillTopic->removeItem(item);
- item--;
- }
+ if(ui.cbWillUpdate->currentIndex() == 0) {
+ ui.leWillUpdateInterval->show();
+ ui.lWillUpdateInterval->show();
}
+ } else if (state == Qt::Unchecked) {
+ qDebug()<<"will use unchecked";
+ ui.chbWillRetain->hide();
+ ui.cbWillQoS->hide();
+ ui.cbWillMessageType->hide();
+ ui.cbWillTopic->hide();
+ ui.cbWillUpdate->hide();
+ ui.leWillOwnMessage->hide();
+ ui.leWillUpdateInterval->hide();
+ ui.lWillMessageType->hide();
+ ui.lWillOwnMessage->hide();
+ ui.lWillQos->hide();
+ ui.lWillTopic->hide();
+ ui.lWillUpdate->hide();
+ ui.lWillUpdateInterval->hide();
+ ui.lWillStatistics->hide();
+ ui.lwWillStatistics->hide();
+ }
+}
+
+
+/*!
+ *\brief called when the selected will message type is changed,
+ * shows the options for the selected message type, hides the irrelevant ones
+ *
+ * \param type the selected will message type
+ */
+void ImportFileWidget::willMessageTypeChanged(int type) {
+ if(static_cast<MQTTClient::WillMessageType> (type) == \
MQTTClient::WillMessageType::OwnMessage) { + ui.leWillOwnMessage->show();
+ ui.lWillOwnMessage->show();
+ ui.lWillStatistics->hide();
+ ui.lwWillStatistics->hide();
+ } else if(static_cast<MQTTClient::WillMessageType> (type) == \
MQTTClient::WillMessageType::LastMessage) { + ui.leWillOwnMessage->hide();
+ ui.lWillOwnMessage->hide();
+ ui.lWillStatistics->hide();
+ ui.lwWillStatistics->hide();
+ } else if(static_cast<MQTTClient::WillMessageType> (type) == \
MQTTClient::WillMessageType::Statistics) { + qDebug()<<"will message type changed \
show statistics"; + ui.lWillStatistics->show();
+ ui.lwWillStatistics->show();
+ ui.leWillOwnMessage->hide();
+ ui.lWillOwnMessage->hide();
+ }
+}
- emit subscriptionMade();
- refreshPreview();
+/*!
+ *\brief called when newTopicForWill signal is emitted,
+ * updates the topics that can be selected as the will message's topic
+ */
+void ImportFileWidget::updateWillTopics() {
+ QString current = ui.cbWillTopic->currentText();
+ ui.cbWillTopic->clear();
+ for(int i = 0; i < m_subscribedTopicNames.size(); ++i) {
+ ui.cbWillTopic->addItem(m_subscribedTopicNames[i]);
}
+ ui.cbWillTopic->setCurrentText(current);
}
-void ImportFileWidget::addSubscriptionChildren(QTreeWidgetItem * topic, \
QTreeWidgetItem * subscription) {
- if(topic->childCount() > 0) {
- for(int i = 0; i < topic->childCount(); ++i) {
- QTreeWidgetItem* temp = topic->child(i);
- QString name;
- if(topic->child(i)->childCount() > 0) {
- name.append(temp->text(0) + "/#");
- while(temp->parent() != nullptr) {
- temp = temp->parent();
- name.prepend(temp->text(0) + "/");
- }
+/*!
+ *\brief called when the selected update type for the will message is changed,
+ * shows the options for the selected update type, hides the irrelevant ones
+ *
+ * \param type the selected will update type
+ */
+void ImportFileWidget::willUpdateTypeChanged(int updateType) {
+ if(static_cast<MQTTClient::WillUpdateType>(updateType) == \
MQTTClient::WillUpdateType::TimePeriod) { + ui.leWillUpdateInterval->show();
+ ui.lWillUpdateInterval->show();
+ }
+ else if (static_cast<MQTTClient::WillUpdateType>(updateType) == \
MQTTClient::WillUpdateType::OnClick) { + ui.leWillUpdateInterval->hide();
+ ui.lWillUpdateInterval->hide();
+ }
+}
- } else {
- name.append(temp->text(0));
- while(temp->parent() != nullptr) {
- temp = temp->parent();
- name.prepend(temp->text(0) + "/");
- }
- }
- QStringList nameList;
- nameList.append(name);
- QTreeWidgetItem* childItem = new QTreeWidgetItem(nameList);
- subscription->addChild(childItem);
- addSubscriptionChildren(topic->child(i), childItem);
- }
+/*!
+ *\brief called when the clientError of the MQTT client changes
+ *
+ * \param clientError the current error of the client
+ */
+void ImportFileWidget::mqttErrorChanged(QMqttClient::ClientError clientError) {
+ switch (clientError) {
+ case QMqttClient::BadUsernameOrPassword:
+ QMessageBox::warning(this, "Couldn't connect", "Bad username or password");
+ break;
+ case QMqttClient::IdRejected:
+ QMessageBox::warning(this, "Couldn't connect", "The client ID wasn't accepted");
+ break;
+ case QMqttClient::ServerUnavailable:
+ QMessageBox::warning(this, "Server unavailable", "The network connection has been \
established, but the service is unavailable on the broker side."); + break;
+ case QMqttClient::NotAuthorized:
+ QMessageBox::warning(this, "Couldn't connect", "The client is not authorized to \
connect."); + break;
+ case QMqttClient::UnknownError:
+ QMessageBox::warning(this, "Unknown MQTT error", "An unknown error occurred.");
+ break;
+ default:
+ break;
}
}
-void ImportFileWidget::mqttTimeout() {
- m_client->disconnectFromHost();
- m_timeoutTimer->stop();
- QMessageBox::warning(this, "Warning", "Couldn't connect to the given broker");
+/*!
+ *\brief called when leTopics' text is changed
+ * if the rootName can be found in twTopics, then we scroll it to the top of the \
tree widget + *
+ * \param rootName the current text of leTopics
+ */
+void ImportFileWidget::scrollToTreeItem(const QString& rootName) {
+ m_searching = true;
+ m_searchTimer->start();
+
+ int topItemIdx = -1;
+ for(int i = 0; i < ui.twTopics->topLevelItemCount(); ++i)
+ if(ui.twTopics->topLevelItem(i)->text(0) == rootName) {
+ topItemIdx = i;
+ break;
+ }
+
+ if(topItemIdx >= 0) {
+ ui.twTopics->scrollToItem(ui.twTopics->topLevelItem(topItemIdx), \
QAbstractItemView::ScrollHint::PositionAtTop); + }
}
+/*!
+ *\brief called when any option of the client (host, port, id, etc.) is changed \
before connecting to the broker, + * checks if every option needed for the \
connection is set, if it is, then enables the connect button + */
void ImportFileWidget::checkConnectEnable() {
bool authenticationUsed = ui.chbAuthentication->isChecked();
bool idUsed = ui.chbID->isChecked();
@@ -2384,182 +2749,14 @@ void ImportFileWidget::checkConnectEnable() {
ui.bConnect->setEnabled(enable);
}
-void ImportFileWidget::findSubscriptionLeafChildren(QVector<QTreeWidgetItem *>& \
children, QTreeWidgetItem* root) {
- if(root->childCount() == 0) {
- children.push_back(root);
- } else {
- for(int i = 0; i < root->childCount(); ++i) {
- findSubscriptionLeafChildren(children, root->child(i));
- }
- }
-}
-
-int ImportFileWidget::checkCommonChildCount(int levelIdx, int level, QStringList& \
commonList, QTreeWidgetItem* currentItem) {
- qDebug()<<"LevelIdx: "<<levelIdx<<" level: "<<level<<" current Item: \
"<<currentItem->text(0);
- if(levelIdx < level - 1) {
- if(commonList[levelIdx] != "+") {
- for(int j = 0; j < currentItem->childCount(); ++j) {
- if(currentItem->child(j)->text(0) == commonList[levelIdx]) {
- qDebug()<<"level index: "<<levelIdx<<" "<<currentItem->child(j)->text(0)<<" \
"<<commonList[levelIdx];
- return checkCommonChildCount(levelIdx + 1, level, commonList, \
currentItem->child(j));
- }
- }
- } else {
- int childCount = -1;
- bool ok = true;
- for(int j = 0; j < currentItem->childCount(); ++j) {
- int temp = checkCommonChildCount(levelIdx + 1, level, commonList, \
currentItem->child(j));
-
- if((j > 0) && (temp != childCount)) {
- ok = false;
- break;
- }
- childCount = temp;
- }
-
- if(ok)
- return childCount;
- else
- return -1;
- }
- } else if (levelIdx == level - 1) {
- if(commonList[levelIdx] != "+") {
- for(int j = 0; j < currentItem->childCount(); ++j) {
- if(currentItem->child(j)->text(0) == commonList[levelIdx]) {
- qDebug()<<"level index: "<<levelIdx<<" "<<currentItem->child(j)->text(0)<<" \
"<<commonList[levelIdx];
- return currentItem->child(j)->childCount();
- }
- }
- } else {
- int childCount = -1;
- bool ok = true;
- for(int j = 0; j < currentItem->childCount(); ++j) {
- if((j > 0) && (currentItem->child(j)->childCount() != childCount)) {
- ok = false;
- break;
- }
- childCount = currentItem->child(j)->childCount();
- }
-
- if(ok)
- return childCount;
- else
- return -1;
- }
- } else if (level == 1 && levelIdx == 1)
- return currentItem->childCount();
-
- return -1;
-}
-
-void ImportFileWidget::manageCommonLevelSubscriptions() {
- bool foundEqual = false;
-
- do{
- foundEqual = false;
- QMap<QString, QVector<QString>> equalTopicsMap;
- QVector<QString> equalTopics;
-
- qDebug()<<"Search for common topic after unsubscribe";
- for(int i = 0; i < ui.twSubscriptions->topLevelItemCount() - 1; ++i) {
- for(int j = i + 1; j < ui.twSubscriptions->topLevelItemCount(); ++j) {
- qDebug()<<ui.twSubscriptions->topLevelItem(i)->text(0)<<" \
"<<ui.twSubscriptions->topLevelItem(j)->text(0);
- QString commonTopic = \
checkCommonLevel(ui.twSubscriptions->topLevelItem(i)->text(0), \
ui.twSubscriptions->topLevelItem(j)->text(0));
- if(!commonTopic.isEmpty()) {
- if(!equalTopicsMap[commonTopic].contains(ui.twSubscriptions->topLevelItem(i)->text(0))) \
{
- qDebug()<<commonTopic<<": "<<ui.twSubscriptions->topLevelItem(i)->text(0);
- equalTopicsMap[commonTopic].push_back(ui.twSubscriptions->topLevelItem(i)->text(0));
- }
-
- if(!equalTopicsMap[commonTopic].contains(ui.twSubscriptions->topLevelItem(j)->text(0))) \
{
- qDebug()<<commonTopic<<": "<<ui.twSubscriptions->topLevelItem(i)->text(0);
- equalTopicsMap[commonTopic].push_back(ui.twSubscriptions->topLevelItem(j)->text(0));
- }
- }
- }
- }
-
- if(!equalTopicsMap.isEmpty()) {
- qDebug()<<"Equal topics not empty";
-
- QVector<QString> commonTopics;
- QMapIterator<QString, QVector<QString>> topics(equalTopicsMap);
- while(topics.hasNext()) {
- topics.next();
- qDebug()<<"Checking: " << topics.key();
-
- int level = commonLevelIndex(topics.value().last(), topics.value().first());
- QStringList commonList = topics.value().first().split('/', \
QString::SkipEmptyParts);
- QTreeWidgetItem* currentItem;
- for(int i = 0; i < ui.twTopics->topLevelItemCount(); ++i) {
- if(ui.twTopics->topLevelItem(i)->text(0) == commonList.first()) {
- currentItem = ui.twTopics->topLevelItem(i);
- break;
- }
- }
-
- qDebug()<<"level "<<level;
- int childCount = checkCommonChildCount(1, level, commonList, currentItem);
- qDebug()<<"child count: " << childCount;
- if(childCount > 0) {
- if(topics.value().size() == childCount) {
- foundEqual = true;
- commonTopics.push_back(topics.key());
- qDebug()<<topics.key()<<" equal is true";
- }
- }
- }
-
- if(foundEqual) {
- int highestLevel = INT_MAX;
- int topicIdx = -1;
- for(int i = 0; i < commonTopics.size(); ++i) {
- int level = commonLevelIndex(equalTopicsMap[commonTopics[i]].first(), \
commonTopics[i]);
- if(level < highestLevel) {
- topicIdx = i;
- highestLevel = level;
- }
- }
-
- equalTopics.append(equalTopicsMap[commonTopics[topicIdx]]);
-
- qDebug()<<"Adding common topic";
- QString commonTopic;
-
- commonTopic = checkCommonLevel(equalTopics.first(), equalTopics.last());
- QStringList nameList;
- nameList.append(commonTopic);
- QTreeWidgetItem* newTopic = new QTreeWidgetItem(nameList);
- ui.twSubscriptions->addTopLevelItem(newTopic);
- QMqttTopicFilter filter {commonTopic};
- QMqttSubscription *temp_subscription = m_client->subscribe(filter, \
static_cast<quint8> (ui.cbQos->currentText().toUInt()) );
-
- if(temp_subscription) {
- m_mqttSubscriptions.push_back(temp_subscription);
- connect(temp_subscription, &QMqttSubscription::messageReceived, this, \
&ImportFileWidget::mqttSubscriptionMessageReceived);
- emit subscriptionMade();
- }
-
- qDebug()<<"unsubscribe from equal topics";
- for(int i = 0; i < equalTopics.size(); ++i) {
- for(int j = 0; j < ui.twSubscriptions->topLevelItemCount(); ++j){
- if(ui.twSubscriptions->topLevelItem(j)->text(0) == equalTopics[i]) {
- newTopic->addChild(ui.twSubscriptions->takeTopLevelItem(j));
- unsubscribeFromTopic(equalTopics[i]);
- break;
- }
- }
- }
-
- for(int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
- if(checkTopicContains(commonTopic, \
ui.twSubscriptions->topLevelItem(i)->text(0)) &&
- commonTopic != ui.twSubscriptions->topLevelItem(i)->text(0) ) {
- unsubscribeFromTopic(ui.twSubscriptions->topLevelItem(i)->text(0));
- i--;
- }
- }
- }
- }
- } while(foundEqual);
+/*!
+ *\brief called when m_connectTimeoutTimer ticks,
+ * meaning that the client couldn't connect to the broker in 5 seconds
+ * disconnects the client, stops the timer, and warns the user
+ */
+void ImportFileWidget::mqttConnectTimeout() {
+ m_client->disconnectFromHost();
+ m_connectTimeoutTimer->stop();
+ QMessageBox::warning(this, "Warning", "Couldn't connect to the given broker");
}
#endif
diff --git a/src/kdefrontend/datasources/ImportFileWidget.h \
b/src/kdefrontend/datasources/ImportFileWidget.h index c700cc56..3414a307 100644
--- a/src/kdefrontend/datasources/ImportFileWidget.h
+++ b/src/kdefrontend/datasources/ImportFileWidget.h
@@ -159,7 +159,7 @@ private:
QStringList m_topicList;
bool m_searching;
QTimer *m_searchTimer;
- QTimer *m_timeoutTimer;
+ QTimer *m_connectTimeoutTimer;
QMap<QMqttTopicName, bool> m_messageArrived;
QMap<QMqttTopicName, QMqttMessage> m_lastMessage;
bool m_mqttReadyForPreview;
@@ -172,7 +172,7 @@ public:
signals:
void newTopic(QString);
- void subscriptionMade();
+ void subscriptionsChanged();
void checkFileType();
void newTopicForWill();
@@ -191,10 +191,10 @@ private slots:
void useWillMessage(int);
void willMessageTypeChanged(int);
void updateWillTopics();
- void willUpdateChanged(int);
+ void willUpdateTypeChanged(int);
void mqttErrorChanged(QMqttClient::ClientError);
- void searchTreeItem(const QString&);
- void mqttTimeout();
+ void scrollToTreeItem(const QString&);
+ void mqttConnectTimeout();
void checkConnectEnable();
#endif
};
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic