Merge pull request #948 from hypnosis-i2p/openssl

fixes #945 and #935
pull/950/head
orignal 7 years ago committed by GitHub
commit 5ae93d852e

@ -3,14 +3,15 @@
#include "SignatureTypeComboboxFactory.h" #include "SignatureTypeComboboxFactory.h"
#include "QVBoxLayout" #include "QVBoxLayout"
ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf): ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow):
TunnelPane(tunnelsPageUpdateListener, tunconf) {} TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_, mainWindow) {}
void ClientTunnelPane::setGroupBoxTitle(const QString & title) { void ClientTunnelPane::setGroupBoxTitle(const QString & title) {
clientTunnelNameGroupBox->setTitle(title); clientTunnelNameGroupBox->setTitle(title);
} }
void ClientTunnelPane::deleteClientTunnelForm() { void ClientTunnelPane::deleteClientTunnelForm() {
TunnelPane::deleteTunnelForm();
delete clientTunnelNameGroupBox; delete clientTunnelNameGroupBox;
clientTunnelNameGroupBox=nullptr; clientTunnelNameGroupBox=nullptr;

@ -14,7 +14,7 @@ class TunnelPane;
class ClientTunnelPane : public TunnelPane { class ClientTunnelPane : public TunnelPane {
Q_OBJECT Q_OBJECT
public: public:
ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf); ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow);
virtual ~ClientTunnelPane(){} virtual ~ClientTunnelPane(){}
virtual ServerTunnelPane* asServerTunnelPane(); virtual ServerTunnelPane* asServerTunnelPane();
virtual ClientTunnelPane* asClientTunnelPane(); virtual ClientTunnelPane* asClientTunnelPane();
@ -68,6 +68,7 @@ private:
} }
protected: protected:
virtual bool applyDataFromUIToTunnelConfig() { virtual bool applyDataFromUIToTunnelConfig() {
QString cannotSaveSettings = QApplication::tr("Cannot save settings.");
bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); bool ok=TunnelPane::applyDataFromUIToTunnelConfig();
if(!ok)return false; if(!ok)return false;
ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig(); ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig();
@ -78,7 +79,11 @@ protected:
auto portStr=portLineEdit->text(); auto portStr=portLineEdit->text();
int portInt=portStr.toInt(&ok); int portInt=portStr.toInt(&ok);
if(!ok)return false;
if(!ok){
highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit);
return false;
}
ctc->setport(portInt); ctc->setport(portInt);
ctc->setkeys(keysLineEdit->text().toStdString()); ctc->setkeys(keysLineEdit->text().toStdString());
@ -87,7 +92,10 @@ protected:
auto dportStr=destinationPortLineEdit->text(); auto dportStr=destinationPortLineEdit->text();
int dportInt=dportStr.toInt(&ok); int dportInt=dportStr.toInt(&ok);
if(!ok)return false; if(!ok){
highlightWrongInput(QApplication::tr("Bad destinationPort, must be int.")+" "+cannotSaveSettings,destinationPortLineEdit);
return false;
}
ctc->setdestinationPort(dportInt); ctc->setdestinationPort(dportInt);
ctc->setsigType(readSigTypeComboboxUI(sigTypeComboBox)); ctc->setsigType(readSigTypeComboboxUI(sigTypeComboBox));

@ -2,8 +2,8 @@
#include "ClientContext.h" #include "ClientContext.h"
#include "SignatureTypeComboboxFactory.h" #include "SignatureTypeComboboxFactory.h"
ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf): ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow):
TunnelPane(tunnelsPageUpdateListener, tunconf) {} TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_, mainWindow) {}
void ServerTunnelPane::setGroupBoxTitle(const QString & title) { void ServerTunnelPane::setGroupBoxTitle(const QString & title) {
serverTunnelNameGroupBox->setTitle(title); serverTunnelNameGroupBox->setTitle(title);
@ -266,6 +266,7 @@ int ServerTunnelPane::appendServerTunnelForm(
} }
void ServerTunnelPane::deleteServerTunnelForm() { void ServerTunnelPane::deleteServerTunnelForm() {
TunnelPane::deleteTunnelForm();
delete serverTunnelNameGroupBox;//->deleteLater(); delete serverTunnelNameGroupBox;//->deleteLater();
serverTunnelNameGroupBox=nullptr; serverTunnelNameGroupBox=nullptr;

@ -1,9 +1,6 @@
#ifndef SERVERTUNNELPANE_H #ifndef SERVERTUNNELPANE_H
#define SERVERTUNNELPANE_H #define SERVERTUNNELPANE_H
#include "TunnelPane.h"
#include "TunnelsPageUpdateListener.h"
#include <QtCore/QVariant> #include <QtCore/QVariant>
#include <QtWidgets/QAction> #include <QtWidgets/QAction>
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
@ -23,6 +20,9 @@
#include "assert.h" #include "assert.h"
#include "TunnelPane.h"
#include "TunnelsPageUpdateListener.h"
class ServerTunnelConfig; class ServerTunnelConfig;
class ClientTunnelPane; class ClientTunnelPane;
@ -31,7 +31,7 @@ class ServerTunnelPane : public TunnelPane {
Q_OBJECT Q_OBJECT
public: public:
ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf); ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow);
virtual ~ServerTunnelPane(){} virtual ~ServerTunnelPane(){}
virtual ServerTunnelPane* asServerTunnelPane(); virtual ServerTunnelPane* asServerTunnelPane();
@ -119,6 +119,7 @@ private:
protected: protected:
virtual bool applyDataFromUIToTunnelConfig() { virtual bool applyDataFromUIToTunnelConfig() {
QString cannotSaveSettings = QApplication::tr("Cannot save settings.");
bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); bool ok=TunnelPane::applyDataFromUIToTunnelConfig();
if(!ok)return false; if(!ok)return false;
ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig(); ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig();
@ -127,14 +128,20 @@ protected:
auto portStr=portLineEdit->text(); auto portStr=portLineEdit->text();
int portInt=portStr.toInt(&ok); int portInt=portStr.toInt(&ok);
if(!ok)return false; if(!ok){
highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit);
return false;
}
stc->setport(portInt); stc->setport(portInt);
stc->setkeys(keysLineEdit->text().toStdString()); stc->setkeys(keysLineEdit->text().toStdString());
auto str=inPortLineEdit->text(); auto str=inPortLineEdit->text();
int inPortInt=str.toInt(&ok); int inPortInt=str.toInt(&ok);
if(!ok)return false; if(!ok){
highlightWrongInput(QApplication::tr("Bad inPort, must be int.")+" "+cannotSaveSettings,inPortLineEdit);
return false;
}
stc->setinPort(inPortInt); stc->setinPort(inPortInt);
stc->setaccessList(accessListLineEdit->text().toStdString()); stc->setaccessList(accessListLineEdit->text().toStdString());
@ -147,7 +154,10 @@ protected:
auto mcStr=maxConnsLineEdit->text(); auto mcStr=maxConnsLineEdit->text();
uint32_t mcInt=(uint32_t)mcStr.toInt(&ok); uint32_t mcInt=(uint32_t)mcStr.toInt(&ok);
if(!ok)return false; if(!ok){
highlightWrongInput(QApplication::tr("Bad maxConns, must be int.")+" "+cannotSaveSettings,maxConnsLineEdit);
return false;
}
stc->setmaxConns(mcInt); stc->setmaxConns(mcInt);
stc->setgzip(gzipCheckBox->isChecked()); stc->setgzip(gzipCheckBox->isChecked());

@ -21,7 +21,7 @@ void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) {
if (i2cpParameters.getCrypto_tagsToSend().toUShort() != i2p::client::DEFAULT_TAGS_TO_SEND) if (i2cpParameters.getCrypto_tagsToSend().toUShort() != i2p::client::DEFAULT_TAGS_TO_SEND)
out << i2p::client::I2CP_PARAM_TAGS_TO_SEND << "=" out << i2p::client::I2CP_PARAM_TAGS_TO_SEND << "="
<< i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n"; << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n";
if (!i2cpParameters.getExplicitPeers().isEmpty()) if (!i2cpParameters.getExplicitPeers().isEmpty()) //todo #947
out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "=" out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "="
<< i2cpParameters.getExplicitPeers().toStdString() << "\n"; << i2cpParameters.getExplicitPeers().toStdString() << "\n";
out << "\n"; out << "\n";

@ -1,8 +1,13 @@
#include "TunnelPane.h" #include "TunnelPane.h"
#include "QMessageBox" #include "QMessageBox"
#include "mainwindow.h"
TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_): TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_):
QObject(), QObject(),
mainWindow(mainWindow_),
wrongInputPane(wrongInputPane_),
wrongInputLabel(wrongInputLabel_),
tunnelConfig(tunnelConfig_), tunnelConfig(tunnelConfig_),
tunnelsPageUpdateListener(tunnelsPageUpdateListener_), tunnelsPageUpdateListener(tunnelsPageUpdateListener_),
gridLayoutWidget_2(nullptr) {} gridLayoutWidget_2(nullptr) {}
@ -179,7 +184,7 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters,
void TunnelPane::updated() { void TunnelPane::updated() {
std::string oldName=tunnelConfig->getName(); std::string oldName=tunnelConfig->getName();
if(!applyDataFromUIToTunnelConfig())return;//TODO visualise bad input if(!applyDataFromUIToTunnelConfig())return;
tunnelsPageUpdateListener->updated(oldName, tunnelConfig); tunnelsPageUpdateListener->updated(oldName, tunnelConfig);
} }
@ -218,3 +223,14 @@ QString TunnelPane::readTunnelTypeComboboxData() {
i2p::data::SigningKeyType TunnelPane::readSigTypeComboboxUI(QComboBox* sigTypeComboBox) { i2p::data::SigningKeyType TunnelPane::readSigTypeComboboxUI(QComboBox* sigTypeComboBox) {
return (i2p::data::SigningKeyType) sigTypeComboBox->currentData().toInt(); return (i2p::data::SigningKeyType) sigTypeComboBox->currentData().toInt();
} }
void TunnelPane::deleteTunnelForm() {
widgetlocks.deleteListeners();
}
void TunnelPane::highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) {
wrongInputPane->setVisible(true);
wrongInputLabel->setText(warningText);
if(controlWithWrongInput)controlWithWrongInput->setFocus();
mainWindow->showTunnelsPage();
}

@ -23,18 +23,28 @@ class ClientTunnelPane;
class TunnelConfig; class TunnelConfig;
class I2CPParameters; class I2CPParameters;
class MainWindow;
class TunnelPane : public QObject { class TunnelPane : public QObject {
Q_OBJECT Q_OBJECT
public: public:
TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf); TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_);
virtual ~TunnelPane(){} virtual ~TunnelPane(){}
void deleteTunnelForm();
void hideWrongInputLabel() const { wrongInputPane->setVisible(false); }
void highlightWrongInput(QString warningText, QWidget* controlWithWrongInput);
virtual ServerTunnelPane* asServerTunnelPane()=0; virtual ServerTunnelPane* asServerTunnelPane()=0;
virtual ClientTunnelPane* asClientTunnelPane()=0; virtual ClientTunnelPane* asClientTunnelPane()=0;
protected: protected:
MainWindow* mainWindow;
QWidget * wrongInputPane;
QLabel* wrongInputLabel;
TunnelConfig* tunnelConfig; TunnelConfig* tunnelConfig;
widgetlockregistry widgetlocks; widgetlockregistry widgetlocks;
TunnelsPageUpdateListener* tunnelsPageUpdateListener; TunnelsPageUpdateListener* tunnelsPageUpdateListener;
@ -82,8 +92,10 @@ protected:
//should be created by factory //should be created by factory
i2p::data::SigningKeyType readSigTypeComboboxUI(QComboBox* sigTypeComboBox); i2p::data::SigningKeyType readSigTypeComboboxUI(QComboBox* sigTypeComboBox);
public:
//returns false when invalid data at UI //returns false when invalid data at UI
virtual bool applyDataFromUIToTunnelConfig() { virtual bool applyDataFromUIToTunnelConfig() {
hideWrongInputLabel();
tunnelConfig->setName(nameLineEdit->text().toStdString()); tunnelConfig->setName(nameLineEdit->text().toStdString());
tunnelConfig->setType(readTunnelTypeComboboxData()); tunnelConfig->setType(readTunnelTypeComboboxData());
I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters(); I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters();
@ -94,7 +106,7 @@ protected:
i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text()); i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text());
return true; return true;
} }
protected:
void setupTunnelPane( void setupTunnelPane(
TunnelConfig* tunnelConfig, TunnelConfig* tunnelConfig,
QGroupBox *tunnelGroupBox, QGroupBox *tunnelGroupBox,

@ -929,7 +929,7 @@
<item> <item>
<widget class="QLabel" name="label_7"> <widget class="QLabel" name="label_7">
<property name="text"> <property name="text">
<string>Port (leave empty to auto-assign):</string> <string>Port (leave 0 to auto-assign):</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -1500,7 +1500,7 @@
<item> <item>
<widget class="QLabel" name="bandwidthLabel"> <widget class="QLabel" name="bandwidthLabel">
<property name="text"> <property name="text">
<string>Bandwidth limit (integer):</string> <string>Bandwidth limit (integer or a letter):</string>
</property> </property>
</widget> </widget>
</item> </item>

@ -82,6 +82,11 @@ MainWindow::MainWindow(QWidget *parent) :
ui->settingsContents->setAutoFillBackground(true); ui->settingsContents->setAutoFillBackground(true);
ui->settingsContents->setPalette(pal); ui->settingsContents->setPalette(pal);
*/ */
QPalette pal(palette());
pal.setColor(QPalette::Background, Qt::red);
ui->wrongInputLabel->setAutoFillBackground(true);
ui->wrongInputLabel->setPalette(pal);
ui->wrongInputLabel->setVisible(false);
#ifndef ANDROID #ifndef ANDROID
createActions(); createActions();
@ -565,7 +570,7 @@ void MainWindow::initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, Q
configItems.append(new UInt16StringItem(option, numberLineEdit, fieldNameTranslated)); configItems.append(new UInt16StringItem(option, numberLineEdit, fieldNameTranslated));
} }
void MainWindow::initStringBox(ConfigOption option, QLineEdit* lineEdit){ void MainWindow::initStringBox(ConfigOption option, QLineEdit* lineEdit){
configItems.append(new BaseStringItem(option, lineEdit)); configItems.append(new BaseStringItem(option, lineEdit, QString()));
} }
NonGUIOptionItem* MainWindow::initNonGUIOption(ConfigOption option) { NonGUIOptionItem* MainWindow::initNonGUIOption(ConfigOption option) {
NonGUIOptionItem * retValue; NonGUIOptionItem * retValue;
@ -623,6 +628,9 @@ void MainWindow::loadAllConfigs(){
} }
/** returns false iff not valid items present and save was aborted */ /** returns false iff not valid items present and save was aborted */
bool MainWindow::saveAllConfigs(){ bool MainWindow::saveAllConfigs(){
QString cannotSaveSettings = QApplication::tr("Cannot save settings.");
ui->wrongInputLabel->setVisible(false);
programOptionsWriterCurrentSection=""; programOptionsWriterCurrentSection="";
/*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file")); /*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file"));
else logOption->optionValue=boost::any(std::string("stdout"));*/ else logOption->optionValue=boost::any(std::string("stdout"));*/
@ -632,7 +640,10 @@ bool MainWindow::saveAllConfigs(){
std::stringstream out; std::stringstream out;
for(QList<MainWindowItem*>::iterator it = configItems.begin(); it!= configItems.end(); ++it) { for(QList<MainWindowItem*>::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
MainWindowItem* item = *it; MainWindowItem* item = *it;
if(!item->isValid()) return false; if(!item->isValid()){
highlightWrongInput(QApplication::tr("Invalid value for")+" "+item->getConfigOption().section+"::"+item->getConfigOption().option+". "+item->getRequirementToBeValid()+" "+cannotSaveSettings, item->getWidgetToFocus());
return false;
}
} }
for(QList<MainWindowItem*>::iterator it = configItems.begin(); it!= configItems.end(); ++it) { for(QList<MainWindowItem*>::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
@ -688,27 +699,33 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) {
TunnelConfig* tunconf = it->second; TunnelConfig* tunconf = it->second;
ServerTunnelConfig* stc = tunconf->asServerTunnelConfig(); ServerTunnelConfig* stc = tunconf->asServerTunnelConfig();
if(stc){ if(stc){
ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc); ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc, ui->wrongInputLabel, ui->wrongInputLabel, this);
int h=tunnelPane->appendServerTunnelForm(stc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); int h=tunnelPane->appendServerTunnelForm(stc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height);
height+=h; height+=h;
qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size();
tunnelPanes.push_back(tunnelPane); tunnelPanes.push_back(tunnelPane);
if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus(); if(name==tunnelNameToFocus){
tunnelPane->getNameLineEdit()->setFocus();
//todo ui->settingsScrollArea->###scroll
}
continue; continue;
} }
ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig(); ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig();
if(ctc){ if(ctc){
ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc); ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc, ui->wrongInputLabel, ui->wrongInputLabel, this);
int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height);
height+=h; height+=h;
qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size();
tunnelPanes.push_back(tunnelPane); tunnelPanes.push_back(tunnelPane);
if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus(); if(name==tunnelNameToFocus){
tunnelPane->getNameLineEdit()->setFocus();
//todo ui->settingsScrollArea->###scroll
}
continue; continue;
} }
throw "unknown TunnelConfig subtype"; throw "unknown TunnelConfig subtype";
} }
qDebug() << "tun.setting height:" << height; //qDebug() << "tun.setting height:" << height;
ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height)); ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height));
QList<QWidget*> childWidgets = ui->tunnelsScrollAreaWidgetContents->findChildren<QWidget*>(); QList<QWidget*> childWidgets = ui->tunnelsScrollAreaWidgetContents->findChildren<QWidget*>();
foreach(QWidget* widget, childWidgets) foreach(QWidget* widget, childWidgets)
@ -748,6 +765,15 @@ void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) {
void MainWindow::SaveTunnelsConfig() { void MainWindow::SaveTunnelsConfig() {
std::stringstream out; std::stringstream out;
//validate and show red if wrong
for (std::list<TunnelPane*>::iterator it=tunnelPanes.begin(); it!=tunnelPanes.end(); ++it) {
TunnelPane* tunpane = *it;
if(!tunpane->applyDataFromUIToTunnelConfig()) {
//!valid
return;
}
}
for (std::map<std::string,TunnelConfig*>::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { for (std::map<std::string,TunnelConfig*>::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) {
const std::string& name = it->first; const std::string& name = it->first;
TunnelConfig* tunconf = it->second; TunnelConfig* tunconf = it->second;
@ -777,7 +803,7 @@ void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string ol
if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it); if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it);
mainWindow->tunnelConfigs[tunConf->getName()]=tunConf; mainWindow->tunnelConfigs[tunConf->getName()]=tunConf;
} }
mainWindow->SaveTunnelsConfig(); mainWindow->saveAllConfigs();
} }
void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){ void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){
@ -833,3 +859,10 @@ void MainWindow::anchorClickedHandler(const QUrl & link) {
void MainWindow::backClickedFromChild() { void MainWindow::backClickedFromChild() {
showStatusPage(statusPage); showStatusPage(statusPage);
} }
void MainWindow::highlightWrongInput(QString warningText, QWidget* widgetToFocus) {
ui->wrongInputLabel->setVisible(true);
ui->wrongInputLabel->setText(warningText);
if(widgetToFocus)widgetToFocus->setFocus();
showSettingsPage();
}

@ -93,8 +93,13 @@ class MainWindow;
class MainWindowItem : public QObject { class MainWindowItem : public QObject {
Q_OBJECT Q_OBJECT
ConfigOption option; ConfigOption option;
QWidget* widgetToFocus;
QString requirementToBeValid;
public: public:
MainWindowItem(ConfigOption option_) : option(option_) {} MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_) : option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_) {}
QWidget* getWidgetToFocus(){return widgetToFocus;}
QString& getRequirementToBeValid() { return requirementToBeValid; }
ConfigOption& getConfigOption() { return option; }
boost::any optionValue; boost::any optionValue;
virtual ~MainWindowItem(){} virtual ~MainWindowItem(){}
virtual void installListeners(MainWindow *mainWindow); virtual void installListeners(MainWindow *mainWindow);
@ -145,7 +150,7 @@ public:
}; };
class NonGUIOptionItem : public MainWindowItem { class NonGUIOptionItem : public MainWindowItem {
public: public:
NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_) {}; NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_, nullptr, QString()) {};
virtual ~NonGUIOptionItem(){} virtual ~NonGUIOptionItem(){}
virtual bool isValid() { return true; } virtual bool isValid() { return true; }
}; };
@ -153,7 +158,7 @@ class BaseStringItem : public MainWindowItem {
Q_OBJECT Q_OBJECT
public: public:
QLineEdit* lineEdit; QLineEdit* lineEdit;
BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_) : MainWindowItem(option_), lineEdit(lineEdit_){}; BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_) : MainWindowItem(option_, lineEdit_, requirementToBeValid_), lineEdit(lineEdit_){};
virtual ~BaseStringItem(){} virtual ~BaseStringItem(){}
virtual void installListeners(MainWindow *mainWindow); virtual void installListeners(MainWindow *mainWindow);
virtual QString toString(){ virtual QString toString(){
@ -175,7 +180,7 @@ class FileOrFolderChooserItem : public BaseStringItem {
public: public:
QPushButton* browsePushButton; QPushButton* browsePushButton;
FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) : FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) :
BaseStringItem(option_, lineEdit_), browsePushButton(browsePushButton_) {} BaseStringItem(option_, lineEdit_, QString()), browsePushButton(browsePushButton_) {}
virtual ~FileOrFolderChooserItem(){} virtual ~FileOrFolderChooserItem(){}
}; };
class FileChooserItem : public FileOrFolderChooserItem { class FileChooserItem : public FileOrFolderChooserItem {
@ -201,7 +206,7 @@ public:
class ComboBoxItem : public MainWindowItem { class ComboBoxItem : public MainWindowItem {
public: public:
QComboBox* comboBox; QComboBox* comboBox;
ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_), comboBox(comboBox_){}; ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_,comboBox_,QString()), comboBox(comboBox_){};
virtual ~ComboBoxItem(){} virtual ~ComboBoxItem(){}
virtual void installListeners(MainWindow *mainWindow); virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption()=0; virtual void loadFromConfigOption()=0;
@ -260,7 +265,7 @@ public:
class CheckBoxItem : public MainWindowItem { class CheckBoxItem : public MainWindowItem {
public: public:
QCheckBox* checkBox; QCheckBox* checkBox;
CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_), checkBox(checkBox_){}; CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_,checkBox_,QString()), checkBox(checkBox_){};
virtual ~CheckBoxItem(){} virtual ~CheckBoxItem(){}
virtual void installListeners(MainWindow *mainWindow); virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption(){ virtual void loadFromConfigOption(){
@ -276,58 +281,77 @@ public:
class BaseFormattedStringItem : public BaseStringItem { class BaseFormattedStringItem : public BaseStringItem {
public: public:
QString fieldNameTranslated; QString fieldNameTranslated;
BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, QString requirementToBeValid_) :
BaseStringItem(option_, lineEdit_), fieldNameTranslated(fieldNameTranslated_) {}; BaseStringItem(option_, lineEdit_, requirementToBeValid_), fieldNameTranslated(fieldNameTranslated_) {};
virtual ~BaseFormattedStringItem(){} virtual ~BaseFormattedStringItem(){}
virtual bool isValid()=0; virtual bool isValid()=0;
}; };
class IntegerStringItem : public BaseFormattedStringItem { class IntegerStringItem : public BaseFormattedStringItem {
public: public:
IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be a valid integer.")) {};
virtual ~IntegerStringItem(){} virtual ~IntegerStringItem(){}
virtual bool isValid(){return true;} virtual bool isValid(){
auto str=lineEdit->text();
bool ok;
str.toInt(&ok);
return ok;
}
virtual QString toString(){return QString::number(boost::any_cast<int>(optionValue));} virtual QString toString(){return QString::number(boost::any_cast<int>(optionValue));}
virtual boost::any fromString(QString s){return boost::any(std::stoi(s.toStdString()));} virtual boost::any fromString(QString s){return boost::any(std::stoi(s.toStdString()));}
}; };
class UShortStringItem : public BaseFormattedStringItem { class UShortStringItem : public BaseFormattedStringItem {
public: public:
UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned short integer.")) {};
virtual ~UShortStringItem(){} virtual ~UShortStringItem(){}
virtual bool isValid(){return true;} virtual bool isValid(){
auto str=lineEdit->text();
bool ok;
str.toUShort(&ok);
return ok;
}
virtual QString toString(){return QString::number(boost::any_cast<unsigned short>(optionValue));} virtual QString toString(){return QString::number(boost::any_cast<unsigned short>(optionValue));}
virtual boost::any fromString(QString s){return boost::any((unsigned short)std::stoi(s.toStdString()));} virtual boost::any fromString(QString s){return boost::any((unsigned short)std::stoi(s.toStdString()));}
}; };
class UInt32StringItem : public BaseFormattedStringItem { class UInt32StringItem : public BaseFormattedStringItem {
public: public:
UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 32-bit integer.")) {};
virtual ~UInt32StringItem(){} virtual ~UInt32StringItem(){}
virtual bool isValid(){return true;} virtual bool isValid(){
auto str=lineEdit->text();
bool ok;
str.toUInt(&ok);
return ok;
}
virtual QString toString(){return QString::number(boost::any_cast<uint32_t>(optionValue));} virtual QString toString(){return QString::number(boost::any_cast<uint32_t>(optionValue));}
virtual boost::any fromString(QString s){return boost::any((uint32_t)std::stoi(s.toStdString()));} virtual boost::any fromString(QString s){return boost::any((uint32_t)std::stoi(s.toStdString()));}
}; };
class UInt16StringItem : public BaseFormattedStringItem { class UInt16StringItem : public BaseFormattedStringItem {
public: public:
UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer.")) {};
virtual ~UInt16StringItem(){} virtual ~UInt16StringItem(){}
virtual bool isValid(){return true;} virtual bool isValid(){
auto str=lineEdit->text();
bool ok;
str.toUShort(&ok);
return ok;
}
virtual QString toString(){return QString::number(boost::any_cast<uint16_t>(optionValue));} virtual QString toString(){return QString::number(boost::any_cast<uint16_t>(optionValue));}
virtual boost::any fromString(QString s){return boost::any((uint16_t)std::stoi(s.toStdString()));} virtual boost::any fromString(QString s){return boost::any((uint16_t)std::stoi(s.toStdString()));}
}; };
class IPAddressStringItem : public BaseFormattedStringItem { class IPAddressStringItem : public BaseFormattedStringItem {
public: public:
IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be an IPv4 address")) {};
virtual bool isValid(){return true;} virtual bool isValid(){return true;}//todo
}; };
class TCPPortStringItem : public UShortStringItem { class TCPPortStringItem : public UShortStringItem {
public: public:
TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
UShortStringItem(option_, lineEdit_, fieldNameTranslated_) {}; UShortStringItem(option_, lineEdit_, fieldNameTranslated_) {};
virtual bool isValid(){return true;}
}; };
namespace Ui { namespace Ui {
@ -354,6 +378,8 @@ public:
void setI2PController(i2p::qt::Controller* controller_); void setI2PController(i2p::qt::Controller* controller_);
void highlightWrongInput(QString warningText, QWidget* widgetToFocus);
//typedef std::function<QString ()> DefaultValueGetter; //typedef std::function<QString ()> DefaultValueGetter;
//#ifndef ANDROID //#ifndef ANDROID
@ -385,7 +411,7 @@ private slots:
void runPeerTest(); void runPeerTest();
void enableTransit(); void enableTransit();
void disableTransit(); void disableTransit();
public slots:
void showStatus_local_destinations_Page(); void showStatus_local_destinations_Page();
void showStatus_leasesets_Page(); void showStatus_leasesets_Page();
void showStatus_tunnels_Page(); void showStatus_tunnels_Page();
@ -546,9 +572,9 @@ private:
TunnelConfig* tc=it->second; TunnelConfig* tc=it->second;
tunnelConfigs.erase(it); tunnelConfigs.erase(it);
delete tc; delete tc;
SaveTunnelsConfig();
reloadTunnelsConfigAndUI("");
} }
saveAllConfigs();
reloadTunnelsConfigAndUI("");
} }
std::string GenerateNewTunnelName() { std::string GenerateNewTunnelName() {
@ -583,7 +609,7 @@ private:
destinationPort, destinationPort,
sigType); sigType);
SaveTunnelsConfig(); saveAllConfigs();
reloadTunnelsConfigAndUI(name); reloadTunnelsConfigAndUI(name);
} }
@ -622,7 +648,7 @@ private:
isUniqueLocal); isUniqueLocal);
SaveTunnelsConfig(); saveAllConfigs();
reloadTunnelsConfigAndUI(name); reloadTunnelsConfigAndUI(name);
} }

@ -50,7 +50,7 @@
<x>10</x> <x>10</x>
<y>10</y> <y>10</y>
<width>888</width> <width>888</width>
<height>530</height> <height>555</height>
</rect> </rect>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
@ -167,6 +167,442 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="wrongInputLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Light">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="Midlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>63</green>
<blue>63</blue>
</color>
</brush>
</colorrole>
<colorrole role="Dark">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Mid">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="BrightText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="AlternateBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Light">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="Midlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>63</green>
<blue>63</blue>
</color>
</brush>
</colorrole>
<colorrole role="Dark">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Mid">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="BrightText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="AlternateBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Light">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="Midlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>63</green>
<blue>63</blue>
</color>
</brush>
</colorrole>
<colorrole role="Dark">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Mid">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="BrightText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="AlternateBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>10</number>
</property>
</widget>
</item>
<item> <item>
<widget class="QStackedWidget" name="stackedWidget"> <widget class="QStackedWidget" name="stackedWidget">
<property name="sizePolicy"> <property name="sizePolicy">
@ -178,7 +614,7 @@
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>0</width> <width>0</width>
<height>528</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="maximumSize">
@ -496,6 +932,8 @@
</widget> </widget>
</item> </item>
</layout> </layout>
</item>
</layout>
</widget> </widget>
</widget> </widget>
</widget> </widget>

@ -12,6 +12,7 @@ class widgetlock : public QObject {
private: private:
QWidget* widget; QWidget* widget;
QPushButton* lockButton; QPushButton* lockButton;
public slots: public slots:
void lockButtonClicked(bool) { void lockButtonClicked(bool) {
bool wasEnabled = widget->isEnabled(); bool wasEnabled = widget->isEnabled();
@ -25,7 +26,8 @@ public:
lockButton->setText(lockButton->tr("Edit")); lockButton->setText(lockButton->tr("Edit"));
QObject::connect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool))); QObject::connect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool)));
} }
virtual ~widgetlock() { virtual ~widgetlock() {}
void deleteListener() {
QObject::disconnect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool))); QObject::disconnect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool)));
} }
}; };

@ -9,15 +9,19 @@ class widgetlockregistry {
public: public:
widgetlockregistry() : locks() {} widgetlockregistry() : locks() {}
virtual ~widgetlockregistry() { virtual ~widgetlockregistry() {}
void add(widgetlock* lock) {
locks.push_back(lock);
}
void deleteListeners() {
while(!locks.empty()) { while(!locks.empty()) {
delete locks.back(); widgetlock* lock = locks.back();
lock->deleteListener();
delete lock;
locks.pop_back(); locks.pop_back();
} }
} }
void add(widgetlock* lock) {
locks.push_back(lock);
}
}; };
#endif // WIDGETLOCKREGISTRY_H #endif // WIDGETLOCKREGISTRY_H

Loading…
Cancel
Save