[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