Browse Source

import qt code, update paths in project and sources

Signed-off-by: R4SAS <r4sas@i2pmail.org>
pull/30/head
R4SAS 3 years ago
commit
dfd1632b78
Signed by: r4sas
GPG Key ID: 66F6C87B98EBCFE2
  1. 12
      .gitignore
  2. 3
      .gitmodules
  3. 27
      LICENSE
  4. 3
      README.md
  5. 2
      contrib/.gitignore
  6. BIN
      contrib/icons/128x128/website.i2pd.i2pd.png
  7. BIN
      contrib/icons/16x16/website.i2pd.i2pd.png
  8. BIN
      contrib/icons/22x22/website.i2pd.i2pd.png
  9. BIN
      contrib/icons/24x24/website.i2pd.i2pd.png
  10. BIN
      contrib/icons/256x256/website.i2pd.i2pd.png
  11. BIN
      contrib/icons/32x32/website.i2pd.i2pd.png
  12. BIN
      contrib/icons/48x48/website.i2pd.i2pd.png
  13. BIN
      contrib/icons/512x512/website.i2pd.i2pd.png
  14. BIN
      contrib/icons/64x64/website.i2pd.i2pd.png
  15. 57
      contrib/website.i2pd.i2pd.appdata.xml
  16. 11
      contrib/website.i2pd.i2pd.desktop
  17. 184
      i2pd_qt.pro
  18. 21
      src/AboutDialog.cpp
  19. 22
      src/AboutDialog.h
  20. 194
      src/AboutDialog.ui
  21. 7
      src/BuildDateTimeQt.h
  22. 220
      src/ClientTunnelPane.cpp
  23. 126
      src/ClientTunnelPane.h
  24. 195
      src/DaemonQT.cpp
  25. 88
      src/DaemonQT.h
  26. 3
      src/DelayedSaveManager.cpp
  27. 26
      src/DelayedSaveManager.h
  28. 140
      src/DelayedSaveManagerImpl.cpp
  29. 84
      src/DelayedSaveManagerImpl.h
  30. 7
      src/I2pdQtTypes.h
  31. 12
      src/I2pdQtUtil.cpp
  32. 9
      src/I2pdQtUtil.h
  33. 2
      src/MainWindowItems.cpp
  34. 17
      src/MainWindowItems.h
  35. 6
      src/Saver.cpp
  36. 25
      src/Saver.h
  37. 81
      src/SaverImpl.cpp
  38. 33
      src/SaverImpl.h
  39. 278
      src/ServerTunnelPane.cpp
  40. 183
      src/ServerTunnelPane.h
  41. 2
      src/SignatureTypeComboboxFactory.cpp
  42. 86
      src/SignatureTypeComboboxFactory.h
  43. 67
      src/TunnelConfig.cpp
  44. 260
      src/TunnelConfig.h
  45. 405
      src/TunnelPane.cpp
  46. 191
      src/TunnelPane.h
  47. 12
      src/TunnelsPageUpdateListener.h
  48. 3810
      src/generalsettingswidget.ui
  49. 1
      src/i2pd
  50. 6
      src/i2pd.qrc
  51. 32
      src/i2pd.rc
  52. 45
      src/logviewermanager.cpp
  53. 130
      src/logviewermanager.h
  54. 1126
      src/mainwindow.cpp
  55. 883
      src/mainwindow.h
  56. 1053
      src/mainwindow.ui
  57. 24
      src/pagewithbackbutton.cpp
  58. 21
      src/pagewithbackbutton.h
  59. BIN
      src/resources/icons/mask.ico
  60. BIN
      src/resources/images/icon.png
  61. 127
      src/routercommandswidget.ui
  62. 163
      src/statusbuttons.ui
  63. 9
      src/textbrowsertweaked1.cpp
  64. 26
      src/textbrowsertweaked1.h
  65. 104
      src/tunnelform.ui
  66. 1
      src/widgetlock.cpp
  67. 35
      src/widgetlock.h
  68. 2
      src/widgetlockregistry.cpp
  69. 27
      src/widgetlockregistry.h

12
.gitignore vendored

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
i2pd_qt.pro.user*
moc_*
ui_*
qrc_*
i2pd_qt
Makefile*
*.stash
object_script.*
i2pd_qt_plugin_import.cpp
i2pd_qt.pro.autosave*
/debug
/release

3
.gitmodules vendored

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
[submodule "src/i2pd"]
path = src/i2pd
url = https://github.com/PurpleI2P/i2pd.git

27
LICENSE

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
Copyright (c) 2013-2020, The PurpleI2P Project
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used
to endorse or promote products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

3
README.md

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
# Build Requirements
* Qt 5 is necessary (because Qt4 lacks QtWidgets/ folder)

2
contrib/.gitignore vendored

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
*.tmp.xml

BIN
contrib/icons/128x128/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
contrib/icons/16x16/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
contrib/icons/22x22/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
contrib/icons/24x24/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
contrib/icons/256x256/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
contrib/icons/32x32/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
contrib/icons/48x48/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
contrib/icons/512x512/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

BIN
contrib/icons/64x64/website.i2pd.i2pd.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

57
contrib/website.i2pd.i2pd.appdata.xml

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2018 Viktor Villainov <supervillain@riseup.net> -->
<component type="desktop">
<id>website.i2pd.i2pd</id>
<launchable type="desktop-id">website.i2pd.i2pd.desktop</launchable>
<metadata_license>CC0-1.0</metadata_license>
<project_license>BSD-3-Clause</project_license>
<name>i2pd</name>
<summary>Invisible Internet</summary>
<description>
<p>i2pd (I2P Daemon) is a full-featured C++ implementation of I2P client.</p>
<p>I2P (Invisible Internet Protocol) is a universal anonymous network layer.
All communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses. </p>
<p>I2P allows people from all around the world to communicate and share information
without restrictions.</p>
<p>Features:</p>
<ul>
<li>Distributed anonymous networking framework</li>
<li>End-to-end encrypted communications</li>
<li>Small footprint, simple dependencies, fast performance</li>
<li>Rich set of APIs for developers of secure applications</li>
</ul>
</description>
<screenshots>
<screenshot type="default">
<image height="590" width="923">https://i2pd.website/images/i2pd_qt.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://i2pd.website/</url>
<url type="bugtracker">https://github.com/PurpleI2P/i2pd/issues</url>
<url type="help">https://i2pd.readthedocs.io/en/latest/</url>
<update_contact>supervillain@riseup.net</update_contact>
<developer_name>PurpleI2P Team</developer_name>
<translation type="qt" />
<releases>
<release version="2.35.0" date="2020-11-30" />
<release version="2.34.0" date="2020-10-27" />
<release version="2.33.0" date="2020-08-24" />
<release version="2.32.1" date="2020-06-02" />
<release version="2.32.0" date="2020-05-25" />
<release version="2.31.0" date="2020-04-10" />
<release version="2.30.0" date="2020-02-25" />
<release version="2.29.0" date="2019-10-21" />
<release version="2.28.0" date="2019-08-27" />
<release version="2.27.0" date="2019-07-03" />
<release version="2.26.0" date="2019-06-07" />
<release version="2.25.0" date="2019-05-09" />
<release version="2.24.0" date="2019-03-21" />
<release version="2.23.0" date="2019-01-21" />
<release version="2.22.0" date="2018-11-09" />
<release version="2.21.1" date="2018-10-22" />
<release version="2.21.0" date="2018-10-04" />
</releases>
<content_rating type="oars-1.1" />
</component>

11
contrib/website.i2pd.i2pd.desktop

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
[Desktop Entry]
Categories=Network;P2P;Qt;
Exec=i2pd_qt
GenericName=Invisible Internet
Comment=A universal anonymous network layer
Icon=website.i2pd.i2pd
Name=i2pd
Terminal=false
Type=Application
StartupNotify=false
Keywords=i2p;i2pd;vpn;p2p;

184
i2pd_qt.pro

@ -0,0 +1,184 @@ @@ -0,0 +1,184 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = i2pd_qt
TEMPLATE = app
QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized -Wno-deprecated-copy
CONFIG += strict_c++ c++11
CONFIG(debug, debug|release) {
message(Debug build)
# do not redirect logging to std::ostream and to Log pane
DEFINES += DEBUG_WITH_DEFAULT_LOGGING
DEFINES += I2PD_QT_DEBUG
I2PDMAKE += DEBUG=yes
}
CONFIG(release, debug|release) {
message(Release build)
DEFINES += I2PD_QT_RELEASE
I2PDMAKE += DEBUG=no
}
SOURCES += \
src/DaemonQT.cpp \
src/mainwindow.cpp \
src/ClientTunnelPane.cpp \
src/MainWindowItems.cpp \
src/ServerTunnelPane.cpp \
src/SignatureTypeComboboxFactory.cpp \
src/TunnelConfig.cpp \
src/TunnelPane.cpp \
src/textbrowsertweaked1.cpp \
src/pagewithbackbutton.cpp \
src/widgetlock.cpp \
src/widgetlockregistry.cpp \
src/logviewermanager.cpp \
src/DelayedSaveManager.cpp \
src/Saver.cpp \
src/DelayedSaveManagerImpl.cpp \
src/SaverImpl.cpp \
src/i2pd/daemon/Daemon.cpp \
src/i2pd/daemon/HTTPServer.cpp \
src/i2pd/daemon/I2PControl.cpp \
src/i2pd/daemon/i2pd.cpp \
src/i2pd/daemon/UPnP.cpp \
src/AboutDialog.cpp \
src/I2pdQtUtil.cpp
HEADERS += \
src/DaemonQT.h \
src/mainwindow.h \
src/ClientTunnelPane.h \
src/MainWindowItems.h \
src/ServerTunnelPane.h \
src/SignatureTypeComboboxFactory.h \
src/TunnelConfig.h \
src/TunnelPane.h \
src/TunnelsPageUpdateListener.h \
src/textbrowsertweaked1.h \
src/pagewithbackbutton.h \
src/widgetlock.h \
src/widgetlockregistry.h \
src/i2pd.rc \
src/logviewermanager.h \
src/DelayedSaveManager.h \
src/Saver.h \
src/DelayedSaveManagerImpl.h \
src/SaverImpl.h \
src/i2pd/daemon/Daemon.h \
src/i2pd/daemon/HTTPServer.h \
src/i2pd/daemon/I2PControl.h \
src/i2pd/daemon/UPnP.h \
src/AboutDialog.h \
src/BuildDateTimeQt.h \
src/I2pdQtUtil.h \
src/I2pdQtTypes.h
INCLUDEPATH += src
INCLUDEPATH += src/i2pd/daemon
INCLUDEPATH += src/i2pd/libi2pd
INCLUDEPATH += src/i2pd/libi2pd_client
FORMS += \
src/mainwindow.ui \
src/tunnelform.ui \
src/statusbuttons.ui \
src/routercommandswidget.ui \
src/generalsettingswidget.ui \
src/AboutDialog.ui
LIBS += src/i2pd/libi2pd.a src/i2pd/libi2pdclient.a -lz
libi2pd.commands = @echo Building i2pd libraries
libi2pd.target = src/i2pd/libi2pd.a
libi2pd.depends = i2pd FORCE
i2pd.commands = cd src/i2pd/ && mkdir -p obj/libi2pd obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes $$I2PDMAKE mk_obj_dir api_client
i2pd.target += src/i2pd/libi2pdclient.a
i2pd.depends = FORCE
cleani2pd.commands = cd src/i2pd/ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) clean
#cleani2pd.depends = clean
PRE_TARGETDEPS += src/i2pd/libi2pd.a src/i2pd/libi2pdclient.a
QMAKE_EXTRA_TARGETS += cleani2pd i2pd libi2pd
CLEAN_DEPS += cleani2pd
BuildDateTimeQtTarget.target = src/BuildDateTimeQt.h
BuildDateTimeQtTarget.depends = FORCE
# 'touch' is unix-only; will probably break on non-unix, TBD
BuildDateTimeQtTarget.commands = touch src/BuildDateTimeQt.h
PRE_TARGETDEPS += src/BuildDateTimeQt.h
QMAKE_EXTRA_TARGETS += BuildDateTimeQtTarget
# git only, port to other VCS, too. TBD
DEFINES += VCS_COMMIT_INFO="\\\"git:$(shell git -C \""$$_PRO_FILE_PWD_"\" describe)\\\""
macx {
message("using mac os x target")
BREWROOT=/usr/local
BOOSTROOT=$$BREWROOT/opt/boost
SSLROOT=$$BREWROOT/opt/libressl
UPNPROOT=$$BREWROOT/opt/miniupnpc
INCLUDEPATH += $$BOOSTROOT/include
INCLUDEPATH += $$SSLROOT/include
INCLUDEPATH += $$UPNPROOT/include
LIBS += $$SSLROOT/lib/libcrypto.a
LIBS += $$SSLROOT/lib/libssl.a
LIBS += $$BOOSTROOT/lib/libboost_system.a
LIBS += $$BOOSTROOT/lib/libboost_date_time.a
LIBS += $$BOOSTROOT/lib/libboost_filesystem.a
LIBS += $$BOOSTROOT/lib/libboost_program_options.a
LIBS += $$UPNPROOT/lib/libminiupnpc.a
LIBS += -Wl,-dead_strip
LIBS += -Wl,-dead_strip_dylibs
LIBS += -Wl,-bind_at_load
}
linux:!android {
message("Using Linux settings")
LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc
}
windows {
message("Using Windows settings")
RC_FILE = src/i2pd.rc
DEFINES += BOOST_USE_WINDOWS_H WINDOWS _WINDOWS WIN32_LEAN_AND_MEAN MINIUPNP_STATICLIB
DEFINES -= UNICODE _UNICODE
BOOST_SUFFIX = -mt
QMAKE_CXXFLAGS_RELEASE = -Os
QMAKE_LFLAGS = -Wl,-Bstatic -static-libgcc -static-libstdc++ -mwindows
# linker's -s means "strip"
QMAKE_LFLAGS_RELEASE += -s
LIBS = \
src/i2pd/libi2pd.a src/i2pd/libi2pdclient.a \
-lminiupnpc \
-lboost_system$$BOOST_SUFFIX \
-lboost_date_time$$BOOST_SUFFIX \
-lboost_filesystem$$BOOST_SUFFIX \
-lboost_program_options$$BOOST_SUFFIX \
-lssl \
-lcrypto \
-lz \
-lwsock32 \
-lws2_32 \
-lgdi32 \
-liphlpapi \
-lstdc++ \
-lpthread
}
!android:!symbian:!maemo5:!simulator {
message("Build with a system tray icon")
# see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince*
#sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images
RESOURCES = src/i2pd.qrc
QT += xml
#INSTALLS += sources
}

21
src/AboutDialog.cpp

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
#include "AboutDialog.h"
#include "ui_AboutDialog.h"
#include <QDebug>
#include "version.h"
#include "BuildDateTimeQt.h"
AboutDialog::AboutDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AboutDialog)
{
ui->setupUi(this);
ui->i2pdVersionLabel->setText(I2PD_VERSION);
ui->i2pVersionLabel->setText(I2P_VERSION);
ui->buildDateTimeLabel->setText(BUILD_DATE_TIME_QT);
ui->vcsCommitInfoLabel->setText(VCS_COMMIT_INFO);
}
AboutDialog::~AboutDialog()
{
delete ui;
}

22
src/AboutDialog.h

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
#ifndef ABOUTDIALOG_H
#define ABOUTDIALOG_H
#include <QDialog>
namespace Ui {
class AboutDialog;
}
class AboutDialog : public QDialog
{
Q_OBJECT
public:
explicit AboutDialog(QWidget *parent = 0);
~AboutDialog();
private:
Ui::AboutDialog *ui;
};
#endif // ABOUTDIALOG_H

194
src/AboutDialog.ui

@ -0,0 +1,194 @@ @@ -0,0 +1,194 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AboutDialog</class>
<widget class="QDialog" name="AboutDialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>199</height>
</rect>
</property>
<property name="windowTitle">
<string>About i2pd_qt</string>
</property>
<property name="windowIcon">
<iconset resource="i2pd.qrc">
<normaloff>:/icons/mask</normaloff>:/icons/mask</iconset>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>10</x>
<y>160</y>
<width>381</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>381</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;About i2pd_qt&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>131</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>i2pd Version:</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>131</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Build Date/Time:</string>
</property>
</widget>
<widget class="QLabel" name="i2pdVersionLabel">
<property name="geometry">
<rect>
<x>150</x>
<y>40</y>
<width>241</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>I2PD_VERSION_LABEL</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>10</x>
<y>130</y>
<width>131</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>I2P Version:</string>
</property>
</widget>
<widget class="QLabel" name="i2pVersionLabel">
<property name="geometry">
<rect>
<x>150</x>
<y>130</y>
<width>241</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>I2P_VERSION_LABEL</string>
</property>
</widget>
<widget class="QLabel" name="buildDateTimeLabel">
<property name="geometry">
<rect>
<x>150</x>
<y>70</y>
<width>241</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>BUILD_DATE_TIME_LABEL</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>10</x>
<y>100</y>
<width>131</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Version Control:</string>
</property>
</widget>
<widget class="QLabel" name="vcsCommitInfoLabel">
<property name="geometry">
<rect>
<x>150</x>
<y>100</y>
<width>241</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>VCS_COMMIT_INFO_LABEL</string>
</property>
</widget>
</widget>
<resources>
<include location="i2pd.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AboutDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AboutDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

7
src/BuildDateTimeQt.h

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
#ifndef BUILDDATETIMEQT_H
#define BUILDDATETIMEQT_H
#include <QString>
const QString BUILD_DATE_TIME_QT = QStringLiteral(__DATE__ " " __TIME__);
#endif // BUILDDATETIMEQT_H

220
src/ClientTunnelPane.cpp

@ -0,0 +1,220 @@ @@ -0,0 +1,220 @@
#include "ClientTunnelPane.h"
#include "ClientContext.h"
#include "SignatureTypeComboboxFactory.h"
#include "QVBoxLayout"
ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow):
TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_, mainWindow) {}
void ClientTunnelPane::setGroupBoxTitle(const QString & title) {
clientTunnelNameGroupBox->setTitle(title);
}
void ClientTunnelPane::deleteClientTunnelForm() {
TunnelPane::deleteTunnelForm();
delete clientTunnelNameGroupBox;
clientTunnelNameGroupBox=nullptr;
//gridLayoutWidget_2->deleteLater();
//gridLayoutWidget_2=nullptr;
}
int ClientTunnelPane::appendClientTunnelForm(
ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) {
ClientTunnelPane& ui = *this;
clientTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget);
clientTunnelNameGroupBox->setObjectName(QStringLiteral("clientTunnelNameGroupBox"));
//tunnel
gridLayoutWidget_2 = new QWidget(clientTunnelNameGroupBox);
QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2);
tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox"));
tunnelTypeComboBox->addItem("Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT);
tunnelTypeComboBox->addItem("Socks", i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS);
tunnelTypeComboBox->addItem("Websocks", i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS);
tunnelTypeComboBox->addItem("HTTP Proxy", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY);
tunnelTypeComboBox->addItem("UDP Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT);
int h=(7+4)*60;
gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h));
clientTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h));
{
const QString& type = tunnelConfig->getType();
int index=0;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)tunnelTypeComboBox->setCurrentIndex(index);
++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;
*/
//host
ui.horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.destinationLabel = new QLabel(gridLayoutWidget_2);
destinationLabel->setObjectName(QStringLiteral("destinationLabel"));
horizontalLayout_2->addWidget(destinationLabel);
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);
/*
* int port;
*/
int gridIndex = 2;
{
int port = tunnelConfig->getport();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.portLabel = new QLabel(gridLayoutWidget_2);
portLabel->setObjectName(QStringLiteral("portLabel"));
horizontalLayout_2->addWidget(portLabel);
ui.portLineEdit = new QLineEdit(gridLayoutWidget_2);
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);
}
/*
* std::string keys;
*/
{
std::string keys = tunnelConfig->getkeys();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.keysLabel = new QLabel(gridLayoutWidget_2);
keysLabel->setObjectName(QStringLiteral("keysLabel"));
horizontalLayout_2->addWidget(keysLabel);
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);
}
/*
* std::string address;
*/
{
std::string address = tunnelConfig->getaddress();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.addressLabel = new QLabel(gridLayoutWidget_2);
addressLabel->setObjectName(QStringLiteral("addressLabel"));
horizontalLayout_2->addWidget(addressLabel);
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);
}
/*
int destinationPort;
i2p::data::SigningKeyType sigType;
*/
{
int destinationPort = tunnelConfig->getdestinationPort();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.destinationPortLabel = new QLabel(gridLayoutWidget_2);
destinationPortLabel->setObjectName(QStringLiteral("destinationPortLabel"));
horizontalLayout_2->addWidget(destinationPortLabel);
ui.destinationPortLineEdit = new QLineEdit(gridLayoutWidget_2);
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);
}
{
int cryptoType = tunnelConfig->getcryptoType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2);
cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel"));
horizontalLayout_2->addWidget(cryptoTypeLabel);
ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2);
cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit"));
cryptoTypeLineEdit->setText(QString::number(cryptoType));
cryptoTypeLineEdit->setMaximumWidth(80);
QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(cryptoTypeLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
i2p::data::SigningKeyType sigType = tunnelConfig->getsigType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.sigTypeLabel = new QLabel(gridLayoutWidget_2);
sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel"));
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);
QPushButton * lockButton2 = new QPushButton(gridLayoutWidget_2);
horizontalLayout_2->addWidget(lockButton2);
widgetlocks.add(new widgetlock(sigTypeComboBox, lockButton2));
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters();
appendControlsForI2CPParameters(i2cpParameters, gridIndex);
}
retranslateClientTunnelForm(ui);
tunnelGridLayout->invalidate();
return h;
}
ServerTunnelPane* ClientTunnelPane::asServerTunnelPane(){return nullptr;}
ClientTunnelPane* ClientTunnelPane::asClientTunnelPane(){return this;}

126
src/ClientTunnelPane.h

@ -0,0 +1,126 @@ @@ -0,0 +1,126 @@
#ifndef CLIENTTUNNELPANE_H
#define CLIENTTUNNELPANE_H
#include "QGridLayout"
#include "QVBoxLayout"
#include "TunnelPane.h"
class ClientTunnelConfig;
class ServerTunnelPane;
class TunnelPane;
class ClientTunnelPane : public TunnelPane {
Q_OBJECT
public:
ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow);
virtual ~ClientTunnelPane(){}
virtual ServerTunnelPane* asServerTunnelPane();
virtual ClientTunnelPane* asClientTunnelPane();
int appendClientTunnelForm(ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget,
int tunnelsRow, int height);
void deleteClientTunnelForm();
private:
QGroupBox *clientTunnelNameGroupBox;
//tunnel
QWidget *gridLayoutWidget_2;
//destination
QHBoxLayout *horizontalLayout_2;
QLabel *destinationLabel;
QLineEdit *destinationLineEdit;
QSpacerItem *destinationHorizontalSpacer;
//port
QLabel * portLabel;
QLineEdit * portLineEdit;
//keys
QLabel * keysLabel;
QLineEdit * keysLineEdit;
//address
QLabel * addressLabel;
QLineEdit * addressLineEdit;
//destinationPort
QLabel * destinationPortLabel;
QLineEdit * destinationPortLineEdit;
//sigType
QLabel * sigTypeLabel;
QComboBox * sigTypeComboBox;
//cryptoType
QLabel * cryptoTypeLabel;
QLineEdit * cryptoTypeLineEdit;
protected slots:
virtual void setGroupBoxTitle(const QString & title);
private:
void retranslateClientTunnelForm(ClientTunnelPane& /*ui*/) {
typeLabel->setText(QApplication::translate("cltTunForm", "Client tunnel type:", 0));
destinationLabel->setText(QApplication::translate("cltTunForm", "Destination:", 0));
portLabel->setText(QApplication::translate("cltTunForm", "Port:", 0));
cryptoTypeLabel->setText(QApplication::translate("cltTunForm", "Crypto type:", 0));
keysLabel->setText(QApplication::translate("cltTunForm", "Keys:", 0));
destinationPortLabel->setText(QApplication::translate("cltTunForm", "Destination port:", 0));
addressLabel->setText(QApplication::translate("cltTunForm", "Address:", 0));
sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0));
}
protected:
virtual bool applyDataFromUIToTunnelConfig() {
QString cannotSaveSettings = QApplication::tr("Cannot save settings.");
bool ok=TunnelPane::applyDataFromUIToTunnelConfig();
if(!ok)return false;
ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig();
assert(ctc!=nullptr);
if(!isValidSingleLine(destinationLineEdit))return false;
if(!isValidSingleLine(portLineEdit))return false;
if(!isValidSingleLine(cryptoTypeLineEdit))return false;
if(!isValidSingleLine(keysLineEdit))return false;
if(!isValidSingleLine(addressLineEdit))return false;
if(!isValidSingleLine(destinationPortLineEdit))return false;
//destination
ctc->setdest(destinationLineEdit->text().toStdString());
auto portStr=portLineEdit->text();
int portInt=portStr.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit);
return false;
}
ctc->setport(portInt);
auto cryptoTypeStr=cryptoTypeLineEdit->text();
int cryptoTypeInt=cryptoTypeStr.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit);
return false;
}
ctc->setcryptoType(cryptoTypeInt);
ctc->setkeys(keysLineEdit->text().toStdString());
ctc->setaddress(addressLineEdit->text().toStdString());
auto dportStr=destinationPortLineEdit->text();
int dportInt=dportStr.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad destinationPort, must be int.")+" "+cannotSaveSettings,destinationPortLineEdit);
return false;
}
ctc->setdestinationPort(dportInt);
ctc->setsigType(readSigTypeComboboxUI(sigTypeComboBox));
return true;
}
};
#endif // CLIENTTUNNELPANE_H

195
src/DaemonQT.cpp

@ -0,0 +1,195 @@ @@ -0,0 +1,195 @@
#include <memory>
#include "DaemonQT.h"
#include "Daemon.h"
#include "mainwindow.h"
#include "Log.h"
#include <QMessageBox>
#include <QApplication>
#include <QMutexLocker>
#include <QThread>
//#define DEBUG_WITH_DEFAULT_LOGGING (1)
namespace i2p
{
namespace qt
{
Worker::Worker (DaemonQTImpl& daemon):
m_Daemon (daemon)
{
}
void Worker::startDaemon()
{
qDebug("Performing daemon start...");
//try{
m_Daemon.start();
qDebug("Daemon started.");
emit resultReady(false, "");
/*}catch(std::exception ex){
emit resultReady(true, ex.what());
}catch(...){
emit resultReady(true, QObject::tr("Error: unknown exception"));
}*/
}
void Worker::restartDaemon()
{
qDebug("Performing daemon restart...");
//try{
m_Daemon.restart();
qDebug("Daemon restarted.");
emit resultReady(false, "");
/*}catch(std::exception ex){
emit resultReady(true, ex.what());
}catch(...){
emit resultReady(true, QObject::tr("Error: unknown exception"));
}*/
}
void Worker::stopDaemon() {
qDebug("Performing daemon stop...");
//try{
m_Daemon.stop();
qDebug("Daemon stopped.");
emit resultReady(false, "");
/*}catch(std::exception ex){
emit resultReady(true, ex.what());
}catch(...){
emit resultReady(true, QObject::tr("Error: unknown exception"));
}*/
}
Controller::Controller(DaemonQTImpl& daemon):
m_Daemon (daemon)
{
Worker *worker = new Worker (m_Daemon);
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::startDaemon, worker, &Worker::startDaemon);
connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon);
connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
Controller::~Controller()
{
qDebug("Closing and waiting for daemon worker thread...");
workerThread.quit();
workerThread.wait();
qDebug("Waiting for daemon worker thread finished.");
if(m_Daemon.isRunning())
{
qDebug("Stopping the daemon...");
m_Daemon.stop();
qDebug("Stopped the daemon.");
}
}
DaemonQTImpl::DaemonQTImpl ():
mutex(nullptr), m_IsRunning(nullptr), m_RunningChangedCallback(nullptr)
{
}
DaemonQTImpl::~DaemonQTImpl ()
{
delete mutex;
}
bool DaemonQTImpl::init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream)
{
mutex=new QMutex(QMutex::Recursive);
setRunningCallback(0);
m_IsRunning=false;
return Daemon.init(argc,argv,logstream);
}
void DaemonQTImpl::start()
{
QMutexLocker locker(mutex);
setRunning(true);
Daemon.start();
}
void DaemonQTImpl::stop()
{
QMutexLocker locker(mutex);
Daemon.stop();
setRunning(false);
}
void DaemonQTImpl::restart()
{
QMutexLocker locker(mutex);
stop();
start();
}
void DaemonQTImpl::setRunningCallback(runningChangedCallback cb)
{
m_RunningChangedCallback = cb;
}
bool DaemonQTImpl::isRunning()
{
return m_IsRunning;
}
void DaemonQTImpl::setRunning(bool newValue)
{
bool oldValue = m_IsRunning;
if(oldValue!=newValue)
{
m_IsRunning = newValue;
if(m_RunningChangedCallback)
m_RunningChangedCallback();
}
}
int RunQT (int argc, char* argv[])
{
QApplication app(argc, argv);
int result;
{
std::shared_ptr<std::iostream> logstreamptr=
#ifdef DEBUG_WITH_DEFAULT_LOGGING
nullptr
#else
std::make_shared<std::stringstream>()
#endif
;
//TODO move daemon init deinit to a bg thread
DaemonQTImpl daemon;
if(logstreamptr) (*logstreamptr) << "Initialising the daemon..." << std::endl;
bool daemonInitSuccess = daemon.init(argc, argv, logstreamptr);
if(!daemonInitSuccess)
{
QMessageBox::critical(0, "Error", "Daemon init failed");
return 1;
}
LogPrint(eLogDebug, "Initialised, creating the main window...");
MainWindow w(logstreamptr);
LogPrint(eLogDebug, "Before main window.show()...");
w.show ();
{
i2p::qt::Controller daemonQtController(daemon);
w.setI2PController(&daemonQtController);
LogPrint(eLogDebug, "Starting the daemon...");
emit daemonQtController.startDaemon();
//daemon.start ();
LogPrint(eLogDebug, "Starting GUI event loop...");
result = app.exec();
//daemon.stop ();
}
}
//QMessageBox::information(&w, "Debug", "demon stopped");
LogPrint(eLogDebug, "Exiting the application");
return result;
}
}
}

88
src/DaemonQT.h

@ -0,0 +1,88 @@ @@ -0,0 +1,88 @@
#ifndef DAEMONQT_H
#define DAEMONQT_H
#include <memory>
#include <QObject>
#include <QThread>
#include <QMutex>
#include <QMessageBox>
namespace i2p
{
namespace qt
{
class DaemonQTImpl
{
public:
DaemonQTImpl ();
~DaemonQTImpl ();
typedef void (*runningChangedCallback)();
/**
* @brief init
* @param argc
* @param argv
* @return success
*/
bool init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream);
void start();
void stop();
void restart();
void setRunningCallback(runningChangedCallback cb);
bool isRunning();
private:
void setRunning(bool running);
void showError(std::string errorMsg);
private:
QMutex* mutex;
bool m_IsRunning;
runningChangedCallback m_RunningChangedCallback;
};
class Worker : public QObject
{
Q_OBJECT
public:
Worker (DaemonQTImpl& daemon);
private:
DaemonQTImpl& m_Daemon;
public slots:
void startDaemon();
void restartDaemon();
void stopDaemon();
signals:
void resultReady(bool failed, QString failureMessage);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller(DaemonQTImpl& daemon);
~Controller();
private:
DaemonQTImpl& m_Daemon;
public slots:
void handleResults(bool failed, QString failureMessage){
if(failed){
QMessageBox::critical(0, QObject::tr("Error"), failureMessage);
}
}
signals:
void startDaemon();
void stopDaemon();
void restartDaemon();
};
}
}
#endif // DAEMONQT_H

3
src/DelayedSaveManager.cpp

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
#include "DelayedSaveManager.h"
DelayedSaveManager::DelayedSaveManager(){}

26
src/DelayedSaveManager.h

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
#ifndef DELAYEDSAVEMANAGER_H
#define DELAYEDSAVEMANAGER_H
#include "Saver.h"
#include "I2pdQtTypes.h"
class DelayedSaveManager
{
public:
DelayedSaveManager();
virtual void setSaver(Saver* saver)=0;
typedef unsigned int DATA_SERIAL_TYPE;
virtual void delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus)=0;
//returns false iff save failed
virtual bool appExiting()=0;
virtual FocusEnum getFocusOn()=0;
virtual std::string& getTunnelNameToFocus()=0;
virtual QWidget* getWidgetToFocus()=0;
};
#endif // DELAYEDSAVEMANAGER_H

140
src/DelayedSaveManagerImpl.cpp

@ -0,0 +1,140 @@ @@ -0,0 +1,140 @@
#include "DelayedSaveManagerImpl.h"
#include <assert.h>
DelayedSaveManagerImpl::DelayedSaveManagerImpl() :
widgetToFocus(nullptr),
saver(nullptr),
lastDataSerialSeen(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL),
lastSaveStartedTimestamp(A_VERY_OBSOLETE_TIMESTAMP),
exiting(false),
thread(new DelayedSaveThread(this))
{
}
void DelayedSaveManagerImpl::setSaver(Saver* saver) {
this->saver = saver;
}
void DelayedSaveManagerImpl::start() {
thread->start();
}
bool DelayedSaveManagerImpl::isSaverValid() {
return saver != nullptr;
}
void DelayedSaveManagerImpl::delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus) {
if(lastDataSerialSeen==dataSerial)return;
this->reloadAfterSave = reloadAfterSave;
this->focusOn = focusOn;
this->tunnelNameToFocus = tunnelNameToFocus;
this->widgetToFocus = widgetToFocus;
lastDataSerialSeen=dataSerial;
assert(isSaverValid());
TIMESTAMP_TYPE now = getTime();
TIMESTAMP_TYPE wakeTime = lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS;
if(now < wakeTime) {
//defer save until lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS
thread->deferSaveUntil(wakeTime);
return;
}
lastSaveStartedTimestamp = now;
thread->startSavingNow();
}
bool DelayedSaveManagerImpl::appExiting() {
exiting=true;
thread->wakeThreadAndJoinThread();
assert(isSaverValid());
saver->save(false, FocusEnum::noFocus);
return true;
}
DelayedSaveThread::DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl_):
delayedSaveManagerImpl(delayedSaveManagerImpl_),
mutex(new QMutex()),
waitCondition(new QWaitCondition()),
saveNow(false),
defer(false)
{
mutex->lock();
}
DelayedSaveThread::~DelayedSaveThread(){
mutex->unlock();
delete mutex;
delete waitCondition;
}
void DelayedSaveThread::run() {
forever {
if(delayedSaveManagerImpl->isExiting())return;
waitCondition->wait(mutex, WAIT_TIME_MILLIS);
if(delayedSaveManagerImpl->isExiting())return;
Saver* saver = delayedSaveManagerImpl->getSaver();
assert(saver!=nullptr);
if(saveNow) {
saveNow = false;
const FocusEnum focusOn = delayedSaveManagerImpl->getFocusOn();
const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus();
QWidget* widgetToFocus = delayedSaveManagerImpl->getWidgetToFocus();
saver->save(delayedSaveManagerImpl->isReloadAfterSave(), focusOn, tunnelNameToFocus, widgetToFocus);
continue;
}
if(defer) {
defer=false;
#define max(a,b) (((a)>(b))?(a):(b))
forever {
TIMESTAMP_TYPE now = DelayedSaveManagerImpl::getTime();
TIMESTAMP_TYPE millisToWait = max(wakeTime-now, 0);
if(millisToWait>0) {
waitCondition->wait(mutex, millisToWait);
if(delayedSaveManagerImpl->isExiting())return;
continue;
}
const FocusEnum focusOn = delayedSaveManagerImpl->getFocusOn();
const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus();
QWidget* widgetToFocus = delayedSaveManagerImpl->getWidgetToFocus();
saver->save(delayedSaveManagerImpl->isReloadAfterSave(), focusOn, tunnelNameToFocus, widgetToFocus);
break; //break inner loop
}
}
}
}
void DelayedSaveThread::wakeThreadAndJoinThread() {
waitCondition->wakeAll();
quit();
wait();//join //"similar to the POSIX pthread_join()"
}
DelayedSaveManagerImpl::TIMESTAMP_TYPE DelayedSaveManagerImpl::getTime() {
return QDateTime::currentMSecsSinceEpoch();
}
void DelayedSaveThread::deferSaveUntil(TIMESTAMP_TYPE wakeTime_) {
wakeTime = wakeTime_;
defer = true;
waitCondition->wakeAll();
}
void DelayedSaveThread::startSavingNow() {
//mutex->lock();
saveNow=true;
waitCondition->wakeAll();
//mutex->unlock();
}
DelayedSaveManagerImpl::~DelayedSaveManagerImpl() {
thread->wakeThreadAndJoinThread();
delete thread;
}
bool DelayedSaveManagerImpl::isExiting() {
return exiting;
}
Saver* DelayedSaveManagerImpl::getSaver() {
return saver;
}

84
src/DelayedSaveManagerImpl.h

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
#ifndef DELAYEDSAVEMANAGERIMPL_H
#define DELAYEDSAVEMANAGERIMPL_H
#include <QObject>
#include <QThread>
#include <QWaitCondition>
#include <QMutex>
#include <QDateTime>
#include "I2pdQtTypes.h"
#include "DelayedSaveManager.h"
#include "Saver.h"
class DelayedSaveManagerImpl;
class Saver;
class DelayedSaveThread : public QThread {
Q_OBJECT
public:
static constexpr unsigned long WAIT_TIME_MILLIS = 1000L;
typedef qint64 TIMESTAMP_TYPE;
static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=0;
DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl);
virtual ~DelayedSaveThread();
void run() override;
void deferSaveUntil(TIMESTAMP_TYPE wakeTime);
void startSavingNow();
void wakeThreadAndJoinThread();
private:
DelayedSaveManagerImpl* delayedSaveManagerImpl;
QMutex* mutex;
QWaitCondition* waitCondition;
volatile bool saveNow;
volatile bool defer;
volatile TIMESTAMP_TYPE wakeTime;
};
class DelayedSaveManagerImpl : public DelayedSaveManager {
FocusEnum focusOn;
std::string tunnelNameToFocus;
QWidget* widgetToFocus;
bool reloadAfterSave;
public:
DelayedSaveManagerImpl();
virtual ~DelayedSaveManagerImpl();
virtual void setSaver(Saver* saver);
virtual void start();
virtual void delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus);
virtual bool appExiting();
typedef DelayedSaveThread::TIMESTAMP_TYPE TIMESTAMP_TYPE;
static constexpr DATA_SERIAL_TYPE INITIAL_DATA_SERIAL=0;
bool isExiting();
Saver* getSaver();
static TIMESTAMP_TYPE getTime();
bool isReloadAfterSave() { return reloadAfterSave; }
FocusEnum getFocusOn() { return focusOn; }
std::string& getTunnelNameToFocus() { return tunnelNameToFocus; }
QWidget* getWidgetToFocus() { return widgetToFocus; }
private:
Saver* saver;
bool isSaverValid();
DATA_SERIAL_TYPE lastDataSerialSeen;
static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=DelayedSaveThread::A_VERY_OBSOLETE_TIMESTAMP;
TIMESTAMP_TYPE lastSaveStartedTimestamp;
bool exiting;
DelayedSaveThread* thread;
void wakeThreadAndJoinThread();
};
#endif // DELAYEDSAVEMANAGERIMPL_H

7
src/I2pdQtTypes.h

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
#ifndef I2PDQTTYPES_H
#define I2PDQTTYPES_H
enum WrongInputPageEnum { generalSettingsPage, tunnelsSettingsPage };
enum FocusEnum { noFocus, focusOnTunnelName, focusOnWidget };
#endif // I2PDQTTYPES_H

12
src/I2pdQtUtil.cpp

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
#include "I2pdQtUtil.h"
bool isValidSingleLine(QLineEdit* widget, WrongInputPageEnum inputPage, MainWindow* mainWindow) {
bool correct = !widget->text().contains(QRegularExpression("[\r\n]"), nullptr);
if(!correct) {
mainWindow->highlightWrongInput(
QApplication::tr("Single line input expected, but it's multiline"),
inputPage,
widget);
}
return correct;
}

9
src/I2pdQtUtil.h

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
#ifndef I2pdQtUtil_H
#define I2pdQtUtil_H
class QLineEdit;
#include "mainwindow.h"
bool isValidSingleLine(QLineEdit* widget, WrongInputPageEnum inputPage, MainWindow* mainWindow);
#endif // I2pdQtUtil_H

2
src/MainWindowItems.cpp

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
#include "MainWindowItems.h"

17
src/MainWindowItems.h

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
#ifndef MAINWINDOWITEMS_H
#define MAINWINDOWITEMS_H
#include <QString>
#include <QLineEdit>
#include <QPushButton>
#include <QComboBox>
#include <QCheckBox>
#include <sstream>
#include <functional>
#include "mainwindow.h"
class MainWindow;
#endif // MAINWINDOWITEMS_H

6
src/Saver.cpp

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
#include "Saver.h"
Saver::Saver()
{
}

25
src/Saver.h

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
#ifndef SAVER_H
#define SAVER_H
#include <string>
#include <QObject>
#include <QString>
class QWidget;
#include "I2pdQtTypes.h"
class Saver : public QObject
{
Q_OBJECT
public:
Saver();
//FocusEnum::focusNone iff failures //??? wtf
virtual bool save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus="", QWidget* widgetToFocus=nullptr)=0;
signals:
void reloadTunnelsConfigAndUISignal(const QString);
};
#endif // SAVER_H

81
src/SaverImpl.cpp

@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
#include "SaverImpl.h"
#include <fstream>
#include <assert.h>
#include <sstream>
#include "QList"
#include "QString"
#include "mainwindow.h"
SaverImpl::SaverImpl(MainWindow *mainWindowPtr_, QList<MainWindowItem*> * configItems_, std::map<std::string,TunnelConfig*>* tunnelConfigs_) :
configItems(configItems_), tunnelConfigs(tunnelConfigs_), confpath(), tunconfpath(), mainWindowPtr(mainWindowPtr_)
{}
SaverImpl::~SaverImpl() {}
bool SaverImpl::save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus, QWidget* widgetToFocus) {
//save main config
{
std::stringstream out;
for(QList<MainWindowItem*>::iterator it = configItems->begin(); it!= configItems->end(); ++it) {
MainWindowItem* item = *it;
item->saveToStringStream(out);
}
using namespace std;
QString backup=confpath+"~";
if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors
if(QFile::exists(confpath)) QFile::rename(confpath, backup);//TODO handle errors
ofstream outfile;
outfile.open(confpath.toStdString());//TODO handle errors
outfile << out.str().c_str();
outfile.close();
}
//save tunnels config
{
std::stringstream out;
for (std::map<std::string,TunnelConfig*>::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
if(QFile::exists(tunconfpath)) QFile::rename(tunconfpath, backup);//TODO handle errors
ofstream outfile;
outfile.open(tunconfpath.toStdString());//TODO handle errors
outfile << out.str().c_str();
outfile.close();
}
if(reloadAfterSave) {
//reload saved configs
#if 0
i2p::client::context.ReloadConfig();
#endif
if(reloadAfterSave) emit reloadTunnelsConfigAndUISignal(focusOn==FocusEnum::focusOnTunnelName?QString::fromStdString(tunnelNameToFocus):"");
}
return true;
}
void SaverImpl::setConfPath(QString& confpath_) { confpath = confpath_; }
void SaverImpl::setTunnelsConfPath(QString& tunconfpath_) { tunconfpath = tunconfpath_; }
/*void SaverImpl::setTunnelFocus(bool focusOnTunnel, std::string tunnelNameToFocus) {
this->focusOnTunnel=focusOnTunnel;
this->tunnelNameToFocus=tunnelNameToFocus;
}*/

33
src/SaverImpl.h

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
#ifndef SAVERIMPL_H
#define SAVERIMPL_H
#include <map>
#include <string>
#include <QObject>
#include "QList"
#include "mainwindow.h"
#include "TunnelConfig.h"
#include "Saver.h"
class MainWindowItem;
class TunnelConfig;
class SaverImpl : public Saver
{
public:
SaverImpl(MainWindow *mainWindowPtr_, QList<MainWindowItem*> * configItems_, std::map<std::string,TunnelConfig*>* tunnelConfigs_);
virtual ~SaverImpl();
virtual bool save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus, QWidget* widgetToFocus);
void setConfPath(QString& confpath_);
void setTunnelsConfPath(QString& tunconfpath_);
private:
QList<MainWindowItem*> * configItems;
std::map<std::string,TunnelConfig*>* tunnelConfigs;
QString confpath;
QString tunconfpath;
MainWindow* mainWindowPtr;
};
#endif // SAVERIMPL_H

278
src/ServerTunnelPane.cpp

@ -0,0 +1,278 @@ @@ -0,0 +1,278 @@
#include "ServerTunnelPane.h"
#include "ClientContext.h"
#include "SignatureTypeComboboxFactory.h"
ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow):
TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_, mainWindow) {}
void ServerTunnelPane::setGroupBoxTitle(const QString & title) {
serverTunnelNameGroupBox->setTitle(title);
}
int ServerTunnelPane::appendServerTunnelForm(
ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) {
ServerTunnelPane& ui = *this;
serverTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget);
serverTunnelNameGroupBox->setObjectName(QStringLiteral("serverTunnelNameGroupBox"));
//tunnel
gridLayoutWidget_2 = new QWidget(serverTunnelNameGroupBox);
QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2);
tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox"));
tunnelTypeComboBox->addItem("Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER);
tunnelTypeComboBox->addItem("HTTP", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP);
tunnelTypeComboBox->addItem("IRC", i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC);
tunnelTypeComboBox->addItem("UDP Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER);
int h=19*60;
gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h));
serverTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h));
{
const QString& type = tunnelConfig->getType();
int index=0;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER)tunnelTypeComboBox->setCurrentIndex(index);
++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"));
ui.hostLabel = new QLabel(gridLayoutWidget_2);
hostLabel->setObjectName(QStringLiteral("hostLabel"));
horizontalLayout_2->addWidget(hostLabel);
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);
int gridIndex = 2;
{
int port = tunnelConfig->getport();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.portLabel = new QLabel(gridLayoutWidget_2);
portLabel->setObjectName(QStringLiteral("portLabel"));
horizontalLayout_2->addWidget(portLabel);
ui.portLineEdit = new QLineEdit(gridLayoutWidget_2);
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);
}
{
std::string keys = tunnelConfig->getkeys();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.keysLabel = new QLabel(gridLayoutWidget_2);
keysLabel->setObjectName(QStringLiteral("keysLabel"));
horizontalLayout_2->addWidget(keysLabel);
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);
}
{
int inPort = tunnelConfig->getinPort();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.inPortLabel = new QLabel(gridLayoutWidget_2);
inPortLabel->setObjectName(QStringLiteral("inPortLabel"));
horizontalLayout_2->addWidget(inPortLabel);
ui.inPortLineEdit = new QLineEdit(gridLayoutWidget_2);
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);
}
{
std::string accessList = tunnelConfig->getaccessList();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.accessListLabel = new QLabel(gridLayoutWidget_2);
accessListLabel->setObjectName(QStringLiteral("accessListLabel"));
horizontalLayout_2->addWidget(accessListLabel);
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);
}
{
std::string hostOverride = tunnelConfig->gethostOverride();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.hostOverrideLabel = new QLabel(gridLayoutWidget_2);
hostOverrideLabel->setObjectName(QStringLiteral("hostOverrideLabel"));
horizontalLayout_2->addWidget(hostOverrideLabel);
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);
}
{
std::string webIRCPass = tunnelConfig->getwebircpass();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.webIRCPassLabel = new QLabel(gridLayoutWidget_2);
webIRCPassLabel->setObjectName(QStringLiteral("webIRCPassLabel"));
horizontalLayout_2->addWidget(webIRCPassLabel);
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);
}
{
bool gzip = tunnelConfig->getgzip();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
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);
}
{
i2p::data::SigningKeyType sigType = tunnelConfig->getsigType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.sigTypeLabel = new QLabel(gridLayoutWidget_2);
sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel"));
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);
QPushButton * lockButton2 = new QPushButton(gridLayoutWidget_2);
horizontalLayout_2->addWidget(lockButton2);
widgetlocks.add(new widgetlock(sigTypeComboBox, lockButton2));
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
std::string address = tunnelConfig->getaddress();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.addressLabel = new QLabel(gridLayoutWidget_2);
addressLabel->setObjectName(QStringLiteral("addressLabel"));
horizontalLayout_2->addWidget(addressLabel);
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);
}
{
bool isUniqueLocal = tunnelConfig->getisUniqueLocal();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
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);
}
{
int cryptoType = tunnelConfig->getcryptoType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2);
cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel"));
horizontalLayout_2->addWidget(cryptoTypeLabel);
ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2);
cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit"));
cryptoTypeLineEdit->setText(QString::number(cryptoType));
cryptoTypeLineEdit->setMaximumWidth(80);
QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(cryptoTypeLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters();
appendControlsForI2CPParameters(i2cpParameters, gridIndex);
}
retranslateServerTunnelForm(ui);
tunnelGridLayout->invalidate();
return h;
}
void ServerTunnelPane::deleteServerTunnelForm() {
TunnelPane::deleteTunnelForm();
delete serverTunnelNameGroupBox;//->deleteLater();
serverTunnelNameGroupBox=nullptr;
//gridLayoutWidget_2->deleteLater();
//gridLayoutWidget_2=nullptr;
}
ServerTunnelPane* ServerTunnelPane::asServerTunnelPane(){return this;}
ClientTunnelPane* ServerTunnelPane::asClientTunnelPane(){return nullptr;}

183
src/ServerTunnelPane.h

@ -0,0 +1,183 @@ @@ -0,0 +1,183 @@
#ifndef SERVERTUNNELPANE_H
#define SERVERTUNNELPANE_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QWidget>
#include "QVBoxLayout"
#include "QCheckBox"
#include "assert.h"
#include "TunnelPane.h"
#include "TunnelsPageUpdateListener.h"
class ServerTunnelConfig;
class ClientTunnelPane;
class ServerTunnelPane : public TunnelPane {
Q_OBJECT
public:
ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow);
virtual ~ServerTunnelPane(){}
virtual ServerTunnelPane* asServerTunnelPane();
virtual ClientTunnelPane* asClientTunnelPane();
int appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget,
int tunnelsRow, int height);
void deleteServerTunnelForm();
private:
QGroupBox *serverTunnelNameGroupBox;
//tunnel
QWidget *gridLayoutWidget_2;
//host
QHBoxLayout *horizontalLayout_2;
QLabel *hostLabel;
QLineEdit *hostLineEdit;
QSpacerItem *hostHorizontalSpacer;
//port
QLabel * portLabel;
QLineEdit * portLineEdit;
//keys
QLabel * keysLabel;
QLineEdit * keysLineEdit;
//inPort
QLabel * inPortLabel;
QLineEdit * inPortLineEdit;
//cryptoType
QLabel * cryptoTypeLabel;
QLineEdit * cryptoTypeLineEdit;
//accessList
QLabel * accessListLabel;
QLineEdit * accessListLineEdit;
//hostOverride
QLabel * hostOverrideLabel;
QLineEdit * hostOverrideLineEdit;
//webIRCPass
QLabel * webIRCPassLabel;
QLineEdit * webIRCPassLineEdit;
//address
QLabel * addressLabel;
QLineEdit * addressLineEdit;
//gzip
QCheckBox * gzipCheckBox;
//isUniqueLocal
QCheckBox * isUniqueLocalCheckBox;
//sigType
QLabel * sigTypeLabel;
QComboBox * sigTypeComboBox;
protected slots:
virtual void setGroupBoxTitle(const QString & title);
private:
void retranslateServerTunnelForm(ServerTunnelPane& /*ui*/) {
typeLabel->setText(QApplication::translate("srvTunForm", "Server tunnel type:", 0));
hostLabel->setText(QApplication::translate("srvTunForm", "Host:", 0));
portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0));
keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0));
inPortLabel->setText(QApplication::translate("srvTunForm", "InPort:", 0));
cryptoTypeLabel->setText(QApplication::translate("srvTunForm", "Crypto type:", 0));
accessListLabel->setText(QApplication::translate("srvTunForm", "Access list:", 0));
hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0));
webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0));
addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0));
gzipCheckBox->setText(QApplication::translate("srvTunForm", "GZip", 0));
isUniqueLocalCheckBox->setText(QApplication::translate("srvTunForm", "Is unique local", 0));
sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0));
}
protected:
virtual bool applyDataFromUIToTunnelConfig() {
QString cannotSaveSettings = QApplication::tr("Cannot save settings.");
bool ok=TunnelPane::applyDataFromUIToTunnelConfig();
if(!ok)return false;
ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig();
assert(stc!=nullptr);
if(!isValidSingleLine(hostLineEdit))return false;
if(!isValidSingleLine(portLineEdit))return false;
if(!isValidSingleLine(cryptoTypeLineEdit))return false;
if(!isValidSingleLine(keysLineEdit))return false;
if(!isValidSingleLine(inPortLineEdit))return false;
if(!isValidSingleLine(accessListLineEdit))return false;
if(!isValidSingleLine(hostOverrideLineEdit))return false;
if(!isValidSingleLine(webIRCPassLineEdit))return false;
if(!isValidSingleLine(addressLineEdit))return false;
stc->sethost(hostLineEdit->text().toStdString());
auto portStr=portLineEdit->text();
int portInt=portStr.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit);
return false;
}
stc->setport(portInt);
auto cryptoTypeStr=cryptoTypeLineEdit->text();
int cryptoTypeInt=cryptoTypeStr.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit);
return false;
}
stc->setcryptoType(cryptoTypeInt);
stc->setkeys(keysLineEdit->text().toStdString());
auto str=inPortLineEdit->text();
int inPortInt=str.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad inPort, must be int.")+" "+cannotSaveSettings,inPortLineEdit);
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());
stc->setgzip(gzipCheckBox->isChecked());
stc->setisUniqueLocal(isUniqueLocalCheckBox->isChecked());
stc->setsigType(readSigTypeComboboxUI(sigTypeComboBox));
return true;
}
};
#endif // SERVERTUNNELPANE_H

2
src/SignatureTypeComboboxFactory.cpp

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
#include "SignatureTypeComboboxFactory.h"

86
src/SignatureTypeComboboxFactory.h

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
#ifndef SIGNATURETYPECOMBOBOXFACTORY_H
#define SIGNATURETYPECOMBOBOXFACTORY_H
#include <QApplication>
#include <QComboBox>
#include <QWidget>
#include "Identity.h"
class SignatureTypeComboBoxFactory
{
static const QVariant createUserData(const uint16_t sigType) {
return QVariant::fromValue((uint)sigType);
}
static void addItem(QComboBox* signatureTypeCombobox, QString text, const uint16_t sigType) {
const QVariant userData = createUserData(sigType);
signatureTypeCombobox->addItem(text, userData);
}
public:
static uint16_t getSigType(const QVariant& var) {
return (uint16_t)var.toInt();
}
static void fillComboBox(QComboBox* signatureTypeCombobox, uint16_t selectedSigType) {
/*
<orignal> https://geti2p.net/spec/common-structures#certificate
<orignal> все коды перечислены
<Hypnosis> это таблица "The defined Signing Public Key types are:" ?
<orignal> да
see also: Identity.h line 55
*/
int index=0;
bool foundSelected=false;
using namespace i2p::data;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "DSA_SHA1", 0), SIGNING_KEY_TYPE_DSA_SHA1); //0
if(selectedSigType==SIGNING_KEY_TYPE_DSA_SHA1){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA256_P256", 0), SIGNING_KEY_TYPE_ECDSA_SHA256_P256); //1
if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA256_P256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA384_P384", 0), SIGNING_KEY_TYPE_ECDSA_SHA384_P384); //2
if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA384_P384){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA512_P521", 0), SIGNING_KEY_TYPE_ECDSA_SHA512_P521); //3
if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA512_P521){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA256_2048", 0), SIGNING_KEY_TYPE_RSA_SHA256_2048); //4
if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA256_2048){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA384_3072", 0), SIGNING_KEY_TYPE_RSA_SHA384_3072); //5
if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA384_3072){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA512_4096", 0), SIGNING_KEY_TYPE_RSA_SHA512_4096); //6
if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA512_4096){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); //7
if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519PH", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph); //8
if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
// the following signature type should never appear in netid=2
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256", 0), SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256); //9
if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512); //10
if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
if(!foundSelected){
addItem(signatureTypeCombobox, QString::number(selectedSigType), selectedSigType); //unknown sigtype
signatureTypeCombobox->setCurrentIndex(index);
}
}
static QComboBox* createSignatureTypeComboBox(QWidget* parent, uint16_t selectedSigType) {
QComboBox* signatureTypeCombobox = new QComboBox(parent);
fillComboBox(signatureTypeCombobox, selectedSigType);
return signatureTypeCombobox;
}
};
#endif // SIGNATURETYPECOMBOBOXFACTORY_H

67
src/TunnelConfig.cpp

@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
#include "TunnelConfig.h"
void TunnelConfig::saveHeaderToStringStream(std::stringstream& out) {
out << "[" << name << "]\n"
<< "type=" << type.toStdString() << "\n";
}
void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) {
if (i2cpParameters.getInbound_length().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNEL_LENGTH)
out << i2p::client::I2CP_PARAM_INBOUND_TUNNEL_LENGTH << "="
<< i2cpParameters.getInbound_length().toStdString() << "\n";
if (i2cpParameters.getOutbound_length().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNEL_LENGTH)
out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH << "="
<< i2cpParameters.getOutbound_length().toStdString() << "\n";
if (i2cpParameters.getInbound_quantity().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNELS_QUANTITY)
out << i2p::client::I2CP_PARAM_INBOUND_TUNNELS_QUANTITY << "="
<< i2cpParameters.getInbound_quantity().toStdString() << "\n";
if (i2cpParameters.getOutbound_quantity().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNELS_QUANTITY)
out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY << "="
<< i2cpParameters.getOutbound_quantity().toStdString() << "\n";
if (i2cpParameters.getCrypto_tagsToSend().toUShort() != i2p::client::DEFAULT_TAGS_TO_SEND)
out << i2p::client::I2CP_PARAM_TAGS_TO_SEND << "="
<< i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n";
if (!i2cpParameters.getExplicitPeers().isEmpty()) //todo #947
out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "="
<< i2cpParameters.getExplicitPeers().toStdString() << "\n";
out << i2p::client::I2CP_PARAM_LEASESET_AUTH_TYPE << "="
<< i2cpParameters.get_i2cp_leaseSetAuthType().toStdString() << "\n";
out << i2p::client::I2CP_PARAM_LEASESET_ENCRYPTION_TYPE << "="
<< i2cpParameters.get_i2cp_leaseSetEncType().toStdString() << "\n";
out << i2p::client::I2CP_PARAM_LEASESET_PRIV_KEY << "="
<< i2cpParameters.get_i2cp_leaseSetPrivKey().toStdString() << "\n";
out << i2p::client::I2CP_PARAM_LEASESET_TYPE << "="
<< i2cpParameters.get_i2cp_leaseSetType().toStdString() << "\n";
out << i2p::client::I2CP_PARAM_STREAMING_ANSWER_PINGS << "="
<< (i2cpParameters.get_i2p_streaming_answerPings() ? "true" : "false") << "\n";
out << i2p::client::I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY << "="
<< i2cpParameters.get_i2p_streaming_initialAckDelay().toStdString() << "\n";
out << "\n";
}
void ClientTunnelConfig::saveToStringStream(std::stringstream& out) {
out << "address=" << address << "\n"
<< "port=" << port << "\n"
<< "destination=" << dest << "\n"
<< "destinationport=" << destinationPort << "\n"
<< "cryptoType=" << getcryptoType() << "\n"
<< "signaturetype=" << sigType << "\n";
if(!keys.empty()) out << "keys=" << keys << "\n";
}
void ServerTunnelConfig::saveToStringStream(std::stringstream& out) {
out << "host=" << host << "\n"
<< "port=" << port << "\n"
<< "signaturetype=" << sigType << "\n"
<< "inport=" << inPort << "\n";
if(accessList.size()>0) { out << "accesslist=" << accessList << "\n"; }
out << "gzip=" << (gzip?"true":"false") << "\n"
<< "cryptoType=" << getcryptoType() << "\n"
<< "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n"
<< "address=" << address << "\n"
<< "hostoverride=" << hostOverride << "\n"
<< "webircpassword=" << webircpass << "\n";
if(!keys.empty()) out << "keys=" << keys << "\n";
}

260
src/TunnelConfig.h

@ -0,0 +1,260 @@ @@ -0,0 +1,260 @@
#ifndef TUNNELCONFIG_H
#define TUNNELCONFIG_H
#include "QString"
#include <string>
#include "ClientContext.h"
#include "Destination.h"
#include "TunnelsPageUpdateListener.h"
class I2CPParameters{
QString inbound_length;//number of hops of an inbound tunnel. 3 by default; lower value is faster but dangerous
QString outbound_length;//number of hops of an outbound tunnel. 3 by default; lower value is faster but dangerous
QString inbound_quantity; //number of inbound tunnels. 5 by default
QString outbound_quantity; //number of outbound tunnels. 5 by default
QString crypto_tagsToSend; //number of ElGamal/AES tags to send. 40 by default; too low value may cause problems with tunnel building
QString explicitPeers; //list of comma-separated b64 addresses of peers to use, default: unset
QString i2p_streaming_initialAckDelay; //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default
bool i2p_streaming_answerPings; //i2p.streaming.answerPings -- enable sending pongs. true by default
QString i2cp_leaseSetType; //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default
QString i2cp_leaseSetEncType; //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default
QString i2cp_leaseSetPrivKey; //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH
QString i2cp_leaseSetAuthType; //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK
public:
I2CPParameters(): inbound_length(),
outbound_length(),
inbound_quantity(),
outbound_quantity(),
crypto_tagsToSend(),
explicitPeers(),
i2p_streaming_initialAckDelay(),
i2p_streaming_answerPings(true),
i2cp_leaseSetType(),
i2cp_leaseSetEncType(),
i2cp_leaseSetPrivKey(),
i2cp_leaseSetAuthType() {}
const QString& getInbound_length(){return inbound_length;}
const QString& getOutbound_length(){return outbound_length;}
const QString& getInbound_quantity(){return inbound_quantity;}
const QString& getOutbound_quantity(){return outbound_quantity;}
const QString& getCrypto_tagsToSend(){return crypto_tagsToSend;}
const QString& getExplicitPeers(){return explicitPeers;}
const QString& get_i2p_streaming_initialAckDelay(){return i2p_streaming_initialAckDelay;}
bool get_i2p_streaming_answerPings(){return i2p_streaming_answerPings;}
const QString& get_i2cp_leaseSetType(){return i2cp_leaseSetType;}
const QString& get_i2cp_leaseSetEncType(){return i2cp_leaseSetEncType;}
const QString& get_i2cp_leaseSetPrivKey(){return i2cp_leaseSetPrivKey;}
const QString& get_i2cp_leaseSetAuthType(){return i2cp_leaseSetAuthType;}
void setInbound_length(QString inbound_length_){inbound_length=inbound_length_;}
void setOutbound_length(QString outbound_length_){outbound_length=outbound_length_;}
void setInbound_quantity(QString inbound_quantity_){inbound_quantity=inbound_quantity_;}
void setOutbound_quantity(QString outbound_quantity_){outbound_quantity=outbound_quantity_;}
void setCrypto_tagsToSend(QString crypto_tagsToSend_){crypto_tagsToSend=crypto_tagsToSend_;}
void setExplicitPeers(QString explicitPeers_){explicitPeers=explicitPeers_;}
void set_i2p_streaming_initialAckDelay(QString i2p_streaming_initialAckDelay_){i2p_streaming_initialAckDelay=i2p_streaming_initialAckDelay_;}
void set_i2p_streaming_answerPings(bool i2p_streaming_answerPings_){i2p_streaming_answerPings=i2p_streaming_answerPings_;}
void set_i2cp_leaseSetType(QString i2cp_leaseSetType_){i2cp_leaseSetType=i2cp_leaseSetType_;}
void set_i2cp_leaseSetEncType(QString i2cp_leaseSetEncType_){i2cp_leaseSetEncType=i2cp_leaseSetEncType_;}
void set_i2cp_leaseSetPrivKey(QString i2cp_leaseSetPrivKey_){i2cp_leaseSetPrivKey=i2cp_leaseSetPrivKey_;}
void set_i2cp_leaseSetAuthType(QString i2cp_leaseSetAuthType_){i2cp_leaseSetAuthType=i2cp_leaseSetAuthType_;}
};
class ClientTunnelConfig;
class ServerTunnelConfig;
class TunnelPane;
class TunnelConfig {
/*
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 type;
std::string name;
TunnelPane* tunnelPane;
int cryptoType;
public:
TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_, int cryptoType_):
type(type_), name(name_), cryptoType(cryptoType_), i2cpParameters(i2cpParameters_) {}
virtual ~TunnelConfig(){}
const QString& getType(){return type;}
const std::string& getName(){return name;}
int getcryptoType(){return cryptoType;}
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;
void setTunnelPane(TunnelPane* tp){this->tunnelPane = tp;}
TunnelPane* getTunnelPane() {return tunnelPane;}
void setcryptoType(int cryptoType_){cryptoType=cryptoType_;}
private:
I2CPParameters i2cpParameters;
};
/*
# mandatory parameters:
std::string dest;
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION);
int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT);
# optional parameters (may be omitted)
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 destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
# * keys -- our identity, if unset, will be generated on every startup,
# if set and file missing, keys will be generated and placed to this file
# * address -- local interface to bind
# * signaturetype -- signature type for new destination. 0 (DSA/SHA1), 1 (EcDSA/SHA256) or 7 (EdDSA/SHA512)
[somelabel]
type = client
address = 127.0.0.1
port = 6668
destination = irc.postman.i2p
keys = irc-keys.dat
*/
class ClientTunnelConfig : public TunnelConfig {
std::string dest;
int port;
std::string keys;
std::string address;
int destinationPort;
i2p::data::SigningKeyType sigType;
public:
ClientTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_,
std::string dest_,
int port_,
std::string keys_,
std::string address_,
int destinationPort_,
i2p::data::SigningKeyType sigType_,
int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_),
dest(dest_),
port(port_),
keys(keys_),
address(address_),
destinationPort(destinationPort_),
sigType(sigType_) {}
std::string& getdest(){return dest;}
int getport(){return port;}
std::string & getkeys(){return keys;}
std::string & getaddress(){return address;}
int getdestinationPort(){return destinationPort;}
i2p::data::SigningKeyType getsigType(){return sigType;}
void setdest(const std::string& dest_){dest=dest_;}
void setport(int port_){port=port_;}
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;}
};
/*
# mandatory parameters:
# * host -- ip address of our service
# * port -- port of our service
# * keys -- file with LeaseSet of address in i2p
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
int port = section.second.get<int> (I2P_SERVER_TUNNEL_PORT);
std::string keys = section.second.get<std::string> (I2P_SERVER_TUNNEL_KEYS);
# optional parameters (may be omitted)
int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0);
std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, "");
std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, "");
std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
# * inport -- optional, i2p service port, if unset - the same as 'port'
# * accesslist -- comma-separated list of i2p addresses, allowed to connect
# every address is b32 without '.b32.i2p' part
[somelabel]
type = server
host = 127.0.0.1
port = 6667
keys = irc.dat
*/
class ServerTunnelConfig : public TunnelConfig {
std::string host;
int port;
std::string keys;
int inPort;
std::string accessList;
std::string hostOverride;
std::string webircpass;
bool gzip;
i2p::data::SigningKeyType sigType;
std::string address;
bool isUniqueLocal;
public:
ServerTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_,
std::string host_,
int port_,
std::string keys_,
int inPort_,
std::string accessList_,
std::string hostOverride_,
std::string webircpass_,
bool gzip_,
i2p::data::SigningKeyType sigType_,
std::string address_,
bool isUniqueLocal_,
int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_),
host(host_),
port(port_),
keys(keys_),
inPort(inPort_),
accessList(accessList_),
hostOverride(hostOverride_),
webircpass(webircpass_),
gzip(gzip_),
sigType(sigType_),
address(address_),
isUniqueLocal(isUniqueLocal_) {}
std::string& gethost(){return host;}
int getport(){return port;}
std::string& getkeys(){return keys;}
int getinPort(){return inPort;}
std::string& getaccessList(){return accessList;}
std::string& gethostOverride(){return hostOverride;}
std::string& getwebircpass(){return webircpass;}
bool getgzip(){return gzip;}
i2p::data::SigningKeyType getsigType(){return sigType;}
std::string& getaddress(){return address;}
bool getisUniqueLocal(){return isUniqueLocal;}
void sethost(const std::string& host_){host=host_;}
void setport(int port_){port=port_;}
void setkeys(const std::string& keys_){keys=keys_;}
void setinPort(int inPort_){inPort=inPort_;}
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 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;}
};
#endif // TUNNELCONFIG_H

405
src/TunnelPane.cpp

@ -0,0 +1,405 @@ @@ -0,0 +1,405 @@
#include "TunnelPane.h"
#include "QMessageBox"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "I2pdQtUtil.h"
TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_):
QObject(),
mainWindow(mainWindow_),
wrongInputPane(wrongInputPane_),
wrongInputLabel(wrongInputLabel_),
tunnelConfig(tunnelConfig_),
tunnelsPageUpdateListener(tunnelsPageUpdateListener_),
gridLayoutWidget_2(nullptr) {}
void TunnelPane::setupTunnelPane(
TunnelConfig* tunnelConfig,
QGroupBox *tunnelGroupBox,
QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox,
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 QVBoxLayout(gridLayoutWidget_2);
tunnelGridLayout->setObjectName(QStringLiteral("tunnelGridLayout"));
tunnelGridLayout->setContentsMargins(10, 25, 10, 10);
tunnelGridLayout->setSpacing(5);
//header
QHBoxLayout *headerHorizontalLayout = new QHBoxLayout();
headerHorizontalLayout->setObjectName(QStringLiteral("headerHorizontalLayout"));
nameLabel = new QLabel(gridLayoutWidget_2);
nameLabel->setObjectName(QStringLiteral("nameLabel"));
headerHorizontalLayout->addWidget(nameLabel);
nameLineEdit = new QLineEdit(gridLayoutWidget_2);
nameLineEdit->setObjectName(QStringLiteral("nameLineEdit"));
const QString& tunnelName=tunnelConfig->getName().c_str();
nameLineEdit->setText(tunnelName);
setGroupBoxTitle(tunnelName);
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);
deletePushButton->setObjectName(QStringLiteral("deletePushButton"));
QObject::connect(deletePushButton, SIGNAL(released()),
this, SLOT(deleteButtonReleased()));//MainWindow::DeleteTunnelNamed(std::string name) {
headerHorizontalLayout->addWidget(deletePushButton);
tunnelGridLayout->addLayout(headerHorizontalLayout);
//type
{
//const QString& type = tunnelConfig->getType();
QHBoxLayout * horizontalLayout_ = new QHBoxLayout();
horizontalLayout_->setObjectName(QStringLiteral("horizontalLayout_"));
typeLabel = new QLabel(gridLayoutWidget_2);
typeLabel->setObjectName(QStringLiteral("typeLabel"));
horizontalLayout_->addWidget(typeLabel);
horizontalLayout_->addWidget(tunnelTypeComboBox);
QPushButton * lockButton1 = new QPushButton(gridLayoutWidget_2);
horizontalLayout_->addWidget(lockButton1);
widgetlocks.add(new widgetlock(tunnelTypeComboBox, lockButton1));
this->tunnelTypeComboBox=tunnelTypeComboBox;
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_);
}
retranslateTunnelForm(*this);
}
void TunnelPane::deleteWidget() {
//gridLayoutWidget_2->deleteLater();
tunnelGroupBox->deleteLater();
}
void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex) {
{
//number of hops of an inbound tunnel
const QString& inbound_length=i2cpParameters.getInbound_length();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
inbound_lengthLabel = new QLabel(gridLayoutWidget_2);
inbound_lengthLabel->setObjectName(QStringLiteral("inbound_lengthLabel"));
horizontalLayout_2->addWidget(inbound_lengthLabel);
inbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2);
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);
}
{
//number of hops of an outbound tunnel
const QString& outbound_length=i2cpParameters.getOutbound_length();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
outbound_lengthLabel = new QLabel(gridLayoutWidget_2);
outbound_lengthLabel->setObjectName(QStringLiteral("outbound_lengthLabel"));
horizontalLayout_2->addWidget(outbound_lengthLabel);
outbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2);
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);
}
{
//number of inbound tunnels
const QString& inbound_quantity=i2cpParameters.getInbound_quantity();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
inbound_quantityLabel = new QLabel(gridLayoutWidget_2);
inbound_quantityLabel->setObjectName(QStringLiteral("inbound_quantityLabel"));
horizontalLayout_2->addWidget(inbound_quantityLabel);
inbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2);
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);
}
{
//number of outbound tunnels
const QString& outbound_quantity=i2cpParameters.getOutbound_quantity();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
outbound_quantityLabel = new QLabel(gridLayoutWidget_2);
outbound_quantityLabel->setObjectName(QStringLiteral("outbound_quantityLabel"));
horizontalLayout_2->addWidget(outbound_quantityLabel);
outbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2);
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);
}
{
//number of ElGamal/AES tags to send
const QString& crypto_tagsToSend=i2cpParameters.getCrypto_tagsToSend();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
crypto_tagsToSendLabel = new QLabel(gridLayoutWidget_2);
crypto_tagsToSendLabel->setObjectName(QStringLiteral("crypto_tagsToSendLabel"));
horizontalLayout_2->addWidget(crypto_tagsToSendLabel);
crypto_tagsToSendLineEdit = new QLineEdit(gridLayoutWidget_2);
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);
}
{
//explicitPeers -- list of comma-separated b64 addresses of peers to use, default: unset
const QString& value=i2cpParameters.getExplicitPeers();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
explicitPeersLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
explicitPeersLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default
const QString& value=i2cpParameters.get_i2p_streaming_initialAckDelay();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
i2p_streaming_initialAckDelayLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
i2p_streaming_initialAckDelayLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2p.streaming.answerPings -- enable sending pongs. true by default
const bool value=i2cpParameters.get_i2p_streaming_answerPings();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QCheckBox *_CheckBox;
i2p_streaming_answerPingsCheckBox = _CheckBox = new QCheckBox(gridLayoutWidget_2);
_CheckBox->setObjectName(QStringLiteral("_CheckBox"));
horizontalLayout_2->addWidget(_CheckBox);
_CheckBox->setChecked(value);
QObject::connect(_CheckBox, SIGNAL(toggled(bool)),
this, SLOT(updated()));
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default
const QString& value=i2cpParameters.get_i2cp_leaseSetType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
i2cp_leaseSetTypeLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
i2cp_leaseSetTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default
const QString& value=i2cpParameters.get_i2cp_leaseSetEncType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
i2cp_leaseSetEncTypeLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
i2cp_leaseSetEncTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH
const QString& value=i2cpParameters.get_i2cp_leaseSetPrivKey();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
i2cp_leaseSetPrivKeyLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
i2cp_leaseSetPrivKeyLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK
const QString& value=i2cpParameters.get_i2cp_leaseSetAuthType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
i2cp_leaseSetAuthTypeLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
i2cp_leaseSetAuthTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
retranslateI2CPParameters();
}
void TunnelPane::updated() {
std::string oldName=tunnelConfig->getName();
//validate and show red if invalid
hideWrongInputLabel();
if(!mainWindow->applyTunnelsUiToConfigs())return;
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
hideWrongInputLabel();
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();
}
void TunnelPane::deleteTunnelForm() {
widgetlocks.deleteListeners();
}
void TunnelPane::highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) {
wrongInputPane->setVisible(true);
wrongInputLabel->setText(warningText);
mainWindow->adjustSizesAccordingToWrongLabel();
if(controlWithWrongInput){
mainWindow->ui->tunnelsScrollArea->ensureWidgetVisible(controlWithWrongInput);
controlWithWrongInput->setFocus();
}
mainWindow->showTunnelsPage();
}
void TunnelPane::hideWrongInputLabel() const {
wrongInputPane->setVisible(false);
mainWindow->adjustSizesAccordingToWrongLabel();
}
bool TunnelPane::isValidSingleLine(QLineEdit* widget) {
return ::isValidSingleLine(widget, WrongInputPageEnum::tunnelsSettingsPage, mainWindow);
}

191
src/TunnelPane.h

@ -0,0 +1,191 @@ @@ -0,0 +1,191 @@
#ifndef TUNNELPANE_H
#define TUNNELPANE_H
#include "QObject"
#include "QWidget"
#include "QComboBox"
#include "QGridLayout"
#include "QLabel"
#include "QPushButton"
#include "QApplication"
#include "QLineEdit"
#include "QGroupBox"
#include "QVBoxLayout"
#include "QCheckBox"
#include "TunnelConfig.h"
#include <widgetlock.h>
#include <widgetlockregistry.h>
class ServerTunnelPane;
class ClientTunnelPane;
class TunnelConfig;
class I2CPParameters;
class MainWindow;
class TunnelPane : public QObject {
Q_OBJECT
public:
TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_);
virtual ~TunnelPane(){}
void deleteTunnelForm();
void hideWrongInputLabel() const;
void highlightWrongInput(QString warningText, QWidget* controlWithWrongInput);
virtual ServerTunnelPane* asServerTunnelPane()=0;
virtual ClientTunnelPane* asClientTunnelPane()=0;
void deleteWidget();
protected:
MainWindow* mainWindow;
QWidget * wrongInputPane;
QLabel* wrongInputLabel;
TunnelConfig* tunnelConfig;
widgetlockregistry widgetlocks;
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;
//type
QComboBox *tunnelTypeComboBox;
QLabel *typeLabel;
//i2cp
QLabel * inbound_lengthLabel;
QLineEdit * inbound_lengthLineEdit;
QLabel * outbound_lengthLabel;
QLineEdit * outbound_lengthLineEdit;
QLabel * inbound_quantityLabel;
QLineEdit * inbound_quantityLineEdit;
QLabel * outbound_quantityLabel;
QLineEdit * outbound_quantityLineEdit;
QLabel * crypto_tagsToSendLabel;
QLineEdit * crypto_tagsToSendLineEdit;
QLabel * explicitPeersLabel;
QLineEdit * explicitPeersLineEdit;
QLabel * i2p_streaming_initialAckDelayLabel;
QLineEdit * i2p_streaming_initialAckDelayLineEdit;
QCheckBox * i2p_streaming_answerPingsCheckBox;
QLabel * i2cp_leaseSetTypeLabel;
QLineEdit * i2cp_leaseSetTypeLineEdit;
QLabel * i2cp_leaseSetEncTypeLabel;
QLineEdit * i2cp_leaseSetEncTypeLineEdit;
QLabel * i2cp_leaseSetPrivKeyLabel;
QLineEdit * i2cp_leaseSetPrivKeyLineEdit;
QLabel * i2cp_leaseSetAuthTypeLabel;
QLineEdit * i2cp_leaseSetAuthTypeLineEdit;
QString readTunnelTypeComboboxData();
//should be created by factory
i2p::data::SigningKeyType readSigTypeComboboxUI(QComboBox* sigTypeComboBox);
public:
//returns false when invalid data at UI
virtual bool applyDataFromUIToTunnelConfig() {
if(!isValidSingleLine(nameLineEdit)){
setGroupBoxTitle(QApplication::translate("tunPage", "invalid_tunnel_name"));
return false;
}
if(!isValidSingleLine(inbound_lengthLineEdit))return false;
if(!isValidSingleLine(inbound_quantityLineEdit))return false;
if(!isValidSingleLine(outbound_lengthLineEdit))return false;
if(!isValidSingleLine(outbound_quantityLineEdit))return false;
if(!isValidSingleLine(crypto_tagsToSendLineEdit))return false;
if(!isValidSingleLine(i2cp_leaseSetAuthTypeLineEdit))return false;
if(!isValidSingleLine(i2cp_leaseSetEncTypeLineEdit))return false;
if(!isValidSingleLine(i2cp_leaseSetPrivKeyLineEdit))return false;
if(!isValidSingleLine(i2cp_leaseSetTypeLineEdit))return false;
if(!isValidSingleLine(i2p_streaming_initialAckDelayLineEdit))return false;
setGroupBoxTitle(nameLineEdit->text());
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());
i2cpParams.set_i2cp_leaseSetAuthType(i2cp_leaseSetAuthTypeLineEdit->text());
i2cpParams.set_i2cp_leaseSetEncType(i2cp_leaseSetEncTypeLineEdit->text());
i2cpParams.set_i2cp_leaseSetPrivKey(i2cp_leaseSetPrivKeyLineEdit->text());
i2cpParams.set_i2cp_leaseSetType(i2cp_leaseSetTypeLineEdit->text());
i2cpParams.set_i2p_streaming_answerPings(i2p_streaming_answerPingsCheckBox->isChecked());
i2cpParams.set_i2p_streaming_initialAckDelay(i2p_streaming_initialAckDelayLineEdit->text());
return true;
}
protected:
void setupTunnelPane(
TunnelConfig* tunnelConfig,
QGroupBox *tunnelGroupBox,
QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox,
QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h);
void appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex);
public:
int height() {
return gridLayoutWidget_2?gridLayoutWidget_2->height():0;
}
protected slots:
virtual void setGroupBoxTitle(const QString & title)=0;
private:
void retranslateTunnelForm(TunnelPane& ui) {
ui.deletePushButton->setText(QApplication::translate("tunForm", "Delete Tunnel", 0));
ui.nameLabel->setText(QApplication::translate("tunForm", "Tunnel name:", 0));
}
void retranslateI2CPParameters() {
inbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an inbound tunnel:", 0));;
outbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an outbound tunnel:", 0));;
inbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of inbound tunnels:", 0));;
outbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of outbound tunnels:", 0));;
crypto_tagsToSendLabel->setText(QApplication::translate("tunForm", "Number of ElGamal/AES tags to send:", 0));;
explicitPeersLabel->setText(QApplication::translate("tunForm", "List of comma-separated b64 addresses of peers to use:", 0));;
i2p_streaming_initialAckDelayLabel->setText(QApplication::translate("tunForm", "Milliseconds to wait before sending Ack:", 0));
i2p_streaming_answerPingsCheckBox->setText(QApplication::translate("tunForm", "Enable sending pongs", 0));
i2cp_leaseSetTypeLabel->setText(QApplication::translate("tunForm", "Type of LeaseSet to be sent. 1, 3 or 5:", 0));
i2cp_leaseSetEncTypeLabel->setText(QApplication::translate("tunForm", "Comma-separ. encr. types to be used in LeaseSet type 3 or 5:", 0));
i2cp_leaseSetPrivKeyLabel->setText(QApplication::translate("tunForm", "Decryption key for encrypted LeaseSet in base64. PSK or private DH:", 0));
i2cp_leaseSetAuthTypeLabel->setText(QApplication::translate("tunForm", "Auth type for encrypted LeaseSet. 0 - no auth, 1 - DH, 2 - PSK:", 0));
}
protected:
bool isValidSingleLine(QLineEdit* widget);
};
#endif // TUNNELPANE_H

12
src/TunnelsPageUpdateListener.h

@ -0,0 +1,12 @@ @@ -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

3810
src/generalsettingswidget.ui

File diff suppressed because it is too large Load Diff

1
src/i2pd

@ -0,0 +1 @@ @@ -0,0 +1 @@
Subproject commit 9e5935aea5c979a3a41a1c200811687b48356f68

6
src/i2pd.qrc

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/icons">
<file alias="mask">resources/icons/mask.ico</file>
<file alias="icon">resources/images/icon.png</file>
</qresource>
</RCC>

32
src/i2pd.rc

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
IDI_ICON1 ICON DISCARDABLE "resources/icons/mask.ico"
#include <windows.h> // needed for VERSIONINFO
#include "i2pd/libi2pd/version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH
PRODUCTVERSION I2P_VERSION_MAJOR,I2P_VERSION_MINOR,I2P_VERSION_MICRO,I2P_VERSION_PATCH
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4" // U.S. English - multilingual (hex)
BEGIN
VALUE "CompanyName", "PurpleI2P"
VALUE "FileDescription", "I2Pd Qt"
VALUE "FileVersion", I2PD_VERSION
VALUE "InternalName", "i2pd-qt"
VALUE "LegalCopyright", "Copyright (C) 2013-2020, The PurpleI2P Project"
VALUE "LegalTrademarks1", "Distributed under the BSD 3-Clause software license, see the accompanying file COPYING or https://opensource.org/licenses/BSD-3-Clause."
VALUE "OriginalFilename", "i2pd_qt.exe"
VALUE "ProductName", "i2pd-qt"
VALUE "ProductVersion", I2P_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
END
END

45
src/logviewermanager.cpp

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
#include "logviewermanager.h"
LogViewerManager::LogViewerManager(std::shared_ptr<std::iostream> logStream_,
QPlainTextEdit* logTextEdit_,
QObject *parent) :
QObject(parent),
logStream(logStream_),
logTextEdit(logTextEdit_),
controllerForBgThread(nullptr)
{
assert(logTextEdit!=nullptr);
controllerForBgThread=new i2pd::qt::logviewer::Controller(*this);
}
namespace i2pd {
namespace qt {
namespace logviewer {
QString Worker::pollAndShootATimerForInfiniteRetries() {
std::shared_ptr<std::iostream> logStream=logViewerManager.getLogStream();
if(!logStream)return "";
std::streamsize MAX_SZ=64*1024;
char*buf=(char*)malloc(MAX_SZ*sizeof(char));
if(buf==nullptr)return "";
std::streamsize read=logStream->readsome(buf, MAX_SZ);
if(read<0)read=0;
QString ret=QString::fromUtf8(buf, read);
free(buf);
return ret;
}
Controller::Controller(LogViewerManager &parameter1):logViewerManager(parameter1) {
Worker *worker = new Worker(parameter1);
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::operate1, worker, &Worker::doWork1);
connect(worker, &Worker::resultReady,
&parameter1, &LogViewerManager::appendPlainText_atGuiThread);
workerThread.start();
timerId=startTimer(100/*millis*/);
}
}
}
}

130
src/logviewermanager.h

@ -0,0 +1,130 @@ @@ -0,0 +1,130 @@
#ifndef LOGVIEWERMANAGER_H
#define LOGVIEWERMANAGER_H
#include <QObject>
#include <QString>
#include <QPlainTextEdit>
#include <QScrollBar>
#include <QComboBox>
#include <QTimer>
#include <QThread>
#include <assert.h>
#include <string>
#include "FS.h"
#include "Log.h"
class LogViewerManager;
namespace i2pd {
namespace qt {
namespace logviewer {
class Worker : public QObject
{
Q_OBJECT
private:
LogViewerManager &logViewerManager;
public:
Worker(LogViewerManager &parameter1):logViewerManager(parameter1){}
private:
QString pollAndShootATimerForInfiniteRetries();
public slots:
void doWork1() {
/* ... here is the expensive or blocking operation ... */
QString read=pollAndShootATimerForInfiniteRetries();
emit resultReady(read);
}
signals:
void resultReady(QString read);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
LogViewerManager& logViewerManager;
int timerId;
public:
Controller(LogViewerManager &parameter1);
~Controller() {
if(timerId!=0)killTimer(timerId);
workerThread.quit();
workerThread.wait();
}
signals:
void operate1();
protected:
void timerEvent(QTimerEvent */*event*/) {
emit operate1();
}
};
}
}
}
class LogViewerManager : public QObject
{
Q_OBJECT
private:
std::shared_ptr<std::iostream> logStream;
QPlainTextEdit* logTextEdit;
i2pd::qt::logviewer::Controller* controllerForBgThread;
public:
//also starts a bg thread (QTimer) polling logStream->readsome(buf, n)
explicit LogViewerManager(std::shared_ptr<std::iostream> logStream_,
QPlainTextEdit* logTextEdit_,
QObject *parent);
//also deallocs the bg thread (QTimer)
virtual ~LogViewerManager(){}
const i2pd::qt::logviewer::Controller& getControllerForBgThread() {
assert(controllerForBgThread!=nullptr);
return *controllerForBgThread;
}
const QPlainTextEdit* getLogTextEdit(){ return logTextEdit; }
const std::shared_ptr<std::iostream> getLogStream(){ return logStream; }
signals:
public slots:
//void appendFromNonGuiThread(std::string read) {
//}
public slots:
void appendPlainText_atGuiThread(QString plainText) {
if(plainText.length()==0)return;
assert(logTextEdit!=nullptr);
int scrollPosVert =logTextEdit->verticalScrollBar()->value();
int scrollPosHoriz=logTextEdit->horizontalScrollBar()->value();
int scrollPosVertMax =logTextEdit->verticalScrollBar()->maximum();
const int MAX_LINES=10*1024;
logTextEdit->setMaximumBlockCount(MAX_LINES);
//logTextEdit->appendPlainText(plainText);
//navigate the window to the end
//QTextCursor cursor = logTextEdit->textCursor();
//cursor.movePosition(QTextCursor::MoveOperation::End);
//logTextEdit->setTextCursor(cursor);
//QTextCursor prev_cursor = logTextEdit->textCursor();
logTextEdit->moveCursor(QTextCursor::End);
logTextEdit->insertPlainText(plainText);
if(/*prev_cursor.atEnd()*/scrollPosVert==scrollPosVertMax){
//logTextEdit->moveCursor(QTextCursor::End);
scrollPosVert =logTextEdit->verticalScrollBar()->maximum();
scrollPosHoriz=logTextEdit->horizontalScrollBar()->minimum();
}
//else
// logTextEdit->setTextCursor(prev_cursor);
logTextEdit->verticalScrollBar()->setValue(scrollPosVert);
logTextEdit->horizontalScrollBar()->setValue(scrollPosHoriz);
}
/*
void replaceText_atGuiThread() {
assert(logTextEdit!=nullptr);
logTextEdit->setText(QString::fromStdString(nav.getContent()));
}
*/
};
#endif // LOGVIEWERMANAGER_H

1126
src/mainwindow.cpp

File diff suppressed because it is too large Load Diff

883
src/mainwindow.h

@ -0,0 +1,883 @@ @@ -0,0 +1,883 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QObject>
#include <QMainWindow>
#include <QPushButton>
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QAction>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpacerItem>
#include "QVBoxLayout"
#include "QUrl"
#ifndef ANDROID
# include <QSystemTrayIcon>
# include <QCloseEvent>
# include <QMenu>
#endif
#include <QString>
#include <functional>
#include "MainWindowItems.h"
#include "TunnelPane.h"
#include "ServerTunnelPane.h"
#include "ClientTunnelPane.h"
#include "TunnelConfig.h"
#include "textbrowsertweaked1.h"
#include "Config.h"
#include "FS.h"
#include <QDebug>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "TunnelsPageUpdateListener.h"
#include "DaemonQT.h"
#include "SignatureTypeComboboxFactory.h"
#include "pagewithbackbutton.h"
#include <iostream>
#include "widgetlockregistry.h"
#include "widgetlock.h"
#include "DelayedSaveManager.h"
#include "DelayedSaveManagerImpl.h"
#include "SaverImpl.h"
#include "I2pdQtUtil.h"
class SaverImpl;
class LogViewerManager;
template<typename ValueType>
bool isType(boost::any& a) {
return
#ifdef BOOST_AUX_ANY_TYPE_ID_NAME
std::strcmp(a.type().name(), typeid(ValueType).name()) == 0
#else
a.type() == typeid(ValueType)
#endif
;
}
class ConfigOption {
public:
QString section;
QString option;
//MainWindow::DefaultValueGetter defaultValueGetter;
ConfigOption(QString section_, QString option_/*, DefaultValueGetter defaultValueGetter_*/):
section(section_)
, option(option_)
//, defaultValueGetter(defaultValueGetter_)
{}
};
extern std::string programOptionsWriterCurrentSection;
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_, bool readOnly_=false) :
option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_), readOnly(readOnly_) {}
QWidget* getWidgetToFocus(){return widgetToFocus;}
QString& getRequirementToBeValid() { return requirementToBeValid; }
ConfigOption& getConfigOption() { return option; }
boost::any optionValue;
virtual ~MainWindowItem(){}
virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption(){
std::string optName="";
if(!option.section.isEmpty())optName=option.section.toStdString()+std::string(".");
optName+=option.option.toStdString();
//qDebug() << "loadFromConfigOption[" << optName.c_str() << "]";
boost::any programOption;
i2p::config::GetOptionAsAny(optName, programOption);
optionValue=programOption.empty()?boost::any(std::string(""))
:boost::any_cast<boost::program_options::variable_value>(programOption).value();
}
virtual void saveToStringStream(std::stringstream& out){
if(readOnly)return; //should readOnly items (conf=) error somewhere, instead of silently skipping save?
if(isType<std::string>(optionValue)) {
std::string v = boost::any_cast<std::string>(optionValue);
if(v.empty())return;
}
if(optionValue.empty())return;
std::string rtti = optionValue.type().name();
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();
std::string sectionAsStdStr = option.section.toStdString();
if(!option.section.isEmpty() &&
sectionAsStdStr!=programOptionsWriterCurrentSection) {
out << "[" << sectionAsStdStr << "]\n";
programOptionsWriterCurrentSection=sectionAsStdStr;
}
out << option.option.toStdString() << "=";
if(isType<std::string>(optionValue)) {
out << boost::any_cast<std::string>(optionValue);
}else if(isType<bool>(optionValue)) {
out << (boost::any_cast<bool>(optionValue) ? "true" : "false");
}else if(isType<uint16_t>(optionValue)) {
out << boost::any_cast<uint16_t>(optionValue);
}else if(isType<uint32_t>(optionValue)) {
out << boost::any_cast<uint32_t>(optionValue);
}else if(isType<int>(optionValue)) {
out << boost::any_cast<int>(optionValue);
}else if(isType<unsigned short>(optionValue)) {
out << boost::any_cast<unsigned short>(optionValue);
}else out << boost::any_cast<std::string>(optionValue); //let it throw
out << "\n\n";
}
virtual bool isValid(bool & alreadyDisplayedIfWrong){alreadyDisplayedIfWrong=false;return true;}
};
class NonGUIOptionItem : public MainWindowItem {
public:
NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_, nullptr, QString()) {}
virtual ~NonGUIOptionItem(){}
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class BaseStringItem : public MainWindowItem {
Q_OBJECT
public:
QLineEdit* 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(){
return boost::any_cast<std::string>(optionValue).c_str();
}
virtual boost::any fromString(QString s){return boost::any(s.toStdString());}
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
lineEdit->setText(toString());
}
virtual void saveToStringStream(std::stringstream& out){
optionValue=fromString(lineEdit->text());
MainWindowItem::saveToStringStream(out);
}
virtual bool isValid(bool & alreadyDisplayedIfWrong);
};
class FileOrFolderChooserItem : public BaseStringItem {
protected:
const bool requireExistingFile;
public:
QPushButton* 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 {
Q_OBJECT
private slots:
void pushButtonReleased();
public:
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()));
}
};
class FolderChooserItem : public FileOrFolderChooserItem{
Q_OBJECT
private slots:
void pushButtonReleased();
public:
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_){}
virtual ~ComboBoxItem(){}
virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption()=0;
virtual void saveToStringStream(std::stringstream& out)=0;
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return ; }
};
class LogDestinationComboBoxItem : public ComboBoxItem {
public:
LogDestinationComboBoxItem(ConfigOption option_, QComboBox* comboBox_) :
ComboBoxItem(option_, comboBox_) {}
virtual ~LogDestinationComboBoxItem(){}
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
const char * ld = boost::any_cast<std::string>(optionValue).c_str();
comboBox->setCurrentText(QString(ld));
}
virtual void saveToStringStream(std::stringstream& out){
std::string logDest = comboBox->currentText().toStdString();
optionValue=logDest;
MainWindowItem::saveToStringStream(out);
}
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
Q_OBJECT
};
class LogLevelComboBoxItem : public ComboBoxItem {
public:
LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}
virtual ~LogLevelComboBoxItem(){}
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
const char * ll = boost::any_cast<std::string>(optionValue).c_str();
comboBox->setCurrentText(QString(ll));
}
virtual void saveToStringStream(std::stringstream& out){
optionValue=comboBox->currentText().toStdString();
MainWindowItem::saveToStringStream(out);
}
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class SignatureTypeComboBoxItem : public ComboBoxItem {
public:
SignatureTypeComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}
virtual ~SignatureTypeComboBoxItem(){}
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
while(comboBox->count()>0)comboBox->removeItem(0);
uint16_t selected = (uint16_t) boost::any_cast<unsigned short>(optionValue);
SignatureTypeComboBoxFactory::fillComboBox(comboBox, selected);
}
virtual void saveToStringStream(std::stringstream& out){
uint16_t selected = SignatureTypeComboBoxFactory::getSigType(comboBox->currentData());
optionValue=(unsigned short)selected;
MainWindowItem::saveToStringStream(out);
}
//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_){}
virtual ~CheckBoxItem(){}
virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
//qDebug() << "setting value for checkbox " << checkBox->text();
checkBox->setChecked(boost::any_cast<bool>(optionValue));
}
virtual void saveToStringStream(std::stringstream& out){
optionValue=checkBox->isChecked();
MainWindowItem::saveToStringStream(out);
}
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class BaseFormattedStringItem : public BaseStringItem {
public:
QString fieldNameTranslated;
BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, QString requirementToBeValid_, MainWindow* mw) :
BaseStringItem(option_, lineEdit_, requirementToBeValid_, mw), fieldNameTranslated(fieldNameTranslated_) {}
virtual ~BaseFormattedStringItem(){}
//virtual bool isValid(bool & alreadyDisplayedIfWrong)=0;
};
class IntegerStringItem : public BaseFormattedStringItem {
public:
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(bool & alreadyDisplayedIfWrong){
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
if(!correct)return false;
alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toInt(&ok);
return ok;
}
virtual QString toString(){return QString::number(boost::any_cast<int>(optionValue));}
virtual boost::any fromString(QString s){return boost::any(std::stoi(s.toStdString()));}
};
class UShortStringItem : public BaseFormattedStringItem {
public:
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(bool & alreadyDisplayedIfWrong){
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
if(!correct)return false;
alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toUShort(&ok);
return ok;
}
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()));}
};
class UInt32StringItem : public BaseFormattedStringItem {
public:
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(bool & alreadyDisplayedIfWrong){
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
if(!correct)return false;
alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toUInt(&ok);
return ok;
}
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()));}
};
class UInt16StringItem : public BaseFormattedStringItem {
public:
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(bool & alreadyDisplayedIfWrong){
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
if(!correct)return false;
alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toUShort(&ok);
return ok;
}
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()));}
};
class IPAddressStringItem : public BaseFormattedStringItem {
public:
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_, MainWindow* mw) :
UShortStringItem(option_, lineEdit_, fieldNameTranslated_,mw) {}
};
namespace Ui {
class MainWindow;
class StatusButtonsForm;
class routerCommandsWidget;
class GeneralSettingsContentsForm;
}
using namespace i2p::client;
class TunnelPane;
using namespace i2p::qt;
class Controller;
class DelayedSaveManagerImpl;
class MainWindow : public QMainWindow {
Q_OBJECT
private:
std::string currentLocalDestinationB32;
std::shared_ptr<std::iostream> logStream;
DelayedSaveManagerImpl* delayedSaveManagerPtr;
DelayedSaveManager::DATA_SERIAL_TYPE dataSerial;
public:
explicit MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *parent=nullptr);
~MainWindow();
void setI2PController(i2p::qt::Controller* controller_);
void highlightWrongInput(QString warningText, WrongInputPageEnum inputPage, QWidget* widgetToFocus);
//typedef std::function<QString ()> DefaultValueGetter;
//#ifndef ANDROID
// void setVisible(bool visible);
//#endif
private:
enum StatusPage {main_page, commands, local_destinations, leasesets, tunnels, transit_tunnels,
transports, i2p_tunnels, sam_sessions};
private slots:
void updated();
void handleQuitButton();
void handleGracefulQuitButton();
void handleDoRestartButton();
void handleGracefulQuitTimerEvent();
#ifndef ANDROID
void setIcon();
void iconActivated(QSystemTrayIcon::ActivationReason reason);
void toggleVisibilitySlot();
#endif
void scheduleStatusPageUpdates();
void statusHtmlPageMouseReleased();
void statusHtmlPageSelectionChanged();
void updateStatusPage();
void showStatusMainPage();
void showStatus_commands_Page();
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();
void showStatus_transit_tunnels_Page();
void showStatus_transports_Page();
void showStatus_i2p_tunnels_Page();
void showStatus_sam_sessions_Page();
void showLogViewerPage();
void showSettingsPage();
void showTunnelsPage();
void showRestartPage();
void showQuitPage();
void showAboutBox(const QString & href);
private:
StatusPage statusPage;
QTimer * statusPageUpdateTimer;
bool wasSelectingAtStatusMainPage;
bool showHiddenInfoStatusMainPage;
LogViewerManager *logViewerManagerPtr;
void showStatusPage(StatusPage newStatusPage);
#ifndef ANDROID
void createActions();
void createTrayIcon();
bool quitting;
QAction *toggleWindowVisibleAction;
QSystemTrayIcon *trayIcon;
QMenu *trayIconMenu;
#endif
public:
Ui::MainWindow* ui;
Ui::StatusButtonsForm* statusButtonsUI;
Ui::routerCommandsWidget* routerCommandsUI;
Ui::GeneralSettingsContentsForm* uiSettings;
void adjustSizesAccordingToWrongLabel();
bool applyTunnelsUiToConfigs();
private:
int settingsTitleLabelNominalHeight;
TextBrowserTweaked1 * textBrowser;
QWidget * routerCommandsParent;
PageWithBackButton * pageWithBackButton;
TextBrowserTweaked1 * childTextBrowser;
widgetlockregistry widgetlocks;
i2p::qt::Controller* i2pController;
protected:
void updateRouterCommandsButtons();
#ifndef ANDROID
void closeEvent(QCloseEvent *event);
#endif
void resizeEvent(QResizeEvent* event);
void onResize();
void setStatusButtonsVisible(bool visible);
QString getStatusPageHtml(bool showHiddenInfo);
QList<MainWindowItem*> configItems;
NonGUIOptionItem* daemonOption;
NonGUIOptionItem* serviceOption;
//LogDestinationComboBoxItem* logOption;
FileChooserItem* logFileNameOption;
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);
void initLogLevelCombobox(ConfigOption option, QComboBox* comboBox);
void initSignatureTypeCombobox(ConfigOption option, QComboBox* comboBox);
void initIPAddressBox(ConfigOption option, QLineEdit* addressLineEdit, QString fieldNameTranslated);
void initTCPPortBox(ConfigOption option, QLineEdit* portLineEdit, QString fieldNameTranslated);
void initCheckBox(ConfigOption option, QCheckBox* checkBox);
void initIntegerBox(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
void initUInt32Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
void initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
void initStringBox(ConfigOption option, QLineEdit* lineEdit);
NonGUIOptionItem* initNonGUIOption(ConfigOption option);
void loadAllConfigs(SaverImpl* saverPtr);
void layoutTunnels();
public slots:
/** returns false iff not valid items present and save was aborted */
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_QString(QString tunnelNameToFocus);
void addServerTunnelPushButtonReleased();
void addClientTunnelPushButtonReleased();
void anchorClickedHandler(const QUrl & link);
void backClickedFromChild();
void logDestinationComboBoxValueChanged(const QString & text);
private:
QString datadir;
QString confpath;
QString tunconfpath;
std::map<std::string, TunnelConfig*> tunnelConfigs;
std::list<TunnelPane*> tunnelPanes;
void appendTunnelForms(std::string tunnelNameToFocus);
void deleteTunnelForms();
void deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf);
template<typename Section>
std::string GetI2CPOption (const Section& section, const std::string& name, const std::string& value) const
{
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value);
}
template<typename Section>
std::string GetI2CPOption (const Section& section, const std::string& name, const char* value) const
{
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::string (value));
}
template<typename Section, typename Type>
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const
{
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value));
}
template<typename Section>
void ReadI2CPOptions (const Section& section, std::map<std::string, std::string>& options, I2CPParameters& param
/*TODO fill param*/) const
{
std::string _INBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH);
param.setInbound_length(QString(_INBOUND_TUNNEL_LENGTH.c_str()));
std::string _OUTBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH);
param.setOutbound_length(QString(_OUTBOUND_TUNNEL_LENGTH.c_str()));
std::string _INBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY);
param.setInbound_quantity( QString(_INBOUND_TUNNELS_QUANTITY.c_str()));
std::string _OUTBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY);
param.setOutbound_quantity(QString(_OUTBOUND_TUNNELS_QUANTITY.c_str()));
std::string _TAGS_TO_SEND = options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND);
param.setCrypto_tagsToSend(QString(_TAGS_TO_SEND.c_str()));
std::string _i2cp_leaseSetAuthType = options[I2CP_PARAM_LEASESET_AUTH_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_AUTH_TYPE, 0);
param.set_i2cp_leaseSetAuthType(QString(_i2cp_leaseSetAuthType.c_str()));
const char DEFAULT_LEASESET_ENCRYPTION_TYPE[] = "";
std::string _i2cp_leaseSetEncType = options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, DEFAULT_LEASESET_ENCRYPTION_TYPE);//todo Identity's type by default
param.set_i2cp_leaseSetEncType(QString(_i2cp_leaseSetEncType.c_str()));
std::string _i2cp_leaseSetPrivKey = options[I2CP_PARAM_LEASESET_PRIV_KEY] = GetI2CPOption (section, I2CP_PARAM_LEASESET_PRIV_KEY, "");
param.set_i2cp_leaseSetPrivKey(QString(_i2cp_leaseSetPrivKey.c_str()));
std::string _i2cp_leaseSetType = options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE);
param.set_i2cp_leaseSetType(QString(_i2cp_leaseSetType.c_str()));
std::string _i2p_streaming_answerPings= options[I2CP_PARAM_STREAMING_ANSWER_PINGS] = GetI2CPOption (section, I2CP_PARAM_STREAMING_ANSWER_PINGS, DEFAULT_ANSWER_PINGS);
param.set_i2p_streaming_answerPings((_i2p_streaming_answerPings.compare("true")==0)||(_i2p_streaming_answerPings.compare("yes")==0));
std::string _i2p_streaming_initialAckDelay = options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption (section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY);
param.set_i2p_streaming_initialAckDelay(QString(_i2p_streaming_initialAckDelay.c_str()));
options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY);//TODO include into param
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));
const int _i2cp_leaseSetAuthType = 0;
param.set_i2cp_leaseSetAuthType(QString::number(_i2cp_leaseSetAuthType));
const QString _i2cp_leaseSetEncType = "0,4"; //todo Identity's type by default
param.set_i2cp_leaseSetEncType(_i2cp_leaseSetEncType);
param.set_i2cp_leaseSetPrivKey("");
const int _i2cp_leaseSetType = DEFAULT_LEASESET_TYPE;
param.set_i2cp_leaseSetType(QString::number(_i2cp_leaseSetType));
bool _i2p_streaming_answerPings= DEFAULT_ANSWER_PINGS;
param.set_i2p_streaming_answerPings(_i2p_streaming_answerPings);
const int _i2p_streaming_initialAckDelay = DEFAULT_INITIAL_ACK_DELAY;
param.set_i2p_streaming_initialAckDelay(QString::number(_i2p_streaming_initialAckDelay));
}
void DeleteTunnelNamed(std::string name) {
std::map<std::string,TunnelConfig*>::const_iterator it=tunnelConfigs.find(name);
if(it!=tunnelConfigs.end()){
TunnelConfig* tc=it->second;
deleteTunnelFromUI(name, tc);
tunnelConfigs.erase(it);
delete tc;
}
saveAllConfigs(true, FocusEnum::noFocus);
}
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;
int cryptoType = 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,
cryptoType);
saveAllConfigs(true, FocusEnum::focusOnTunnelName, 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;
std::string address = "127.0.0.1";
bool isUniqueLocal = true;
int cryptoType = 0;
// I2CP
I2CPParameters i2cpParameters;
CreateDefaultI2CPOptions (i2cpParameters);
tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters,
host,
port,
keys,
inPort,
accessList,
hostOverride,
webircpass,
gzip,
sigType,
address,
isUniqueLocal,
cryptoType);
saveAllConfigs(true, FocusEnum::focusOnTunnelName, name);
}
void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels ()
{
boost::property_tree::ptree pt;
std::string tunConf=tunconfpath.toStdString();
if (tunConf == "") {
// TODO: cleanup this in 2.8.0
tunConf = i2p::fs::DataDirPath ("tunnels.cfg");
if (i2p::fs::Exists(tunConf)) {
LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf);
} else {
tunConf = i2p::fs::DataDirPath ("tunnels.conf");
}
}
LogPrint(eLogDebug, "tunnels config file: ", tunConf);
try
{
boost::property_tree::read_ini (tunConf, pt);
}
catch (std::exception& ex)
{
LogPrint (eLogWarning, "Clients: Can't read ", tunConf, ": ", ex.what ());//TODO show err box and disable tunn.page
return;
}
for (auto& section: pt)
{
std::string name = section.first;
try
{
std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE);
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT
|| type == I2P_TUNNELS_SECTION_TYPE_SOCKS
|| type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS
|| type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY
|| type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
{
// mandatory params
std::string dest;
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) {
dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION);
}
int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT);
// 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<int>(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0);
int destinationPort = section.second.get<int>(I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
// I2CP
std::map<std::string, std::string> options;
I2CPParameters i2cpParameters;
ReadI2CPOptions (section, options, i2cpParameters);
tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters,
dest,
port,
keys,
address,
destinationPort,
sigType,
cryptoType);
}
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
|| type == I2P_TUNNELS_SECTION_TYPE_HTTP
|| type == I2P_TUNNELS_SECTION_TYPE_IRC
|| type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
{
// mandatory params
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
int port = section.second.get<int> (I2P_SERVER_TUNNEL_PORT);
// optional params
std::string keys = section.second.get<std::string> (I2P_SERVER_TUNNEL_KEYS, "");
int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0);
std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, "");
std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, "");
std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
int cryptoType = section.second.get<int>(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0);
// I2CP
std::map<std::string, std::string> options;
I2CPParameters i2cpParameters;
ReadI2CPOptions (section, options, i2cpParameters);
/*
std::set<i2p::data::IdentHash> idents;
if (accessList.length () > 0)
{
size_t pos = 0, comma;
do
{
comma = accessList.find (',', pos);
i2p::data::IdentHash ident;
ident.FromBase32 (accessList.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
idents.insert (ident);
pos = comma + 1;
}
while (comma != std::string::npos);
}
*/
tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters,
host,
port,
keys,
inPort,
accessList,
hostOverride,
webircpass,
gzip,
sigType,
address,
isUniqueLocal,
cryptoType);
}
else
LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf);//TODO show err box and disable the tunn gui
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ());//TODO show err box and disable the tunn gui
}
}
}
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;
//void onLoggingOptionsChange() {}
SaverImpl* saverPtr;
};
#endif // MAINWINDOW_H

1053
src/mainwindow.ui

File diff suppressed because it is too large Load Diff

24
src/pagewithbackbutton.cpp

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
#include "pagewithbackbutton.h"
#include "QVBoxLayout"
#include "QHBoxLayout"
#include "QPushButton"
PageWithBackButton::PageWithBackButton(QWidget *parent, QWidget* child) : QWidget(parent)
{
QVBoxLayout * layout = new QVBoxLayout();
setLayout(layout);
QWidget * topBar = new QWidget();
QHBoxLayout * topBarLayout = new QHBoxLayout();
topBar->setLayout(topBarLayout);
layout->addWidget(topBar);
layout->addWidget(child);
QPushButton * backButton = new QPushButton(topBar);
backButton->setText("< Back");
topBarLayout->addWidget(backButton);
connect(backButton, SIGNAL(released()), this, SLOT(backReleasedSlot()));
}
void PageWithBackButton::backReleasedSlot() {
emit backReleased();
}

21
src/pagewithbackbutton.h

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
#ifndef PAGEWITHBACKBUTTON_H
#define PAGEWITHBACKBUTTON_H
#include <QWidget>
class PageWithBackButton : public QWidget
{
Q_OBJECT
public:
explicit PageWithBackButton(QWidget *parent, QWidget* child);
signals:
void backReleased();
private slots:
void backReleasedSlot();
};
#endif // PAGEWITHBACKBUTTON_H

BIN
src/resources/icons/mask.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
src/resources/images/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

127
src/routercommandswidget.ui

@ -0,0 +1,127 @@ @@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>routerCommandsWidget</class>
<widget class="QWidget" name="routerCommandsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>707</width>
<height>300</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>707</width>
<height>301</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Router Commands</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="runPeerTestPushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Run peer test</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="declineTransitTunnelsPushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Decline transit tunnels</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="acceptTransitTunnelsPushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Accept transit tunnels</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancelGracefulQuitPushButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Cancel graceful quit</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

163
src/statusbuttons.ui

@ -0,0 +1,163 @@ @@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>StatusButtonsForm</class>
<widget class="QWidget" name="StatusButtonsForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>171</width>
<height>295</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>171</width>
<height>295</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>21</x>
<y>0</y>
<width>171</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QPushButton" name="mainPagePushButton">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Main page</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="routerCommandsPushButton">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Router commands</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="localDestinationsPushButton">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Local destinations</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="leasesetsPushButton">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Leasesets</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="tunnelsPushButton">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Tunnels</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="transitTunnelsPushButton">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Transit tunnels</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="transportsPushButton">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Transports</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="i2pTunnelsPushButton">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>I2P tunnels</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="samSessionsPushButton">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>SAM sessions</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

9
src/textbrowsertweaked1.cpp

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
#include "textbrowsertweaked1.h"
TextBrowserTweaked1::TextBrowserTweaked1(QWidget * parent): QTextBrowser(parent)
{
}
/*void TextBrowserTweaked1::setSource(const QUrl & url) {
emit navigatedTo(url);
}*/

26
src/textbrowsertweaked1.h

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
#ifndef TEXTBROWSERTWEAKED1_H
#define TEXTBROWSERTWEAKED1_H
#include <QTextBrowser>
#include <QUrl>
class TextBrowserTweaked1 : public QTextBrowser
{
Q_OBJECT
public:
TextBrowserTweaked1(QWidget * parent);
//virtual void setSource(const QUrl & url);
signals:
void mouseReleased();
//void navigatedTo(const QUrl & link);
protected:
void mouseReleaseEvent(QMouseEvent *event) {
QTextBrowser::mouseReleaseEvent(event);
emit mouseReleased();
}
};
#endif // TEXTBROWSERTWEAKED1_H

104
src/tunnelform.ui

@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>527</width>
<height>452</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>521</width>
<height>451</height>
</rect>
</property>
<layout class="QGridLayout" name="formGridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="serverTunnelNameGroupBox">
<property name="title">
<string>server_tunnel_name</string>
</property>
<widget class="QWidget" name="gridLayoutWidget_2">
<property name="geometry">
<rect>
<x>0</x>
<y>20</y>
<width>511</width>
<height>421</height>
</rect>
</property>
<layout class="QGridLayout" name="tunnelGridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="headerHorizontalLayout">
<item>
<widget class="QComboBox" name="tunnelTypeComboBox"/>
</item>
<item>
<spacer name="headerHorizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="deletePushButton">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="hostLabel">
<property name="text">
<string>Host:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="hostLineEdit"/>
</item>
<item>
<spacer name="hostHorizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

1
src/widgetlock.cpp

@ -0,0 +1 @@ @@ -0,0 +1 @@
#include "widgetlock.h"

35
src/widgetlock.h

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
#ifndef WIDGETLOCK_H
#define WIDGETLOCK_H
#include <QWidget>
#include <QObject>
#include <QPushButton>
#include <QApplication>
class widgetlock : public QObject {
Q_OBJECT
private:
QWidget* widget;
QPushButton* lockButton;
public slots:
void lockButtonClicked(bool) {
bool wasEnabled = widget->isEnabled();
widget->setEnabled(!wasEnabled);
lockButton->setText(widget->isEnabled()?lockButton->tr("Lock"):lockButton->tr("Edit"));
}
public:
widgetlock(QWidget* widget_, QPushButton* lockButton_): widget(widget_),lockButton(lockButton_) {
widget->setEnabled(false);
lockButton->setText(lockButton->tr("Edit"));
QObject::connect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool)));
}
virtual ~widgetlock() {}
void deleteListener() {
QObject::disconnect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool)));
}
};
#endif // WIDGETLOCK_H

2
src/widgetlockregistry.cpp

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
#include "widgetlockregistry.h"

27
src/widgetlockregistry.h

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
#ifndef WIDGETLOCKREGISTRY_H
#define WIDGETLOCKREGISTRY_H
#include <vector>
#include <widgetlock.h>
class widgetlockregistry {
std::vector<widgetlock*> locks;
public:
widgetlockregistry() : locks() {}
virtual ~widgetlockregistry() {}
void add(widgetlock* lock) {
locks.push_back(lock);
}
void deleteListeners() {
while(!locks.empty()) {
widgetlock* lock = locks.back();
lock->deleteListener();
delete lock;
locks.pop_back();
}
}
};
#endif // WIDGETLOCKREGISTRY_H
Loading…
Cancel
Save