logStream_, QWidget *parent) :
QMainWindow(parent)
+ ,currentLocalDestinationB32("")
,logStream(logStream_)
,delayedSaveManagerPtr(new DelayedSaveManagerImpl())
,dataSerial(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL)
@@ -65,6 +78,10 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
statusButtonsUI->setupUi(ui->statusButtonsPane);
routerCommandsUI->setupUi(routerCommandsParent);
uiSettings->setupUi(ui->settingsContents);
+
+ ui->aboutHrefLabel->setText(""
+ "i2pd_qt
Version " I2PD_VERSION " · About...
");
+
routerCommandsParent->hide();
ui->verticalLayout_2->addWidget(routerCommandsParent);
//,statusHtmlUI(new Ui::StatusHtmlPaneForm)
@@ -76,15 +93,16 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
setWindowTitle(QApplication::translate("AppTitle","I2PD"));
//TODO handle resizes and change the below into resize() call
- setFixedHeight(550);
- ui->centralWidget->setFixedHeight(550);
+ constexpr auto WINDOW_HEIGHT = 610;
+ setFixedHeight(WINDOW_HEIGHT);
+ ui->centralWidget->setFixedHeight(WINDOW_HEIGHT);
onResize();
ui->stackedWidget->setCurrentIndex(0);
ui->settingsScrollArea->resize(uiSettings->settingsContentsQVBoxLayout->sizeHint().width()+10,380);
//QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar();
- int w = 683;
- int h = 4550;
+ constexpr auto w = 683;
+ constexpr auto h = 4550;
ui->settingsContents->setFixedSize(w, h);
ui->settingsContents->setGeometry(QRect(0,0,w,h));
@@ -118,6 +136,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
//childTextBrowser->setOpenExternalLinks(false);
childTextBrowser->setOpenLinks(false);
connect(textBrowser, SIGNAL(anchorClicked(const QUrl&)), this, SLOT(anchorClickedHandler(const QUrl&)));
+ connect(childTextBrowser, SIGNAL(anchorClicked(const QUrl&)), this, SLOT(anchorClickedHandler(const QUrl&)));
pageWithBackButton = new PageWithBackButton(this, childTextBrowser);
ui->verticalLayout_2->addWidget(pageWithBackButton);
pageWithBackButton->hide();
@@ -143,6 +162,8 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
QObject::connect(routerCommandsUI->acceptTransitTunnelsPushButton, SIGNAL(released()), this, SLOT(enableTransit()));
QObject::connect(routerCommandsUI->declineTransitTunnelsPushButton, SIGNAL(released()), this, SLOT(disableTransit()));
+ QObject::connect(ui->aboutHrefLabel, SIGNAL(linkActivated(const QString &)), this, SLOT(showAboutBox(const QString &)));
+
QObject::connect(ui->logViewerPushButton, SIGNAL(released()), this, SLOT(showLogViewerPage()));
QObject::connect(ui->settingsPagePushButton, SIGNAL(released()), this, SLOT(showSettingsPage()));
@@ -158,9 +179,9 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
# define OPTION(section,option,defaultValueGetter) ConfigOption(QString(section),QString(option))
- initFileChooser( OPTION("","conf",[](){return "";}), uiSettings->configFileLineEdit, uiSettings->configFileBrowsePushButton);
- initFileChooser( OPTION("","tunconf",[](){return "";}), uiSettings->tunnelsConfigFileLineEdit, uiSettings->tunnelsConfigFileBrowsePushButton);
- initFileChooser( OPTION("","pidfile",[]{return "";}), uiSettings->pidFileLineEdit, uiSettings->pidFileBrowsePushButton);
+ initFileChooser( OPTION("","conf",[](){return "";}), uiSettings->configFileLineEdit, uiSettings->configFileBrowsePushButton, false, true);
+ initFileChooser( OPTION("","tunconf",[](){return "";}), uiSettings->tunnelsConfigFileLineEdit, uiSettings->tunnelsConfigFileBrowsePushButton, false);
+ initFileChooser( OPTION("","pidfile",[]{return "";}), uiSettings->pidFileLineEdit, uiSettings->pidFileBrowsePushButton, false);
uiSettings->logDestinationComboBox->clear();
uiSettings->logDestinationComboBox->insertItems(0, QStringList()
@@ -169,9 +190,15 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
<< QApplication::translate("MainWindow", "file", 0)
);
initLogDestinationCombobox( OPTION("","log",[]{return "";}), uiSettings->logDestinationComboBox);
+#ifdef I2PD_QT_RELEASE
+ uiSettings->logDestinationComboBox->setEnabled(false); // #1593
+#endif
- logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), uiSettings->logFileLineEdit, uiSettings->logFileBrowsePushButton);
+ logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), uiSettings->logFileLineEdit, uiSettings->logFileBrowsePushButton, false);
initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), uiSettings->logLevelComboBox);
+
+ QObject::connect(uiSettings->logLevelComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(syncLogLevel(int)));
+
initCheckBox( OPTION("","logclftime",[]{return "false";}), uiSettings->logclftimeCheckBox);//"Write full CLF-formatted date and time to log (default: write only time)"
initFolderChooser( OPTION("","datadir",[]{return "";}), uiSettings->dataFolderLineEdit, uiSettings->dataFolderBrowsePushButton);
initIPAddressBox( OPTION("","host",[]{return "";}), uiSettings->routerExternalHostLineEdit, tr("Router external address -> Host"));
@@ -213,7 +240,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
initIPAddressBox( OPTION("httpproxy","address",[]{return "";}), uiSettings->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address"));
initTCPPortBox( OPTION("httpproxy","port",[]{return "4444";}), uiSettings->httpProxyPortLineEdit, tr("HTTP proxy -> Port"));
initCheckBox( OPTION("httpproxy","addresshelper",[]{return "true";}), uiSettings->httpProxyAddressHelperCheckBox);//Enable address helper (jump). true by default
- initFileChooser( OPTION("httpproxy","keys",[]{return "";}), uiSettings->httpProxyKeyFileLineEdit, uiSettings->httpProxyKeyFilePushButton);
+ initFileChooser( OPTION("httpproxy","keys",[]{return "";}), uiSettings->httpProxyKeyFileLineEdit, uiSettings->httpProxyKeyFilePushButton, false);
initSignatureTypeCombobox(OPTION("httpproxy","signaturetype",[]{return "7";}), uiSettings->comboBox_httpPorxySignatureType);
initStringBox( OPTION("httpproxy","inbound.length",[]{return "3";}), uiSettings->httpProxyInboundTunnelsLenLineEdit);
initStringBox( OPTION("httpproxy","inbound.quantity",[]{return "5";}), uiSettings->httpProxyInboundTunnQuantityLineEdit);
@@ -226,7 +253,7 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
initCheckBox( OPTION("socksproxy","enabled",[]{return "";}), uiSettings->socksProxyEnabledCheckBox);
initIPAddressBox( OPTION("socksproxy","address",[]{return "";}), uiSettings->socksProxyAddressLineEdit, tr("Socks proxy -> IP address"));
initTCPPortBox( OPTION("socksproxy","port",[]{return "4447";}), uiSettings->socksProxyPortLineEdit, tr("Socks proxy -> Port"));
- initFileChooser( OPTION("socksproxy","keys",[]{return "";}), uiSettings->socksProxyKeyFileLineEdit, uiSettings->socksProxyKeyFilePushButton);
+ initFileChooser( OPTION("socksproxy","keys",[]{return "";}), uiSettings->socksProxyKeyFileLineEdit, uiSettings->socksProxyKeyFilePushButton, false);
initSignatureTypeCombobox(OPTION("socksproxy","signaturetype",[]{return "7";}), uiSettings->comboBox_socksProxySignatureType);
initStringBox( OPTION("socksproxy","inbound.length",[]{return "";}), uiSettings->socksProxyInboundTunnelsLenLineEdit);
initStringBox( OPTION("socksproxy","inbound.quantity",[]{return "";}), uiSettings->socksProxyInboundTunnQuantityLineEdit);
@@ -256,8 +283,8 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
initIPAddressBox( OPTION("i2pcontrol","address",[]{return "";}), uiSettings->i2pControlAddressLineEdit, tr("I2PControl -> IP address"));
initTCPPortBox( OPTION("i2pcontrol","port",[]{return "7650";}), uiSettings->i2pControlPortLineEdit, tr("I2PControl -> Port"));
initStringBox( OPTION("i2pcontrol","password",[]{return "";}), uiSettings->i2pControlPasswordLineEdit);
- initFileChooser( OPTION("i2pcontrol","cert",[]{return "i2pcontrol.crt.pem";}), uiSettings->i2pControlCertFileLineEdit, uiSettings->i2pControlCertFileBrowsePushButton);
- initFileChooser( OPTION("i2pcontrol","key",[]{return "i2pcontrol.key.pem";}), uiSettings->i2pControlKeyFileLineEdit, uiSettings->i2pControlKeyFileBrowsePushButton);
+ initFileChooser( OPTION("i2pcontrol","cert",[]{return "i2pcontrol.crt.pem";}), uiSettings->i2pControlCertFileLineEdit, uiSettings->i2pControlCertFileBrowsePushButton, true);
+ initFileChooser( OPTION("i2pcontrol","key",[]{return "i2pcontrol.key.pem";}), uiSettings->i2pControlKeyFileLineEdit, uiSettings->i2pControlKeyFileBrowsePushButton, true);
initCheckBox( OPTION("upnp","enabled",[]{return "true";}), uiSettings->enableUPnPCheckBox);
initStringBox( OPTION("upnp","name",[]{return "I2Pd";}), uiSettings->upnpNameLineEdit);
@@ -265,9 +292,9 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
initCheckBox( OPTION("precomputation","elgamal",[]{return "false";}), uiSettings->useElGamalPrecomputedTablesCheckBox);
initCheckBox( OPTION("reseed","verify",[]{return "";}), uiSettings->reseedVerifyCheckBox);
- initFileChooser( OPTION("reseed","file",[]{return "";}), uiSettings->reseedFileLineEdit, uiSettings->reseedFileBrowsePushButton);
+ initFileChooser( OPTION("reseed","file",[]{return "";}), uiSettings->reseedFileLineEdit, uiSettings->reseedFileBrowsePushButton, true);
initStringBox( OPTION("reseed","urls",[]{return "";}), uiSettings->reseedURLsLineEdit);
- initFileChooser( OPTION("reseed","zipfile",[]{return "";}), uiSettings->reseedZipFileLineEdit, uiSettings->reseedZipFileBrowsePushButton); //Path to local .zip file to reseed from
+ initFileChooser( OPTION("reseed","zipfile",[]{return "";}), uiSettings->reseedZipFileLineEdit, uiSettings->reseedZipFileBrowsePushButton, true); //Path to local .zip file to reseed from
initUInt16Box( OPTION("reseed","threshold",[]{return "25";}), uiSettings->reseedThresholdNumberLineEdit, tr("reseedThreshold")); //Minimum number of known routers before requesting reseed. 25 by default
initStringBox( OPTION("reseed","proxy",[]{return "";}), uiSettings->reseedProxyLineEdit);//URL for https/socks reseed proxy
@@ -306,7 +333,15 @@ MainWindow::MainWindow(std::shared_ptr logStream_, QWidget *paren
# undef OPTION
//widgetlocks.add(new widgetlock(widget,lockbtn));
+
+
+ // #1593
+#ifdef I2PD_QT_RELEASE
+ uiSettings->logDestComboEditPushButton->setEnabled(false);
+#else
widgetlocks.add(new widgetlock(uiSettings->logDestinationComboBox,uiSettings->logDestComboEditPushButton));
+#endif
+
widgetlocks.add(new widgetlock(uiSettings->logLevelComboBox,uiSettings->logLevelComboEditPushButton));
widgetlocks.add(new widgetlock(uiSettings->comboBox_httpPorxySignatureType,uiSettings->httpProxySignTypeComboEditPushButton));
widgetlocks.add(new widgetlock(uiSettings->comboBox_socksProxySignatureType,uiSettings->socksProxySignTypeComboEditPushButton));
@@ -400,6 +435,29 @@ void MainWindow::showStatusPage(StatusPage newStatusPage){
}
wasSelectingAtStatusMainPage=false;
}
+
+void MainWindow::showAboutBox(const QString & href) {
+ AboutDialog dialog(this);
+
+ /*
+ //doesn't work on older qt5: ‘class QStyleHints’ has no member named ‘showIsMaximized’
+ if (!QGuiApplication::styleHints()->showIsFullScreen() && !QGuiApplication::styleHints()->showIsMaximized()) {
+ const QWindow * windowHandle = dialog.windowHandle();
+ qDebug()<<"AboutDialog windowHandle ptr: "<<(size_t)windowHandle<screen():nullptr; //Qt 5.14+: dialog.screen()
+ qDebug()<<"AboutDialog screen ptr: "<<(size_t)screen<availableGeometry();
+ //dialog.resize(availableGeometry.width() / 3, availableGeometry.height() * 2 / 3);
+ dialog.move((availableGeometry.width() - dialog.width()) / 2,
+ (availableGeometry.height() - dialog.height()) / 2);
+ }
+ }
+ */
+
+ (void) dialog.exec();
+}
+
void MainWindow::showLogViewerPage(){ui->stackedWidget->setCurrentIndex(1);setStatusButtonsVisible(false);}
void MainWindow::showSettingsPage(){ui->stackedWidget->setCurrentIndex(2);setStatusButtonsVisible(false);}
void MainWindow::showTunnelsPage(){ui->stackedWidget->setCurrentIndex(3);setStatusButtonsVisible(false);}
@@ -607,15 +665,15 @@ MainWindow::~MainWindow()
//QMessageBox::information(0, "Debug", "mw destructor 2");
}
-FileChooserItem* MainWindow::initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton){
+FileChooserItem* MainWindow::initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton, bool requireExistingFile, bool readOnly){
FileChooserItem* retVal;
- retVal=new FileChooserItem(option, fileNameLineEdit, fileBrowsePushButton);
+ retVal=new FileChooserItem(option, fileNameLineEdit, fileBrowsePushButton, this, requireExistingFile, readOnly);
MainWindowItem* super=retVal;
configItems.append(super);
return retVal;
}
void MainWindow::initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton){
- configItems.append(new FolderChooserItem(option, folderLineEdit, folderBrowsePushButton));
+ configItems.append(new FolderChooserItem(option, folderLineEdit, folderBrowsePushButton, this, true));
}
/*void MainWindow::initCombobox(ConfigOption option, QComboBox* comboBox){
configItems.append(new ComboBoxItem(option, comboBox));
@@ -631,25 +689,25 @@ void MainWindow::initSignatureTypeCombobox(ConfigOption option, QComboBox* combo
configItems.append(new SignatureTypeComboBoxItem(option, comboBox));
}
void MainWindow::initIPAddressBox(ConfigOption option, QLineEdit* addressLineEdit, QString fieldNameTranslated){
- configItems.append(new IPAddressStringItem(option, addressLineEdit, fieldNameTranslated));
+ configItems.append(new IPAddressStringItem(option, addressLineEdit, fieldNameTranslated, this));
}
void MainWindow::initTCPPortBox(ConfigOption option, QLineEdit* portLineEdit, QString fieldNameTranslated){
- configItems.append(new TCPPortStringItem(option, portLineEdit, fieldNameTranslated));
+ configItems.append(new TCPPortStringItem(option, portLineEdit, fieldNameTranslated, this));
}
void MainWindow::initCheckBox(ConfigOption option, QCheckBox* checkBox) {
configItems.append(new CheckBoxItem(option, checkBox));
}
void MainWindow::initIntegerBox(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){
- configItems.append(new IntegerStringItem(option, numberLineEdit, fieldNameTranslated));
+ configItems.append(new IntegerStringItem(option, numberLineEdit, fieldNameTranslated, this));
}
void MainWindow::initUInt32Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){
- configItems.append(new UInt32StringItem(option, numberLineEdit, fieldNameTranslated));
+ configItems.append(new UInt32StringItem(option, numberLineEdit, fieldNameTranslated, this));
}
void MainWindow::initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){
- configItems.append(new UInt16StringItem(option, numberLineEdit, fieldNameTranslated));
+ configItems.append(new UInt16StringItem(option, numberLineEdit, fieldNameTranslated, this));
}
void MainWindow::initStringBox(ConfigOption option, QLineEdit* lineEdit){
- configItems.append(new BaseStringItem(option, lineEdit, QString()));
+ configItems.append(new BaseStringItem(option, lineEdit, QString(), this));
}
NonGUIOptionItem* MainWindow::initNonGUIOption(ConfigOption option) {
NonGUIOptionItem * retValue;
@@ -741,7 +799,7 @@ void MainWindow::deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf) {
}
/** returns false iff not valid items present and save was aborted */
-bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus){
+bool MainWindow::saveAllConfigs(bool reloadAfterSave, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus){
QString cannotSaveSettings = QApplication::tr("Cannot save settings.");
programOptionsWriterCurrentSection="";
/*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file"));
@@ -751,12 +809,17 @@ bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocu
for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
MainWindowItem* item = *it;
- if(!item->isValid()){
- highlightWrongInput(QApplication::tr("Invalid value for")+" "+item->getConfigOption().section+"::"+item->getConfigOption().option+". "+item->getRequirementToBeValid()+" "+cannotSaveSettings, item->getWidgetToFocus());
+ bool alreadyDisplayedIfWrong=false;
+ if(!item->isValid(alreadyDisplayedIfWrong)){
+ if(!alreadyDisplayedIfWrong)
+ highlightWrongInput(
+ QApplication::tr("Invalid value for")+" "+item->getConfigOption().section+"::"+item->getConfigOption().option+". "+item->getRequirementToBeValid()+" "+cannotSaveSettings,
+ WrongInputPageEnum::generalSettingsPage,
+ item->getWidgetToFocus());
return false;
}
}
- delayedSaveManagerPtr->delayedSave(++dataSerial, focusOnTunnel, tunnelNameToFocus);
+ delayedSaveManagerPtr->delayedSave(reloadAfterSave, ++dataSerial, focusOn, tunnelNameToFocus, widgetToFocus);//TODO does dataSerial work? //FIXME
//onLoggingOptionsChange();
return true;
@@ -764,11 +827,14 @@ bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocu
void FileChooserItem::pushButtonReleased() {
QString fileName = lineEdit->text().trimmed();
- fileName = QFileDialog::getOpenFileName(nullptr, tr("Open File"), fileName, tr("All Files (*.*)"));
+ fileName = requireExistingFile ?
+ QFileDialog::getOpenFileName(nullptr, tr("Open File"), fileName, tr("All Files (*.*)")) :
+ QFileDialog::getSaveFileName(nullptr, tr("Open File"), fileName, tr("All Files (*.*)"));
if(fileName.length()>0)lineEdit->setText(fileName);
}
void FolderChooserItem::pushButtonReleased() {
QString fileName = lineEdit->text().trimmed();
+ assert(requireExistingFile);
fileName = QFileDialog::getExistingDirectory(nullptr, tr("Open Folder"), fileName);
if(fileName.length()>0)lineEdit->setText(fileName);
}
@@ -776,6 +842,11 @@ void FolderChooserItem::pushButtonReleased() {
void BaseStringItem::installListeners(MainWindow *mainWindow) {
QObject::connect(lineEdit, SIGNAL(textChanged(const QString &)), mainWindow, SLOT(updated()));
}
+bool BaseStringItem::isValid(bool & alreadyDisplayedIfWrong) {
+ alreadyDisplayedIfWrong=true;
+ return ::isValidSingleLine(lineEdit, WrongInputPageEnum::generalSettingsPage, mainWindow);
+}
+
void ComboBoxItem::installListeners(MainWindow *mainWindow) {
QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), mainWindow, SLOT(updated()));
}
@@ -787,8 +858,9 @@ void MainWindow::updated() {
ui->wrongInputLabel->setVisible(false);
adjustSizesAccordingToWrongLabel();
- applyTunnelsUiToConfigs();
- saveAllConfigs(false);
+ bool correct = applyTunnelsUiToConfigs();
+ if(!correct) return;
+ saveAllConfigs(false, FocusEnum::noFocus);
}
void MainWindowItem::installListeners(MainWindow *mainWindow) {}
@@ -863,11 +935,11 @@ bool MainWindow::applyTunnelsUiToConfigs() {
return true;
}
-void MainWindow::reloadTunnelsConfigAndUI_QString(const QString tunnelNameToFocus) {
- reloadTunnelsConfigAndUI(tunnelNameToFocus.toStdString());
+void MainWindow::reloadTunnelsConfigAndUI_QString(QString tunnelNameToFocus) {
+ reloadTunnelsConfigAndUI(tunnelNameToFocus.toStdString(), nullptr);
}
-void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) {
+void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus, QWidget* widgetToFocus) {
deleteTunnelForms();
for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) {
TunnelConfig* tunconf = it->second;
@@ -884,8 +956,10 @@ void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string ol
std::map::const_iterator it=mainWindow->tunnelConfigs.find(oldName);
if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it);
mainWindow->tunnelConfigs[tunConf->getName()]=tunConf;
+ mainWindow->saveAllConfigs(true, FocusEnum::focusOnTunnelName, tunConf->getName());
}
- mainWindow->saveAllConfigs(true, tunConf->getName());
+ else
+ mainWindow->saveAllConfigs(false, FocusEnum::noFocus);
}
void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){
@@ -923,20 +997,71 @@ void MainWindow::anchorClickedHandler(const QUrl & link) {
qDebug()< params;
+ i2p::http::URL url;
+ url.parse(str.toStdString());
+ url.parse_query(params);
+ const std::string page = params["page"];
+ const std::string cmd = params["cmd"];
+ if (page == "sam_session") {
pageWithBackButton->show();
textBrowser->hide();
std::stringstream s;
- std::string strstd = str.toStdString();
+ i2p::http::ShowSAMSession (s, params["sam_id"]);
+ childTextBrowser->setHtml(QString::fromStdString(s.str()));
+ } else if (page == "local_destination") {
+ std::string b32 = params["b32"];
+ currentLocalDestinationB32 = b32;
+ pageWithBackButton->show();
+ textBrowser->hide();
+ std::stringstream s;
+ std::string strstd = currentLocalDestinationB32;
i2p::http::ShowLocalDestination(s,strstd,0);
childTextBrowser->setHtml(QString::fromStdString(s.str()));
- }
+ } else if (page == "i2cp_local_destination") {
+ pageWithBackButton->show();
+ textBrowser->hide();
+ std::stringstream s;
+ i2p::http::ShowI2CPLocalDestination (s, params["i2cp_id"]);
+ childTextBrowser->setHtml(QString::fromStdString(s.str()));
+ } else if(cmd == "closestream") {
+ std::string b32 = params["b32"];
+ uint32_t streamID = std::stoul(params["streamID"], nullptr);
+
+ i2p::data::IdentHash ident;
+ ident.FromBase32 (b32);
+ auto dest = i2p::client::context.FindLocalDestination (ident);
+
+ if (streamID) {
+ if (dest) {
+ if(dest->DeleteStream (streamID))
+ QMessageBox::information(
+ this,
+ QApplication::tr("Success"),
+ QApplication::tr("SUCCESS: Stream closed"));
+ else
+ QMessageBox::critical(
+ this,
+ QApplication::tr("Error"),
+ QApplication::tr("ERROR: Stream not found or already was closed"));
+ }
+ else
+ QMessageBox::critical(
+ this,
+ QApplication::tr("Error"),
+ QApplication::tr("ERROR: Destination not found"));
+ }
+ else
+ QMessageBox::critical(
+ this,
+ QApplication::tr("Error"),
+ QApplication::tr("ERROR: StreamID is null"));
+ std::stringstream s;
+ std::string strstd = currentLocalDestinationB32;
+ i2p::http::ShowLocalDestination(s,strstd,0);
+ childTextBrowser->setHtml(QString::fromStdString(s.str()));
+ }
}
void MainWindow::backClickedFromChild() {
@@ -944,39 +1069,58 @@ void MainWindow::backClickedFromChild() {
}
void MainWindow::adjustSizesAccordingToWrongLabel() {
+ constexpr auto HEIGHT = 581;
+ constexpr auto WIDTH = 707;
if(ui->wrongInputLabel->isVisible()) {
int dh = ui->wrongInputLabel->height()+ui->verticalLayout_7->layout()->spacing();
ui->verticalLayout_7->invalidate();
ui->wrongInputLabel->adjustSize();
ui->stackedWidget->adjustSize();
- ui->stackedWidget->setFixedHeight(531-dh);
- ui->settingsPage->setFixedHeight(531-dh);
- ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, 711, 531-dh));
- ui->stackedWidget->setFixedHeight(531-dh);
- ui->settingsScrollArea->setFixedHeight(531-dh-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing());
+ const auto height = HEIGHT - dh;
+ ui->stackedWidget->setFixedHeight(height);
+ ui->settingsPage->setFixedHeight(height);
+ ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, WIDTH, height));
+ ui->stackedWidget->setFixedHeight(height);
+ ui->settingsScrollArea->setFixedHeight(height-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing());
ui->settingsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight);
- ui->tunnelsScrollArea->setFixedHeight(531-dh-settingsTitleLabelNominalHeight-ui->horizontalLayout_42->geometry().height()-2*ui->verticalLayout_4->spacing());
+ ui->tunnelsScrollArea->setFixedHeight(height-settingsTitleLabelNominalHeight-ui->horizontalLayout_42->geometry().height()-2*ui->verticalLayout_4->spacing());
ui->tunnelsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight);
}else{
ui->verticalLayout_7->invalidate();
ui->wrongInputLabel->adjustSize();
ui->stackedWidget->adjustSize();
- ui->stackedWidget->setFixedHeight(531);
- ui->settingsPage->setFixedHeight(531);
- ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, 711, 531));
- ui->stackedWidget->setFixedHeight(531);
- ui->settingsScrollArea->setFixedHeight(531-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing());
+ ui->stackedWidget->setFixedHeight(HEIGHT);
+ ui->settingsPage->setFixedHeight(HEIGHT);
+ ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, WIDTH, HEIGHT));
+ ui->stackedWidget->setFixedHeight(HEIGHT);
+ ui->settingsScrollArea->setFixedHeight(HEIGHT-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing());
ui->settingsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight);
- ui->tunnelsScrollArea->setFixedHeight(531-settingsTitleLabelNominalHeight-ui->horizontalLayout_42->geometry().height()-2*ui->verticalLayout_4->spacing());
+ ui->tunnelsScrollArea->setFixedHeight(HEIGHT-settingsTitleLabelNominalHeight-ui->horizontalLayout_42->geometry().height()-2*ui->verticalLayout_4->spacing());
ui->tunnelsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight);
}
}
-void MainWindow::highlightWrongInput(QString warningText, QWidget* widgetToFocus) {
+void MainWindow::highlightWrongInput(QString warningText, WrongInputPageEnum inputPage, QWidget* widgetToFocus) {
bool redVisible = ui->wrongInputLabel->isVisible();
ui->wrongInputLabel->setVisible(true);
ui->wrongInputLabel->setText(warningText);
if(!redVisible)adjustSizesAccordingToWrongLabel();
if(widgetToFocus){ui->settingsScrollArea->ensureWidgetVisible(widgetToFocus);widgetToFocus->setFocus();}
- showSettingsPage();
+ switch(inputPage) {
+ case WrongInputPageEnum::generalSettingsPage: showSettingsPage(); break;
+ case WrongInputPageEnum::tunnelsSettingsPage: showTunnelsPage(); break;
+ default: assert(false); break;
+ }
}
+
+void MainWindow::syncLogLevel (int /*comboBoxIndex*/) {
+ std::string level = uiSettings->logLevelComboBox->currentText().toLower().toStdString();
+ if (level == "none" || level == "error" || level == "warn" || level == "info" || level == "debug")
+ i2p::log::Logger().SetLogLevel(level);
+ else {
+ LogPrint(eLogError, "unknown loglevel set attempted");
+ return;
+ }
+ i2p::log::Logger().Reopen ();
+}
+
diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h
index 77c8826b..e1ddcc6e 100644
--- a/qt/i2pd_qt/mainwindow.h
+++ b/qt/i2pd_qt/mainwindow.h
@@ -66,6 +66,8 @@
#include "DelayedSaveManagerImpl.h"
#include "SaverImpl.h"
+#include "I2pdQtUtil.h"
+
class SaverImpl;
class LogViewerManager;
@@ -100,12 +102,14 @@ class MainWindow;
class MainWindowItem : public QObject {
Q_OBJECT
+private:
ConfigOption option;
QWidget* widgetToFocus;
QString requirementToBeValid;
+ const bool readOnly;
public:
- MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_) :
- option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_) {}
+ MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_, bool readOnly_=false) :
+ option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_), readOnly(readOnly_) {}
QWidget* getWidgetToFocus(){return widgetToFocus;}
QString& getRequirementToBeValid() { return requirementToBeValid; }
ConfigOption& getConfigOption() { return option; }
@@ -116,13 +120,14 @@ public:
std::string optName="";
if(!option.section.isEmpty())optName=option.section.toStdString()+std::string(".");
optName+=option.option.toStdString();
- qDebug() << "loadFromConfigOption[" << optName.c_str() << "]";
+ //qDebug() << "loadFromConfigOption[" << optName.c_str() << "]";
boost::any programOption;
i2p::config::GetOptionAsAny(optName, programOption);
optionValue=programOption.empty()?boost::any(std::string(""))
:boost::any_cast(programOption).value();
}
virtual void saveToStringStream(std::stringstream& out){
+ if(readOnly)return; //should readOnly items (conf=) error somewhere, instead of silently skipping save?
if(isType(optionValue)) {
std::string v = boost::any_cast(optionValue);
if(v.empty())return;
@@ -132,7 +137,7 @@ public:
std::string optName="";
if(!option.section.isEmpty())optName=option.section.toStdString()+std::string(".");
optName+=option.option.toStdString();
- qDebug() << "Writing option" << optName.c_str() << "of type" << rtti.c_str();
+ //qDebug() << "Writing option" << optName.c_str() << "of type" << rtti.c_str();
std::string sectionAsStdStr = option.section.toStdString();
if(!option.section.isEmpty() &&
sectionAsStdStr!=programOptionsWriterCurrentSection) {
@@ -155,19 +160,24 @@ public:
}else out << boost::any_cast(optionValue); //let it throw
out << "\n\n";
}
- virtual bool isValid(){return true;}
+ virtual bool isValid(bool & alreadyDisplayedIfWrong){alreadyDisplayedIfWrong=false;return true;}
};
class NonGUIOptionItem : public MainWindowItem {
public:
- NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_, nullptr, QString()) {};
+ NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_, nullptr, QString()) {}
virtual ~NonGUIOptionItem(){}
- virtual bool isValid() { return true; }
+ //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class BaseStringItem : public MainWindowItem {
Q_OBJECT
public:
QLineEdit* lineEdit;
- BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_) : MainWindowItem(option_, lineEdit_, requirementToBeValid_), lineEdit(lineEdit_){};
+ MainWindow *mainWindow;
+ BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_, MainWindow* mainWindow_, bool readOnly=false):
+ MainWindowItem(option_, lineEdit_, requirementToBeValid_, readOnly),
+ lineEdit(lineEdit_),
+ mainWindow(mainWindow_)
+ {};
virtual ~BaseStringItem(){}
virtual void installListeners(MainWindow *mainWindow);
virtual QString toString(){
@@ -183,13 +193,15 @@ public:
optionValue=fromString(lineEdit->text());
MainWindowItem::saveToStringStream(out);
}
- virtual bool isValid() { return true; }
+ virtual bool isValid(bool & alreadyDisplayedIfWrong);
};
class FileOrFolderChooserItem : public BaseStringItem {
+protected:
+ const bool requireExistingFile;
public:
QPushButton* browsePushButton;
- FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) :
- BaseStringItem(option_, lineEdit_, QString()), browsePushButton(browsePushButton_) {}
+ FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile_, bool readOnly) :
+ BaseStringItem(option_, lineEdit_, QString(), mw, readOnly), requireExistingFile(requireExistingFile_), browsePushButton(browsePushButton_) {}
virtual ~FileOrFolderChooserItem(){}
};
class FileChooserItem : public FileOrFolderChooserItem {
@@ -197,8 +209,8 @@ class FileChooserItem : public FileOrFolderChooserItem {
private slots:
void pushButtonReleased();
public:
- FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) :
- FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_) {
+ FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile, bool readOnly) :
+ FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFile, readOnly) {
QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased()));
}
};
@@ -207,20 +219,20 @@ class FolderChooserItem : public FileOrFolderChooserItem{
private slots:
void pushButtonReleased();
public:
- FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) :
- FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_) {
+ FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFolder) :
+ FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFolder, false) {
QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased()));
}
};
class ComboBoxItem : public MainWindowItem {
public:
QComboBox* comboBox;
- ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_,comboBox_,QString()), comboBox(comboBox_){};
+ ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_,comboBox_,QString()), comboBox(comboBox_){}
virtual ~ComboBoxItem(){}
virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption()=0;
virtual void saveToStringStream(std::stringstream& out)=0;
- virtual bool isValid() { return true; }
+ //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return ; }
};
class LogDestinationComboBoxItem : public ComboBoxItem {
public:
@@ -237,13 +249,13 @@ public:
optionValue=logDest;
MainWindowItem::saveToStringStream(out);
}
- virtual bool isValid() { return true; }
+ //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
Q_OBJECT
};
class LogLevelComboBoxItem : public ComboBoxItem {
public:
- LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {};
+ LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}
virtual ~LogLevelComboBoxItem(){}
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
@@ -254,11 +266,11 @@ public:
optionValue=comboBox->currentText().toStdString();
MainWindowItem::saveToStringStream(out);
}
- virtual bool isValid() { return true; }
+ //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class SignatureTypeComboBoxItem : public ComboBoxItem {
public:
- SignatureTypeComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {};
+ SignatureTypeComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}
virtual ~SignatureTypeComboBoxItem(){}
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
@@ -271,39 +283,42 @@ public:
optionValue=(unsigned short)selected;
MainWindowItem::saveToStringStream(out);
}
- virtual bool isValid() { return true; }
+ //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class CheckBoxItem : public MainWindowItem {
public:
QCheckBox* checkBox;
- CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_,checkBox_,QString()), checkBox(checkBox_){};
+ CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_,checkBox_,QString()), checkBox(checkBox_){}
virtual ~CheckBoxItem(){}
virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
- qDebug() << "setting value for checkbox " << checkBox->text();
+ //qDebug() << "setting value for checkbox " << checkBox->text();
checkBox->setChecked(boost::any_cast(optionValue));
}
virtual void saveToStringStream(std::stringstream& out){
optionValue=checkBox->isChecked();
MainWindowItem::saveToStringStream(out);
}
- virtual bool isValid() { return true; }
+ //virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class BaseFormattedStringItem : public BaseStringItem {
public:
QString fieldNameTranslated;
- BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, QString requirementToBeValid_) :
- BaseStringItem(option_, lineEdit_, requirementToBeValid_), fieldNameTranslated(fieldNameTranslated_) {};
+ BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, QString requirementToBeValid_, MainWindow* mw) :
+ BaseStringItem(option_, lineEdit_, requirementToBeValid_, mw), fieldNameTranslated(fieldNameTranslated_) {}
virtual ~BaseFormattedStringItem(){}
- virtual bool isValid()=0;
+ //virtual bool isValid(bool & alreadyDisplayedIfWrong)=0;
};
class IntegerStringItem : public BaseFormattedStringItem {
public:
- IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
- BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be a valid integer.")) {};
+ IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) :
+ BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be a valid integer."), mw) {}
virtual ~IntegerStringItem(){}
- virtual bool isValid(){
+ virtual bool isValid(bool & alreadyDisplayedIfWrong){
+ bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
+ if(!correct)return false;
+ alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toInt(&ok);
@@ -314,10 +329,13 @@ public:
};
class UShortStringItem : public BaseFormattedStringItem {
public:
- UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
- BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned short integer.")) {};
+ UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) :
+ BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned short integer."), mw) {}
virtual ~UShortStringItem(){}
- virtual bool isValid(){
+ virtual bool isValid(bool & alreadyDisplayedIfWrong){
+ bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
+ if(!correct)return false;
+ alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toUShort(&ok);
@@ -328,10 +346,13 @@ public:
};
class UInt32StringItem : public BaseFormattedStringItem {
public:
- UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
- BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 32-bit integer.")) {};
+ UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) :
+ BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 32-bit integer."), mw) {}
virtual ~UInt32StringItem(){}
- virtual bool isValid(){
+ virtual bool isValid(bool & alreadyDisplayedIfWrong){
+ bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
+ if(!correct)return false;
+ alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toUInt(&ok);
@@ -342,10 +363,13 @@ public:
};
class UInt16StringItem : public BaseFormattedStringItem {
public:
- UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
- BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer.")) {};
+ UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) :
+ BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer."), mw) {}
virtual ~UInt16StringItem(){}
- virtual bool isValid(){
+ virtual bool isValid(bool & alreadyDisplayedIfWrong){
+ bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
+ if(!correct)return false;
+ alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toUShort(&ok);
@@ -356,14 +380,14 @@ public:
};
class IPAddressStringItem : public BaseFormattedStringItem {
public:
- IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
- BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be an IPv4 address")) {};
- virtual bool isValid(){return true;}//todo
+ IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) :
+ BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be an IPv4 address"), mw) {}
+ //virtual bool isValid(bool & alreadyDisplayedIfWrong){return true;}//todo
};
class TCPPortStringItem : public UShortStringItem {
public:
- TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
- UShortStringItem(option_, lineEdit_, fieldNameTranslated_) {};
+ TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) :
+ UShortStringItem(option_, lineEdit_, fieldNameTranslated_,mw) {}
};
namespace Ui {
@@ -386,6 +410,7 @@ class DelayedSaveManagerImpl;
class MainWindow : public QMainWindow {
Q_OBJECT
private:
+ std::string currentLocalDestinationB32;
std::shared_ptr logStream;
DelayedSaveManagerImpl* delayedSaveManagerPtr;
DelayedSaveManager::DATA_SERIAL_TYPE dataSerial;
@@ -395,7 +420,7 @@ public:
void setI2PController(i2p::qt::Controller* controller_);
- void highlightWrongInput(QString warningText, QWidget* widgetToFocus);
+ void highlightWrongInput(QString warningText, WrongInputPageEnum inputPage, QWidget* widgetToFocus);
//typedef std::function DefaultValueGetter;
@@ -428,7 +453,10 @@ private slots:
void runPeerTest();
void enableTransit();
void disableTransit();
+
public slots:
+ void syncLogLevel (int comboBoxIndex);
+
void showStatus_local_destinations_Page();
void showStatus_leasesets_Page();
void showStatus_tunnels_Page();
@@ -442,6 +470,7 @@ public slots:
void showTunnelsPage();
void showRestartPage();
void showQuitPage();
+ void showAboutBox(const QString & href);
private:
StatusPage statusPage;
@@ -499,7 +528,7 @@ protected:
//LogDestinationComboBoxItem* logOption;
FileChooserItem* logFileNameOption;
- FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton);
+ FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton, bool requireExistingFile, bool readOnly=false);
void initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton);
//void initCombobox(ConfigOption option, QComboBox* comboBox);
void initLogDestinationCombobox(ConfigOption option, QComboBox* comboBox);
@@ -519,12 +548,12 @@ protected:
public slots:
/** returns false iff not valid items present and save was aborted */
- bool saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus="");
- void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus);
+ bool saveAllConfigs(bool reloadAfterSave, FocusEnum focusOn, std::string tunnelNameToFocus="", QWidget* widgetToFocus=nullptr);
+ void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus, QWidget* widgetToFocus);
+ void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI("", nullptr); }
//focus none
- void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI(""); }
- void reloadTunnelsConfigAndUI_QString(const QString tunnelNameToFocus);
+ void reloadTunnelsConfigAndUI_QString(QString tunnelNameToFocus);
void addServerTunnelPushButtonReleased();
void addClientTunnelPushButtonReleased();
@@ -629,7 +658,7 @@ private:
tunnelConfigs.erase(it);
delete tc;
}
- saveAllConfigs(false);
+ saveAllConfigs(true, FocusEnum::noFocus);
}
std::string GenerateNewTunnelName() {
@@ -666,7 +695,7 @@ private:
sigType,
cryptoType);
- saveAllConfigs(true, name);
+ saveAllConfigs(true, FocusEnum::focusOnTunnelName, name);
}
void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels ()
@@ -704,7 +733,7 @@ private:
cryptoType);
- saveAllConfigs(true, name);
+ saveAllConfigs(true, FocusEnum::focusOnTunnelName, name);
}
void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels ()
@@ -747,16 +776,13 @@ private:
std::string dest;
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) {
dest = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION);
- std::cout << "had read tunnel dest: " << dest << std::endl;
}
int port = section.second.get (I2P_CLIENT_TUNNEL_PORT);
- std::cout << "had read tunnel port: " << port << std::endl;
// optional params
std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, "");
std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1");
int cryptoType = section.second.get(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0);
int destinationPort = section.second.get(I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
- std::cout << "had read tunnel destinationPort: " << destinationPort << std::endl;
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
// I2CP
std::map options;
diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui
index dcdf88bd..8f942b08 100644
--- a/qt/i2pd_qt/mainwindow.ui
+++ b/qt/i2pd_qt/mainwindow.ui
@@ -7,7 +7,7 @@
0
0
908
- 554
+ 604