diff --git a/ZeroTierUI/aboutwindow.h b/ZeroTierUI/aboutwindow.h index 41adc64d3..6c883b9ba 100644 --- a/ZeroTierUI/aboutwindow.h +++ b/ZeroTierUI/aboutwindow.h @@ -13,7 +13,7 @@ class AboutWindow : public QDialog public: explicit AboutWindow(QWidget *parent = 0); - ~AboutWindow(); + virtual ~AboutWindow(); private slots: void on_uninstallButton_clicked(); diff --git a/ZeroTierUI/mainwindow.cpp b/ZeroTierUI/mainwindow.cpp index 04a7919d7..c618243aa 100644 --- a/ZeroTierUI/mainwindow.cpp +++ b/ZeroTierUI/mainwindow.cpp @@ -127,6 +127,11 @@ void MainWindow::customEvent(QEvent *event) if (hdr.size() >= 5) this->myVersion = hdr[4].c_str(); } else if (hdr[1] == "listnetworks") { + const QObjectList &existingNetworks = ui->networksScrollAreaContentWidget->children(); + + for(unsigned long i=1;iztMessage.size();++i) { + std::vector l(ZeroTier::Node::LocalClient::splitLine(m->ztMessage[i])); + } } else if (hdr[1] == "listpeers") { this->numPeers = 0; for(unsigned long i=1;iztMessage.size();++i) { @@ -151,6 +156,18 @@ void MainWindow::customEvent(QEvent *event) void MainWindow::on_joinNetworkButton_clicked() { + QString toJoin(ui->networkIdLineEdit->text()); + ui->networkIdLineEdit->setText(QString()); + + if (!zeroTierClient) // sanity check + return; + + if (toJoin.size() != 16) { + QMessageBox::information(this,"Invalid Network ID","The network ID you entered was not valid. Enter a 16-digit hexadecimal network ID, like '8056c2e21c000001'.",QMessageBox::Ok,QMessageBox::NoButton); + return; + } + + zeroTierClient->send((QString("join ") + toJoin).toStdString()); } void MainWindow::on_actionAbout_triggered() @@ -165,10 +182,6 @@ void MainWindow::on_actionJoin_Network_triggered() on_joinNetworkButton_clicked(); } -void MainWindow::on_actionShow_Detailed_Status_triggered() -{ -} - void MainWindow::on_networkIdLineEdit_textChanged(const QString &text) { QString newText; diff --git a/ZeroTierUI/mainwindow.h b/ZeroTierUI/mainwindow.h index 39c4318aa..ed11ff44b 100644 --- a/ZeroTierUI/mainwindow.h +++ b/ZeroTierUI/mainwindow.h @@ -21,6 +21,8 @@ class MainWindow : public QMainWindow Q_OBJECT public: + // Event used to pass messages from the Node::LocalClient thread to the + // main window to update network lists and stats. class ZTMessageEvent : public QEvent { public: @@ -44,7 +46,6 @@ private slots: void on_joinNetworkButton_clicked(); void on_actionAbout_triggered(); void on_actionJoin_Network_triggered(); - void on_actionShow_Detailed_Status_triggered(); void on_networkIdLineEdit_textChanged(const QString &arg1); void on_statusAndAddressButton_clicked(); diff --git a/ZeroTierUI/mainwindow.ui b/ZeroTierUI/mainwindow.ui index a09460ae8..45b8fe633 100644 --- a/ZeroTierUI/mainwindow.ui +++ b/ZeroTierUI/mainwindow.ui @@ -54,7 +54,7 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - + 0 @@ -225,7 +225,6 @@ File - @@ -242,11 +241,6 @@ Join Network - - - Show Detailed Status - - Exit diff --git a/ZeroTierUI/network.cpp b/ZeroTierUI/network.cpp index 3826a8dab..1a6a631d7 100644 --- a/ZeroTierUI/network.cpp +++ b/ZeroTierUI/network.cpp @@ -1,13 +1,22 @@ #include "network.h" +#include "mainwindow.h" #include "ui_network.h" #include +#include +#include +#include +#include +#include +#include -Network::Network(QWidget *parent) : +Network::Network(QWidget *parent,const std::string &nwid) : QWidget(parent), - ui(new Ui::Network) + ui(new Ui::Network), + networkIdStr(nwid) { ui->setupUi(this); + ui->networkIdPushButton->setText(QString(nwid.c_str())); } Network::~Network() @@ -15,8 +24,74 @@ Network::~Network() delete ui; } +void Network::setStatus(const std::string &status) +{ + ui->statusLabel->setText(QString(status.c_str())); +} + +void Network::setNetworkName(const std::string &status) +{ + ui->nameLabel->setText(QString(status.c_str())); +} + +void Network::setNetworkType(const std::string &type) +{ + ui->networkTypeLabel->setText(QString(status.c_str())); + if (type == "?") + ui->networkTypeLabel->setToolTip("Waiting for configuration..."); + else if (type == "public") + ui->networkTypeLabel->setToolTip("This network can be joined by anyone."); + else if (type == "private") + ui->networkTypeLabel->setToolTip("This network is private, only authorized peers can join."); + else ui->networkTypeLabel->setToolTip(QString()); +} + +void Network::setNetworkDeviceName(const std::string &dev) +{ + ui->deviceLabel->setText(QString(dev.c_str())); +} + +void Network::setIps(const std::string &commaSeparatedList) +{ + QStringList ips(QString(commaSeparatedList.c_str()).split(QChar(','),QString::SkipEmptyParts)); + if (commaSeparatedList == "-") + ips.clear(); + + QStringList tmp; + ips.sort(); + for(QStringList::iterator i(ips.begin());i!=ips.end();++i) { + QString ipOnly(*i); + int slashIdx = ipOnly.indexOf('/'); + if (slashIdx > 0) + ipOnly.truncate(slashIdx); + tmp.append(ipOnly); + } + ips = tmp; + + for(QStringList::iterator i(ips.begin());i!=ips.end();++i) { + if (ui->ipListWidget->findItems(*i).size() == 0) + ui->ipListWidget->addItem(*i); + } + + QList inList(ui->ipListWidget->items()); + for(QList::iterator i(inList.begin());i!=inList.end();++i) { + QListWidgetItem *item = *i; + if (!ips.contains(item->text())) + ui->ipListWidget->removeItemWidget(item); + } +} + +const std::string &Network::networkId() +{ + return networkIdStr; +} + void Network::on_leaveNetworkButton_clicked() { + if (QMessageBox::question(this,"Leave Network?",QString("Are you sure you want to leave network '") + networkIdStr.c_str() + "'?",QMessageBox::No,QMessageBox::Yes) == QMessageBox::Yes) { + zeroTierClient->send((QString("leave ") + networkIdStr.c_str()).toStdString()); + this->setEnabled(false); + } } void Network::on_networkIdPushButton_clicked() diff --git a/ZeroTierUI/network.h b/ZeroTierUI/network.h index 730b79825..1048767e2 100644 --- a/ZeroTierUI/network.h +++ b/ZeroTierUI/network.h @@ -1,6 +1,8 @@ #ifndef NETWORK_H #define NETWORK_H +#include + #include namespace Ui { @@ -12,16 +14,24 @@ class Network : public QWidget Q_OBJECT public: - explicit Network(QWidget *parent = 0); - ~Network(); + explicit Network(QWidget *parent = 0,const std::string &nwid); + virtual ~Network(); + + void setStatus(const std::string &status); + void setNetworkName(const std::string &name); + void setNetworkType(const std::string &type); + void setNetworkDeviceName(const std::string &dev); + void setIps(const std::string &commaSeparatedList); + + const std::string &networkId(); private slots: void on_leaveNetworkButton_clicked(); - void on_networkIdPushButton_clicked(); private: Ui::Network *ui; + std::string networkIdStr; }; #endif // NETWORK_H diff --git a/ZeroTierUI/network.ui b/ZeroTierUI/network.ui index 1f80a4c82..a9b288a38 100644 --- a/ZeroTierUI/network.ui +++ b/ZeroTierUI/network.ui @@ -7,7 +7,7 @@ 0 0 618 - 93 + 108 @@ -112,6 +112,16 @@ text-align: left; + + + Name: + + + Qt::PlainText + + + + Status: @@ -121,7 +131,7 @@ text-align: left; - + @@ -143,7 +153,7 @@ text-align: left; - + Device: @@ -153,7 +163,7 @@ text-align: left; - + @@ -169,7 +179,7 @@ text-align: left; - + @@ -231,6 +241,48 @@ text-align: left; + + + + + 75 + true + + + + (name) + + + Qt::PlainText + + + + + + + Type: + + + Qt::PlainText + + + + + + + + 75 + true + + + + public + + + Qt::PlainText + + + @@ -251,6 +303,9 @@ text-align: left; false + + true + diff --git a/node/Node.hpp b/node/Node.hpp index 2f7d43ed2..476ec7cda 100644 --- a/node/Node.hpp +++ b/node/Node.hpp @@ -28,6 +28,9 @@ #ifndef _ZT_NODE_HPP #define _ZT_NODE_HPP +#include +#include + namespace ZeroTier { /** @@ -70,6 +73,7 @@ public: */ unsigned long send(const char *command) throw(); + inline unsigned long send(const std::string &command) throw() { return send(command.c_str()); } /** * Split a line of results by space diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index 027f65ce3..d56c73aeb 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -200,7 +200,7 @@ std::vector NodeConfig::execute(const char *command) _r->topology->eachPeer(_DumpPeerStatistics(r)); } else if (cmd[0] == "listnetworks") { Mutex::Lock _l(_networks_m); - _P("200 listnetworks "); + _P("200 listnetworks "); for(std::map< uint64_t,SharedPtr >::const_iterator nw(_networks.begin());nw!=_networks.end();++nw) { std::string tmp; std::set ips(nw->second->tap().ips()); @@ -211,8 +211,9 @@ std::vector NodeConfig::execute(const char *command) } SharedPtr nconf(nw->second->config2()); - _P("200 listnetworks %.16llx %s %s %s %s", + _P("200 listnetworks %.16llx %s %s %s %s %s", (unsigned long long)nw->first, + ((nconf) ? nconf->name().c_str() : "?"), Network::statusString(nw->second->status()), ((nconf) ? (nconf->isOpen() ? "public" : "private") : "?"), nw->second->tap().deviceName().c_str(),