From 298181999d5eda338778ea59c5b791fc63e6085d Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 2 Jun 2017 22:59:13 +0800 Subject: [PATCH] qtui first draft completed --- qt/i2pd_qt/ClientTunnelPane.cpp | 64 ++++++---- qt/i2pd_qt/ClientTunnelPane.h | 34 +++++- qt/i2pd_qt/ServerTunnelPane.cpp | 88 +++++++++----- qt/i2pd_qt/ServerTunnelPane.h | 53 ++++++++- qt/i2pd_qt/SignatureTypeComboboxFactory.h | 2 +- qt/i2pd_qt/TunnelConfig.cpp | 39 ++++++ qt/i2pd_qt/TunnelConfig.h | 27 +++-- qt/i2pd_qt/TunnelPane.cpp | 94 ++++++++++++--- qt/i2pd_qt/TunnelPane.h | 34 +++++- qt/i2pd_qt/TunnelsPageUpdateListener.h | 12 ++ qt/i2pd_qt/mainwindow.cpp | 107 ++++++++++++----- qt/i2pd_qt/mainwindow.h | 137 ++++++++++++++++++++-- qt/i2pd_qt/mainwindow.ui | 54 +++++---- 13 files changed, 588 insertions(+), 157 deletions(-) create mode 100644 qt/i2pd_qt/TunnelsPageUpdateListener.h diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp index b7abb0a7..6ece1eaf 100644 --- a/qt/i2pd_qt/ClientTunnelPane.cpp +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -1,28 +1,25 @@ #include "ClientTunnelPane.h" #include "../../ClientContext.h" #include "SignatureTypeComboboxFactory.h" +#include "QVBoxLayout" -ClientTunnelPane::ClientTunnelPane() -{ - -} +ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf): + TunnelPane(tunnelsPageUpdateListener, tunconf) {} void ClientTunnelPane::setGroupBoxTitle(const QString & title) { clientTunnelNameGroupBox->setTitle(title); } -void ClientTunnelPane::deleteClientTunnelForm(QGridLayout *tunnelsFormGridLayout) { - tunnelsFormGridLayout->removeWidget(clientTunnelNameGroupBox); - - clientTunnelNameGroupBox->deleteLater(); +void ClientTunnelPane::deleteClientTunnelForm() { + delete clientTunnelNameGroupBox; clientTunnelNameGroupBox=nullptr; - gridLayoutWidget_2->deleteLater(); - gridLayoutWidget_2=nullptr; + //gridLayoutWidget_2->deleteLater(); + //gridLayoutWidget_2=nullptr; } -void ClientTunnelPane::appendClientTunnelForm( - ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow) { +int ClientTunnelPane::appendClientTunnelForm( + ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) { ClientTunnelPane& ui = *this; @@ -30,7 +27,7 @@ void ClientTunnelPane::appendClientTunnelForm( clientTunnelNameGroupBox->setObjectName(QStringLiteral("clientTunnelNameGroupBox")); //tunnel - ui.gridLayoutWidget_2 = new QWidget(clientTunnelNameGroupBox); + gridLayoutWidget_2 = new QWidget(clientTunnelNameGroupBox); QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2); tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox")); @@ -40,13 +37,10 @@ void ClientTunnelPane::appendClientTunnelForm( tunnelTypeComboBox->addItem("HTTP Proxy", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY); tunnelTypeComboBox->addItem("UDP Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT); - gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, (7+4)*60)); + int h=(7+4)*60; + gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h)); + clientTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h)); - setupTunnelPane(tunnelConfig, - clientTunnelNameGroupBox, - gridLayoutWidget_2, tunnelTypeComboBox, - tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelsRow); - //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, (7+5)*40+10)); { const QString& type = tunnelConfig->getType(); int index=0; @@ -62,6 +56,12 @@ void ClientTunnelPane::appendClientTunnelForm( ++index; } + setupTunnelPane(tunnelConfig, + clientTunnelNameGroupBox, + gridLayoutWidget_2, tunnelTypeComboBox, + tunnelsFormGridLayoutWidget, tunnelsRow, height, h); + //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, (7+5)*40+10)); + /* std::string destination; */ @@ -75,10 +75,12 @@ void ClientTunnelPane::appendClientTunnelForm( ui.destinationLineEdit = new QLineEdit(gridLayoutWidget_2); destinationLineEdit->setObjectName(QStringLiteral("destinationLineEdit")); destinationLineEdit->setText(tunnelConfig->getdest().c_str()); + QObject::connect(destinationLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(destinationLineEdit); ui.destinationHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(destinationHorizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, 2, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); /* * int port; @@ -95,10 +97,12 @@ void ClientTunnelPane::appendClientTunnelForm( portLineEdit->setObjectName(QStringLiteral("portLineEdit")); portLineEdit->setText(QString::number(port)); portLineEdit->setMaximumWidth(80); + QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(portLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } /* * std::string keys; @@ -113,10 +117,12 @@ void ClientTunnelPane::appendClientTunnelForm( ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2); keysLineEdit->setObjectName(QStringLiteral("keysLineEdit")); keysLineEdit->setText(keys.c_str()); + QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(keysLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } /* * std::string address; @@ -131,10 +137,12 @@ void ClientTunnelPane::appendClientTunnelForm( ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2); addressLineEdit->setObjectName(QStringLiteral("addressLineEdit")); addressLineEdit->setText(address.c_str()); + QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(addressLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } /* @@ -152,10 +160,12 @@ void ClientTunnelPane::appendClientTunnelForm( destinationPortLineEdit->setObjectName(QStringLiteral("destinationPortLineEdit")); destinationPortLineEdit->setText(QString::number(destinationPort)); destinationPortLineEdit->setMaximumWidth(80); + QObject::connect(destinationPortLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(destinationPortLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); @@ -166,10 +176,12 @@ void ClientTunnelPane::appendClientTunnelForm( horizontalLayout_2->addWidget(sigTypeLabel); ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType); sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox")); + QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updated())); horizontalLayout_2->addWidget(sigTypeComboBox); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); @@ -179,6 +191,8 @@ void ClientTunnelPane::appendClientTunnelForm( retranslateClientTunnelForm(ui); tunnelGridLayout->invalidate(); + + return h; } ServerTunnelPane* ClientTunnelPane::asServerTunnelPane(){return nullptr;} diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h index df4420f9..16416cd8 100644 --- a/qt/i2pd_qt/ClientTunnelPane.h +++ b/qt/i2pd_qt/ClientTunnelPane.h @@ -2,6 +2,7 @@ #define CLIENTTUNNELPANE_H #include "QGridLayout" +#include "QVBoxLayout" #include "TunnelPane.h" @@ -13,13 +14,13 @@ class TunnelPane; class ClientTunnelPane : public TunnelPane { Q_OBJECT public: - ClientTunnelPane(); + ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf); virtual ~ClientTunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane(); virtual ClientTunnelPane* asClientTunnelPane(); - void appendClientTunnelForm(ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, - QGridLayout *tunnelsFormGridLayout, int tunnelsRow); - void deleteClientTunnelForm(QGridLayout *tunnelsFormGridLayout); + int appendClientTunnelForm(ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, + int tunnelsRow, int height); + void deleteClientTunnelForm(); private: QGroupBox *clientTunnelNameGroupBox; @@ -65,7 +66,32 @@ private: addressLabel->setText(QApplication::translate("cltTunForm", "Address:", 0)); sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0)); } +protected: + virtual bool applyDataFromUIToTunnelConfig() { + bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); + if(!ok)return false; + ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig(); + assert(ctc!=nullptr); + //destination + ctc->setdest(destinationLineEdit->text().toStdString()); + + auto portStr=portLineEdit->text(); + int portInt=portStr.toInt(&ok); + if(!ok)return false; + ctc->setport(portInt); + + ctc->setkeys(keysLineEdit->text().toStdString()); + + ctc->setaddress(addressLineEdit->text().toStdString()); + + auto dportStr=portLineEdit->text(); + int dportInt=dportStr.toInt(&ok); + if(!ok)return false; + ctc->setdestinationPort(dportInt); + + ctc->setsigType(readSigTypeComboboxUI(sigTypeComboBox)); + } }; #endif // CLIENTTUNNELPANE_H diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp index 4a1c8971..7261336e 100644 --- a/qt/i2pd_qt/ServerTunnelPane.cpp +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -2,14 +2,15 @@ #include "../../ClientContext.h" #include "SignatureTypeComboboxFactory.h" -ServerTunnelPane::ServerTunnelPane(): TunnelPane() {} +ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf): + TunnelPane(tunnelsPageUpdateListener, tunconf) {} void ServerTunnelPane::setGroupBoxTitle(const QString & title) { serverTunnelNameGroupBox->setTitle(title); } -void ServerTunnelPane::appendServerTunnelForm( - ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow) { +int ServerTunnelPane::appendServerTunnelForm( + ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) { ServerTunnelPane& ui = *this; @@ -17,7 +18,7 @@ void ServerTunnelPane::appendServerTunnelForm( serverTunnelNameGroupBox->setObjectName(QStringLiteral("serverTunnelNameGroupBox")); //tunnel - ui.gridLayoutWidget_2 = new QWidget(serverTunnelNameGroupBox); + gridLayoutWidget_2 = new QWidget(serverTunnelNameGroupBox); QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2); tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox")); @@ -26,14 +27,9 @@ void ServerTunnelPane::appendServerTunnelForm( tunnelTypeComboBox->addItem("IRC", i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC); tunnelTypeComboBox->addItem("UDP Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER); - gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, 18*60)); - - - setupTunnelPane(tunnelConfig, - serverTunnelNameGroupBox, - gridLayoutWidget_2, tunnelTypeComboBox, - tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelsRow); - //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, 18*40+10)); + int h=19*60; + gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h)); + serverTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h)); { const QString& type = tunnelConfig->getType(); @@ -48,6 +44,12 @@ void ServerTunnelPane::appendServerTunnelForm( ++index; } + setupTunnelPane(tunnelConfig, + serverTunnelNameGroupBox, + gridLayoutWidget_2, tunnelTypeComboBox, + tunnelsFormGridLayoutWidget, tunnelsRow, height, h); + //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, 18*40+10)); + //host ui.horizontalLayout_2 = new QHBoxLayout(); horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); @@ -57,10 +59,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.hostLineEdit = new QLineEdit(gridLayoutWidget_2); hostLineEdit->setObjectName(QStringLiteral("hostLineEdit")); hostLineEdit->setText(tunnelConfig->gethost().c_str()); + QObject::connect(hostLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(hostLineEdit); ui.hostHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(hostHorizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, 2, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); int gridIndex = 2; { @@ -74,10 +78,12 @@ void ServerTunnelPane::appendServerTunnelForm( portLineEdit->setObjectName(QStringLiteral("portLineEdit")); portLineEdit->setText(QString::number(port)); portLineEdit->setMaximumWidth(80); + QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(portLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { std::string keys = tunnelConfig->getkeys(); @@ -89,10 +95,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2); keysLineEdit->setObjectName(QStringLiteral("keysLineEdit")); keysLineEdit->setText(keys.c_str()); + QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(keysLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { int inPort = tunnelConfig->getinPort(); @@ -105,10 +113,12 @@ void ServerTunnelPane::appendServerTunnelForm( inPortLineEdit->setObjectName(QStringLiteral("inPortLineEdit")); inPortLineEdit->setText(QString::number(inPort)); inPortLineEdit->setMaximumWidth(80); + QObject::connect(inPortLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(inPortLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { std::string accessList = tunnelConfig->getaccessList(); @@ -120,10 +130,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.accessListLineEdit = new QLineEdit(gridLayoutWidget_2); accessListLineEdit->setObjectName(QStringLiteral("accessListLineEdit")); accessListLineEdit->setText(accessList.c_str()); + QObject::connect(accessListLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(accessListLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { std::string hostOverride = tunnelConfig->gethostOverride(); @@ -135,10 +147,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.hostOverrideLineEdit = new QLineEdit(gridLayoutWidget_2); hostOverrideLineEdit->setObjectName(QStringLiteral("hostOverrideLineEdit")); hostOverrideLineEdit->setText(hostOverride.c_str()); + QObject::connect(hostOverrideLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(hostOverrideLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { std::string webIRCPass = tunnelConfig->getwebircpass(); @@ -150,10 +164,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.webIRCPassLineEdit = new QLineEdit(gridLayoutWidget_2); webIRCPassLineEdit->setObjectName(QStringLiteral("webIRCPassLineEdit")); webIRCPassLineEdit->setText(webIRCPass.c_str()); + QObject::connect(webIRCPassLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(webIRCPassLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { bool gzip = tunnelConfig->getgzip(); @@ -162,10 +178,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.gzipCheckBox = new QCheckBox(gridLayoutWidget_2); gzipCheckBox->setObjectName(QStringLiteral("gzipCheckBox")); gzipCheckBox->setChecked(gzip); + QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)), + this, SLOT(updated())); horizontalLayout_2->addWidget(gzipCheckBox); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); @@ -176,10 +194,12 @@ void ServerTunnelPane::appendServerTunnelForm( horizontalLayout_2->addWidget(sigTypeLabel); ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType); sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox")); + QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updated())); horizontalLayout_2->addWidget(sigTypeComboBox); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { uint32_t maxConns = tunnelConfig->getmaxConns(); @@ -192,10 +212,12 @@ void ServerTunnelPane::appendServerTunnelForm( maxConnsLineEdit->setObjectName(QStringLiteral("maxConnsLineEdit")); maxConnsLineEdit->setText(QString::number(maxConns)); maxConnsLineEdit->setMaximumWidth(80); + QObject::connect(maxConnsLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(maxConnsLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { std::string address = tunnelConfig->getaddress(); @@ -207,10 +229,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2); addressLineEdit->setObjectName(QStringLiteral("addressLineEdit")); addressLineEdit->setText(address.c_str()); + QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(addressLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { bool isUniqueLocal = tunnelConfig->getisUniqueLocal(); @@ -219,10 +243,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.isUniqueLocalCheckBox = new QCheckBox(gridLayoutWidget_2); isUniqueLocalCheckBox->setObjectName(QStringLiteral("isUniqueLocalCheckBox")); isUniqueLocalCheckBox->setChecked(isUniqueLocal); + QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)), + this, SLOT(updated())); horizontalLayout_2->addWidget(isUniqueLocalCheckBox); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); @@ -232,16 +258,16 @@ void ServerTunnelPane::appendServerTunnelForm( retranslateServerTunnelForm(ui); tunnelGridLayout->invalidate(); -} -void ServerTunnelPane::deleteServerTunnelForm(QGridLayout *tunnelsFormGridLayout) { - tunnelsFormGridLayout->removeWidget(tunnelGroupBox); + return h; +} - tunnelGroupBox->deleteLater(); - tunnelGroupBox=nullptr; +void ServerTunnelPane::deleteServerTunnelForm() { + delete serverTunnelNameGroupBox;//->deleteLater(); + serverTunnelNameGroupBox=nullptr; - gridLayoutWidget_2->deleteLater(); - gridLayoutWidget_2=nullptr; + //gridLayoutWidget_2->deleteLater(); + //gridLayoutWidget_2=nullptr; } diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h index 2bab41d6..a6994841 100644 --- a/qt/i2pd_qt/ServerTunnelPane.h +++ b/qt/i2pd_qt/ServerTunnelPane.h @@ -2,7 +2,7 @@ #define SERVERTUNNELPANE_H #include "TunnelPane.h" -#include "mainwindow.h" +#include "TunnelsPageUpdateListener.h" #include #include @@ -18,6 +18,10 @@ #include #include #include +#include "QVBoxLayout" +#include "QCheckBox" + +#include "assert.h" class ServerTunnelConfig; @@ -27,15 +31,15 @@ class ServerTunnelPane : public TunnelPane { Q_OBJECT public: - ServerTunnelPane(); + ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf); virtual ~ServerTunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane(); virtual ClientTunnelPane* asClientTunnelPane(); - void appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, - QGridLayout *tunnelsFormGridLayout, int tunnelsRow); - void deleteServerTunnelForm(QGridLayout *tunnelsFormGridLayout); + int appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, + int tunnelsRow, int height); + void deleteServerTunnelForm(); private: QGroupBox *serverTunnelNameGroupBox; @@ -113,6 +117,45 @@ private: sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0)); } +protected: + virtual bool applyDataFromUIToTunnelConfig() { + bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); + if(!ok)return false; + ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig(); + assert(stc!=nullptr); + stc->sethost(hostLineEdit->text().toStdString()); + + auto portStr=portLineEdit->text(); + int portInt=portStr.toInt(&ok); + if(!ok)return false; + stc->setport(portInt); + + stc->setkeys(keysLineEdit->text().toStdString()); + + auto str=inPortLineEdit->text(); + int inPortInt=str.toInt(&ok); + if(!ok)return false; + stc->setinPort(inPortInt); + + stc->setaccessList(accessListLineEdit->text().toStdString()); + + stc->sethostOverride(hostOverrideLineEdit->text().toStdString()); + + stc->setwebircpass(webIRCPassLineEdit->text().toStdString()); + + stc->setaddress(addressLineEdit->text().toStdString()); + + auto mcStr=maxConnsLineEdit->text(); + uint32_t mcInt=(uint32_t)mcStr.toInt(&ok); + if(!ok)return false; + stc->setmaxConns(mcInt); + + stc->setgzip(gzipCheckBox->isChecked()); + + stc->setisUniqueLocal(isUniqueLocalCheckBox->isChecked()); + + stc->setsigType(readSigTypeComboboxUI(sigTypeComboBox)); + } }; #endif // SERVERTUNNELPANE_H diff --git a/qt/i2pd_qt/SignatureTypeComboboxFactory.h b/qt/i2pd_qt/SignatureTypeComboboxFactory.h index 9c9190ed..111b7296 100644 --- a/qt/i2pd_qt/SignatureTypeComboboxFactory.h +++ b/qt/i2pd_qt/SignatureTypeComboboxFactory.h @@ -8,7 +8,7 @@ class SignatureTypeComboBoxFactory { - static const QVariant& createUserData(const uint16_t sigType) { + static const QVariant createUserData(const uint16_t sigType) { return QVariant::fromValue((uint)sigType); } diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp index fbd8a2ab..0de17486 100644 --- a/qt/i2pd_qt/TunnelConfig.cpp +++ b/qt/i2pd_qt/TunnelConfig.cpp @@ -1,2 +1,41 @@ #include "TunnelConfig.h" +void TunnelConfig::saveHeaderToStringStream(std::stringstream& out) { + out << "[" << name << "]\n" + << "type=" << type.toStdString() << "\n"; +} + +void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) { + out << "inbound.length=" << i2cpParameters.getInbound_length().toStdString() << "\n" + << "outbound.length=" << i2cpParameters.getOutbound_length().toStdString() << "\n" + << "inbound.quantity=" << i2cpParameters.getInbound_quantity().toStdString() << "\n" + << "outbound.quantity=" << i2cpParameters.getOutbound_quantity().toStdString() << "\n" + << "crypto.tagsToSend=" << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n" + << "explicitPeers=" << i2cpParameters.getExplicitPeers().toStdString() << "\n\n"; +} + +void ClientTunnelConfig::saveToStringStream(std::stringstream& out) { + out << "address=" << address << "\n" + << "port=" << port << "\n" + << "destination=" << dest << "\n" + << "keys=" << keys << "\n" + << "destinationport=" << destinationPort << "\n" + << "signaturetype=" << sigType << "\n"; +} + + +void ServerTunnelConfig::saveToStringStream(std::stringstream& out) { + out << "host=" << host << "\n" + << "port=" << port << "\n" + << "keys=" << keys << "\n" + << "signaturetype=" << sigType << "\n" + << "inport=" << inPort << "\n" + << "accesslist=" << accessList << "\n" + << "gzip=" << (gzip?"true":"false") << "\n" + << "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n" + << "address=" << address << "\n" + << "hostoverride=" << hostOverride << "\n" + << "webircpassword=" << webircpass << "\n" + << "maxconns=" << maxConns << "\n"; +} + diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h index 806d082c..471afdef 100644 --- a/qt/i2pd_qt/TunnelConfig.h +++ b/qt/i2pd_qt/TunnelConfig.h @@ -5,6 +5,7 @@ #include #include "../../ClientContext.h" +#include "TunnelsPageUpdateListener.h" class I2CPParameters{ @@ -53,13 +54,17 @@ class TunnelConfig { QString type; std::string name; public: - TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_): type(type_), name(name_), i2cpParameters(i2cpParameters_) {} + TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_): + type(type_), name(name_), i2cpParameters(i2cpParameters_) {} virtual ~TunnelConfig(){} const QString& getType(){return type;} const std::string& getName(){return name;} void setType(const QString& type_){type=type_;} void setName(const std::string& name_){name=name_;} I2CPParameters& getI2cpParameters(){return i2cpParameters;} + void saveHeaderToStringStream(std::stringstream& out); + void saveI2CPParametersToStringStream(std::stringstream& out); + virtual void saveToStringStream(std::stringstream& out)=0; virtual ClientTunnelConfig* asClientTunnelConfig()=0; virtual ServerTunnelConfig* asServerTunnelConfig()=0; @@ -116,12 +121,13 @@ public: std::string & getaddress(){return address;} int getdestinationPort(){return destinationPort;} i2p::data::SigningKeyType getsigType(){return sigType;} - void setdest(std::string& dest_){dest=dest_;} + void setdest(const std::string& dest_){dest=dest_;} void setport(int port_){port=port_;} - void setkeys(std::string & keys_){keys=keys_;} - void setaddress(std::string & address_){address=address_;} + void setkeys(const std::string & keys_){keys=keys_;} + void setaddress(const std::string & address_){address=address_;} void setdestinationPort(int destinationPort_){destinationPort=destinationPort_;} void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} + virtual void saveToStringStream(std::stringstream& out); virtual ClientTunnelConfig* asClientTunnelConfig(){return this;} virtual ServerTunnelConfig* asServerTunnelConfig(){return nullptr;} }; @@ -203,18 +209,19 @@ public: uint32_t getmaxConns(){return maxConns;} std::string& getaddress(){return address;} bool getisUniqueLocal(){return isUniqueLocal;} - void sethost(std::string& host_){host=host_;} + void sethost(const std::string& host_){host=host_;} void setport(int port_){port=port_;} - void setkeys(std::string& keys_){keys=keys_;} + void setkeys(const std::string& keys_){keys=keys_;} void setinPort(int inPort_){inPort=inPort_;} - void setaccessList(std::string& accessList_){accessList=accessList_;} - void sethostOverride(std::string& hostOverride_){hostOverride=hostOverride_;} - void setwebircpass(std::string& webircpass_){webircpass=webircpass_;} + void setaccessList(const std::string& accessList_){accessList=accessList_;} + void sethostOverride(const std::string& hostOverride_){hostOverride=hostOverride_;} + void setwebircpass(const std::string& webircpass_){webircpass=webircpass_;} void setgzip(bool gzip_){gzip=gzip_;} void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} void setmaxConns(uint32_t maxConns_){maxConns=maxConns_;} - void setaddress(std::string& address_){address=address_;} + void setaddress(const std::string& address_){address=address_;} void setisUniqueLocal(bool isUniqueLocal_){isUniqueLocal=isUniqueLocal_;} + virtual void saveToStringStream(std::stringstream& out); virtual ClientTunnelConfig* asClientTunnelConfig(){return nullptr;} virtual ServerTunnelConfig* asServerTunnelConfig(){return this;} }; diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index d0d3a28e..0dda5185 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -1,26 +1,32 @@ #include "TunnelPane.h" +#include "QMessageBox" -TunnelPane::TunnelPane(): QObject(),gridLayoutWidget_2(nullptr) { -} +TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_): + QObject(), + tunnelConfig(tunnelConfig_), + tunnelsPageUpdateListener(tunnelsPageUpdateListener_), + gridLayoutWidget_2(nullptr) {} void TunnelPane::setupTunnelPane( TunnelConfig* tunnelConfig, QGroupBox *tunnelGroupBox, QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, - QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow) { - tunnelsFormGridLayoutWidget->resize(527, tunnelsFormGridLayoutWidget->height()+gridLayoutWidget_2->height()); - tunnelGroupBox->resize(gridLayoutWidget_2->width(), gridLayoutWidget_2->height()); - tunnelsFormGridLayout->addWidget(tunnelGroupBox, tunnelsRow, 0); + QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h) { + tunnelGroupBox->setGeometry(0, tunnelsFormGridLayoutWidget->height(), gridLayoutWidget_2->width(), h); + tunnelsFormGridLayoutWidget->resize(527, tunnelsFormGridLayoutWidget->height()+h); + + QObject::connect(tunnelTypeComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updated())); this->tunnelGroupBox=tunnelGroupBox; gridLayoutWidget_2->setObjectName(QStringLiteral("gridLayoutWidget_2")); this->gridLayoutWidget_2=gridLayoutWidget_2; - tunnelGridLayout = new QGridLayout(gridLayoutWidget_2); + tunnelGridLayout = new QVBoxLayout(gridLayoutWidget_2); tunnelGridLayout->setObjectName(QStringLiteral("tunnelGridLayout")); tunnelGridLayout->setContentsMargins(5, 5, 5, 5); - tunnelGridLayout->setVerticalSpacing(5); + tunnelGridLayout->setSpacing(5); //header QHBoxLayout *headerHorizontalLayout = new QHBoxLayout(); @@ -37,14 +43,18 @@ void TunnelPane::setupTunnelPane( QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(setGroupBoxTitle(const QString &))); + QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); headerHorizontalLayout->addWidget(nameLineEdit); headerHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); headerHorizontalLayout->addItem(headerHorizontalSpacer); - deletePushButton = new QPushButton(gridLayoutWidget_2);//TODO handle it + deletePushButton = new QPushButton(gridLayoutWidget_2); deletePushButton->setObjectName(QStringLiteral("deletePushButton")); + QObject::connect(deletePushButton, SIGNAL(released()), + this, SLOT(deleteButtonReleased()));//MainWindow::DeleteTunnelNamed(std::string name) { headerHorizontalLayout->addWidget(deletePushButton); - tunnelGridLayout->addLayout(headerHorizontalLayout, 0, 0, 1, 1); + tunnelGridLayout->addLayout(headerHorizontalLayout); //type { @@ -58,7 +68,7 @@ void TunnelPane::setupTunnelPane( this->tunnelTypeComboBox=tunnelTypeComboBox; QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_, 1, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_); } retranslateTunnelForm(*this); @@ -77,10 +87,12 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, inbound_lengthLineEdit->setObjectName(QStringLiteral("inbound_lengthLineEdit")); inbound_lengthLineEdit->setText(inbound_length); inbound_lengthLineEdit->setMaximumWidth(80); + QObject::connect(inbound_lengthLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(inbound_lengthLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //number of hops of an outbound tunnel @@ -94,10 +106,12 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, outbound_lengthLineEdit->setObjectName(QStringLiteral("outbound_lengthLineEdit")); outbound_lengthLineEdit->setText(outbound_length); outbound_lengthLineEdit->setMaximumWidth(80); + QObject::connect(outbound_lengthLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(outbound_lengthLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //number of inbound tunnels @@ -111,10 +125,12 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, inbound_quantityLineEdit->setObjectName(QStringLiteral("inbound_quantityLineEdit")); inbound_quantityLineEdit->setText(inbound_quantity); inbound_quantityLineEdit->setMaximumWidth(80); + QObject::connect(inbound_quantityLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(inbound_quantityLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //number of outbound tunnels @@ -128,10 +144,12 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, outbound_quantityLineEdit->setObjectName(QStringLiteral("outbound_quantityLineEdit")); outbound_quantityLineEdit->setText(outbound_quantity); outbound_quantityLineEdit->setMaximumWidth(80); + QObject::connect(outbound_quantityLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(outbound_quantityLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //number of ElGamal/AES tags to send @@ -145,11 +163,55 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, crypto_tagsToSendLineEdit->setObjectName(QStringLiteral("crypto_tagsToSendLineEdit")); crypto_tagsToSendLineEdit->setText(crypto_tagsToSend); crypto_tagsToSendLineEdit->setMaximumWidth(80); + QObject::connect(crypto_tagsToSendLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(crypto_tagsToSendLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } retranslateI2CPParameters(); } + +void TunnelPane::updated() { + std::string oldName=tunnelConfig->getName(); + if(!applyDataFromUIToTunnelConfig())return;//TODO visualise bad input + tunnelsPageUpdateListener->updated(oldName, tunnelConfig); +} + +void TunnelPane::deleteButtonReleased() { + QMessageBox msgBox; + msgBox.setText(QApplication::tr("Are you sure to delete this tunnel?")); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Cancel); + int ret = msgBox.exec(); + switch (ret) { + case QMessageBox::Ok: + // OK was clicked + tunnelsPageUpdateListener->needsDeleting(tunnelConfig->getName()); + break; + case QMessageBox::Cancel: + // Cancel was clicked + return; + } +} + +/* +const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client"; +const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server"; +const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http"; +const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc"; +const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient"; +const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver"; +const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks"; +const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks"; +const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy"; +*/ +QString TunnelPane::readTunnelTypeComboboxData() { + return tunnelTypeComboBox->currentData().toString(); +} + +i2p::data::SigningKeyType TunnelPane::readSigTypeComboboxUI(QComboBox* sigTypeComboBox) { + return (i2p::data::SigningKeyType) sigTypeComboBox->currentData().toInt(); +} diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index af6c7351..d0a3d6a8 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -10,6 +10,7 @@ #include "QApplication" #include "QLineEdit" #include "QGroupBox" +#include "QVBoxLayout" #include "TunnelConfig.h" @@ -24,20 +25,30 @@ class TunnelPane : public QObject { Q_OBJECT public: - TunnelPane(); + TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf); virtual ~TunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane()=0; virtual ClientTunnelPane* asClientTunnelPane()=0; protected: - QGridLayout *tunnelGridLayout; + TunnelConfig* tunnelConfig; + TunnelsPageUpdateListener* tunnelsPageUpdateListener; + QVBoxLayout *tunnelGridLayout; QGroupBox *tunnelGroupBox; QWidget* gridLayoutWidget_2; //header QLabel *nameLabel; QLineEdit *nameLineEdit; +public: + QLineEdit * getNameLineEdit() { return nameLineEdit; } + +public slots: + void updated(); + void deleteButtonReleased(); + +protected: QSpacerItem *headerHorizontalSpacer; QPushButton *deletePushButton; @@ -62,11 +73,28 @@ protected: QLabel * crypto_tagsToSendLabel; QLineEdit * crypto_tagsToSendLineEdit; + QString readTunnelTypeComboboxData(); + + //should be created by factory + i2p::data::SigningKeyType readSigTypeComboboxUI(QComboBox* sigTypeComboBox); + + //returns false when invalid data at UI + virtual bool applyDataFromUIToTunnelConfig() { + tunnelConfig->setName(nameLineEdit->text().toStdString()); + tunnelConfig->setType(readTunnelTypeComboboxData()); + I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters(); + i2cpParams.setInbound_length(inbound_lengthLineEdit->text()); + i2cpParams.setInbound_quantity(inbound_quantityLineEdit->text()); + i2cpParams.setOutbound_length(outbound_lengthLineEdit->text()); + i2cpParams.setOutbound_quantity(outbound_quantityLineEdit->text()); + i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text()); + } + void setupTunnelPane( TunnelConfig* tunnelConfig, QGroupBox *tunnelGroupBox, QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, - QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow); + QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h); void appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex); public: int height() { diff --git a/qt/i2pd_qt/TunnelsPageUpdateListener.h b/qt/i2pd_qt/TunnelsPageUpdateListener.h new file mode 100644 index 00000000..83b4e9fe --- /dev/null +++ b/qt/i2pd_qt/TunnelsPageUpdateListener.h @@ -0,0 +1,12 @@ +#ifndef TUNNELSPAGEUPDATELISTENER_H +#define TUNNELSPAGEUPDATELISTENER_H + +class TunnelConfig; + +class TunnelsPageUpdateListener { +public: + virtual void updated(std::string oldName, TunnelConfig* tunConf)=0; + virtual void needsDeleting(std::string oldName)=0; +}; + +#endif // TUNNELSPAGEUPDATELISTENER_H diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 37eea4c4..decd5470 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -29,6 +29,7 @@ MainWindow::MainWindow(QWidget *parent) : ,datadir() ,confpath() ,tunconfpath() + ,tunnelsPageUpdateListener(this) { ui->setupUi(this); @@ -185,16 +186,12 @@ MainWindow::MainWindow(QWidget *parent) : loadAllConfigs(); - tunnelsFormGridLayoutWidget = new QWidget(ui->tunnelsScrollAreaWidgetContents); - tunnelsFormGridLayoutWidget->setObjectName(QStringLiteral("tunnelsFormGridLayoutWidget")); - tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, 451)); + //tunnelsFormGridLayoutWidget = new QWidget(ui->tunnelsScrollAreaWidgetContents); + //tunnelsFormGridLayoutWidget->setObjectName(QStringLiteral("tunnelsFormGridLayoutWidget")); + //tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, 451)); ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, 451)); - tunnelsFormGridLayout = new QGridLayout(tunnelsFormGridLayoutWidget); - tunnelsFormGridLayout->setObjectName(QStringLiteral("tunnelsFormGridLayout")); - tunnelsFormGridLayout->setContentsMargins(5, 5, 5, 5); - tunnelsFormGridLayout->setVerticalSpacing(5); - appendTunnelForms(); + appendTunnelForms(""); ui->configFileLineEdit->setEnabled(false); ui->configFileBrowsePushButton->setEnabled(false); @@ -209,6 +206,8 @@ MainWindow::MainWindow(QWidget *parent) : QObject::connect(ui->tunnelsConfigFileLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(reloadTunnelsConfigAndUI())); + QObject::connect(ui->addServerTunnelPushButton, SIGNAL(released()), this, SLOT(addServerTunnelPushButtonReleased())); + QObject::connect(ui->addClientTunnelPushButton, SIGNAL(released()), this, SLOT(addClientTunnelPushButtonReleased())); #ifndef ANDROID @@ -476,10 +475,11 @@ bool MainWindow::saveAllConfigs(){ QFile::rename(confpath, backup);//TODO handle errors ofstream outfile; outfile.open(confpath.toStdString());//TODO handle errors - string dataToWrite = out.str(); - outfile << dataToWrite.c_str(); + outfile << out.str().c_str(); outfile.close(); + SaveTunnelsConfig(); + return true; } @@ -507,47 +507,53 @@ void CheckBoxItem::installListeners(MainWindow *mainWindow) { void MainWindowItem::installListeners(MainWindow *mainWindow) {} -void MainWindow::appendTunnelForms() { +void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) { int height=0; - tunnelsFormGridLayoutWidget->setGeometry(0,0,0,0); - for(std::list::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { - TunnelConfig* tunconf = *it; + ui->tunnelsScrollAreaWidgetContents->setGeometry(0,0,0,0); + for(std::map::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { + const std::string& name=it->first; + TunnelConfig* tunconf = it->second; ServerTunnelConfig* stc = tunconf->asServerTunnelConfig(); if(stc){ - ServerTunnelPane * tunnelPane=new ServerTunnelPane(); - tunnelPane->appendServerTunnelForm(stc, tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelPanes.size()); - height+=tunnelPane->height(); + ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc); + int h=tunnelPane->appendServerTunnelForm(stc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); + height+=h; qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); tunnelPanes.push_back(tunnelPane); + if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus(); continue; } ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig(); if(ctc){ - ClientTunnelPane * tunnelPane=new ClientTunnelPane(); - tunnelPane->appendClientTunnelForm(ctc, tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelPanes.size()); - height+=tunnelPane->height(); + ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc); + int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); + height+=h; qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); tunnelPanes.push_back(tunnelPane); + if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus(); continue; } throw "unknown TunnelConfig subtype"; } qDebug() << "tun.setting height:" << height; - tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, height)); - tunnelsFormGridLayout->invalidate(); ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height)); + QList childWidgets = ui->tunnelsScrollAreaWidgetContents->findChildren(); + foreach(QWidget* widget, childWidgets) + widget->show(); } void MainWindow::deleteTunnelForms() { for(std::list::iterator it = tunnelPanes.begin(); it != tunnelPanes.end(); ++it) { TunnelPane* tp = *it; ServerTunnelPane* stp = tp->asServerTunnelPane(); if(stp){ - stp->deleteServerTunnelForm(tunnelsFormGridLayout); + stp->deleteServerTunnelForm(); + delete stp; continue; } ClientTunnelPane* ctp = tp->asClientTunnelPane(); if(ctp){ - ctp->deleteClientTunnelForm(tunnelsFormGridLayout); + ctp->deleteClientTunnelForm(); + delete ctp; continue; } throw "unknown TunnelPane subtype"; @@ -555,13 +561,58 @@ void MainWindow::deleteTunnelForms() { tunnelPanes.clear(); } -void MainWindow::reloadTunnelsConfigAndUI() { +void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) { deleteTunnelForms(); - for(std::list::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { - TunnelConfig* tunconf = *it; + for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { + TunnelConfig* tunconf = it->second; delete tunconf; } tunnelConfigs.clear(); ReadTunnelsConfig(); - appendTunnelForms(); + appendTunnelForms(tunnelNameToFocus); +} + +void MainWindow::SaveTunnelsConfig() { + std::stringstream out; + + for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { + const std::string& name = it->first; + TunnelConfig* tunconf = it->second; + tunconf->saveHeaderToStringStream(out); + tunconf->saveToStringStream(out); + tunconf->saveI2CPParametersToStringStream(out); + } + + using namespace std; + + QString backup=tunconfpath+"~"; + if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors + QFile::rename(tunconfpath, backup);//TODO handle errors + ofstream outfile; + outfile.open(tunconfpath.toStdString());//TODO handle errors + outfile << out.str().c_str(); + outfile.close(); + +} + +void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string oldName, TunnelConfig* tunConf) { + if(oldName!=tunConf->getName()) { + //name has changed + std::map::const_iterator it=mainWindow->tunnelConfigs.find(oldName); + if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it); + mainWindow->tunnelConfigs[tunConf->getName()]=tunConf; + } + mainWindow->SaveTunnelsConfig(); +} + +void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){ + mainWindow->DeleteTunnelNamed(oldName); +} + +void MainWindow::addServerTunnelPushButtonReleased() { + CreateDefaultServerTunnel(); +} + +void MainWindow::addClientTunnelPushButtonReleased() { + CreateDefaultClientTunnel(); } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index f94a7b9d..4d465f1a 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -23,6 +23,7 @@ #include #include #include +#include "QVBoxLayout" #ifndef ANDROID # include @@ -48,6 +49,8 @@ #include #include +#include "TunnelsPageUpdateListener.h" + template bool isType(boost::any& a) { return @@ -380,20 +383,23 @@ protected: public slots: /** returns false iff not valid items present and save was aborted */ bool saveAllConfigs(); - void reloadTunnelsConfigAndUI(); + void SaveTunnelsConfig(); + void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus); + + //focus none + void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI(""); } + void addServerTunnelPushButtonReleased(); + void addClientTunnelPushButtonReleased(); private: QString datadir; QString confpath; QString tunconfpath; - std::list tunnelConfigs; + std::map tunnelConfigs; std::list tunnelPanes; - QWidget *tunnelsFormGridLayoutWidget; - QGridLayout *tunnelsFormGridLayout; - - void appendTunnelForms(); + void appendTunnelForms(std::string tunnelNameToFocus); void deleteTunnelForms(); @@ -427,6 +433,107 @@ private: options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);//TODO include into param } + void CreateDefaultI2CPOptions (I2CPParameters& param + /*TODO fill param*/) const + { + const int _INBOUND_TUNNEL_LENGTH = DEFAULT_INBOUND_TUNNEL_LENGTH; + param.setInbound_length(QString::number(_INBOUND_TUNNEL_LENGTH)); + const int _OUTBOUND_TUNNEL_LENGTH = DEFAULT_OUTBOUND_TUNNEL_LENGTH; + param.setOutbound_length(QString::number(_OUTBOUND_TUNNEL_LENGTH)); + const int _INBOUND_TUNNELS_QUANTITY = DEFAULT_INBOUND_TUNNELS_QUANTITY; + param.setInbound_quantity( QString::number(_INBOUND_TUNNELS_QUANTITY)); + const int _OUTBOUND_TUNNELS_QUANTITY = DEFAULT_OUTBOUND_TUNNELS_QUANTITY; + param.setOutbound_quantity(QString::number(_OUTBOUND_TUNNELS_QUANTITY)); + const int _TAGS_TO_SEND = DEFAULT_TAGS_TO_SEND; + param.setCrypto_tagsToSend(QString::number(_TAGS_TO_SEND)); + } + + + void DeleteTunnelNamed(std::string name) { + std::map::const_iterator it=tunnelConfigs.find(name); + if(it!=tunnelConfigs.end()){ + TunnelConfig* tc=it->second; + tunnelConfigs.erase(it); + delete tc; + SaveTunnelsConfig(); + reloadTunnelsConfigAndUI(""); + } + } + + std::string GenerateNewTunnelName() { + int i=1; + while(true){ + std::stringstream name; + name << "name" << i; + const std::string& str=name.str(); + if(tunnelConfigs.find(str)==tunnelConfigs.end())return str; + ++i; + } + } + + void CreateDefaultClientTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels () + std::string name=GenerateNewTunnelName(); + std::string type = I2P_TUNNELS_SECTION_TYPE_CLIENT; + std::string dest = "127.0.0.1"; + int port = 0; + std::string keys = ""; + std::string address = "127.0.0.1"; + int destinationPort = 0; + i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256; + // I2CP + I2CPParameters i2cpParameters; + CreateDefaultI2CPOptions (i2cpParameters); + + tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters, + dest, + port, + keys, + address, + destinationPort, + sigType); + + SaveTunnelsConfig(); + reloadTunnelsConfigAndUI(name); + } + + void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels () + std::string name=GenerateNewTunnelName(); + std::string type=I2P_TUNNELS_SECTION_TYPE_SERVER; + std::string host = "127.0.0.1"; + int port = 0; + std::string keys = ""; + int inPort = 0; + std::string accessList = ""; + std::string hostOverride = ""; + std::string webircpass = ""; + bool gzip = true; + i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256; + uint32_t maxConns = i2p::stream::DEFAULT_MAX_CONNS_PER_MIN; + std::string address = "127.0.0.1"; + bool isUniqueLocal = true; + + // I2CP + I2CPParameters i2cpParameters; + CreateDefaultI2CPOptions (i2cpParameters); + + tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters, + host, + port, + keys, + inPort, + accessList, + hostOverride, + webircpass, + gzip, + sigType, + maxConns, + address, + isUniqueLocal); + + + SaveTunnelsConfig(); + reloadTunnelsConfigAndUI(name); + } void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels () { @@ -479,13 +586,13 @@ private: I2CPParameters i2cpParameters; ReadI2CPOptions (section, options, i2cpParameters); - tunnelConfigs.push_back(new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters, + tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters, dest, port, keys, address, destinationPort, - sigType)); + sigType); } else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP @@ -528,7 +635,7 @@ private: while (comma != std::string::npos); } */ - tunnelConfigs.push_back(new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters, + tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters, host, port, keys, @@ -540,7 +647,7 @@ private: sigType, maxConns, address, - isUniqueLocal)); + isUniqueLocal); } else LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf);//TODO show err box and disable the tunn gui @@ -553,6 +660,16 @@ private: } } +private: + class TunnelsPageUpdateListenerMainWindowImpl : public TunnelsPageUpdateListener { + MainWindow* mainWindow; + public: + TunnelsPageUpdateListenerMainWindowImpl(MainWindow* mainWindow_):mainWindow(mainWindow_){} + virtual void updated(std::string oldName, TunnelConfig* tunConf); + virtual void needsDeleting(std::string oldName); + }; + + TunnelsPageUpdateListenerMainWindowImpl tunnelsPageUpdateListener; }; #endif // MAINWINDOW_H diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index b51f36cb..ca07c036 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -136,7 +136,7 @@ - 2 + 1 @@ -193,7 +193,7 @@ 0 0 701 - 450 + 400 @@ -231,8 +231,8 @@ 0 0 - 683 - 416 + 679 + 400 @@ -246,12 +246,13 @@ 10 11 - 661 - 3048 + 679 + 2962 + @@ -281,7 +282,7 @@ Enabled - + 0 @@ -290,9 +291,9 @@ 31 - + - + IP address to listen on: @@ -302,7 +303,7 @@ - + Qt::Horizontal @@ -316,18 +317,18 @@ - + 0 70 661 - 342 + 31 - + - + Port to listen on: @@ -344,7 +345,7 @@ - + Qt::Horizontal @@ -359,6 +360,9 @@ + + + @@ -1877,13 +1881,13 @@ 0 - 120 + 180 16777215 - 120 + 180 @@ -1918,31 +1922,33 @@ 0 40 391 - 21 + 42 - Make direct I2P connections only to routers in specified Family: + Make direct I2P connections only to +routers in specified Family: 0 - 60 + 82 661 - 16 + 42 - Make direct I2P connections only to routers specified here. Comma separated list of base64 identities: + Make direct I2P connections only to routers specified here. +Comma separated list of base64 identities: 0 - 80 + 124 661 23 @@ -1952,7 +1958,7 @@ 0 - 100 + 147 661 21