Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
- index 33e3a9208..11d7d561e 100644
- --- a/src/CMakeLists.txt
- +++ b/src/CMakeLists.txt
- @@ -40,6 +40,7 @@ set(GUI_SOURCES
- ${KDEFRONTEND_DIR}/datasources/FITSOptionsWidget.cpp
- ${KDEFRONTEND_DIR}/datasources/MQTTErrorWidget.cpp
- ${KDEFRONTEND_DIR}/datasources/MQTTHelpers.cpp
- + ${KDEFRONTEND_DIR}/datasources/MQTTSubscriptionWidget
- ${KDEFRONTEND_DIR}/datasources/JsonOptionsWidget.cpp
- ${KDEFRONTEND_DIR}/datasources/MQTTConnectionManagerWidget.cpp
- ${KDEFRONTEND_DIR}/datasources/MQTTConnectionManagerDialog.cpp
- @@ -122,6 +123,7 @@ set(UI_SOURCES
- ${KDEFRONTEND_DIR}/ui/datasources/rootoptionswidget.ui
- ${KDEFRONTEND_DIR}/ui/datasources/fitsoptionswidget.ui
- ${KDEFRONTEND_DIR}/ui/datasources/mqtterrorwidget.ui
- + ${KDEFRONTEND_DIR}/ui/datasources/mqttsubscriptionwidget.ui
- ${KDEFRONTEND_DIR}/ui/datasources/jsonoptionswidget.ui
- ${KDEFRONTEND_DIR}/ui/datasources/mqttconnectionmanagerwidget.ui
- ${KDEFRONTEND_DIR}/ui/dockwidgets/axisdock.ui
- diff --git a/src/kdefrontend/datasources/ImportFileWidget.cpp b/src/kdefrontend/datasources/ImportFileWidget.cpp
- index 7471f7cda..9673f3089 100644
- --- a/src/kdefrontend/datasources/ImportFileWidget.cpp
- +++ b/src/kdefrontend/datasources/ImportFileWidget.cpp
- @@ -6,7 +6,7 @@ Description : import file data widget
- Copyright : (C) 2009-2018 Stefan Gerlach (stefan.gerlach@uni.kn)
- Copyright : (C) 2009-2019 Alexander Semke (alexander.semke@web.de)
- Copyright : (C) 2017-2018 Fabian Kristof (fkristofszabolcs@gmail.com)
- -Copyright : (C) 2018 Kovacs Ferencz (kferike98@gmail.com)
- +Copyright : (C) 2018-2019 Kovacs Ferencz (kferike98@gmail.com)
- ***************************************************************************/
- @@ -67,6 +67,7 @@ Copyright : (C) 2018 Kovacs Ferencz (kferike98@gmail.com)
- #include "kdefrontend/widgets/MQTTWillSettingsWidget.h"
- #include "MQTTConnectionManagerDialog.h"
- #include "MQTTHelpers.h"
- +#include "MQTTSubscriptionWidget.h"
- #include <QMqttClient>
- #include <QMqttSubscription>
- #include <QMqttTopicFilter>
- @@ -86,9 +87,9 @@ ImportFileWidget::ImportFileWidget(QWidget* parent, bool liveDataSource, const Q
- m_fileName(fileName),
- m_liveDataSource(liveDataSource)
- #ifdef HAVE_MQTT
- - ,
- - m_searchTimer(new QTimer(this)),
- - m_connectTimeoutTimer(new QTimer(this))
- + ,
- + m_connectTimeoutTimer(new QTimer(this)),
- + m_subscriptionWidget(new MQTTSubscriptionWidget(this))
- #endif
- {
- ui.setupUi(this);
- @@ -135,7 +136,6 @@ ImportFileWidget::ImportFileWidget(QWidget* parent, bool liveDataSource, const Q
- ui.tabWidget->removeTab(2);
- #ifdef HAVE_MQTT
- - m_searchTimer->setInterval(10000);
- m_connectTimeoutTimer->setInterval(6000);
- #endif
- }
- @@ -173,35 +173,16 @@ ImportFileWidget::ImportFileWidget(QWidget* parent, bool liveDataSource, const Q
- ui.cbSourceType->addItem(QLatin1String("MQTT"));
- m_configPath = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).constFirst() + QLatin1String("MQTT_connections");
- - const int size = ui.leTopics->height();
- - ui.lTopicSearch->setPixmap( QIcon::fromTheme(QLatin1String("go-next")).pixmap(size, size) );
- - ui.lSubscriptionSearch->setPixmap( QIcon::fromTheme(QLatin1String("go-next")).pixmap(size, size) );
- - ui.bSubscribe->setIcon(ui.bSubscribe->style()->standardIcon(QStyle::SP_ArrowRight));
- - ui.bSubscribe->setToolTip(i18n("Subscribe selected topics"));
- - ui.bUnsubscribe->setIcon(ui.bUnsubscribe->style()->standardIcon(QStyle::SP_ArrowLeft));
- - ui.bUnsubscribe->setToolTip(i18n("Unsubscribe selected topics"));
- + ui.swSubscriptions->addWidget(m_subscriptionWidget);
- + ui.swSubscriptions->setCurrentWidget(m_subscriptionWidget);
- ui.bManageConnections->setIcon(QIcon::fromTheme(QLatin1String("network-server")));
- - ui.bManageConnections->setToolTip(i18n("Manage MQTT connections"));
- + ui.bManageConnections->setToolTip(i18n("Manage MQTT connections"));
- - QString info = i18n("Enter the name of the topic to navigate to it.");
- - ui.lTopicSearch->setToolTip(info);
- - ui.leTopics->setToolTip(info);
- - ui.lSubscriptionSearch->setToolTip(info);
- - ui.leSubscriptions->setToolTip(info);
- -
- - info = i18n("Specify the 'Last Will and Testament' message (LWT). At least one topic has to be subscribed.");
- + QString info = i18n("Specify the 'Last Will and Testament' message (LWT). At least one topic has to be subscribed.");
- ui.lLWT->setToolTip(info);
- ui.bLWT->setToolTip(info);
- ui.bLWT->setEnabled(false);
- - ui.bLWT->setIcon(ui.bLWT->style()->standardIcon(QStyle::SP_FileDialogDetailedView));
- -
- - info = i18n("Set the Quality of Service (QoS) for the subscription to define the guarantee of the message delivery:"
- - "<ul>"
- - "<li>0 - deliver at most once</li>"
- - "<li>1 - deliver at least once</li>"
- - "<li>2 - deliver exactly once</li>"
- - "</ul>");
- - ui.cbQos->setToolTip(info);
- + ui.bLWT->setIcon(ui.bLWT->style()->standardIcon(QStyle::SP_FileDialogDetailedView));
- #endif
- //TODO: implement save/load of user-defined settings later and activate these buttons again
- @@ -316,6 +297,10 @@ ImportFileWidget::~ImportFileWidget() {
- conf.writeEntry("UpdateInterval", ui.sbUpdateInterval->value());
- #ifdef HAVE_MQTT
- +
- + delete m_connectTimeoutTimer;
- + delete m_subscriptionWidget;
- +
- //MQTT related settings
- conf.writeEntry("Connection", ui.cbConnection->currentText());
- conf.writeEntry("mqttWillMessageType", static_cast<int>(m_willSettings.willMessageType));
- @@ -367,19 +352,14 @@ void ImportFileWidget::initSlots() {
- connect(ui.bRefreshPreview, &QPushButton::clicked, this, &ImportFileWidget::refreshPreview);
- #ifdef HAVE_MQTT
- - connect(ui.cbConnection, static_cast<void (QComboBox::*) (int)>(&QComboBox::currentIndexChanged), this, &ImportFileWidget::mqttConnectionChanged);
- - connect(ui.bSubscribe, &QPushButton::clicked, this, &ImportFileWidget::mqttSubscribe);
- - connect(ui.bUnsubscribe, &QPushButton::clicked, this,&ImportFileWidget::mqttUnsubscribe);
- - connect(this, &ImportFileWidget::newTopic, this, &ImportFileWidget::setTopicCompleter);
- - connect(m_searchTimer, &QTimer::timeout, this, &ImportFileWidget::topicTimeout);
- + connect(ui.cbConnection, static_cast<void (QComboBox::*) (int)>(&QComboBox::currentIndexChanged), this, &ImportFileWidget::mqttConnectionChanged);
- connect(m_connectTimeoutTimer, &QTimer::timeout, this, &ImportFileWidget::mqttConnectTimeout);
- - connect(ui.cbFileType, static_cast<void (QComboBox::*) (int)>(&QComboBox::currentIndexChanged), [this]() {emit checkFileType();});
- - connect(ui.leTopics, &QLineEdit::textChanged, this, &ImportFileWidget::scrollToTopicTreeItem);
- - connect(ui.leSubscriptions, &QLineEdit::textChanged, this, &ImportFileWidget::scrollToSubsriptionTreeItem);
- + connect(ui.cbFileType, static_cast<void (QComboBox::*) (int)>(&QComboBox::currentIndexChanged), [this]() {emit checkFileType();});
- connect(ui.bManageConnections, &QPushButton::clicked, this, &ImportFileWidget::showMQTTConnectionManager);
- - connect(ui.bLWT, &QPushButton::clicked, this, &ImportFileWidget::showWillSettings);
- - connect(ui.twTopics, &QTreeWidget::itemDoubleClicked, this, &ImportFileWidget::mqttAvailableTopicDoubleClicked);
- - connect(ui.twSubscriptions, &QTreeWidget::itemDoubleClicked, this, &ImportFileWidget::mqttSubscribedTopicDoubleClicked);
- + connect(ui.bLWT, &QPushButton::clicked, this, &ImportFileWidget::showWillSettings);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::makeSubscription, this, &ImportFileWidget::mqttSubscribe);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::MQTTUnsubscribeFromTopic, this, &ImportFileWidget::unsubscribeFromTopic);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::enableWill, this, &ImportFileWidget::enableWill);
- #endif
- }
- @@ -774,16 +754,19 @@ void ImportFileWidget::selectFile() {
- void ImportFileWidget::setMQTTVisible(bool visible) {
- ui.lConnections->setVisible(visible);
- ui.cbConnection->setVisible(visible);
- - ui.bManageConnections->setVisible(visible);
- - ui.cbQos->setVisible(visible);
- + ui.bManageConnections->setVisible(visible);
- //topics
- if (ui.cbConnection->currentIndex() != -1 && visible) {
- ui.lTopics->setVisible(true);
- - ui.gbManageSubscriptions->setVisible(true);
- + ui.swSubscriptions->setVisible(true);
- + m_subscriptionWidget->setVisible(true);
- + m_subscriptionWidget->makeVisible(true);
- } else {
- ui.lTopics->setVisible(false);
- - ui.gbManageSubscriptions->setVisible(false);
- + ui.swSubscriptions->setVisible(false);
- + m_subscriptionWidget->setVisible(false);
- + m_subscriptionWidget->makeVisible(false);
- }
- //will message
- @@ -801,7 +784,7 @@ bool ImportFileWidget::isMqttValid() {
- return false;
- bool connected = (m_client->state() == QMqttClient::ClientState::Connected);
- - bool subscribed = (ui.twSubscriptions->topLevelItemCount() > 0);
- + bool subscribed = (m_subscriptionWidget->subscriptionCount() > 0);
- bool fileTypeOk = false;
- if (this->currentFileType() == AbstractFileFilter::FileType::Ascii)
- fileTypeOk = true;
- @@ -814,7 +797,7 @@ bool ImportFileWidget::isMqttValid() {
- *
- * \param topicName the name of a topic we want to unsubscribe from
- */
- -void ImportFileWidget::unsubscribeFromTopic(const QString& topicName) {
- +void ImportFileWidget::unsubscribeFromTopic(const QString& topicName, QVector<QTreeWidgetItem*> children) {
- if (topicName.isEmpty())
- return;
- @@ -841,14 +824,7 @@ void ImportFileWidget::unsubscribeFromTopic(const QString& topicName) {
- j.next();
- if (MQTTHelpers::checkTopicContains(topicName, j.key().name()))
- m_lastMessage.remove(j.key());
- - }
- -
- - 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);
- - }
- - }
- + }
- for (int i = 0; i < m_subscribedTopicNames.size(); ++i) {
- if (MQTTHelpers::checkTopicContains(topicName, m_subscribedTopicNames[i])) {
- @@ -857,10 +833,8 @@ void ImportFileWidget::unsubscribeFromTopic(const QString& topicName) {
- }
- }
- - if (m_willSettings.willTopic == topicName) {
- - QVector<QTreeWidgetItem*> children;
- - if (ui.twSubscriptions->topLevelItemCount() > 0) {
- - MQTTHelpers::findSubscriptionLeafChildren(children, ui.twSubscriptions->topLevelItem(0));
- + if (m_willSettings.willTopic == topicName) {
- + if (m_subscriptionWidget->subscriptionCount() > 0) {
- m_willSettings.willTopic = children[0]->text(0);
- } else
- m_willSettings.willTopic = "";
- @@ -870,185 +844,6 @@ void ImportFileWidget::unsubscribeFromTopic(const QString& topicName) {
- emit subscriptionsChanged();
- refreshPreview();
- }
- -
- -/*!
- - *\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;
- -
- - do {
- - foundEqual = false;
- - QMap<QString, QVector<QString>> equalTopicsMap;
- - QVector<QString> equalTopics;
- -
- - //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) {
- - QString commonTopic = MQTTHelpers::checkCommonLevel(ui.twSubscriptions->topLevelItem(i)->text(0), ui.twSubscriptions->topLevelItem(j)->text(0));
- -
- - //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 (!equalTopicsMap[commonTopic].contains(ui.twSubscriptions->topLevelItem(j)->text(0)))
- - equalTopicsMap[commonTopic].push_back(ui.twSubscriptions->topLevelItem(j)->text(0));
- - }
- - }
- - }
- -
- - if (!equalTopicsMap.isEmpty()) {
- - DEBUG("Manage common topics");
- -
- - QVector<QString> commonTopics;
- - QMapIterator<QString, QVector<QString>> topics(equalTopicsMap);
- -
- - //check for every map entry, if the found topics can be merged or not
- - while (topics.hasNext()) {
- - topics.next();
- -
- - int level = MQTTHelpers::commonLevelIndex(topics.value().last(), topics.value().first());
- - QStringList commonList = topics.value().first().split('/', QString::SkipEmptyParts);
- - QTreeWidgetItem* currentItem = nullptr;
- - //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;
- - }
- - }
- -
- - if (!currentItem)
- - break;
- -
- - //calculate the number of topics the new + wildcard could replace
- - int childCount = MQTTHelpers::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) {
- - QDEBUG("Found common topic to manage: " << topics.key());
- - 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 = MQTTHelpers::commonLevelIndex(equalTopicsMap[commonTopics[i]].first(), commonTopics[i]);
- - if (level < lowestLevel) {
- - topicIdx = i;
- - lowestLevel = level;
- - }
- - }
- - QDEBUG("Manage: " << commonTopics[topicIdx]);
- - equalTopics.append(equalTopicsMap[commonTopics[topicIdx]]);
- -
- - //Add the common topic ("merging")
- - QString commonTopic;
- - commonTopic = MQTTHelpers::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
- - 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 (MQTTHelpers::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 Fills twSubscriptions with the subscriptions made by the client
- - */
- -void ImportFileWidget::updateSubscriptionTree() {
- - DEBUG("ImportFileWidget::updateSubscriptionTree()");
- - ui.twSubscriptions->clear();
- -
- - for (int i = 0; i < m_mqttSubscriptions.size(); ++i) {
- - QStringList name;
- - name.append(m_mqttSubscriptions[i]->topic().filter());
- -
- - bool found = false;
- - for (int j = 0; j < ui.twSubscriptions->topLevelItemCount(); ++j) {
- - if (ui.twSubscriptions->topLevelItem(j)->text(0) == m_mqttSubscriptions[i]->topic().filter()) {
- - found = true;
- - break;
- - }
- - }
- -
- - if (!found) {
- - //Add the subscription to the tree widget
- - QTreeWidgetItem* newItem = new QTreeWidgetItem(name);
- - ui.twSubscriptions->addTopLevelItem(newItem);
- - name.clear();
- - name = m_mqttSubscriptions[i]->topic().filter().split('/', QString::SkipEmptyParts);
- -
- - //find the corresponding "root" item in twTopics
- - QTreeWidgetItem* topic = nullptr;
- - for (int j = 0; j < ui.twTopics->topLevelItemCount(); ++j) {
- - if (ui.twTopics->topLevelItem(j)->text(0) == name[0]) {
- - topic = ui.twTopics->topLevelItem(j);
- - break;
- - }
- - }
- -
- - //restore the children of the subscription
- - if (topic != nullptr && topic->childCount() > 0) {
- - MQTTHelpers::restoreSubscriptionChildren(topic, newItem, name, 1);
- - }
- - }
- - }
- - m_searching = false;
- -}
- -
- -/*!
- - *\brief Updates the completer for leSubscriptions
- - */
- -void ImportFileWidget::updateSubscriptionCompleter() {
- - QStringList subscriptionList;
- - for (int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i)
- - subscriptionList.append(ui.twSubscriptions->topLevelItem(i)->text(0));
- -
- - if (!subscriptionList.isEmpty()) {
- - m_subscriptionCompleter = new QCompleter(subscriptionList, this);
- - m_subscriptionCompleter->setCompletionMode(QCompleter::PopupCompletion);
- - m_subscriptionCompleter->setCaseSensitivity(Qt::CaseSensitive);
- - ui.leSubscriptions->setCompleter(m_subscriptionCompleter);
- - } else
- - ui.leSubscriptions->setCompleter(nullptr);
- -}
- #endif
- /************** SLOTS **************************************************************/
- @@ -1963,9 +1758,7 @@ void ImportFileWidget::mqttConnectionChanged() {
- //disconnected from the broker that was selected before, if this is the case
- if (m_client && m_client->state() == QMqttClient::ClientState::Connected) {
- - ui.twTopics->clear();
- - ui.twSubscriptions->clear();
- - ui.twTopics->headerItem()->setText(0, i18n("Available"));
- + emit MQTTClearTopics();
- disconnect(m_client, &QMqttClient::disconnected, this, &ImportFileWidget::onMqttDisconnect);
- QDEBUG("Disconnecting from " << m_client->hostname());
- m_client->disconnectFromHost();
- @@ -2008,7 +1801,9 @@ void ImportFileWidget::mqttConnectionChanged() {
- void ImportFileWidget::onMqttConnect() {
- if (m_client->error() == QMqttClient::NoError) {
- m_connectTimeoutTimer->stop();
- - ui.gbManageSubscriptions->setVisible(true);
- + ui.swSubscriptions->setVisible(true);
- + m_subscriptionWidget->setVisible(true);
- + m_subscriptionWidget->makeVisible(true);
- if (!m_client->subscribe(QMqttTopicFilter(QLatin1String("#")), 1))
- QMessageBox::critical(this, i18n("Couldn't subscribe"), i18n("Couldn't subscribe to all available topics. Something went wrong"));
- @@ -2022,20 +1817,16 @@ void ImportFileWidget::onMqttConnect() {
- * removes every information about the former connection
- */
- void ImportFileWidget::onMqttDisconnect() {
- - DEBUG("Disconected from " << m_client->hostname().toStdString());
- - m_searchTimer->stop();
- + DEBUG("Disconected from " << m_client->hostname().toStdString());
- m_connectTimeoutTimer->stop();
- ui.lTopics->hide();
- - ui.gbManageSubscriptions->hide();
- + ui.swSubscriptions->hide();
- ui.lLWT->hide();
- ui.bLWT->hide();
- ui.cbConnection->setItemText(ui.cbConnection->currentIndex(), ui.cbConnection->currentText() + " " + i18n("(Disconnected)"));
- - m_mqttReadyForPreview = false;
- - m_searching = false;
- - delete m_topicCompleter;
- - delete m_subscriptionCompleter;
- + m_mqttReadyForPreview = false;
- emit subscriptionsChanged();
- RESET_CURSOR;
- @@ -2043,175 +1834,21 @@ void ImportFileWidget::onMqttDisconnect() {
- i18n("Disconnected from the broker '%1' before the connection was successful.", m_client->hostname()));
- }
- -/*!
- - *\brief When a leaf topic is double clicked in the topics tree widget we subscribe on that
- - */
- -void ImportFileWidget::mqttAvailableTopicDoubleClicked(QTreeWidgetItem* item, int column) {
- - Q_UNUSED(column)
- - // Only for leaf topics
- - if (item->childCount() == 0)
- - mqttSubscribe();
- -}
- -
- -/*!
- - *\brief When a leaf subscription is double clicked in the topics tree widget we unsubscribe
- - */
- -void ImportFileWidget::mqttSubscribedTopicDoubleClicked(QTreeWidgetItem* item, int column) {
- - Q_UNUSED(column)
- - // Only for leaf subscriptions
- - if (item->childCount() == 0)
- - mqttUnsubscribe();
- -}
- -
- /*!
- *\brief called when the subscribe button is pressed
- * subscribes to the topic represented by the current item of twTopics
- */
- -void ImportFileWidget::mqttSubscribe() {
- - QTreeWidgetItem* item = ui.twTopics->currentItem();
- - if (!item) {
- - QMessageBox::warning(this, i18n("Warning"), i18n("You didn't select any item from the Tree Widget"));
- - return;
- - }
- -
- - //determine the topic name that the current item represents
- - QTreeWidgetItem* tempItem = item;
- - QString name = item->text(0);
- - if (item->childCount() != 0)
- - name.append("/#");
- -
- - while (tempItem->parent()) {
- - tempItem = tempItem->parent();
- - name.prepend(tempItem->text(0) + '/');
- - }
- -
- - //check if the subscription already exists
- - const QList<QTreeWidgetItem*>& topLevelList = ui.twSubscriptions->findItems(name, Qt::MatchExactly);
- - if (topLevelList.isEmpty() || topLevelList.first()->parent() != nullptr) {
- - QDEBUG("Subscribe to: " << name);
- - bool foundSuperior = false;
- -
- - for (int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
- - //if the new subscirptions contains an already existing one, we remove the inferior one
- - if (MQTTHelpers::checkTopicContains(name, ui.twSubscriptions->topLevelItem(i)->text(0))
- - && name != ui.twSubscriptions->topLevelItem(i)->text(0)) {
- - unsubscribeFromTopic(ui.twSubscriptions->topLevelItem(i)->text(0));
- - --i;
- - continue;
- - }
- -
- - //if there is a subscription containing the new one we set foundSuperior true
- - if (MQTTHelpers::checkTopicContains(ui.twSubscriptions->topLevelItem(i)->text(0), name)
- - && name != ui.twSubscriptions->topLevelItem(i)->text(0)) {
- - foundSuperior = true;
- - QDEBUG("Can't continue subscribing. Found superior for " << name << " : " << ui.twSubscriptions->topLevelItem(i)->text(0));
- - break;
- - }
- - }
- -
- - //if there wasn't a superior subscription we can subscribe to the new topic
- - if (!foundSuperior) {
- - QStringList toplevelName;
- - toplevelName.push_back(name);
- - QTreeWidgetItem* newTopLevelItem = new QTreeWidgetItem(toplevelName);
- - ui.twSubscriptions->addTopLevelItem(newTopLevelItem);
- -
- - const QMqttTopicFilter filter {name};
- - QMqttSubscription *tempSubscription = m_client->subscribe(filter, static_cast<quint8>(ui.cbQos->currentText().toUInt()) );
- -
- - if (tempSubscription) {
- - m_mqttSubscriptions.push_back(tempSubscription);
- - connect(tempSubscription, &QMqttSubscription::messageReceived, this, &ImportFileWidget::mqttSubscriptionMessageReceived);
- - emit subscriptionsChanged();
- - }
- -
- - if (name.endsWith('#')) {
- - //adding every topic that the subscription contains to twSubscriptions
- - MQTTHelpers::addSubscriptionChildren(item, newTopLevelItem);
- -
- - //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
- - const QStringList nameList = name.split('/', QString::SkipEmptyParts);
- - const 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
- - MQTTHelpers::findSubscriptionLeafChildren(children, ui.twSubscriptions->topLevelItem(i));
- - for (int j = 0; j < children.size(); ++j) {
- - if (MQTTHelpers::checkTopicContains(name, children[j]->text(0))) {
- - //if the new subscription contains a topic, we unsubscribe from it
- - ui.twSubscriptions->setCurrentItem(children[j]);
- - mqttUnsubscribe();
- - --i;
- - }
- - }
- - }
- - }
- - }
- -
- - manageCommonLevelSubscriptions();
- - updateSubscriptionCompleter();
- -
- - if (!ui.bLWT->isEnabled())
- - ui.bLWT->setEnabled(true);
- - } else
- - QMessageBox::warning(this, i18n("Warning"), i18n("You already subscribed to a topic containing this one"));
- - } else
- - QMessageBox::warning(this, i18n("Warning"), i18n("You already subscribed to this topic"));
- +void ImportFileWidget::mqttSubscribe(const QString& name, uint QoS) {
- + const QMqttTopicFilter filter {name};
- + QMqttSubscription *tempSubscription = m_client->subscribe(filter, static_cast<quint8>(QoS) );
- +
- + if (tempSubscription) {
- + m_mqttSubscriptions.push_back(tempSubscription);
- + connect(tempSubscription, &QMqttSubscription::messageReceived, this, &ImportFileWidget::mqttSubscriptionMessageReceived);
- + emit subscriptionsChanged();
- + }
- }
- -/*!
- - *\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 (!unsubscribeItem) {
- - QMessageBox::warning(this, i18n("Warning"), i18n("You didn't select any item from the Tree Widget"));
- - return;
- - }
- -
- - QDEBUG("Unsubscribe from: " << unsubscribeItem->text(0));
- - //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));
- -
- - //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 twSubscriptions)
- - else {
- - while (unsubscribeItem->parent() != nullptr) {
- - for (int i = 0; i < unsubscribeItem->parent()->childCount(); ++i) {
- - if (unsubscribeItem->text(0) != unsubscribeItem->parent()->child(i)->text(0)) {
- - const QMqttTopicFilter filter {unsubscribeItem->parent()->child(i)->text(0)};
- - QMqttSubscription *tempSubscription = m_client->subscribe(filter, static_cast<quint8>(ui.cbQos->currentText().toUInt()) );
- -
- - ui.twSubscriptions->addTopLevelItem(unsubscribeItem->parent()->takeChild(i));
- -
- - if (tempSubscription) {
- - m_mqttSubscriptions.push_back(tempSubscription);
- - connect(tempSubscription, &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();
- - }
- - updateSubscriptionCompleter();
- -
- - if (ui.twSubscriptions->topLevelItemCount() <= 0)
- - ui.bLWT->setEnabled(false);
- -}
- /*!
- *\brief called when the client receives a message
- @@ -2224,7 +1861,7 @@ void ImportFileWidget::mqttMessageReceived(const QByteArray& message, const QMqt
- return;
- m_addedTopics.push_back(topic.name());
- - ui.twTopics->headerItem()->setText(0, i18n("Available (%1)", m_addedTopics.size()));
- + m_subscriptionWidget->setTopicTreeText(i18n("Available (%1)", m_addedTopics.size()));
- QStringList name;
- QString rootName;
- const QChar sep = '/';
- @@ -2237,8 +1874,8 @@ void ImportFileWidget::mqttMessageReceived(const QByteArray& message, const QMqt
- name.append(list.at(0));
- 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)) {
- + for (int i = 0; i < m_subscriptionWidget->topicCount(); ++i) {
- + if (m_subscriptionWidget->topLevelTopic(i)->text(0) == list.at(0)) {
- topItemIdx = i;
- break;
- }
- @@ -2247,7 +1884,7 @@ void ImportFileWidget::mqttMessageReceived(const QByteArray& message, const QMqt
- //if not we simply add every level of the topic to the tree
- if (topItemIdx < 0) {
- QTreeWidgetItem* currentItem = new QTreeWidgetItem(name);
- - ui.twTopics->addTopLevelItem(currentItem);
- + m_subscriptionWidget->addTopic(currentItem);
- for (int i = 1; i < list.size(); ++i) {
- name.clear();
- name.append(list.at(i));
- @@ -2258,7 +1895,7 @@ void ImportFileWidget::mqttMessageReceived(const QByteArray& message, const QMqt
- //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 {
- - QTreeWidgetItem* currentItem = ui.twTopics->topLevelItem(topItemIdx);
- + QTreeWidgetItem* currentItem = m_subscriptionWidget->topLevelTopic(topItemIdx);
- int listIdx = 1;
- for (; listIdx < list.size(); ++listIdx) {
- QTreeWidgetItem* childItem = nullptr;
- @@ -2289,15 +1926,18 @@ void ImportFileWidget::mqttMessageReceived(const QByteArray& message, const QMqt
- } else {
- rootName = topic.name();
- name.append(topic.name());
- - ui.twTopics->addTopLevelItem(new QTreeWidgetItem(name));
- + m_subscriptionWidget->addTopic(new QTreeWidgetItem(name));
- }
- //if a subscribed topic contains the new topic, we have to update twSubscriptions
- - for (int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
- - const QStringList subscriptionName = ui.twSubscriptions->topLevelItem(i)->text(0).split('/', QString::SkipEmptyParts);
- + for (int i = 0; i < m_subscriptionWidget->subscriptionCount(); ++i) {
- + const QStringList subscriptionName = m_subscriptionWidget->topLevelSubscription(i)->text(0).split('/', QString::SkipEmptyParts);
- if (!subscriptionName.isEmpty()) {
- if (rootName == subscriptionName.first()) {
- - updateSubscriptionTree();
- + QVector<QString> subscriptions;
- + for(int i = 0; i < m_mqttSubscriptions.size(); ++i)
- + subscriptions.push_back(m_mqttSubscriptions[i]->topic().filter());
- + emit updateSubscriptionTree(subscriptions);
- break;
- }
- }
- @@ -2307,32 +1947,6 @@ void ImportFileWidget::mqttMessageReceived(const QByteArray& message, const QMqt
- emit newTopic(rootName);
- }
- -/*!
- - *\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::setTopicCompleter(const QString& topic) {
- - if (!m_topicList.contains(topic)) {
- - m_topicList.append(topic);
- - if (!m_searching) {
- - m_topicCompleter = new QCompleter(m_topicList, this);
- - m_topicCompleter->setCompletionMode(QCompleter::PopupCompletion);
- - m_topicCompleter->setCaseSensitivity(Qt::CaseSensitive);
- - ui.leTopics->setCompleter(m_topicCompleter);
- - }
- - }
- -}
- -
- -/*!
- - *\brief called when 10 seconds passed since the last time the user searched for a certain root in twTopics
- - * enables updating the completer for le
- - */
- -void ImportFileWidget::topicTimeout() {
- - m_searching = false;
- - m_searchTimer->stop();
- -}
- -
- /*!
- *\brief called when the client receives a message from a subscribed topic (that isn't the "#" wildcard)
- */
- @@ -2399,48 +2013,6 @@ void ImportFileWidget::mqttErrorChanged(QMqttClient::ClientError clientError) {
- }
- }
- -/*!
- - *\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::scrollToTopicTreeItem(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 leSubscriptions' text is changed
- - * if the rootName can be found in twSubscriptions, then we scroll it to the top of the tree widget
- - *
- - * \param rootName the current text of leSubscriptions
- - */
- -void ImportFileWidget::scrollToSubsriptionTreeItem(const QString& rootName) {
- - m_searching = true;
- - m_searchTimer->start();
- -
- - int topItemIdx = -1;
- - for (int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i)
- - if (ui.twSubscriptions->topLevelItem(i)->text(0) == rootName) {
- - topItemIdx = i;
- - break;
- - }
- -
- - if (topItemIdx >= 0)
- - ui.twSubscriptions->scrollToItem(ui.twSubscriptions->topLevelItem(topItemIdx), QAbstractItemView::ScrollHint::PositionAtTop);
- -}
- -
- /*!
- *\brief called when m_connectTimeoutTimer ticks,
- * meaning that the client couldn't connect to the broker in 5 seconds
- @@ -2510,8 +2082,8 @@ void ImportFileWidget::showWillSettings() {
- QMenu menu;
- QVector<QTreeWidgetItem*> children;
- - for (int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i)
- - MQTTHelpers::findSubscriptionLeafChildren(children, ui.twSubscriptions->topLevelItem(i));
- + for (int i = 0; i < m_subscriptionWidget->subscriptionCount(); ++i)
- + MQTTHelpers::findSubscriptionLeafChildren(children, m_subscriptionWidget->topLevelSubscription(i));
- QVector<QString> topics;
- for (int i = 0; i < children.size(); ++i)
- @@ -2531,4 +2103,13 @@ void ImportFileWidget::showWillSettings() {
- menu.exec(ui.bLWT->mapToGlobal(pos));
- }
- +void ImportFileWidget::enableWill(bool enable) {
- + if(enable) {
- + if(!ui.bLWT->isEnabled())
- + ui.bLWT->setEnabled(enable);
- + } else {
- + ui.bLWT->setEnabled(enable);
- + }
- +}
- +
- #endif
- diff --git a/src/kdefrontend/datasources/ImportFileWidget.h b/src/kdefrontend/datasources/ImportFileWidget.h
- index 4f4b7043f..77f948236 100644
- --- a/src/kdefrontend/datasources/ImportFileWidget.h
- +++ b/src/kdefrontend/datasources/ImportFileWidget.h
- @@ -6,6 +6,7 @@
- Copyright : (C) 2009-2017 by Stefan Gerlach (stefan.gerlach@uni-konstanz.de)
- Copyright : (C) 2009-2019 Alexander Semke (alexander.semke@web.de)
- Copyright : (C) 2017-2018 Fabian Kristof (fkristofszabolcs@gmail.com)
- + Copyright : (C) 2018-2019 Kovacs Ferencz (kferike98@gmail.com)
- ***************************************************************************/
- @@ -36,6 +37,7 @@
- #ifdef HAVE_MQTT
- #include "backend/datasources/MQTTClient.h"
- +class MQTTSubscriptionWidget;
- #endif
- #include <QVector>
- @@ -138,18 +140,10 @@ signals:
- #ifdef HAVE_MQTT
- private:
- - void updateSubscriptionCompleter();
- - void unsubscribeFromTopic(const QString&);
- - void manageCommonLevelSubscriptions();
- - void updateSubscriptionTree();
- + void unsubscribeFromTopic(const QString&, QVector<QTreeWidgetItem*> children);
- QMqttClient* m_client{nullptr};
- - QVector<QMqttSubscription*> m_mqttSubscriptions;
- - QCompleter* m_topicCompleter{nullptr};
- - QCompleter* m_subscriptionCompleter{nullptr};
- - QStringList m_topicList;
- - bool m_searching{false};
- - QTimer* m_searchTimer;
- + QVector<QMqttSubscription*> m_mqttSubscriptions;
- QTimer* m_connectTimeoutTimer;
- QMap<QMqttTopicName, bool> m_messageArrived;
- QMap<QMqttTopicName, QMqttMessage> m_lastMessage;
- @@ -158,36 +152,34 @@ private:
- QVector<QString> m_addedTopics;
- QString m_configPath;
- bool m_initialisingMQTT{false};
- - bool m_connectionTimedOut{false};
- + bool m_connectionTimedOut{false};
- MQTTClient::MQTTWill m_willSettings;
- + MQTTSubscriptionWidget* m_subscriptionWidget;
- +
- public:
- void saveMQTTSettings(MQTTClient*) const;
- - bool isMqttValid();
- + bool isMqttValid();
- signals:
- - void newTopic(QString);
- + void newTopic(const QString&);
- void subscriptionsChanged();
- void checkFileType();
- + void updateSubscriptionTree(const QVector<QString>&);
- + void MQTTClearTopics();
- private slots:
- void mqttConnectionChanged();
- - void onMqttConnect();
- - void mqttAvailableTopicDoubleClicked(QTreeWidgetItem*, int);
- - void mqttSubscribedTopicDoubleClicked(QTreeWidgetItem*, int);
- - void mqttSubscribe();
- - void mqttUnsubscribe();
- - void mqttMessageReceived(const QByteArray&, const QMqttTopicName&);
- - void setTopicCompleter(const QString&);
- - void topicTimeout();
- + void onMqttConnect();
- + void mqttSubscribe(const QString&, uint);
- + void mqttMessageReceived(const QByteArray&, const QMqttTopicName&);
- void mqttSubscriptionMessageReceived(const QMqttMessage& );
- void onMqttDisconnect();
- - void mqttErrorChanged(QMqttClient::ClientError);
- - void scrollToTopicTreeItem(const QString&);
- - void scrollToSubsriptionTreeItem(const QString&);
- + void mqttErrorChanged(QMqttClient::ClientError);
- void mqttConnectTimeout();
- void showMQTTConnectionManager();
- void readMQTTConnections();
- void showWillSettings();
- + void enableWill(bool);
- #endif
- };
- diff --git a/src/kdefrontend/dockwidgets/LiveDataDock.cpp b/src/kdefrontend/dockwidgets/LiveDataDock.cpp
- index 482757467..4787cdc56 100644
- --- a/src/kdefrontend/dockwidgets/LiveDataDock.cpp
- +++ b/src/kdefrontend/dockwidgets/LiveDataDock.cpp
- @@ -4,7 +4,7 @@ Project : LabPlot
- Description : Dock widget for live data properties
- --------------------------------------------------------------------
- Copyright : (C) 2017 by Fabian Kristof (fkristofszabolcs@gmail.com)
- -Copyright : (C) 2018 by Kovacs Ferencz (kferike98@gmail.com)
- +Copyright : (C) 2018-2019 Kovacs Ferencz (kferike98@gmail.com)
- Copyright : (C) 2018 by Stefan Gerlach (stefan.gerlach@uni.kn)
- ***************************************************************************/
- @@ -37,6 +37,7 @@ Copyright : (C) 2018 by Stefan Gerlach (stefan.gerlach@uni.kn)
- #ifdef HAVE_MQTT
- #include "kdefrontend/widgets/MQTTWillSettingsWidget.h"
- #include "kdefrontend/datasources/MQTTHelpers.h"
- +#include "kdefrontend/datasources/MQTTSubscriptionWidget.h"
- #include <QMessageBox>
- #include <QWidgetAction>
- #include <QMenu>
- @@ -44,8 +45,8 @@ Copyright : (C) 2018 by Stefan Gerlach (stefan.gerlach@uni.kn)
- LiveDataDock::LiveDataDock(QWidget* parent) : QWidget(parent)
- #ifdef HAVE_MQTT
- - ,
- - m_searchTimer(new QTimer(this))
- + ,
- + m_subscriptionWidget(new MQTTSubscriptionWidget(this))
- #endif
- {
- ui.setupUi(this);
- @@ -63,55 +64,30 @@ LiveDataDock::LiveDataDock(QWidget* parent) : QWidget(parent)
- connect(ui.cbReadingType, static_cast<void (QComboBox::*) (int)>(&QComboBox::currentIndexChanged), this, &LiveDataDock::readingTypeChanged);
- #ifdef HAVE_MQTT
- - m_searchTimer->setInterval(10000);
- -
- - const int size = ui.leTopics->height();
- - ui.lTopicSearch->setPixmap( QIcon::fromTheme(QLatin1String("go-next")).pixmap(size, size) );
- - ui.lSubscriptionSearch->setPixmap( QIcon::fromTheme(QLatin1String("go-next")).pixmap(size, size) );
- -
- - connect(this, &LiveDataDock::newTopic, this, &LiveDataDock::setTopicCompleter);
- - connect(m_searchTimer, &QTimer::timeout, this, &LiveDataDock::topicTimeout);
- - connect(ui.bSubscribe, &QPushButton::clicked, this, &LiveDataDock::addSubscription);
- - connect(ui.bUnsubscribe, &QPushButton::clicked, this, &LiveDataDock::removeSubscription);
- - connect(ui.bWillUpdateNow, &QPushButton::clicked, this, &LiveDataDock::willUpdateNow);
- - connect(ui.leTopics, &QLineEdit::textChanged, this, &LiveDataDock::scrollToTopicTreeItem);
- - connect(ui.leSubscriptions, &QLineEdit::textChanged, this, &LiveDataDock::scrollToSubsriptionTreeItem);
- - connect(ui.bLWT, &QPushButton::clicked, this, &LiveDataDock::showWillSettings);
- -
- - ui.bSubscribe->setIcon(ui.bSubscribe->style()->standardIcon(QStyle::SP_ArrowRight));
- - ui.bSubscribe->setToolTip(i18n("Subscribe selected topics"));
- - ui.bUnsubscribe->setIcon(ui.bUnsubscribe->style()->standardIcon(QStyle::SP_ArrowLeft));
- - ui.bUnsubscribe->setToolTip(i18n("Unsubscribe selected topics"));
- + connect(ui.bWillUpdateNow, &QPushButton::clicked, this, &LiveDataDock::willUpdateNow);
- + connect(ui.bLWT, &QPushButton::clicked, this, &LiveDataDock::showWillSettings);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::enableWill, this, &LiveDataDock::enableWill);
- +
- + ui.swSubscriptions->addWidget(m_subscriptionWidget);
- + ui.swSubscriptions->setCurrentWidget(m_subscriptionWidget);
- +
- ui.bLWT->setToolTip(i18n("Manage MQTT connection's will settings"));
- ui.bLWT->setIcon(ui.bLWT->style()->standardIcon(QStyle::SP_FileDialogDetailedView));
- - QString info = i18n("Enter the name of the topic to navigate to it.");
- - ui.lTopicSearch->setToolTip(info);
- - ui.leTopics->setToolTip(info);
- - ui.lSubscriptionSearch->setToolTip(info);
- - ui.leSubscriptions->setToolTip(info);
- -
- - info = i18n("Specify the 'Last Will and Testament' message (LWT). At least one topic has to be subscribed.");
- + QString info = i18n("Specify the 'Last Will and Testament' message (LWT). At least one topic has to be subscribed.");
- ui.lLWT->setToolTip(info);
- ui.bLWT->setToolTip(info);
- ui.bLWT->setEnabled(false);
- - ui.bLWT->setIcon(ui.bLWT->style()->standardIcon(QStyle::SP_FileDialogDetailedView));
- -
- - info = i18n("Set the Quality of Service (QoS) for the subscription to define the guarantee of the message delivery:"
- - "<ul>"
- - "<li>0 - deliver at most once</li>"
- - "<li>1 - deliver at least once</li>"
- - "<li>2 - deliver exactly once</li>"
- - "</ul>");
- - ui.cbQoS->setToolTip(info);
- + ui.bLWT->setIcon(ui.bLWT->style()->standardIcon(QStyle::SP_FileDialogDetailedView));
- #endif
- }
- #ifdef HAVE_MQTT
- LiveDataDock::~LiveDataDock() {
- - delete m_searchTimer;
- for (auto & host : m_hosts)
- delete host.client;
- +
- + delete m_subscriptionWidget;
- }
- #else
- LiveDataDock::~LiveDataDock() = default;
- @@ -169,15 +145,10 @@ void LiveDataDock::setMQTTClient(MQTTClient* const client) {
- m_mqttClient = client; // updates may be applied from now on
- //show MQTT connected options
- - ui.lTopics->show();
- - ui.gbManageSubscriptions->show();
- - ui.bSubscribe->show();
- - ui.bUnsubscribe->show();
- - ui.twTopics->show();
- - ui.leTopics->show();
- - ui.lTopicSearch->show();
- - ui.twSubscriptions->show();
- - ui.cbQoS->show();
- + ui.lTopics->show();
- + ui.swSubscriptions->setVisible(true);
- + m_subscriptionWidget->setVisible(true);
- + m_subscriptionWidget->makeVisible(true);
- ui.lLWT->show();
- ui.bLWT->show();
- @@ -194,6 +165,12 @@ void LiveDataDock::setMQTTClient(MQTTClient* const client) {
- connect(m_currentHost->client, &QMqttClient::connected, this, &LiveDataDock::onMQTTConnect);
- connect(m_currentHost->client, &QMqttClient::messageReceived, this, &LiveDataDock::mqttMessageReceived);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::reparentTopic, client, &MQTTClient::reparentTopic);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::addBeforeRemoveSubscription, client, &MQTTClient::addBeforeRemoveSubscription);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::removeMQTTSubscription, client, &MQTTClient::removeMQTTSubscription);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::makeSubscription, client, &MQTTClient::addMQTTSubscription);
- +
- +
- m_currentHost->client->setHostname(id.first);
- m_currentHost->client->setPort(id.second);
- @@ -211,38 +188,50 @@ void LiveDataDock::setMQTTClient(MQTTClient* const client) {
- ++m_currentHost->count;
- }
- - if (m_previousMQTTClient == nullptr) {
- - connect(client, &MQTTClient::MQTTSubscribed, this, &LiveDataDock::fillSubscriptions);
- + if (m_previousMQTTClient == nullptr) {
- + m_updateSubscriptionConn = connect(client, &MQTTClient::MQTTSubscribed, [this]() {emit updateSubscriptionTree(m_mqttClient->MQTTSubscriptions());});
- //Fill the subscription tree(useful if the MQTTClient was loaded)
- QVector<QString> topics = client->topicNames();
- for (const auto& topic : topics) {
- addTopicToTree(topic);
- }
- - fillSubscriptions();
- + emit updateSubscriptionTree(m_mqttClient->MQTTSubscriptions());
- }
- //if the previous MQTTClient's host name was different from the current one we have to disconnect some slots
- //and clear the tree widgets
- - else if (m_previousMQTTClient->clientHostName() != client->clientHostName()) {
- - disconnect(m_previousMQTTClient, &MQTTClient::MQTTSubscribed, this, &LiveDataDock::fillSubscriptions);
- + else if (m_previousMQTTClient->clientHostName() != client->clientHostName()) {
- + disconnect(m_updateSubscriptionConn);
- disconnect(m_previousHost->client, &QMqttClient::messageReceived, this, &LiveDataDock::mqttMessageReceived);
- connect(m_previousHost->client, &QMqttClient::messageReceived, this, &LiveDataDock::mqttMessageReceivedInBackground);
- disconnect(m_currentHost->client, &QMqttClient::messageReceived, this, &LiveDataDock::mqttMessageReceivedInBackground);
- - ui.twTopics->clear();
- + disconnect(m_subscriptionWidget, &MQTTSubscriptionWidget::reparentTopic, m_previousMQTTClient, &MQTTClient::reparentTopic);
- + disconnect(m_subscriptionWidget, &MQTTSubscriptionWidget::addBeforeRemoveSubscription, m_previousMQTTClient, &MQTTClient::addBeforeRemoveSubscription);
- + disconnect(m_subscriptionWidget, &MQTTSubscriptionWidget::removeMQTTSubscription, m_previousMQTTClient, &MQTTClient::removeMQTTSubscription);
- + disconnect(m_subscriptionWidget, &MQTTSubscriptionWidget::makeSubscription, m_previousMQTTClient, &MQTTClient::addMQTTSubscription);
- +
- + m_previousHost->topicList = m_subscriptionWidget->getTopicList();
- + m_subscriptionWidget->setTopicList(m_currentHost->topicList);
- +
- + emit MQTTClearTopics();
- //repopulating the tree widget with the already known topics of the client
- for (int i = 0; i < m_currentHost->addedTopics.size(); ++i) {
- addTopicToTree(m_currentHost->addedTopics.at(i));
- }
- - //fill subscriptions tree widget
- - ui.twSubscriptions->clear();
- - fillSubscriptions();
- + //fill subscriptions tree widget
- + emit updateSubscriptionTree(m_mqttClient->MQTTSubscriptions());
- - connect(client, &MQTTClient::MQTTSubscribed, this, &LiveDataDock::fillSubscriptions);
- + m_updateSubscriptionConn = connect(client, &MQTTClient::MQTTSubscribed, [this]() {emit updateSubscriptionTree(m_mqttClient->MQTTSubscriptions());});
- connect(m_currentHost->client, &QMqttClient::messageReceived, this, &LiveDataDock::mqttMessageReceived);
- +
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::reparentTopic, client, &MQTTClient::reparentTopic);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::addBeforeRemoveSubscription, client, &MQTTClient::addBeforeRemoveSubscription);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::removeMQTTSubscription, client, &MQTTClient::removeMQTTSubscription);
- + connect(m_subscriptionWidget, &MQTTSubscriptionWidget::makeSubscription, client, &MQTTClient::addMQTTSubscription);
- }
- if (client->willUpdateType() == MQTTClient::OnClick && client->MQTTWillUse())
- @@ -275,7 +264,7 @@ void LiveDataDock::setLiveDataSource(LiveDataSource* const source) {
- switch (sourceType) {
- case LiveDataSource::FileOrPipe:
- - ui.leSourceInfo->setText(source->fileName());
- + ui.leSourceInfo->setText(source->fileName());
- break;
- case LiveDataSource::NetworkTcpSocket:
- case LiveDataSource::NetworkUdpSocket:
- @@ -345,14 +334,9 @@ void LiveDataDock::setLiveDataSource(LiveDataSource* const source) {
- ui.bLWT->hide();
- ui.lLWT->hide();
- ui.bWillUpdateNow->hide();
- - ui.bSubscribe->hide();
- - ui.bUnsubscribe->hide();
- - ui.twTopics->hide();
- - ui.leTopics->hide();
- - ui.lTopicSearch->hide();
- - ui.twSubscriptions->hide();
- - ui.gbManageSubscriptions->hide();
- -
- + ui.swSubscriptions->setVisible(false);
- + m_subscriptionWidget->setVisible(false);
- + m_subscriptionWidget->makeVisible(false);
- m_liveDataSource = source; // updates may be applied from now on
- }
- @@ -705,425 +689,6 @@ void LiveDataDock::mqttMessageReceived(const QByteArray& message, const QMqttTop
- }
- }
- -/*!
- - *\brief called when the subscribe button is pressed
- - * subscribes to the topic represented by the current item of twTopics in every client from m_mqttClients
- - */
- -void LiveDataDock::addSubscription() {
- - QString name;
- - QTreeWidgetItem* item = ui.twTopics->currentItem();
- - if (item != nullptr) {
- - QTreeWidgetItem* tempItem = item;
- -
- - //determine 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) + '/');
- - }
- -
- - //check if the subscription already exists
- - const QList<QTreeWidgetItem *> topLevelList = ui.twSubscriptions->findItems(name, Qt::MatchExactly);
- - if (topLevelList.isEmpty() || topLevelList.first()->parent() != nullptr) {
- - qDebug() << "LiveDataDock: start to add new subscription: " << name;
- - bool foundSuperior = false;
- -
- - for (int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
- - //if the new subscriptions contains an already existing one, we remove the inferior one
- - if (MQTTHelpers::checkTopicContains(name, ui.twSubscriptions->topLevelItem(i)->text(0))
- - && name != ui.twSubscriptions->topLevelItem(i)->text(0)) {
- - ui.twSubscriptions->topLevelItem(i)->takeChildren();
- - ui.twSubscriptions->takeTopLevelItem(i);
- - --i;
- - continue;
- - }
- -
- - //if there is a subscription containing the new one we set foundSuperior true
- - if (MQTTHelpers::checkTopicContains(ui.twSubscriptions->topLevelItem(i)->text(0), name)
- - && name != ui.twSubscriptions->topLevelItem(i)->text(0)) {
- - foundSuperior = true;
- - qDebug()<<"Can't add "<<name<<" because found superior: "<< ui.twSubscriptions->topLevelItem(i)->text(0);
- - break;
- - }
- - }
- -
- - //if there wasn't a superior subscription we can subscribe to the new topic
- - if (!foundSuperior) {
- - QStringList toplevelName;
- - toplevelName.push_back(name);
- - QTreeWidgetItem* newTopLevelItem = new QTreeWidgetItem(toplevelName);
- - ui.twSubscriptions->addTopLevelItem(newTopLevelItem);
- -
- - if (name.endsWith('#')) {
- - //adding every topic that the subscription contains to twSubscriptions
- - MQTTHelpers::addSubscriptionChildren(item, newTopLevelItem);
- - }
- -
- - m_mqttClient->addMQTTSubscription(name, ui.cbQoS->currentIndex());
- -
- - if (name.endsWith('#')) {
- - //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
- - const QStringList& nameList = name.split('/', QString::SkipEmptyParts);
- - const 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
- - MQTTHelpers::findSubscriptionLeafChildren(children, ui.twSubscriptions->topLevelItem(i));
- - for (int j = 0; j < children.size(); ++j) {
- - if (MQTTHelpers::checkTopicContains(name, children[j]->text(0))) {
- - //if the new subscription contains a topic, we unsubscribe from it
- - QTreeWidgetItem* unsubscribeItem = children[j];
- - while (unsubscribeItem->parent() != nullptr) {
- - for (int i = 0; i < unsubscribeItem->parent()->childCount(); ++i) {
- -
- - if (unsubscribeItem->text(0) != unsubscribeItem->parent()->child(i)->text(0)) {
- - //add topic as subscription
- - m_mqttClient->addBeforeRemoveSubscription(unsubscribeItem->parent()->child(i)->text(0), ui.cbQoS->currentIndex());
- - //also add it to twSubscriptions
- - ui.twSubscriptions->addTopLevelItem(unsubscribeItem->parent()->takeChild(i));
- - --i;
- - } else {
- - //before we remove the topic, we reparent it to the new subscription
- - //so no data is lost
- - m_mqttClient->reparentTopic(unsubscribeItem->text(0), name);
- - }
- - }
- - unsubscribeItem = unsubscribeItem->parent();
- - }
- -
- - qDebug()<<"Remove: "<<unsubscribeItem->text(0);
- - m_mqttClient->removeMQTTSubscription(unsubscribeItem->text(0));
- -
- - ui.twSubscriptions->takeTopLevelItem(ui.twSubscriptions->indexOfTopLevelItem(unsubscribeItem));
- - }
- - }
- - }
- - }
- - }
- -
- - manageCommonLevelSubscriptions();
- - updateSubscriptionCompleter();
- -
- - if (!ui.bLWT->isEnabled())
- - ui.bLWT->setEnabled(true);
- - } else {
- - 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");
- -}
- -
- -/*!
- - *\brief called when the unsubscribe button is pressed
- - * unsubscribes from the topic represented by the current item of twSubscription in m_mqttClient
- - */
- -void LiveDataDock::removeSubscription() {
- - QTreeWidgetItem* unsubscribeItem = ui.twSubscriptions->currentItem();
- -
- - if (unsubscribeItem != nullptr) {
- - qDebug() << "LiveDataDock: unsubscribe from " << unsubscribeItem->text(0);
- -
- - //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) {
- - m_mqttClient->removeMQTTSubscription(unsubscribeItem->text(0));
- - ui.twSubscriptions->takeTopLevelItem(ui.twSubscriptions->indexOfTopLevelItem(unsubscribeItem));
- - }
- - //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 twSubscriptions)
- - else {
- - while (unsubscribeItem->parent() != nullptr) {
- - for (int i = 0; i < unsubscribeItem->parent()->childCount(); ++i) {
- - if (unsubscribeItem->text(0) != unsubscribeItem->parent()->child(i)->text(0)) {
- - //add topic as subscription
- - m_mqttClient->addBeforeRemoveSubscription(unsubscribeItem->parent()->child(i)->text(0), ui.cbQoS->currentIndex());
- - ui.twSubscriptions->addTopLevelItem(unsubscribeItem->parent()->takeChild(i));
- - --i;
- - }
- - }
- - unsubscribeItem = unsubscribeItem->parent();
- - }
- -
- - //remove topic/subscription
- - m_mqttClient->removeMQTTSubscription(unsubscribeItem->text(0));
- - ui.twSubscriptions->takeTopLevelItem(ui.twSubscriptions->indexOfTopLevelItem(unsubscribeItem));
- -
- - //check if any common topics were subscribed, if possible merge them
- - manageCommonLevelSubscriptions();
- - }
- -
- - if (ui.twSubscriptions->topLevelItemCount() <= 0)
- - ui.bLWT->setEnabled(false);
- -
- - updateSubscriptionCompleter();
- - } else
- - QMessageBox::warning(this, "Warning", "You didn't select any item from the Tree Widget");
- -}
- -
- -/*!
- - *\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 LiveDataDock::setTopicCompleter(const QString& topicName) {
- - if (!m_searching) {
- - const QStringList& list = topicName.split('/', QString::SkipEmptyParts);
- - QString topic;
- - if (!list.isEmpty()) {
- - topic = list.at(0);
- - } else
- - topic = topicName;
- -
- - if (!m_currentHost->topicList.contains(topic)) {
- - m_currentHost->topicList.append(topic);
- - m_topicCompleter = new QCompleter(m_currentHost->topicList, this);
- - m_topicCompleter->setCompletionMode(QCompleter::PopupCompletion);
- - m_topicCompleter->setCaseSensitivity(Qt::CaseSensitive);
- - ui.leTopics->setCompleter(m_topicCompleter);
- - }
- - }
- -}
- -
- -/*!
- - *\brief Updates the completer for leSubscriptions
- - */
- -void LiveDataDock::updateSubscriptionCompleter() {
- - QStringList subscriptionList;
- - const QVector<QString>& subscriptions = m_mqttClient->MQTTSubscriptions();
- -
- - if (!subscriptions.isEmpty()) {
- - for (const auto& subscription : subscriptions)
- - subscriptionList << subscription;
- -
- - m_subscriptionCompleter = new QCompleter(subscriptionList, this);
- - m_subscriptionCompleter->setCompletionMode(QCompleter::PopupCompletion);
- - m_subscriptionCompleter->setCaseSensitivity(Qt::CaseSensitive);
- - ui.leSubscriptions->setCompleter(m_subscriptionCompleter);
- - } else {
- - ui.leSubscriptions->setCompleter(nullptr);
- - }
- -}
- -
- -/*!
- - *\brief called when 10 seconds passed since the last time the user searched for a certain root in twTopics
- - * enables updating the completer for le
- - */
- -void LiveDataDock::topicTimeout() {
- - m_searching = false;
- - m_searchTimer->stop();
- -}
- -
- -/*!
- - *\brief called when a new the host name of m_mqttClient changes
- - * or when the MQTTClients initialize their subscriptions
- - * Fills twSubscriptions with the subscriptions of the MQTTClient
- - */
- -void LiveDataDock::fillSubscriptions() {
- - ui.twSubscriptions->clear();
- -
- - QVector<QString> subscriptions = m_mqttClient->MQTTSubscriptions();
- - for (int i = 0; i < subscriptions.count(); ++i) {
- - QStringList name;
- - name.append(subscriptions[i]);
- -
- - bool found = false;
- - for (int j = 0; j < ui.twSubscriptions->topLevelItemCount(); ++j) {
- - if (ui.twSubscriptions->topLevelItem(j)->text(0) == subscriptions[i]) {
- - found = true;
- - break;
- - }
- - }
- -
- - if (!found) {
- - //Add the subscription to the tree widget
- - QTreeWidgetItem* newItem = new QTreeWidgetItem(name);
- - ui.twSubscriptions->addTopLevelItem(newItem);
- - name.clear();
- - name = subscriptions[i].split('/', QString::SkipEmptyParts);
- -
- - //find the corresponding "root" item in twTopics
- - QTreeWidgetItem* topic = nullptr;
- - for (int j = 0; j < ui.twTopics->topLevelItemCount(); ++j) {
- - if (ui.twTopics->topLevelItem(j)->text(0) == name[0]) {
- - topic = ui.twTopics->topLevelItem(j);
- - break;
- - }
- - }
- -
- - //restore the children of the subscription
- - if (topic != nullptr && topic->childCount() > 0)
- - MQTTHelpers::restoreSubscriptionChildren(topic, newItem, name, 1);
- - }
- - }
- - m_searching = false;
- -}
- -
- -/*!
- - *\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 LiveDataDock::scrollToTopicTreeItem(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 leSubscriptions' text is changed
- - * if the rootName can be found in twSubscriptions, then we scroll it to the top of the tree widget
- - *
- - * \param rootName the current text of leSubscriptions
- - */
- -void LiveDataDock::scrollToSubsriptionTreeItem(const QString& rootName) {
- - int topItemIdx = -1;
- - for (int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i)
- - if (ui.twSubscriptions->topLevelItem(i)->text(0) == rootName) {
- - topItemIdx = i;
- - break;
- - }
- -
- - if (topItemIdx >= 0)
- - ui.twSubscriptions->scrollToItem(ui.twSubscriptions->topLevelItem(topItemIdx), QAbstractItemView::ScrollHint::PositionAtTop);
- -}
- -
- -/*!
- - *\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 LiveDataDock::manageCommonLevelSubscriptions() {
- - bool foundEqual = false;
- - do {
- - foundEqual = false;
- - QMap<QString, QVector<QString>> equalTopicsMap;
- - QVector<QString> equalTopics;
- -
- - //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) {
- - QString commonTopic = MQTTHelpers::checkCommonLevel(ui.twSubscriptions->topLevelItem(i)->text(0), ui.twSubscriptions->topLevelItem(j)->text(0));
- -
- - //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 (!equalTopicsMap[commonTopic].contains(ui.twSubscriptions->topLevelItem(j)->text(0))) {
- - equalTopicsMap[commonTopic].push_back(ui.twSubscriptions->topLevelItem(j)->text(0));
- - }
- - }
- - }
- - }
- -
- - if (!equalTopicsMap.isEmpty()) {
- - qDebug()<<"Manage equal topics";
- -
- - QVector<QString> commonTopics;
- - QMapIterator<QString, QVector<QString>> topics(equalTopicsMap);
- -
- - //check for every map entry, if the found topics can be merged or not
- - while (topics.hasNext()) {
- - topics.next();
- -
- - int level = MQTTHelpers::commonLevelIndex(topics.value().last(), topics.value().first());
- - QStringList commonList = topics.value().first().split('/', QString::SkipEmptyParts);
- - QTreeWidgetItem* currentItem = nullptr;
- -
- - //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;
- - }
- - }
- -
- - if (!currentItem)
- - break;
- -
- - //calculate the number of topics the new + wildcard could replace
- - int childCount = MQTTHelpers::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) {
- - qDebug() << "Found common topic to manage: " << topics.key();
- - 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 highestLevel = INT_MAX;
- - int topicIdx = -1;
- - for (int i = 0; i < commonTopics.size(); ++i) {
- - int level = MQTTHelpers::commonLevelIndex(equalTopicsMap[commonTopics[i]].first(), commonTopics[i]);
- - if (level < highestLevel) {
- - topicIdx = i;
- - highestLevel = level;
- - }
- - }
- - qDebug() << "Start to manage: " << commonTopics[topicIdx];
- - equalTopics.append(equalTopicsMap[commonTopics[topicIdx]]);
- -
- - //Add the common topic ("merging")
- - QString commonTopic;
- - commonTopic = MQTTHelpers::checkCommonLevel(equalTopics.first(), equalTopics.last());
- - QStringList nameList;
- - nameList.append(commonTopic);
- - QTreeWidgetItem* newTopic = new QTreeWidgetItem(nameList);
- - ui.twSubscriptions->addTopLevelItem(newTopic);
- -
- - //remove the "merged" 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));
- - break;
- - }
- - }
- - }
- -
- - //remove any subscription that the new subscription contains
- - for (int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
- - if (MQTTHelpers::checkTopicContains(commonTopic, ui.twSubscriptions->topLevelItem(i)->text(0)) &&
- - commonTopic != ui.twSubscriptions->topLevelItem(i)->text(0) ) {
- - ui.twSubscriptions->topLevelItem(i)->takeChildren();
- - ui.twSubscriptions->takeTopLevelItem(i);
- - i--;
- - }
- - }
- -
- - //make the subscription on commonTopic in m_mqttClient
- - m_mqttClient->addMQTTSubscription(commonTopic, ui.cbQoS->currentIndex());
- - }
- - }
- - } while (foundEqual);
- -}
- -
- /*!
- *\brief Adds topicName to twTopics
- *
- @@ -1142,8 +707,8 @@ void LiveDataDock::addTopicToTree(const QString &topicName) {
- QTreeWidgetItem* currentItem;
- //check whether the first level of the topic can be found in twTopics
- int topItemIdx = -1;
- - for (int i = 0; i < ui.twTopics->topLevelItemCount(); ++i) {
- - if (ui.twTopics->topLevelItem(i)->text(0) == list.at(0)) {
- + for (int i = 0; i < m_subscriptionWidget->topicCount(); ++i) {
- + if (m_subscriptionWidget->topLevelTopic(i)->text(0) == list.at(0)) {
- topItemIdx = i;
- break;
- }
- @@ -1151,7 +716,7 @@ void LiveDataDock::addTopicToTree(const QString &topicName) {
- //if not we simply add every level of the topic to the tree
- if ( topItemIdx < 0) {
- currentItem = new QTreeWidgetItem(name);
- - ui.twTopics->addTopLevelItem(currentItem);
- + m_subscriptionWidget->addTopic(currentItem);
- for (int i = 1; i < list.size(); ++i) {
- name.clear();
- name.append(list.at(i));
- @@ -1162,7 +727,7 @@ void LiveDataDock::addTopicToTree(const QString &topicName) {
- //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);
- + currentItem = m_subscriptionWidget->topLevelTopic(topItemIdx);
- int listIdx = 1;
- for (; listIdx < list.size(); ++listIdx) {
- QTreeWidgetItem* childItem = nullptr;
- @@ -1194,14 +759,14 @@ void LiveDataDock::addTopicToTree(const QString &topicName) {
- else {
- rootName = topicName;
- name.append(topicName);
- - ui.twTopics->addTopLevelItem(new QTreeWidgetItem(name));
- + m_subscriptionWidget->addTopic(new QTreeWidgetItem(name));
- }
- //if a subscribed topic contains the new topic, we have to update twSubscriptions
- - for (int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
- - QStringList subscriptionName = ui.twSubscriptions->topLevelItem(i)->text(0).split('/', QString::SkipEmptyParts);
- + for (int i = 0; i < m_subscriptionWidget->subscriptionCount(); ++i) {
- + QStringList subscriptionName = m_subscriptionWidget->topLevelSubscription(i)->text(0).split('/', QString::SkipEmptyParts);
- if (rootName == subscriptionName[0]) {
- - fillSubscriptions();
- + emit updateSubscriptionTree(m_mqttClient->MQTTSubscriptions());
- break;
- }
- }
- @@ -1248,8 +813,7 @@ void LiveDataDock::removeClient(const QString& hostname, quint16 port) {
- }
- if (m_mqttClient->clientHostName() == hostname) {
- - ui.twSubscriptions->clear();
- - ui.twTopics->clear();
- + emit MQTTClearTopics();
- m_mqttClient = nullptr;
- }
- @@ -1264,9 +828,9 @@ void LiveDataDock::removeClient(const QString& hostname, quint16 port) {
- bool LiveDataDock::testSubscribe(const QString& topic) {
- QStringList topicList = topic.split('/', QString::SkipEmptyParts);
- QTreeWidgetItem* currentItem = nullptr;
- - for (int i = 0; i < ui.twTopics->topLevelItemCount(); ++i) {
- - if (ui.twTopics->topLevelItem(i)->text(0) == topicList[0]) {
- - currentItem = ui.twTopics->topLevelItem(i);
- + for (int i = 0; i < m_subscriptionWidget->topicCount(); ++i) {
- + if (m_subscriptionWidget->topLevelTopic(i)->text(0) == topicList[0]) {
- + currentItem = m_subscriptionWidget->topLevelTopic(i);
- break;
- }
- }
- @@ -1288,8 +852,7 @@ bool LiveDataDock::testSubscribe(const QString& topic) {
- } else
- return false;
- - ui.twTopics->setCurrentItem(currentItem);
- - addSubscription();
- + m_subscriptionWidget->testSubscribe(currentItem);
- return true;
- }
- @@ -1299,9 +862,9 @@ bool LiveDataDock::testSubscribe(const QString& topic) {
- */
- bool LiveDataDock::testUnsubscribe(const QString& topic) {
- QTreeWidgetItem* currentItem = nullptr;
- - for (int i = 0; i < ui.twSubscriptions->topLevelItemCount(); ++i) {
- - if (MQTTHelpers::checkTopicContains(ui.twSubscriptions->topLevelItem(i)->text(0), topic)) {
- - currentItem = ui.twSubscriptions->topLevelItem(i);
- + for (int i = 0; i < m_subscriptionWidget->subscriptionCount(); ++i) {
- + if (MQTTHelpers::checkTopicContains(m_subscriptionWidget->topLevelSubscription(i)->text(0), topic)) {
- + currentItem = m_subscriptionWidget->topLevelSubscription(i);
- break;
- }
- }
- @@ -1309,8 +872,7 @@ bool LiveDataDock::testUnsubscribe(const QString& topic) {
- if (currentItem) {
- do {
- if (topic == currentItem->text(0)) {
- - ui.twSubscriptions->setCurrentItem(currentItem);
- - removeSubscription();
- + m_subscriptionWidget->testUnsubscribe(currentItem);
- return true;
- } else {
- for (int i = 0; i < currentItem->childCount(); ++i) {
- @@ -1354,4 +916,13 @@ void LiveDataDock::showWillSettings() {
- QPoint pos(ui.bLWT->sizeHint().width(), ui.bLWT->sizeHint().height());
- menu.exec(ui.bLWT->mapToGlobal(pos));
- }
- +
- +void LiveDataDock::enableWill(bool enable) {
- + if(enable) {
- + if(!ui.bLWT->isEnabled())
- + ui.bLWT->setEnabled(enable);
- + } else {
- + ui.bLWT->setEnabled(enable);
- + }
- +}
- #endif
- diff --git a/src/kdefrontend/dockwidgets/LiveDataDock.h b/src/kdefrontend/dockwidgets/LiveDataDock.h
- index c26843f69..7d580e9d2 100644
- --- a/src/kdefrontend/dockwidgets/LiveDataDock.h
- +++ b/src/kdefrontend/dockwidgets/LiveDataDock.h
- @@ -4,6 +4,7 @@ Project : LabPlot
- Description : Dock widget for live data properties
- --------------------------------------------------------------------
- Copyright : (C) 2017 by Fabian Kristof (fkristofszabolcs@gmail.com)
- +Copyright : (C) 2018-2019 Kovacs Ferencz (kferike98@gmail.com)
- ***************************************************************************/
- /***************************************************************************
- @@ -33,6 +34,8 @@ Copyright : (C) 2017 by Fabian Kristof (fkristofszabolcs@gmail.com)
- #include <QMap>
- #include "backend/datasources/filters/AsciiFilter.h"
- #include "backend/datasources/MQTTClient.h"
- +
- +class MQTTSubscriptionWidget;
- #endif
- #include <QWidget>
- @@ -90,27 +93,21 @@ private slots:
- void willUpdateTypeChanged(int);
- void willUpdateNow();
- void willUpdateIntervalChanged(int);
- - void statisticsChanged(MQTTClient::WillStatisticsType);
- - void addSubscription();
- - void removeSubscription();
- + void statisticsChanged(MQTTClient::WillStatisticsType);
- void onMQTTConnect();
- void mqttMessageReceived(const QByteArray&, const QMqttTopicName&);
- - void mqttMessageReceivedInBackground(const QByteArray&, const QMqttTopicName&);
- - void setTopicCompleter(const QString&);
- - void topicTimeout();
- - void fillSubscriptions();
- - void scrollToTopicTreeItem(const QString&);
- - void scrollToSubsriptionTreeItem(const QString&);
- + void mqttMessageReceivedInBackground(const QByteArray&, const QMqttTopicName&);
- void removeClient(const QString&, quint16);
- void showWillSettings();
- + void enableWill(bool enable);
- signals:
- void newTopic(const QString&);
- + void MQTTClearTopics();
- + void updateSubscriptionTree(const QVector<QString>&);
- private:
- - void updateSubscriptionCompleter();
- - void addTopicToTree(const QString&);
- - void manageCommonLevelSubscriptions();
- + void addTopicToTree(const QString&);
- struct MQTTHost {
- int count;
- @@ -123,13 +120,10 @@ private:
- const MQTTClient* m_previousMQTTClient{nullptr};
- QMap<QPair<QString, int>, MQTTHost> m_hosts;
- MQTTHost* m_currentHost{nullptr};
- - MQTTHost* m_previousHost{nullptr};
- - QCompleter* m_topicCompleter{nullptr};
- - QCompleter* m_subscriptionCompleter{nullptr};
- - bool m_searching{true};
- - QTimer* m_searchTimer;
- - bool m_interpretMessage{true};
- - QString m_mqttUnsubscribeName;
- + MQTTHost* m_previousHost{nullptr};
- + bool m_interpretMessage{true};
- + MQTTSubscriptionWidget* m_subscriptionWidget;
- + QMetaObject::Connection m_updateSubscriptionConn;
- #endif
- };
- diff --git a/src/kdefrontend/ui/datasources/importfilewidget.ui b/src/kdefrontend/ui/datasources/importfilewidget.ui
- index b41dbfdb9..0676de028 100644
- --- a/src/kdefrontend/ui/datasources/importfilewidget.ui
- +++ b/src/kdefrontend/ui/datasources/importfilewidget.ui
- @@ -29,227 +29,88 @@
- <string>Data Source</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- - <item row="9" column="3">
- - <widget class="QPushButton" name="bLWT">
- + <item row="5" column="2" colspan="3">
- + <widget class="QComboBox" name="cbSerialPort"/>
- + </item>
- + <item row="3" column="0">
- + <widget class="QLabel" name="lConnections">
- <property name="text">
- - <string/>
- + <string>Connection:</string>
- </property>
- </widget>
- </item>
- - <item row="10" column="4">
- - <spacer name="spacerWillMessage">
- + <item row="6" column="2" colspan="3">
- + <widget class="QComboBox" name="cbBaudRate"/>
- + </item>
- + <item row="13" column="0">
- + <widget class="QLabel" name="lField">
- + <property name="text">
- + <string>Field:</string>
- + </property>
- + <property name="alignment">
- + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- + </property>
- + </widget>
- + </item>
- + <item row="5" column="0">
- + <widget class="QLabel" name="lSerialPort">
- + <property name="text">
- + <string>Port:</string>
- + </property>
- + </widget>
- + </item>
- + <item row="0" column="1">
- + <spacer name="hsName">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- + <property name="sizeType">
- + <enum>QSizePolicy::Fixed</enum>
- + </property>
- <property name="sizeHint" stdset="0">
- <size>
- - <width>40</width>
- - <height>0</height>
- + <width>10</width>
- + <height>23</height>
- </size>
- </property>
- </spacer>
- </item>
- - <item row="8" column="2" colspan="3">
- - <widget class="QGroupBox" name="gbManageSubscriptions">
- - <property name="sizePolicy">
- - <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- - <horstretch>0</horstretch>
- - <verstretch>0</verstretch>
- - </sizepolicy>
- + <item row="13" column="2" colspan="3">
- + <widget class="QTreeView" name="tvJson">
- + <property name="editTriggers">
- + <set>QAbstractItemView::NoEditTriggers</set>
- </property>
- - <property name="title">
- - <string/>
- + <property name="showDropIndicator" stdset="0">
- + <bool>false</bool>
- </property>
- - <property name="flat">
- - <bool>true</bool>
- + <property name="iconSize">
- + <size>
- + <width>16</width>
- + <height>16</height>
- + </size>
- </property>
- - <layout class="QGridLayout" name="gridLayout_6" columnstretch="1,1,0,1,1">
- - <property name="leftMargin">
- - <number>0</number>
- - </property>
- - <property name="topMargin">
- - <number>0</number>
- - </property>
- - <property name="rightMargin">
- - <number>0</number>
- - </property>
- - <property name="bottomMargin">
- - <number>0</number>
- - </property>
- - <property name="spacing">
- - <number>0</number>
- - </property>
- - <item row="0" column="0" colspan="2">
- - <widget class="QTreeWidget" name="twTopics">
- - <property name="sizePolicy">
- - <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
- - <horstretch>0</horstretch>
- - <verstretch>0</verstretch>
- - </sizepolicy>
- - </property>
- - <column>
- - <property name="text">
- - <string>Available</string>
- - </property>
- - </column>
- - </widget>
- - </item>
- - <item row="1" column="3">
- - <widget class="QLabel" name="lSubscriptionSearch">
- - <property name="sizePolicy">
- - <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- - <horstretch>0</horstretch>
- - <verstretch>0</verstretch>
- - </sizepolicy>
- - </property>
- - <property name="text">
- - <string/>
- - </property>
- - </widget>
- - </item>
- - <item row="0" column="2">
- - <layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,1,1,0,0">
- - <property name="spacing">
- - <number>12</number>
- - </property>
- - <property name="leftMargin">
- - <number>6</number>
- - </property>
- - <property name="topMargin">
- - <number>6</number>
- - </property>
- - <property name="rightMargin">
- - <number>6</number>
- - </property>
- - <item>
- - <spacer name="verticalSpacer_5">
- - <property name="orientation">
- - <enum>Qt::Vertical</enum>
- - </property>
- - <property name="sizeHint" stdset="0">
- - <size>
- - <width>20</width>
- - <height>40</height>
- - </size>
- - </property>
- - </spacer>
- - </item>
- - <item>
- - <widget class="QPushButton" name="bSubscribe">
- - <property name="text">
- - <string/>
- - </property>
- - </widget>
- - </item>
- - <item>
- - <widget class="QPushButton" name="bUnsubscribe">
- - <property name="text">
- - <string/>
- - </property>
- - </widget>
- - </item>
- - <item>
- - <spacer name="verticalSpacer_3">
- - <property name="orientation">
- - <enum>Qt::Vertical</enum>
- - </property>
- - <property name="sizeHint" stdset="0">
- - <size>
- - <width>20</width>
- - <height>40</height>
- - </size>
- - </property>
- - </spacer>
- - </item>
- - <item>
- - <widget class="QComboBox" name="cbQos">
- - <item>
- - <property name="text">
- - <string>QoS 0</string>
- - </property>
- - </item>
- - <item>
- - <property name="text">
- - <string>QoS 1</string>
- - </property>
- - </item>
- - <item>
- - <property name="text">
- - <string>QoS 2</string>
- - </property>
- - </item>
- - </widget>
- - </item>
- - </layout>
- - </item>
- - <item row="1" column="4">
- - <widget class="QLineEdit" name="leSubscriptions">
- - <property name="clearButtonEnabled">
- - <bool>true</bool>
- - </property>
- - </widget>
- - </item>
- - <item row="0" column="3" colspan="2">
- - <widget class="QTreeWidget" name="twSubscriptions">
- - <property name="sizePolicy">
- - <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
- - <horstretch>0</horstretch>
- - <verstretch>0</verstretch>
- - </sizepolicy>
- - </property>
- - <column>
- - <property name="text">
- - <string>Subscribed</string>
- - </property>
- - </column>
- - </widget>
- - </item>
- - <item row="1" column="0">
- - <widget class="QLabel" name="lTopicSearch">
- - <property name="sizePolicy">
- - <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- - <horstretch>0</horstretch>
- - <verstretch>0</verstretch>
- - </sizepolicy>
- - </property>
- - <property name="text">
- - <string/>
- - </property>
- - <property name="alignment">
- - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- - </property>
- - </widget>
- - </item>
- - <item row="1" column="1">
- - <widget class="QLineEdit" name="leTopics">
- - <property name="clearButtonEnabled">
- - <bool>true</bool>
- - </property>
- - </widget>
- - </item>
- - </layout>
- </widget>
- </item>
- - <item row="3" column="2" colspan="3">
- - <widget class="QComboBox" name="cbConnection"/>
- - </item>
- - <item row="6" column="2" colspan="3">
- - <widget class="QComboBox" name="cbBaudRate"/>
- - </item>
- - <item row="12" column="0">
- - <widget class="QLabel" name="lFilter">
- + <item row="9" column="0">
- + <widget class="QLabel" name="lLWT">
- <property name="text">
- - <string>Filter:</string>
- + <string>LWT:</string>
- </property>
- </widget>
- </item>
- - <item row="4" column="2" colspan="3">
- - <widget class="QLineEdit" name="lePort"/>
- + <item row="2" column="2" colspan="3">
- + <widget class="QLineEdit" name="leHost"/>
- </item>
- - <item row="3" column="0">
- - <widget class="QLabel" name="lConnections">
- + <item row="3" column="7">
- + <widget class="QPushButton" name="bManageConnections">
- + <property name="sizePolicy">
- + <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- + <horstretch>0</horstretch>
- + <verstretch>0</verstretch>
- + </sizepolicy>
- + </property>
- <property name="text">
- - <string>Connection:</string>
- + <string/>
- </property>
- </widget>
- </item>
- @@ -260,48 +121,43 @@
- </property>
- </widget>
- </item>
- - <item row="5" column="2" colspan="3">
- - <widget class="QComboBox" name="cbSerialPort"/>
- - </item>
- - <item row="3" column="7">
- - <widget class="QPushButton" name="bManageConnections">
- + <item row="12" column="2" colspan="3">
- + <widget class="KComboBox" name="cbFilter">
- + <property name="enabled">
- + <bool>false</bool>
- + </property>
- <property name="sizePolicy">
- - <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- - <property name="text">
- - <string/>
- - </property>
- </widget>
- </item>
- - <item row="4" column="0">
- - <widget class="QLabel" name="lPort">
- - <property name="text">
- - <string>Port:</string>
- + <item row="1" column="7">
- + <widget class="QPushButton" name="bFileInfo">
- + <property name="enabled">
- + <bool>false</bool>
- </property>
- - </widget>
- - </item>
- - <item row="2" column="0">
- - <widget class="QLabel" name="lHost">
- - <property name="text">
- - <string>Host:</string>
- + <property name="sizePolicy">
- + <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- + <horstretch>0</horstretch>
- + <verstretch>0</verstretch>
- + </sizepolicy>
- </property>
- - </widget>
- - </item>
- - <item row="8" column="0">
- - <widget class="QLabel" name="lTopics">
- - <property name="text">
- - <string>Topics:</string>
- + <property name="toolTip">
- + <string>Show file info</string>
- </property>
- - <property name="alignment">
- - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- + <property name="text">
- + <string/>
- </property>
- </widget>
- </item>
- - <item row="1" column="5" colspan="2">
- - <widget class="QPushButton" name="bOpen">
- + <item row="12" column="6" colspan="2">
- + <widget class="QPushButton" name="bManageFilters">
- + <property name="enabled">
- + <bool>false</bool>
- + </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- @@ -309,35 +165,36 @@
- </sizepolicy>
- </property>
- <property name="toolTip">
- - <string> Select the file to import</string>
- + <string>Manage filters</string>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- - <item row="6" column="0">
- - <widget class="QLabel" name="lBaudRate">
- + <item row="9" column="3">
- + <widget class="QPushButton" name="bLWT">
- <property name="text">
- - <string>Baud rate:</string>
- + <string/>
- </property>
- </widget>
- </item>
- - <item row="0" column="1">
- - <spacer name="hsName">
- - <property name="orientation">
- - <enum>Qt::Horizontal</enum>
- - </property>
- - <property name="sizeType">
- - <enum>QSizePolicy::Fixed</enum>
- + <item row="4" column="2" colspan="3">
- + <widget class="QLineEdit" name="lePort"/>
- + </item>
- + <item row="0" column="0">
- + <widget class="QLabel" name="lSourceType">
- + <property name="text">
- + <string>Source:</string>
- </property>
- - <property name="sizeHint" stdset="0">
- - <size>
- - <width>10</width>
- - <height>23</height>
- - </size>
- + </widget>
- + </item>
- + <item row="4" column="0">
- + <widget class="QLabel" name="lPort">
- + <property name="text">
- + <string>Port:</string>
- </property>
- - </spacer>
- + </widget>
- </item>
- <item row="0" column="2" colspan="3">
- <widget class="QComboBox" name="cbSourceType">
- @@ -368,22 +225,31 @@
- </item>
- </widget>
- </item>
- - <item row="0" column="0">
- - <widget class="QLabel" name="lSourceType">
- + <item row="2" column="0">
- + <widget class="QLabel" name="lHost">
- <property name="text">
- - <string>Source:</string>
- + <string>Host:</string>
- </property>
- </widget>
- </item>
- - <item row="11" column="0">
- - <widget class="QLabel" name="lFileType">
- + <item row="1" column="5" colspan="2">
- + <widget class="QPushButton" name="bOpen">
- + <property name="sizePolicy">
- + <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- + <horstretch>0</horstretch>
- + <verstretch>0</verstretch>
- + </sizepolicy>
- + </property>
- + <property name="toolTip">
- + <string> Select the file to import</string>
- + </property>
- <property name="text">
- - <string>Type:</string>
- + <string/>
- </property>
- </widget>
- </item>
- - <item row="2" column="2" colspan="3">
- - <widget class="QLineEdit" name="leHost"/>
- + <item row="3" column="2" colspan="3">
- + <widget class="QComboBox" name="cbConnection"/>
- </item>
- <item row="1" column="2" colspan="3">
- <widget class="QLineEdit" name="leFileName">
- @@ -395,112 +261,77 @@
- </property>
- </widget>
- </item>
- - <item row="1" column="7">
- - <widget class="QPushButton" name="bFileInfo">
- - <property name="enabled">
- - <bool>false</bool>
- - </property>
- - <property name="sizePolicy">
- - <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- - <horstretch>0</horstretch>
- - <verstretch>0</verstretch>
- - </sizepolicy>
- - </property>
- - <property name="toolTip">
- - <string>Show file info</string>
- - </property>
- + <item row="6" column="0">
- + <widget class="QLabel" name="lBaudRate">
- <property name="text">
- - <string/>
- + <string>Baud rate:</string>
- </property>
- </widget>
- </item>
- - <item row="1" column="0">
- - <widget class="QLabel" name="lFileName">
- + <item row="11" column="0">
- + <widget class="QLabel" name="lFileType">
- <property name="text">
- - <string>Name:</string>
- + <string>Type:</string>
- </property>
- </widget>
- </item>
- - <item row="5" column="0">
- - <widget class="QLabel" name="lSerialPort">
- + <item row="1" column="0">
- + <widget class="QLabel" name="lFileName">
- <property name="text">
- - <string>Port:</string>
- - </property>
- - </widget>
- - </item>
- - <item row="13" column="2" colspan="3">
- - <widget class="QTreeView" name="tvJson">
- - <property name="editTriggers">
- - <set>QAbstractItemView::NoEditTriggers</set>
- - </property>
- - <property name="showDropIndicator" stdset="0">
- - <bool>false</bool>
- - </property>
- - <property name="iconSize">
- - <size>
- - <width>16</width>
- - <height>16</height>
- - </size>
- + <string>Name:</string>
- </property>
- </widget>
- </item>
- - <item row="12" column="6" colspan="2">
- - <widget class="QPushButton" name="bManageFilters">
- + <item row="12" column="5">
- + <widget class="QPushButton" name="bSaveFilter">
- <property name="enabled">
- <bool>false</bool>
- </property>
- - <property name="sizePolicy">
- - <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- - <horstretch>0</horstretch>
- - <verstretch>0</verstretch>
- - </sizepolicy>
- - </property>
- <property name="toolTip">
- - <string>Manage filters</string>
- + <string>Save the current filter settings</string>
- </property>
- + </widget>
- + </item>
- + <item row="12" column="0">
- + <widget class="QLabel" name="lFilter">
- <property name="text">
- - <string/>
- + <string>Filter:</string>
- </property>
- </widget>
- </item>
- - <item row="13" column="0">
- - <widget class="QLabel" name="lField">
- - <property name="text">
- - <string>Field:</string>
- + <item row="10" column="4">
- + <spacer name="spacerWillMessage">
- + <property name="orientation">
- + <enum>Qt::Horizontal</enum>
- </property>
- - <property name="alignment">
- - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- + <property name="sizeHint" stdset="0">
- + <size>
- + <width>40</width>
- + <height>0</height>
- + </size>
- </property>
- - </widget>
- + </spacer>
- </item>
- - <item row="12" column="5">
- - <widget class="QPushButton" name="bSaveFilter">
- - <property name="enabled">
- - <bool>false</bool>
- + <item row="8" column="0">
- + <widget class="QLabel" name="lTopics">
- + <property name="text">
- + <string>Topics:</string>
- </property>
- - <property name="toolTip">
- - <string>Save the current filter settings</string>
- + <property name="alignment">
- + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- </widget>
- </item>
- - <item row="12" column="2" colspan="3">
- - <widget class="KComboBox" name="cbFilter">
- - <property name="enabled">
- - <bool>false</bool>
- - </property>
- + <item row="8" column="3" colspan="2">
- + <widget class="QStackedWidget" name="swSubscriptions">
- <property name="sizePolicy">
- - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- + <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- - </widget>
- - </item>
- - <item row="9" column="0">
- - <widget class="QLabel" name="lLWT">
- - <property name="text">
- - <string>LWT:</string>
- - </property>
- + <widget class="QWidget" name="page_3"/>
- + <widget class="QWidget" name="page_4"/>
- </widget>
- </item>
- </layout>
- diff --git a/src/kdefrontend/ui/dockwidgets/livedatadock.ui b/src/kdefrontend/ui/dockwidgets/livedatadock.ui
- index c09dcf5a5..20798c7e0 100644
- --- a/src/kdefrontend/ui/dockwidgets/livedatadock.ui
- +++ b/src/kdefrontend/ui/dockwidgets/livedatadock.ui
- @@ -11,154 +11,6 @@
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- - <item row="10" column="2" colspan="2">
- - <widget class="QGroupBox" name="gbManageSubscriptions">
- - <property name="sizePolicy">
- - <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- - <horstretch>0</horstretch>
- - <verstretch>0</verstretch>
- - </sizepolicy>
- - </property>
- - <property name="title">
- - <string/>
- - </property>
- - <property name="flat">
- - <bool>true</bool>
- - </property>
- - <layout class="QGridLayout" name="gridLayout_2">
- - <property name="leftMargin">
- - <number>0</number>
- - </property>
- - <property name="topMargin">
- - <number>0</number>
- - </property>
- - <property name="rightMargin">
- - <number>0</number>
- - </property>
- - <property name="bottomMargin">
- - <number>0</number>
- - </property>
- - <property name="spacing">
- - <number>0</number>
- - </property>
- - <item row="2" column="1">
- - <widget class="QLabel" name="lTopicSearch">
- - <property name="text">
- - <string/>
- - </property>
- - <property name="alignment">
- - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- - </property>
- - </widget>
- - </item>
- - <item row="1" column="1" colspan="2">
- - <widget class="QTreeWidget" name="twTopics">
- - <column>
- - <property name="text">
- - <string>Available</string>
- - </property>
- - </column>
- - </widget>
- - </item>
- - <item row="2" column="2">
- - <widget class="QLineEdit" name="leTopics">
- - <property name="clearButtonEnabled">
- - <bool>true</bool>
- - </property>
- - </widget>
- - </item>
- - <item row="1" column="4" colspan="2">
- - <widget class="QTreeWidget" name="twSubscriptions">
- - <column>
- - <property name="text">
- - <string>Subscribed</string>
- - </property>
- - </column>
- - </widget>
- - </item>
- - <item row="2" column="5">
- - <widget class="QLineEdit" name="leSubscriptions">
- - <property name="clearButtonEnabled">
- - <bool>true</bool>
- - </property>
- - </widget>
- - </item>
- - <item row="2" column="4">
- - <widget class="QLabel" name="lSubscriptionSearch">
- - <property name="text">
- - <string/>
- - </property>
- - </widget>
- - </item>
- - <item row="1" column="3">
- - <layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,1,1,0,0">
- - <property name="spacing">
- - <number>12</number>
- - </property>
- - <item>
- - <spacer name="verticalSpacer_5">
- - <property name="orientation">
- - <enum>Qt::Vertical</enum>
- - </property>
- - <property name="sizeHint" stdset="0">
- - <size>
- - <width>20</width>
- - <height>40</height>
- - </size>
- - </property>
- - </spacer>
- - </item>
- - <item>
- - <widget class="QPushButton" name="bSubscribe">
- - <property name="text">
- - <string/>
- - </property>
- - </widget>
- - </item>
- - <item>
- - <widget class="QPushButton" name="bUnsubscribe">
- - <property name="text">
- - <string/>
- - </property>
- - </widget>
- - </item>
- - <item>
- - <spacer name="verticalSpacer_3">
- - <property name="orientation">
- - <enum>Qt::Vertical</enum>
- - </property>
- - <property name="sizeHint" stdset="0">
- - <size>
- - <width>20</width>
- - <height>40</height>
- - </size>
- - </property>
- - </spacer>
- - </item>
- - <item>
- - <widget class="QComboBox" name="cbQoS">
- - <item>
- - <property name="text">
- - <string>QoS 0</string>
- - </property>
- - </item>
- - <item>
- - <property name="text">
- - <string>QoS 1</string>
- - </property>
- - </item>
- - <item>
- - <property name="text">
- - <string>QoS 2</string>
- - </property>
- - </item>
- - </widget>
- - </item>
- - </layout>
- - </item>
- - </layout>
- - </widget>
- - </item>
- <item row="2" column="2" colspan="2">
- <widget class="QLineEdit" name="leSourceInfo">
- <property name="readOnly">
- @@ -456,6 +308,18 @@
- <item row="1" column="2" colspan="2">
- <widget class="QLineEdit" name="leName"/>
- </item>
- + <item row="10" column="2" colspan="2">
- + <widget class="QStackedWidget" name="swSubscriptions">
- + <property name="sizePolicy">
- + <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- + <horstretch>0</horstretch>
- + <verstretch>0</verstretch>
- + </sizepolicy>
- + </property>
- + <widget class="QWidget" name="page"/>
- + <widget class="QWidget" name="page_2"/>
- + </widget>
- + </item>
- </layout>
- </widget>
- <resources/>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement