├── .github └── workflows │ └── build.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── contrib ├── .gitignore ├── icons │ ├── 128x128 │ │ └── apps │ │ │ └── website.i2pd.i2pd.png │ ├── 16x16 │ │ └── apps │ │ │ └── website.i2pd.i2pd.png │ ├── 22x22 │ │ └── apps │ │ │ └── website.i2pd.i2pd.png │ ├── 24x24 │ │ └── apps │ │ │ └── website.i2pd.i2pd.png │ ├── 256x256 │ │ └── apps │ │ │ └── website.i2pd.i2pd.png │ ├── 32x32 │ │ └── apps │ │ │ └── website.i2pd.i2pd.png │ ├── 48x48 │ │ └── apps │ │ │ └── website.i2pd.i2pd.png │ ├── 512x512 │ │ └── apps │ │ │ └── website.i2pd.i2pd.png │ └── 64x64 │ │ └── apps │ │ └── website.i2pd.i2pd.png ├── website.i2pd.i2pd.appdata.xml └── website.i2pd.i2pd.desktop ├── i2pd_qt.pro └── src ├── AboutDialog.cpp ├── AboutDialog.h ├── AboutDialog.ui ├── BuildDateTimeQt.h ├── ClientTunnelPane.cpp ├── ClientTunnelPane.h ├── DaemonQT.cpp ├── DaemonQT.h ├── DelayedSaveManager.cpp ├── DelayedSaveManager.h ├── DelayedSaveManagerImpl.cpp ├── DelayedSaveManagerImpl.h ├── I2pdQtTypes.h ├── I2pdQtUtil.cpp ├── I2pdQtUtil.h ├── MainWindowItems.cpp ├── MainWindowItems.h ├── Saver.cpp ├── Saver.h ├── SaverImpl.cpp ├── SaverImpl.h ├── ServerTunnelPane.cpp ├── ServerTunnelPane.h ├── SignatureTypeComboboxFactory.cpp ├── SignatureTypeComboboxFactory.h ├── TunnelConfig.cpp ├── TunnelConfig.h ├── TunnelPane.cpp ├── TunnelPane.h ├── TunnelsPageUpdateListener.h ├── generalsettingswidget.ui ├── i2pd.qrc ├── i2pd.rc ├── logviewermanager.cpp ├── logviewermanager.h ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── pagewithbackbutton.cpp ├── pagewithbackbutton.h ├── resources ├── icons │ └── mask.ico └── images │ └── icon.png ├── routercommandswidget.ui ├── statusbuttons.ui ├── textbrowsertweaked1.cpp ├── textbrowsertweaked1.h ├── tunnelform.ui ├── widgetlock.cpp ├── widgetlock.h ├── widgetlockregistry.cpp └── widgetlockregistry.h /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build on Ubuntu 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build_qt: 7 | name: With QT GUI 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: [ubuntu-20.04, ubuntu-22.04] 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | submodules: 'recursive' 16 | - name: Install packages on Ubuntu 20.04 17 | if: matrix.os == 'ubuntu-20.04' 18 | run: | 19 | sudo add-apt-repository ppa:mhier/libboost-latest 20 | sudo apt-get update 21 | sudo apt-get install build-essential qt5-default libqt5gui5 libboost1.74-dev libminiupnpc-dev libssl-dev zlib1g-dev 22 | - name: Install packages on Ubuntu 22.04 23 | if: matrix.os == 'ubuntu-22.04' 24 | run: | 25 | sudo apt-get update 26 | sudo apt-get install build-essential qtbase5-dev qt5-qmake libqt5gui5 libboost-all-dev libminiupnpc-dev libssl-dev zlib1g-dev 27 | - name: Build application 28 | run: | 29 | qmake 30 | make -j$(nproc) 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | i2pd_qt.pro.user* 2 | moc_* 3 | ui_* 4 | qrc_* 5 | i2pd_qt 6 | Makefile* 7 | *.stash 8 | object_script.* 9 | i2pd_qt_plugin_import.cpp 10 | i2pd_qt.pro.autosave* 11 | /debug 12 | /release 13 | *.tmp 14 | *.o 15 | 16 | #backups 17 | *~ 18 | 19 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/i2pd"] 2 | path = src/i2pd 3 | url = https://github.com/PurpleI2P/i2pd.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2020, The PurpleI2P Project 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are 6 | permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this list of 9 | conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of 12 | conditions and the following disclaimer in the documentation and/or other materials 13 | provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 | to endorse or promote products derived from this software without specific prior written 17 | permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 26 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # i2pd-qt — A GUI for i2pd 2 | 3 | ![A screenshot of `i2pd-qt`](https://user-images.githubusercontent.com/19966907/184545373-5df5ce7d-6663-4550-ace6-ede24405d64e.png) 4 | 5 | ## Downloads 6 | 7 | Download on Flathub 8 | 9 | ## Building 10 | 11 | See https://i2pd.readthedocs.io/en/latest/devs/building/qt-desktop-gui/ . -------------------------------------------------------------------------------- /contrib/.gitignore: -------------------------------------------------------------------------------- 1 | *.tmp.xml 2 | -------------------------------------------------------------------------------- /contrib/icons/128x128/apps/website.i2pd.i2pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/contrib/icons/128x128/apps/website.i2pd.i2pd.png -------------------------------------------------------------------------------- /contrib/icons/16x16/apps/website.i2pd.i2pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/contrib/icons/16x16/apps/website.i2pd.i2pd.png -------------------------------------------------------------------------------- /contrib/icons/22x22/apps/website.i2pd.i2pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/contrib/icons/22x22/apps/website.i2pd.i2pd.png -------------------------------------------------------------------------------- /contrib/icons/24x24/apps/website.i2pd.i2pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/contrib/icons/24x24/apps/website.i2pd.i2pd.png -------------------------------------------------------------------------------- /contrib/icons/256x256/apps/website.i2pd.i2pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/contrib/icons/256x256/apps/website.i2pd.i2pd.png -------------------------------------------------------------------------------- /contrib/icons/32x32/apps/website.i2pd.i2pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/contrib/icons/32x32/apps/website.i2pd.i2pd.png -------------------------------------------------------------------------------- /contrib/icons/48x48/apps/website.i2pd.i2pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/contrib/icons/48x48/apps/website.i2pd.i2pd.png -------------------------------------------------------------------------------- /contrib/icons/512x512/apps/website.i2pd.i2pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/contrib/icons/512x512/apps/website.i2pd.i2pd.png -------------------------------------------------------------------------------- /contrib/icons/64x64/apps/website.i2pd.i2pd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/contrib/icons/64x64/apps/website.i2pd.i2pd.png -------------------------------------------------------------------------------- /contrib/website.i2pd.i2pd.appdata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | website.i2pd.i2pd 5 | 6 | i2pd 7 | Invisible Internet 8 | 9 | CC0-1.0 10 | BSD-3-Clause 11 | 12 | 13 | PurpleI2P Team 14 | 15 | 16 | 17 |

i2pd (I2P Daemon) is a full-featured C++ implementation of I2P client.

18 |

I2P (Invisible Internet Protocol) is a universal anonymous network layer. 19 | All communications over I2P are anonymous and end-to-end encrypted, participants 20 | don't reveal their real IP addresses.

21 |

I2P allows people from all around the world to communicate and share information 22 | without restrictions.

23 |

Features:

24 | 30 |
31 | 32 | website.i2pd.i2pd.desktop 33 | 34 | 35 | 36 | https://i2pd.website/images/i2pd_qt.png 37 | Main window 38 | 39 | 40 | 41 | https://i2pd.website/ 42 | https://github.com/PurpleI2P/i2pd-qt/issues 43 | https://i2pd.readthedocs.io/en/latest/ 44 | https://github.com/PurpleI2P/i2pd-qt/ 45 | 46 | r4sas@i2pmail.org 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |
96 | -------------------------------------------------------------------------------- /contrib/website.i2pd.i2pd.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Categories=Network;P2P;Qt; 3 | Exec=i2pd_qt 4 | GenericName=Invisible Internet 5 | Comment=A universal anonymous network layer 6 | Icon=website.i2pd.i2pd 7 | Name=i2pd 8 | Terminal=false 9 | Type=Application 10 | StartupNotify=false 11 | Keywords=i2p;i2pd;vpn;p2p; 12 | -------------------------------------------------------------------------------- /i2pd_qt.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | 3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 | 5 | TARGET = i2pd_qt 6 | TARGET.files = i2pd_qt 7 | linux:TARGET.path = /usr/bin/ 8 | 9 | desktop.files = contrib/website.i2pd.i2pd.desktop 10 | linux:desktop.path = /usr/share/applications/ 11 | 12 | icons.files = contrib/icons/* 13 | linux:icons.path = /usr/share/icons/hicolor/ 14 | 15 | TEMPLATE = app 16 | QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized -Wno-deprecated-copy 17 | CONFIG += strict_c++ c++17 18 | 19 | # suppress OpenSSL deprecation warnings 20 | DEFINES += OPENSSL_SUPPRESS_DEPRECATED 21 | 22 | DEFINES += USE_UPNP 23 | 24 | CONFIG(debug, debug|release) { 25 | message(Debug build) 26 | 27 | # do not redirect logging to std::ostream and to Log pane 28 | DEFINES += DEBUG_WITH_DEFAULT_LOGGING 29 | 30 | DEFINES += I2PD_QT_DEBUG 31 | I2PDMAKE += DEBUG=yes 32 | } 33 | CONFIG(release, debug|release) { 34 | message(Release build) 35 | DEFINES += I2PD_QT_RELEASE 36 | I2PDMAKE += DEBUG=no 37 | } 38 | 39 | SOURCES += \ 40 | src/DaemonQT.cpp \ 41 | src/mainwindow.cpp \ 42 | src/ClientTunnelPane.cpp \ 43 | src/MainWindowItems.cpp \ 44 | src/ServerTunnelPane.cpp \ 45 | src/SignatureTypeComboboxFactory.cpp \ 46 | src/TunnelConfig.cpp \ 47 | src/TunnelPane.cpp \ 48 | src/textbrowsertweaked1.cpp \ 49 | src/pagewithbackbutton.cpp \ 50 | src/widgetlock.cpp \ 51 | src/widgetlockregistry.cpp \ 52 | src/logviewermanager.cpp \ 53 | src/DelayedSaveManager.cpp \ 54 | src/Saver.cpp \ 55 | src/DelayedSaveManagerImpl.cpp \ 56 | src/SaverImpl.cpp \ 57 | src/i2pd/daemon/Daemon.cpp \ 58 | src/i2pd/daemon/HTTPServer.cpp \ 59 | src/i2pd/daemon/I2PControlHandlers.cpp \ 60 | src/i2pd/daemon/I2PControl.cpp \ 61 | src/i2pd/daemon/i2pd.cpp \ 62 | src/i2pd/daemon/UPnP.cpp \ 63 | src/AboutDialog.cpp \ 64 | src/I2pdQtUtil.cpp 65 | 66 | HEADERS += \ 67 | src/DaemonQT.h \ 68 | src/mainwindow.h \ 69 | src/ClientTunnelPane.h \ 70 | src/MainWindowItems.h \ 71 | src/ServerTunnelPane.h \ 72 | src/SignatureTypeComboboxFactory.h \ 73 | src/TunnelConfig.h \ 74 | src/TunnelPane.h \ 75 | src/TunnelsPageUpdateListener.h \ 76 | src/textbrowsertweaked1.h \ 77 | src/pagewithbackbutton.h \ 78 | src/widgetlock.h \ 79 | src/widgetlockregistry.h \ 80 | src/i2pd.rc \ 81 | src/logviewermanager.h \ 82 | src/DelayedSaveManager.h \ 83 | src/Saver.h \ 84 | src/DelayedSaveManagerImpl.h \ 85 | src/SaverImpl.h \ 86 | src/i2pd/daemon/Daemon.h \ 87 | src/i2pd/daemon/HTTPServer.h \ 88 | src/i2pd/daemon/I2PControlHandlers.h \ 89 | src/i2pd/daemon/I2PControl.h \ 90 | src/i2pd/daemon/UPnP.h \ 91 | src/AboutDialog.h \ 92 | src/BuildDateTimeQt.h \ 93 | src/I2pdQtUtil.h \ 94 | src/I2pdQtTypes.h 95 | 96 | INCLUDEPATH += src 97 | INCLUDEPATH += src/i2pd/daemon 98 | INCLUDEPATH += src/i2pd/libi2pd 99 | INCLUDEPATH += src/i2pd/libi2pd_client 100 | INCLUDEPATH += src/i2pd/i18n 101 | 102 | FORMS += \ 103 | src/mainwindow.ui \ 104 | src/tunnelform.ui \ 105 | src/statusbuttons.ui \ 106 | src/routercommandswidget.ui \ 107 | src/generalsettingswidget.ui \ 108 | src/AboutDialog.ui 109 | 110 | LIBS += $$PWD/src/i2pd/libi2pd.a $$PWD/src/i2pd/libi2pdclient.a $$PWD/src/i2pd/libi2pdlang.a -lz 111 | 112 | # doing that way due to race condition made by make 113 | i2pd_client.commands = cd $$PWD/src/i2pd/ && mkdir -p obj/libi2pd obj/libi2pd_client obj/i18n && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes $$I2PDMAKE mk_obj_dir api_client lang 114 | i2pd_client.target = $$PWD/src/i2pd/libi2pdclient.a 115 | i2pd_client.depends = i2pd FORCE 116 | 117 | i2pd.commands = cd $$PWD/src/i2pd/ && mkdir -p obj/libi2pd obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes $$I2PDMAKE mk_obj_dir api 118 | i2pd.target += $$PWD/src/i2pd/libi2pd.a 119 | i2pd.depends = FORCE 120 | 121 | cleani2pd.commands = cd $$PWD/src/i2pd/ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) clean 122 | #cleani2pd.depends = clean 123 | 124 | PRE_TARGETDEPS += $$PWD/src/i2pd/libi2pd.a $$PWD/src/i2pd/libi2pdclient.a 125 | QMAKE_EXTRA_TARGETS += cleani2pd i2pd i2pd_client 126 | CLEAN_DEPS += cleani2pd 127 | 128 | BuildDateTimeQtTarget.target = $$PWD/src/BuildDateTimeQt.h 129 | BuildDateTimeQtTarget.depends = FORCE 130 | # 'touch' is unix-only; will probably break on non-unix, TBD 131 | BuildDateTimeQtTarget.commands = touch $$PWD/src/BuildDateTimeQt.h 132 | PRE_TARGETDEPS += $$PWD/src/BuildDateTimeQt.h 133 | QMAKE_EXTRA_TARGETS += BuildDateTimeQtTarget 134 | 135 | # git only, port to other VCS, too. TBD 136 | DEFINES += VCS_COMMIT_INFO="\\\"git:$(shell git -C \""$$_PRO_FILE_PWD_"\" describe --always)\\\"" 137 | 138 | macx { 139 | message("using mac os x target") 140 | BREWROOT=/usr/local 141 | BOOSTROOT=$$BREWROOT/opt/boost 142 | SSLROOT=$$BREWROOT/opt/libressl 143 | UPNPROOT=$$BREWROOT/opt/miniupnpc 144 | INCLUDEPATH += $$BOOSTROOT/include 145 | INCLUDEPATH += $$SSLROOT/include 146 | INCLUDEPATH += $$UPNPROOT/include 147 | LIBS += $$SSLROOT/lib/libssl.a 148 | LIBS += $$SSLROOT/lib/libcrypto.a 149 | LIBS += $$BOOSTROOT/lib/libboost_program_options.a 150 | LIBS += $$UPNPROOT/lib/libminiupnpc.a 151 | LIBS += -Wl,-dead_strip 152 | LIBS += -Wl,-dead_strip_dylibs 153 | LIBS += -Wl,-bind_at_load 154 | } 155 | 156 | linux:!android { 157 | message("Using Linux settings") 158 | LIBS += -lssl -lcrypto -lboost_program_options -lpthread -lminiupnpc 159 | 160 | INSTALLS += TARGET 161 | INSTALLS += icons 162 | INSTALLS += desktop 163 | } 164 | 165 | windows { 166 | message("Using Windows settings") 167 | RC_FILE = src/i2pd.rc 168 | DEFINES += BOOST_USE_WINDOWS_H WINDOWS _WINDOWS WIN32_LEAN_AND_MEAN MINIUPNP_STATICLIB 169 | DEFINES -= UNICODE _UNICODE 170 | BOOST_SUFFIX = -mt 171 | QMAKE_CXXFLAGS_RELEASE = -Os 172 | QMAKE_LFLAGS = -Wl,-Bstatic -static-libgcc -static-libstdc++ -mwindows 173 | 174 | # linker's -s means "strip" 175 | QMAKE_LFLAGS_RELEASE += -s 176 | 177 | LIBS = \ 178 | $$PWD/src/i2pd/libi2pd.a \ 179 | $$PWD/src/i2pd/libi2pdclient.a \ 180 | $$PWD/src/i2pd/libi2pdlang.a \ 181 | -lminiupnpc \ 182 | -lboost_program_options$$BOOST_SUFFIX \ 183 | -lssl \ 184 | -lcrypto \ 185 | -lz \ 186 | -lwsock32 \ 187 | -lws2_32 \ 188 | -lgdi32 \ 189 | -liphlpapi \ 190 | -lstdc++ \ 191 | -lpthread 192 | } 193 | 194 | !android:!symbian:!maemo5:!simulator { 195 | message("Build with a system tray icon") 196 | # see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince* 197 | #sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images 198 | RESOURCES = src/i2pd.qrc 199 | QT += xml 200 | #INSTALLS += sources 201 | } 202 | 203 | -------------------------------------------------------------------------------- /src/AboutDialog.cpp: -------------------------------------------------------------------------------- 1 | #include "AboutDialog.h" 2 | #include "ui_AboutDialog.h" 3 | #include 4 | #include "version.h" 5 | #include "BuildDateTimeQt.h" 6 | 7 | AboutDialog::AboutDialog(QWidget *parent) : 8 | QDialog(parent), 9 | ui(new Ui::AboutDialog) 10 | { 11 | ui->setupUi(this); 12 | ui->i2pdVersionLabel->setText(I2PD_VERSION); 13 | ui->i2pVersionLabel->setText(I2P_VERSION); 14 | ui->buildDateTimeLabel->setText(BUILD_DATE_TIME_QT); 15 | ui->vcsCommitInfoLabel->setText(VCS_COMMIT_INFO); 16 | } 17 | 18 | AboutDialog::~AboutDialog() 19 | { 20 | delete ui; 21 | } 22 | -------------------------------------------------------------------------------- /src/AboutDialog.h: -------------------------------------------------------------------------------- 1 | #ifndef ABOUTDIALOG_H 2 | #define ABOUTDIALOG_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class AboutDialog; 8 | } 9 | 10 | class AboutDialog : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit AboutDialog(QWidget *parent = 0); 16 | ~AboutDialog(); 17 | 18 | private: 19 | Ui::AboutDialog *ui; 20 | }; 21 | 22 | #endif // ABOUTDIALOG_H 23 | -------------------------------------------------------------------------------- /src/AboutDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | AboutDialog 4 | 5 | 6 | Qt::WindowModal 7 | 8 | 9 | 10 | 0 11 | 0 12 | 400 13 | 199 14 | 15 | 16 | 17 | About i2pd_qt 18 | 19 | 20 | 21 | :/icons/mask:/icons/mask 22 | 23 | 24 | 25 | 26 | 10 27 | 160 28 | 381 29 | 32 30 | 31 | 32 | 33 | Qt::Horizontal 34 | 35 | 36 | QDialogButtonBox::Ok 37 | 38 | 39 | 40 | 41 | 42 | 10 43 | 10 44 | 381 45 | 31 46 | 47 | 48 | 49 | 50 | 0 51 | 0 52 | 53 | 54 | 55 | <html><head/><body><p><span style=" font-weight:600;">About i2pd_qt</span></p></body></html> 56 | 57 | 58 | 59 | 60 | 61 | 10 62 | 40 63 | 131 64 | 31 65 | 66 | 67 | 68 | 69 | 0 70 | 0 71 | 72 | 73 | 74 | i2pd Version: 75 | 76 | 77 | 78 | 79 | 80 | 10 81 | 70 82 | 131 83 | 31 84 | 85 | 86 | 87 | 88 | 0 89 | 0 90 | 91 | 92 | 93 | Build Date/Time: 94 | 95 | 96 | 97 | 98 | 99 | 150 100 | 40 101 | 241 102 | 31 103 | 104 | 105 | 106 | 107 | 0 108 | 0 109 | 110 | 111 | 112 | I2PD_VERSION_LABEL 113 | 114 | 115 | 116 | 117 | 118 | 10 119 | 130 120 | 131 121 | 31 122 | 123 | 124 | 125 | 126 | 0 127 | 0 128 | 129 | 130 | 131 | I2P Version: 132 | 133 | 134 | 135 | 136 | 137 | 150 138 | 130 139 | 241 140 | 31 141 | 142 | 143 | 144 | 145 | 0 146 | 0 147 | 148 | 149 | 150 | I2P_VERSION_LABEL 151 | 152 | 153 | 154 | 155 | 156 | 150 157 | 70 158 | 241 159 | 31 160 | 161 | 162 | 163 | 164 | 0 165 | 0 166 | 167 | 168 | 169 | BUILD_DATE_TIME_LABEL 170 | 171 | 172 | 173 | 174 | 175 | 10 176 | 100 177 | 131 178 | 31 179 | 180 | 181 | 182 | 183 | 0 184 | 0 185 | 186 | 187 | 188 | Version Control: 189 | 190 | 191 | 192 | 193 | 194 | 150 195 | 100 196 | 241 197 | 31 198 | 199 | 200 | 201 | 202 | 0 203 | 0 204 | 205 | 206 | 207 | VCS_COMMIT_INFO_LABEL 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | buttonBox 217 | accepted() 218 | AboutDialog 219 | accept() 220 | 221 | 222 | 248 223 | 254 224 | 225 | 226 | 157 227 | 274 228 | 229 | 230 | 231 | 232 | buttonBox 233 | rejected() 234 | AboutDialog 235 | reject() 236 | 237 | 238 | 316 239 | 260 240 | 241 | 242 | 286 243 | 274 244 | 245 | 246 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /src/BuildDateTimeQt.h: -------------------------------------------------------------------------------- 1 | #ifndef BUILDDATETIMEQT_H 2 | #define BUILDDATETIMEQT_H 3 | 4 | #include 5 | const QString BUILD_DATE_TIME_QT = QStringLiteral(__DATE__ " " __TIME__); 6 | 7 | #endif // BUILDDATETIMEQT_H 8 | -------------------------------------------------------------------------------- /src/ClientTunnelPane.cpp: -------------------------------------------------------------------------------- 1 | #include "ClientTunnelPane.h" 2 | #include "ClientContext.h" 3 | #include "SignatureTypeComboboxFactory.h" 4 | #include "QVBoxLayout" 5 | 6 | ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow): 7 | TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_, mainWindow) {} 8 | 9 | void ClientTunnelPane::setGroupBoxTitle(const QString & title) { 10 | clientTunnelNameGroupBox->setTitle(title); 11 | } 12 | 13 | void ClientTunnelPane::deleteClientTunnelForm() { 14 | TunnelPane::deleteTunnelForm(); 15 | delete clientTunnelNameGroupBox; 16 | clientTunnelNameGroupBox=nullptr; 17 | 18 | //gridLayoutWidget_2->deleteLater(); 19 | //gridLayoutWidget_2=nullptr; 20 | } 21 | 22 | int ClientTunnelPane::appendClientTunnelForm( 23 | ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) { 24 | 25 | ClientTunnelPane& ui = *this; 26 | 27 | clientTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget); 28 | clientTunnelNameGroupBox->setObjectName(QStringLiteral("clientTunnelNameGroupBox")); 29 | 30 | //tunnel 31 | gridLayoutWidget_2 = new QWidget(clientTunnelNameGroupBox); 32 | 33 | QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2); 34 | tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox")); 35 | tunnelTypeComboBox->addItem("Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT); 36 | tunnelTypeComboBox->addItem("Socks", i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS); 37 | tunnelTypeComboBox->addItem("Websocks", i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS); 38 | tunnelTypeComboBox->addItem("HTTP Proxy", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY); 39 | tunnelTypeComboBox->addItem("UDP Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT); 40 | 41 | int h=(7+4)*60; 42 | gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h)); 43 | clientTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h)); 44 | 45 | { 46 | const QString& type = tunnelConfig->getType(); 47 | int index=0; 48 | if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT)tunnelTypeComboBox->setCurrentIndex(index); 49 | ++index; 50 | if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS)tunnelTypeComboBox->setCurrentIndex(index); 51 | ++index; 52 | if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)tunnelTypeComboBox->setCurrentIndex(index); 53 | ++index; 54 | if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)tunnelTypeComboBox->setCurrentIndex(index); 55 | ++index; 56 | if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)tunnelTypeComboBox->setCurrentIndex(index); 57 | ++index; 58 | } 59 | 60 | setupTunnelPane(tunnelConfig, 61 | clientTunnelNameGroupBox, 62 | gridLayoutWidget_2, tunnelTypeComboBox, 63 | tunnelsFormGridLayoutWidget, tunnelsRow, height, h); 64 | //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, (7+5)*40+10)); 65 | 66 | /* 67 | std::string destination; 68 | */ 69 | 70 | //host 71 | ui.horizontalLayout_2 = new QHBoxLayout(); 72 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 73 | ui.destinationLabel = new QLabel(gridLayoutWidget_2); 74 | destinationLabel->setObjectName(QStringLiteral("destinationLabel")); 75 | horizontalLayout_2->addWidget(destinationLabel); 76 | ui.destinationLineEdit = new QLineEdit(gridLayoutWidget_2); 77 | destinationLineEdit->setObjectName(QStringLiteral("destinationLineEdit")); 78 | destinationLineEdit->setText(tunnelConfig->getdest().c_str()); 79 | QObject::connect(destinationLineEdit, SIGNAL(textChanged(const QString &)), 80 | this, SLOT(updated())); 81 | horizontalLayout_2->addWidget(destinationLineEdit); 82 | ui.destinationHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 83 | horizontalLayout_2->addItem(destinationHorizontalSpacer); 84 | tunnelGridLayout->addLayout(horizontalLayout_2); 85 | 86 | /* 87 | * int port; 88 | */ 89 | int gridIndex = 2; 90 | { 91 | int port = tunnelConfig->getport(); 92 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 93 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 94 | ui.portLabel = new QLabel(gridLayoutWidget_2); 95 | portLabel->setObjectName(QStringLiteral("portLabel")); 96 | horizontalLayout_2->addWidget(portLabel); 97 | ui.portLineEdit = new QLineEdit(gridLayoutWidget_2); 98 | portLineEdit->setObjectName(QStringLiteral("portLineEdit")); 99 | portLineEdit->setText(QString::number(port)); 100 | portLineEdit->setMaximumWidth(80); 101 | QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)), 102 | this, SLOT(updated())); 103 | horizontalLayout_2->addWidget(portLineEdit); 104 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 105 | horizontalLayout_2->addItem(horizontalSpacer); 106 | tunnelGridLayout->addLayout(horizontalLayout_2); 107 | } 108 | /* 109 | * std::string keys; 110 | */ 111 | { 112 | std::string keys = tunnelConfig->getkeys(); 113 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 114 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 115 | ui.keysLabel = new QLabel(gridLayoutWidget_2); 116 | keysLabel->setObjectName(QStringLiteral("keysLabel")); 117 | horizontalLayout_2->addWidget(keysLabel); 118 | ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2); 119 | keysLineEdit->setObjectName(QStringLiteral("keysLineEdit")); 120 | keysLineEdit->setText(keys.c_str()); 121 | QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)), 122 | this, SLOT(updated())); 123 | horizontalLayout_2->addWidget(keysLineEdit); 124 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 125 | horizontalLayout_2->addItem(horizontalSpacer); 126 | tunnelGridLayout->addLayout(horizontalLayout_2); 127 | } 128 | /* 129 | * std::string address; 130 | */ 131 | { 132 | std::string address = tunnelConfig->getaddress(); 133 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 134 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 135 | ui.addressLabel = new QLabel(gridLayoutWidget_2); 136 | addressLabel->setObjectName(QStringLiteral("addressLabel")); 137 | horizontalLayout_2->addWidget(addressLabel); 138 | ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2); 139 | addressLineEdit->setObjectName(QStringLiteral("addressLineEdit")); 140 | addressLineEdit->setText(address.c_str()); 141 | QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)), 142 | this, SLOT(updated())); 143 | horizontalLayout_2->addWidget(addressLineEdit); 144 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 145 | horizontalLayout_2->addItem(horizontalSpacer); 146 | tunnelGridLayout->addLayout(horizontalLayout_2); 147 | } 148 | 149 | /* 150 | int destinationPort; 151 | i2p::data::SigningKeyType sigType; 152 | */ 153 | { 154 | int destinationPort = tunnelConfig->getdestinationPort(); 155 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 156 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 157 | ui.destinationPortLabel = new QLabel(gridLayoutWidget_2); 158 | destinationPortLabel->setObjectName(QStringLiteral("destinationPortLabel")); 159 | horizontalLayout_2->addWidget(destinationPortLabel); 160 | ui.destinationPortLineEdit = new QLineEdit(gridLayoutWidget_2); 161 | destinationPortLineEdit->setObjectName(QStringLiteral("destinationPortLineEdit")); 162 | destinationPortLineEdit->setText(QString::number(destinationPort)); 163 | destinationPortLineEdit->setMaximumWidth(80); 164 | QObject::connect(destinationPortLineEdit, SIGNAL(textChanged(const QString &)), 165 | this, SLOT(updated())); 166 | horizontalLayout_2->addWidget(destinationPortLineEdit); 167 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 168 | horizontalLayout_2->addItem(horizontalSpacer); 169 | tunnelGridLayout->addLayout(horizontalLayout_2); 170 | } 171 | { 172 | int cryptoType = tunnelConfig->getcryptoType(); 173 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 174 | ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2); 175 | cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel")); 176 | horizontalLayout_2->addWidget(cryptoTypeLabel); 177 | ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2); 178 | cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit")); 179 | cryptoTypeLineEdit->setText(QString::number(cryptoType)); 180 | cryptoTypeLineEdit->setMaximumWidth(80); 181 | QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)), 182 | this, SLOT(updated())); 183 | horizontalLayout_2->addWidget(cryptoTypeLineEdit); 184 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 185 | horizontalLayout_2->addItem(horizontalSpacer); 186 | tunnelGridLayout->addLayout(horizontalLayout_2); 187 | } 188 | { 189 | i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); 190 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 191 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 192 | ui.sigTypeLabel = new QLabel(gridLayoutWidget_2); 193 | sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel")); 194 | horizontalLayout_2->addWidget(sigTypeLabel); 195 | ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType); 196 | sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox")); 197 | QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)), 198 | this, SLOT(updated())); 199 | horizontalLayout_2->addWidget(sigTypeComboBox); 200 | QPushButton * lockButton2 = new QPushButton(gridLayoutWidget_2); 201 | horizontalLayout_2->addWidget(lockButton2); 202 | widgetlocks.add(new widgetlock(sigTypeComboBox, lockButton2)); 203 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 204 | horizontalLayout_2->addItem(horizontalSpacer); 205 | tunnelGridLayout->addLayout(horizontalLayout_2); 206 | } 207 | { 208 | I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); 209 | appendControlsForI2CPParameters(i2cpParameters, gridIndex); 210 | } 211 | 212 | retranslateClientTunnelForm(ui); 213 | 214 | tunnelGridLayout->invalidate(); 215 | 216 | return h; 217 | } 218 | 219 | ServerTunnelPane* ClientTunnelPane::asServerTunnelPane(){return nullptr;} 220 | ClientTunnelPane* ClientTunnelPane::asClientTunnelPane(){return this;} 221 | -------------------------------------------------------------------------------- /src/ClientTunnelPane.h: -------------------------------------------------------------------------------- 1 | #ifndef CLIENTTUNNELPANE_H 2 | #define CLIENTTUNNELPANE_H 3 | 4 | #include "QGridLayout" 5 | #include "QVBoxLayout" 6 | 7 | #include "TunnelPane.h" 8 | 9 | class ClientTunnelConfig; 10 | 11 | class ServerTunnelPane; 12 | class TunnelPane; 13 | 14 | class ClientTunnelPane : public TunnelPane { 15 | Q_OBJECT 16 | public: 17 | ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow); 18 | virtual ~ClientTunnelPane(){} 19 | virtual ServerTunnelPane* asServerTunnelPane(); 20 | virtual ClientTunnelPane* asClientTunnelPane(); 21 | int appendClientTunnelForm(ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, 22 | int tunnelsRow, int height); 23 | void deleteClientTunnelForm(); 24 | private: 25 | QGroupBox *clientTunnelNameGroupBox; 26 | 27 | //tunnel 28 | QWidget *gridLayoutWidget_2; 29 | 30 | //destination 31 | QHBoxLayout *horizontalLayout_2; 32 | QLabel *destinationLabel; 33 | QLineEdit *destinationLineEdit; 34 | QSpacerItem *destinationHorizontalSpacer; 35 | 36 | //port 37 | QLabel * portLabel; 38 | QLineEdit * portLineEdit; 39 | 40 | //keys 41 | QLabel * keysLabel; 42 | QLineEdit * keysLineEdit; 43 | 44 | //address 45 | QLabel * addressLabel; 46 | QLineEdit * addressLineEdit; 47 | 48 | //destinationPort 49 | QLabel * destinationPortLabel; 50 | QLineEdit * destinationPortLineEdit; 51 | 52 | //sigType 53 | QLabel * sigTypeLabel; 54 | QComboBox * sigTypeComboBox; 55 | 56 | //cryptoType 57 | QLabel * cryptoTypeLabel; 58 | QLineEdit * cryptoTypeLineEdit; 59 | 60 | protected slots: 61 | virtual void setGroupBoxTitle(const QString & title); 62 | 63 | private: 64 | void retranslateClientTunnelForm(ClientTunnelPane& /*ui*/) { 65 | typeLabel->setText(QApplication::translate("cltTunForm", "Client tunnel type:", 0)); 66 | destinationLabel->setText(QApplication::translate("cltTunForm", "Destination:", 0)); 67 | portLabel->setText(QApplication::translate("cltTunForm", "Port:", 0)); 68 | cryptoTypeLabel->setText(QApplication::translate("cltTunForm", "Crypto type:", 0)); 69 | keysLabel->setText(QApplication::translate("cltTunForm", "Keys:", 0)); 70 | destinationPortLabel->setText(QApplication::translate("cltTunForm", "Destination port:", 0)); 71 | addressLabel->setText(QApplication::translate("cltTunForm", "Address:", 0)); 72 | sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0)); 73 | } 74 | protected: 75 | virtual bool applyDataFromUIToTunnelConfig() { 76 | QString cannotSaveSettings = QApplication::tr("Cannot save settings."); 77 | bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); 78 | if(!ok)return false; 79 | ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig(); 80 | assert(ctc!=nullptr); 81 | 82 | if(!isValidSingleLine(destinationLineEdit))return false; 83 | if(!isValidSingleLine(portLineEdit))return false; 84 | if(!isValidSingleLine(cryptoTypeLineEdit))return false; 85 | if(!isValidSingleLine(keysLineEdit))return false; 86 | if(!isValidSingleLine(addressLineEdit))return false; 87 | if(!isValidSingleLine(destinationPortLineEdit))return false; 88 | 89 | //destination 90 | ctc->setdest(destinationLineEdit->text().toStdString()); 91 | 92 | auto portStr=portLineEdit->text(); 93 | int portInt=portStr.toInt(&ok); 94 | 95 | if(!ok){ 96 | highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit); 97 | return false; 98 | } 99 | ctc->setport(portInt); 100 | 101 | auto cryptoTypeStr=cryptoTypeLineEdit->text(); 102 | int cryptoTypeInt=cryptoTypeStr.toInt(&ok); 103 | if(!ok){ 104 | highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit); 105 | return false; 106 | } 107 | ctc->setcryptoType(cryptoTypeInt); 108 | 109 | ctc->setkeys(keysLineEdit->text().toStdString()); 110 | 111 | ctc->setaddress(addressLineEdit->text().toStdString()); 112 | 113 | auto dportStr=destinationPortLineEdit->text(); 114 | int dportInt=dportStr.toInt(&ok); 115 | if(!ok){ 116 | highlightWrongInput(QApplication::tr("Bad destinationPort, must be int.")+" "+cannotSaveSettings,destinationPortLineEdit); 117 | return false; 118 | } 119 | ctc->setdestinationPort(dportInt); 120 | 121 | ctc->setsigType(readSigTypeComboboxUI(sigTypeComboBox)); 122 | return true; 123 | } 124 | }; 125 | 126 | #endif // CLIENTTUNNELPANE_H 127 | -------------------------------------------------------------------------------- /src/DaemonQT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "DaemonQT.h" 4 | #include "Daemon.h" 5 | #include "mainwindow.h" 6 | 7 | #include "Log.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | //#define DEBUG_WITH_DEFAULT_LOGGING (1) 15 | 16 | namespace i2p 17 | { 18 | namespace qt 19 | { 20 | Worker::Worker (DaemonQTImpl& daemon): 21 | m_Daemon (daemon) 22 | { 23 | } 24 | 25 | void Worker::startDaemon() 26 | { 27 | qDebug("Performing daemon start..."); 28 | try{ 29 | m_Daemon.start(); 30 | qDebug("Daemon started."); 31 | emit resultReady(false, ""); 32 | }catch(std::exception& ex){ 33 | emit resultReady(true, ex.what()); 34 | }catch(...){ 35 | emit resultReady(true, QObject::tr("Error: unknown exception")); 36 | } 37 | } 38 | void Worker::restartDaemon() 39 | { 40 | qDebug("Performing daemon restart..."); 41 | try{ 42 | m_Daemon.restart(); 43 | qDebug("Daemon restarted."); 44 | emit resultReady(false, ""); 45 | }catch(std::exception& ex){ 46 | emit resultReady(true, ex.what()); 47 | }catch(...){ 48 | emit resultReady(true, QObject::tr("Error: unknown exception")); 49 | } 50 | } 51 | void Worker::stopDaemon() { 52 | qDebug("Performing daemon stop..."); 53 | try{ 54 | m_Daemon.stop(); 55 | qDebug("Daemon stopped."); 56 | emit resultReady(false, ""); 57 | }catch(std::exception& ex){ 58 | emit resultReady(true, ex.what()); 59 | }catch(...){ 60 | emit resultReady(true, QObject::tr("Error: unknown exception")); 61 | } 62 | } 63 | 64 | Controller::Controller(DaemonQTImpl& daemon): 65 | m_Daemon (daemon) 66 | { 67 | Worker *worker = new Worker (m_Daemon); 68 | worker->moveToThread(&workerThread); 69 | connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); 70 | connect(this, &Controller::startDaemon, worker, &Worker::startDaemon); 71 | connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon); 72 | connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon); 73 | connect(worker, &Worker::resultReady, this, &Controller::handleResults); 74 | workerThread.start(); 75 | } 76 | Controller::~Controller() 77 | { 78 | qDebug("Closing and waiting for daemon worker thread..."); 79 | workerThread.quit(); 80 | workerThread.wait(); 81 | qDebug("Waiting for daemon worker thread finished."); 82 | if(m_Daemon.isRunning()) 83 | { 84 | qDebug("Stopping the daemon..."); 85 | m_Daemon.stop(); 86 | qDebug("Stopped the daemon."); 87 | } 88 | } 89 | 90 | DaemonQTImpl::DaemonQTImpl (): 91 | mutex(nullptr), m_IsRunning(nullptr), m_RunningChangedCallback(nullptr) 92 | { 93 | } 94 | 95 | DaemonQTImpl::~DaemonQTImpl () 96 | { 97 | delete mutex; 98 | } 99 | 100 | bool DaemonQTImpl::init(int argc, char* argv[], std::shared_ptr logstream) 101 | { 102 | mutex=new QMutex(QMutex::Recursive); 103 | setRunningCallback(0); 104 | m_IsRunning=false; 105 | return Daemon.init(argc,argv,logstream); 106 | } 107 | 108 | void DaemonQTImpl::start() 109 | { 110 | QMutexLocker locker(mutex); 111 | setRunning(true); 112 | Daemon.start(); 113 | } 114 | 115 | void DaemonQTImpl::stop() 116 | { 117 | QMutexLocker locker(mutex); 118 | Daemon.stop(); 119 | setRunning(false); 120 | } 121 | 122 | void DaemonQTImpl::restart() 123 | { 124 | QMutexLocker locker(mutex); 125 | stop(); 126 | start(); 127 | } 128 | 129 | void DaemonQTImpl::setRunningCallback(runningChangedCallback cb) 130 | { 131 | m_RunningChangedCallback = cb; 132 | } 133 | 134 | bool DaemonQTImpl::isRunning() 135 | { 136 | return m_IsRunning; 137 | } 138 | 139 | void DaemonQTImpl::setRunning(bool newValue) 140 | { 141 | bool oldValue = m_IsRunning; 142 | if(oldValue!=newValue) 143 | { 144 | m_IsRunning = newValue; 145 | if(m_RunningChangedCallback) 146 | m_RunningChangedCallback(); 147 | } 148 | } 149 | 150 | int RunQT (int argc, char* argv[]) 151 | { 152 | QApplication app(argc, argv); 153 | int result; 154 | 155 | { 156 | std::shared_ptr logstreamptr= 157 | #ifdef DEBUG_WITH_DEFAULT_LOGGING 158 | nullptr 159 | #else 160 | std::make_shared() 161 | #endif 162 | ; 163 | //TODO move daemon init deinit to a bg thread 164 | DaemonQTImpl daemon; 165 | if(logstreamptr) (*logstreamptr) << "Initialising the daemon..." << std::endl; 166 | bool daemonInitSuccess = daemon.init(argc, argv, logstreamptr); 167 | if(!daemonInitSuccess) 168 | { 169 | QMessageBox::critical(0, "Error", "Daemon init failed"); 170 | return 1; 171 | } 172 | LogPrint(eLogDebug, "Initialised, creating the main window..."); 173 | MainWindow w(logstreamptr); 174 | LogPrint(eLogDebug, "Before main window.show()..."); 175 | w.show (); 176 | 177 | { 178 | i2p::qt::Controller daemonQtController(daemon); 179 | w.setI2PController(&daemonQtController); 180 | LogPrint(eLogDebug, "Starting the daemon..."); 181 | emit daemonQtController.startDaemon(); 182 | //daemon.start (); 183 | LogPrint(eLogDebug, "Starting GUI event loop..."); 184 | result = app.exec(); 185 | //daemon.stop (); 186 | } 187 | } 188 | 189 | //QMessageBox::information(&w, "Debug", "demon stopped"); 190 | LogPrint(eLogDebug, "Exiting the application"); 191 | return result; 192 | } 193 | } 194 | } 195 | 196 | -------------------------------------------------------------------------------- /src/DaemonQT.h: -------------------------------------------------------------------------------- 1 | #ifndef DAEMONQT_H 2 | #define DAEMONQT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace i2p 11 | { 12 | namespace qt 13 | { 14 | class DaemonQTImpl 15 | { 16 | public: 17 | 18 | DaemonQTImpl (); 19 | ~DaemonQTImpl (); 20 | 21 | typedef void (*runningChangedCallback)(); 22 | 23 | /** 24 | * @brief init 25 | * @param argc 26 | * @param argv 27 | * @return success 28 | */ 29 | bool init(int argc, char* argv[], std::shared_ptr logstream); 30 | void start(); 31 | void stop(); 32 | void restart(); 33 | void setRunningCallback(runningChangedCallback cb); 34 | bool isRunning(); 35 | private: 36 | void setRunning(bool running); 37 | void showError(std::string errorMsg); 38 | private: 39 | QMutex* mutex; 40 | bool m_IsRunning; 41 | runningChangedCallback m_RunningChangedCallback; 42 | }; 43 | 44 | class Worker : public QObject 45 | { 46 | Q_OBJECT 47 | public: 48 | 49 | Worker (DaemonQTImpl& daemon); 50 | 51 | private: 52 | 53 | DaemonQTImpl& m_Daemon; 54 | 55 | public slots: 56 | void startDaemon(); 57 | void restartDaemon(); 58 | void stopDaemon(); 59 | 60 | signals: 61 | void resultReady(bool failed, QString failureMessage); 62 | }; 63 | 64 | class Controller : public QObject 65 | { 66 | Q_OBJECT 67 | QThread workerThread; 68 | public: 69 | Controller(DaemonQTImpl& daemon); 70 | ~Controller(); 71 | private: 72 | DaemonQTImpl& m_Daemon; 73 | 74 | public slots: 75 | void handleResults(bool failed, QString failureMessage){ 76 | if(failed){ 77 | QMessageBox::critical(0, QObject::tr("Error"), failureMessage); 78 | } 79 | } 80 | signals: 81 | void startDaemon(); 82 | void stopDaemon(); 83 | void restartDaemon(); 84 | }; 85 | } 86 | } 87 | 88 | #endif // DAEMONQT_H 89 | -------------------------------------------------------------------------------- /src/DelayedSaveManager.cpp: -------------------------------------------------------------------------------- 1 | #include "DelayedSaveManager.h" 2 | 3 | DelayedSaveManager::DelayedSaveManager(){} 4 | -------------------------------------------------------------------------------- /src/DelayedSaveManager.h: -------------------------------------------------------------------------------- 1 | #ifndef DELAYEDSAVEMANAGER_H 2 | #define DELAYEDSAVEMANAGER_H 3 | 4 | #include "Saver.h" 5 | #include "I2pdQtTypes.h" 6 | 7 | class DelayedSaveManager 8 | { 9 | public: 10 | DelayedSaveManager(); 11 | 12 | virtual void setSaver(Saver* saver)=0; 13 | 14 | typedef unsigned int DATA_SERIAL_TYPE; 15 | 16 | virtual void delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus)=0; 17 | 18 | //returns false iff save failed 19 | virtual bool appExiting()=0; 20 | 21 | virtual FocusEnum getFocusOn()=0; 22 | virtual std::string& getTunnelNameToFocus()=0; 23 | virtual QWidget* getWidgetToFocus()=0; 24 | }; 25 | 26 | #endif // DELAYEDSAVEMANAGER_H 27 | -------------------------------------------------------------------------------- /src/DelayedSaveManagerImpl.cpp: -------------------------------------------------------------------------------- 1 | #include "DelayedSaveManagerImpl.h" 2 | 3 | #include 4 | 5 | DelayedSaveManagerImpl::DelayedSaveManagerImpl() : 6 | widgetToFocus(nullptr), 7 | saver(nullptr), 8 | lastDataSerialSeen(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL), 9 | lastSaveStartedTimestamp(A_VERY_OBSOLETE_TIMESTAMP), 10 | exiting(false), 11 | thread(new DelayedSaveThread(this)) 12 | { 13 | } 14 | 15 | void DelayedSaveManagerImpl::setSaver(Saver* saver) { 16 | this->saver = saver; 17 | } 18 | 19 | void DelayedSaveManagerImpl::start() { 20 | thread->start(); 21 | } 22 | 23 | bool DelayedSaveManagerImpl::isSaverValid() { 24 | return saver != nullptr; 25 | } 26 | 27 | void DelayedSaveManagerImpl::delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus) { 28 | if(lastDataSerialSeen==dataSerial)return; 29 | this->reloadAfterSave = reloadAfterSave; 30 | this->focusOn = focusOn; 31 | this->tunnelNameToFocus = tunnelNameToFocus; 32 | this->widgetToFocus = widgetToFocus; 33 | lastDataSerialSeen=dataSerial; 34 | assert(isSaverValid()); 35 | TIMESTAMP_TYPE now = getTime(); 36 | TIMESTAMP_TYPE wakeTime = lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS; 37 | if(now < wakeTime) { 38 | //defer save until lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS 39 | thread->deferSaveUntil(wakeTime); 40 | return; 41 | } 42 | lastSaveStartedTimestamp = now; 43 | thread->startSavingNow(); 44 | } 45 | 46 | bool DelayedSaveManagerImpl::appExiting() { 47 | exiting=true; 48 | thread->wakeThreadAndJoinThread(); 49 | assert(isSaverValid()); 50 | saver->save(false, FocusEnum::noFocus); 51 | return true; 52 | } 53 | 54 | DelayedSaveThread::DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl_): 55 | delayedSaveManagerImpl(delayedSaveManagerImpl_), 56 | mutex(new QMutex()), 57 | waitCondition(new QWaitCondition()), 58 | saveNow(false), 59 | defer(false) 60 | { 61 | mutex->lock(); 62 | } 63 | 64 | DelayedSaveThread::~DelayedSaveThread(){ 65 | mutex->unlock(); 66 | delete mutex; 67 | delete waitCondition; 68 | } 69 | 70 | void DelayedSaveThread::run() { 71 | forever { 72 | if(delayedSaveManagerImpl->isExiting())return; 73 | waitCondition->wait(mutex, WAIT_TIME_MILLIS); 74 | if(delayedSaveManagerImpl->isExiting())return; 75 | Saver* saver = delayedSaveManagerImpl->getSaver(); 76 | assert(saver!=nullptr); 77 | if(saveNow) { 78 | saveNow = false; 79 | const FocusEnum focusOn = delayedSaveManagerImpl->getFocusOn(); 80 | const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus(); 81 | QWidget* widgetToFocus = delayedSaveManagerImpl->getWidgetToFocus(); 82 | saver->save(delayedSaveManagerImpl->isReloadAfterSave(), focusOn, tunnelNameToFocus, widgetToFocus); 83 | continue; 84 | } 85 | if(defer) { 86 | defer=false; 87 | #define max(a,b) (((a)>(b))?(a):(b)) 88 | forever { 89 | TIMESTAMP_TYPE now = DelayedSaveManagerImpl::getTime(); 90 | TIMESTAMP_TYPE millisToWait = max(wakeTime-now, 0); 91 | if(millisToWait>0) { 92 | waitCondition->wait(mutex, millisToWait); 93 | if(delayedSaveManagerImpl->isExiting())return; 94 | continue; 95 | } 96 | const FocusEnum focusOn = delayedSaveManagerImpl->getFocusOn(); 97 | const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus(); 98 | QWidget* widgetToFocus = delayedSaveManagerImpl->getWidgetToFocus(); 99 | saver->save(delayedSaveManagerImpl->isReloadAfterSave(), focusOn, tunnelNameToFocus, widgetToFocus); 100 | break; //break inner loop 101 | } 102 | } 103 | } 104 | } 105 | 106 | void DelayedSaveThread::wakeThreadAndJoinThread() { 107 | waitCondition->wakeAll(); 108 | quit(); 109 | wait();//join //"similar to the POSIX pthread_join()" 110 | } 111 | 112 | DelayedSaveManagerImpl::TIMESTAMP_TYPE DelayedSaveManagerImpl::getTime() { 113 | return QDateTime::currentMSecsSinceEpoch(); 114 | } 115 | 116 | void DelayedSaveThread::deferSaveUntil(TIMESTAMP_TYPE wakeTime_) { 117 | wakeTime = wakeTime_; 118 | defer = true; 119 | waitCondition->wakeAll(); 120 | } 121 | 122 | void DelayedSaveThread::startSavingNow() { 123 | //mutex->lock(); 124 | saveNow=true; 125 | waitCondition->wakeAll(); 126 | //mutex->unlock(); 127 | } 128 | 129 | DelayedSaveManagerImpl::~DelayedSaveManagerImpl() { 130 | thread->wakeThreadAndJoinThread(); 131 | delete thread; 132 | } 133 | 134 | bool DelayedSaveManagerImpl::isExiting() { 135 | return exiting; 136 | } 137 | Saver* DelayedSaveManagerImpl::getSaver() { 138 | return saver; 139 | } 140 | 141 | -------------------------------------------------------------------------------- /src/DelayedSaveManagerImpl.h: -------------------------------------------------------------------------------- 1 | #ifndef DELAYEDSAVEMANAGERIMPL_H 2 | #define DELAYEDSAVEMANAGERIMPL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "I2pdQtTypes.h" 11 | #include "DelayedSaveManager.h" 12 | #include "Saver.h" 13 | 14 | class DelayedSaveManagerImpl; 15 | class Saver; 16 | 17 | class DelayedSaveThread : public QThread { 18 | Q_OBJECT 19 | 20 | public: 21 | static constexpr unsigned long WAIT_TIME_MILLIS = 1000L; 22 | 23 | typedef qint64 TIMESTAMP_TYPE; 24 | static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=0; 25 | 26 | DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl); 27 | virtual ~DelayedSaveThread(); 28 | 29 | void run() override; 30 | 31 | void deferSaveUntil(TIMESTAMP_TYPE wakeTime); 32 | void startSavingNow(); 33 | 34 | void wakeThreadAndJoinThread(); 35 | 36 | private: 37 | DelayedSaveManagerImpl* delayedSaveManagerImpl; 38 | QMutex* mutex; 39 | QWaitCondition* waitCondition; 40 | volatile bool saveNow; 41 | volatile bool defer; 42 | volatile TIMESTAMP_TYPE wakeTime; 43 | }; 44 | 45 | class DelayedSaveManagerImpl : public DelayedSaveManager { 46 | FocusEnum focusOn; 47 | std::string tunnelNameToFocus; 48 | QWidget* widgetToFocus; 49 | bool reloadAfterSave; 50 | public: 51 | DelayedSaveManagerImpl(); 52 | virtual ~DelayedSaveManagerImpl(); 53 | virtual void setSaver(Saver* saver); 54 | virtual void start(); 55 | virtual void delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus); 56 | virtual bool appExiting(); 57 | 58 | typedef DelayedSaveThread::TIMESTAMP_TYPE TIMESTAMP_TYPE; 59 | 60 | static constexpr DATA_SERIAL_TYPE INITIAL_DATA_SERIAL=0; 61 | bool isExiting(); 62 | Saver* getSaver(); 63 | static TIMESTAMP_TYPE getTime(); 64 | 65 | bool isReloadAfterSave() { return reloadAfterSave; } 66 | FocusEnum getFocusOn() { return focusOn; } 67 | std::string& getTunnelNameToFocus() { return tunnelNameToFocus; } 68 | QWidget* getWidgetToFocus() { return widgetToFocus; } 69 | 70 | private: 71 | Saver* saver; 72 | bool isSaverValid(); 73 | 74 | DATA_SERIAL_TYPE lastDataSerialSeen; 75 | 76 | static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=DelayedSaveThread::A_VERY_OBSOLETE_TIMESTAMP; 77 | TIMESTAMP_TYPE lastSaveStartedTimestamp; 78 | 79 | bool exiting; 80 | DelayedSaveThread* thread; 81 | void wakeThreadAndJoinThread(); 82 | }; 83 | 84 | #endif // DELAYEDSAVEMANAGERIMPL_H 85 | -------------------------------------------------------------------------------- /src/I2pdQtTypes.h: -------------------------------------------------------------------------------- 1 | #ifndef I2PDQTTYPES_H 2 | #define I2PDQTTYPES_H 3 | 4 | enum WrongInputPageEnum { generalSettingsPage, tunnelsSettingsPage }; 5 | enum FocusEnum { noFocus, focusOnTunnelName, focusOnWidget }; 6 | 7 | #endif // I2PDQTTYPES_H 8 | -------------------------------------------------------------------------------- /src/I2pdQtUtil.cpp: -------------------------------------------------------------------------------- 1 | #include "I2pdQtUtil.h" 2 | 3 | bool isValidSingleLine(QLineEdit* widget, WrongInputPageEnum inputPage, MainWindow* mainWindow) { 4 | bool correct = !widget->text().contains(QRegularExpression("[\r\n]"), nullptr); 5 | if(!correct) { 6 | mainWindow->highlightWrongInput( 7 | QApplication::tr("Single line input expected, but it's multiline"), 8 | inputPage, 9 | widget); 10 | } 11 | return correct; 12 | } 13 | -------------------------------------------------------------------------------- /src/I2pdQtUtil.h: -------------------------------------------------------------------------------- 1 | #ifndef I2pdQtUtil_H 2 | #define I2pdQtUtil_H 3 | 4 | class QLineEdit; 5 | #include "mainwindow.h" 6 | 7 | bool isValidSingleLine(QLineEdit* widget, WrongInputPageEnum inputPage, MainWindow* mainWindow); 8 | 9 | #endif // I2pdQtUtil_H 10 | -------------------------------------------------------------------------------- /src/MainWindowItems.cpp: -------------------------------------------------------------------------------- 1 | #include "MainWindowItems.h" 2 | 3 | -------------------------------------------------------------------------------- /src/MainWindowItems.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOWITEMS_H 2 | #define MAINWINDOWITEMS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include "mainwindow.h" 14 | 15 | class MainWindow; 16 | 17 | #endif // MAINWINDOWITEMS_H 18 | -------------------------------------------------------------------------------- /src/Saver.cpp: -------------------------------------------------------------------------------- 1 | #include "Saver.h" 2 | 3 | Saver::Saver() 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /src/Saver.h: -------------------------------------------------------------------------------- 1 | #ifndef SAVER_H 2 | #define SAVER_H 3 | 4 | #include 5 | #include 6 | #include 7 | class QWidget; 8 | 9 | #include "I2pdQtTypes.h" 10 | 11 | class Saver : public QObject 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | Saver(); 17 | //FocusEnum::focusNone iff failures //??? wtf 18 | virtual bool save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus="", QWidget* widgetToFocus=nullptr)=0; 19 | 20 | signals: 21 | void reloadTunnelsConfigAndUISignal(const QString); 22 | void showPreventedSaveTunnelsConfMessage(); 23 | }; 24 | 25 | #endif // SAVER_H 26 | -------------------------------------------------------------------------------- /src/SaverImpl.cpp: -------------------------------------------------------------------------------- 1 | #include "SaverImpl.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "QList" 8 | #include "QString" 9 | 10 | #include "mainwindow.h" 11 | 12 | SaverImpl::SaverImpl(MainWindow *mainWindowPtr_, QList* configItems_, std::map* tunnelConfigs_) : 13 | configItems(configItems_), tunnelConfigs(tunnelConfigs_), confpath(), tunconfpath(), mainWindowPtr(mainWindowPtr_) 14 | { 15 | QObject::connect(this, SIGNAL(showPreventedSaveTunnelsConfMessage()), mainWindowPtr, SLOT(showTunnelsPagePreventedMessage())); 16 | } 17 | 18 | SaverImpl::~SaverImpl() {} 19 | 20 | bool SaverImpl::save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus, QWidget* widgetToFocus) { 21 | //save main config 22 | { 23 | std::stringstream out; 24 | for(QList::iterator it = configItems->begin(); it!= configItems->end(); ++it) { 25 | MainWindowItem* item = *it; 26 | item->saveToStringStream(out); 27 | } 28 | 29 | using namespace std; 30 | 31 | 32 | QString backup=confpath+"~"; 33 | if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors 34 | if(QFile::exists(confpath)) QFile::rename(confpath, backup);//TODO handle errors 35 | ofstream outfile; 36 | outfile.open(confpath.toStdString());//TODO handle errors 37 | outfile << out.str().c_str(); 38 | outfile.close(); 39 | } 40 | 41 | //save tunnels config 42 | if (mainWindowPtr->isPreventSaveTunnelsMode()) { 43 | emit showPreventedSaveTunnelsConfMessage(); 44 | }else{ 45 | std::stringstream out; 46 | 47 | for (std::map::iterator it=tunnelConfigs->begin(); it!=tunnelConfigs->end(); ++it) { 48 | //const std::string& name = it->first; 49 | TunnelConfig* tunconf = it->second; 50 | tunconf->saveHeaderToStringStream(out); 51 | tunconf->saveToStringStream(out); 52 | tunconf->saveI2CPParametersToStringStream(out); 53 | } 54 | 55 | using namespace std; 56 | 57 | QString backup=tunconfpath+"~"; 58 | if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors 59 | if(QFile::exists(tunconfpath)) QFile::rename(tunconfpath, backup);//TODO handle errors 60 | ofstream outfile; 61 | outfile.open(tunconfpath.toStdString());//TODO handle errors 62 | outfile << out.str().c_str(); 63 | outfile.close(); 64 | } 65 | 66 | if(reloadAfterSave) { 67 | //reload saved configs 68 | #if 0 69 | i2p::client::context.ReloadConfig(); 70 | #endif 71 | 72 | if(reloadAfterSave) emit reloadTunnelsConfigAndUISignal(focusOn==FocusEnum::focusOnTunnelName?QString::fromStdString(tunnelNameToFocus):""); 73 | } 74 | 75 | return true; 76 | } 77 | 78 | void SaverImpl::setConfPath(QString& confpath_) { confpath = confpath_; } 79 | 80 | void SaverImpl::setTunnelsConfPath(QString& tunconfpath_) { tunconfpath = tunconfpath_; } 81 | 82 | /*void SaverImpl::setTunnelFocus(bool focusOnTunnel, std::string tunnelNameToFocus) { 83 | this->focusOnTunnel=focusOnTunnel; 84 | this->tunnelNameToFocus=tunnelNameToFocus; 85 | }*/ 86 | -------------------------------------------------------------------------------- /src/SaverImpl.h: -------------------------------------------------------------------------------- 1 | #ifndef SAVERIMPL_H 2 | #define SAVERIMPL_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include "QList" 9 | 10 | #include "mainwindow.h" 11 | #include "TunnelConfig.h" 12 | #include "Saver.h" 13 | 14 | class MainWindowItem; 15 | class TunnelConfig; 16 | 17 | class SaverImpl : public Saver { 18 | public: 19 | SaverImpl(MainWindow *mainWindowPtr_, QList* configItems_, std::map* tunnelConfigs_); 20 | virtual ~SaverImpl(); 21 | virtual bool save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus, QWidget* widgetToFocus); 22 | void setConfPath(QString& confpath_); 23 | void setTunnelsConfPath(QString& tunconfpath_); 24 | private: 25 | QList* configItems; 26 | std::map* tunnelConfigs; 27 | QString confpath; 28 | QString tunconfpath; 29 | MainWindow* mainWindowPtr; 30 | }; 31 | 32 | #endif // SAVERIMPL_H 33 | -------------------------------------------------------------------------------- /src/ServerTunnelPane.cpp: -------------------------------------------------------------------------------- 1 | #include "ServerTunnelPane.h" 2 | #include "ClientContext.h" 3 | #include "SignatureTypeComboboxFactory.h" 4 | 5 | ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow): 6 | TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_, mainWindow) {} 7 | 8 | void ServerTunnelPane::setGroupBoxTitle(const QString & title) { 9 | serverTunnelNameGroupBox->setTitle(title); 10 | } 11 | 12 | int ServerTunnelPane::appendServerTunnelForm( 13 | ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) { 14 | 15 | ServerTunnelPane& ui = *this; 16 | 17 | serverTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget); 18 | serverTunnelNameGroupBox->setObjectName(QStringLiteral("serverTunnelNameGroupBox")); 19 | 20 | //tunnel 21 | gridLayoutWidget_2 = new QWidget(serverTunnelNameGroupBox); 22 | 23 | QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2); 24 | tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox")); 25 | tunnelTypeComboBox->addItem("Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER); 26 | tunnelTypeComboBox->addItem("HTTP", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP); 27 | tunnelTypeComboBox->addItem("IRC", i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC); 28 | tunnelTypeComboBox->addItem("UDP Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER); 29 | 30 | int h=19*60; 31 | gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h)); 32 | serverTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h)); 33 | 34 | const QString& type = tunnelConfig->getType(); 35 | { 36 | int index=0; 37 | if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER)tunnelTypeComboBox->setCurrentIndex(index); 38 | ++index; 39 | if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP)tunnelTypeComboBox->setCurrentIndex(index); 40 | ++index; 41 | if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC)tunnelTypeComboBox->setCurrentIndex(index); 42 | ++index; 43 | if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER)tunnelTypeComboBox->setCurrentIndex(index); 44 | ++index; 45 | } 46 | 47 | setupTunnelPane(tunnelConfig, 48 | serverTunnelNameGroupBox, 49 | gridLayoutWidget_2, tunnelTypeComboBox, 50 | tunnelsFormGridLayoutWidget, tunnelsRow, height, h); 51 | //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, 18*40+10)); 52 | 53 | //host 54 | ui.horizontalLayout_2 = new QHBoxLayout(); 55 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 56 | ui.hostLabel = new QLabel(gridLayoutWidget_2); 57 | hostLabel->setObjectName(QStringLiteral("hostLabel")); 58 | horizontalLayout_2->addWidget(hostLabel); 59 | ui.hostLineEdit = new QLineEdit(gridLayoutWidget_2); 60 | hostLineEdit->setObjectName(QStringLiteral("hostLineEdit")); 61 | hostLineEdit->setText(tunnelConfig->gethost().c_str()); 62 | QObject::connect(hostLineEdit, SIGNAL(textChanged(const QString &)), 63 | this, SLOT(updated())); 64 | horizontalLayout_2->addWidget(hostLineEdit); 65 | ui.hostHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 66 | horizontalLayout_2->addItem(hostHorizontalSpacer); 67 | tunnelGridLayout->addLayout(horizontalLayout_2); 68 | 69 | int gridIndex = 2; 70 | { 71 | int port = tunnelConfig->getport(); 72 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 73 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 74 | ui.portLabel = new QLabel(gridLayoutWidget_2); 75 | portLabel->setObjectName(QStringLiteral("portLabel")); 76 | horizontalLayout_2->addWidget(portLabel); 77 | ui.portLineEdit = new QLineEdit(gridLayoutWidget_2); 78 | portLineEdit->setObjectName(QStringLiteral("portLineEdit")); 79 | portLineEdit->setText(QString::number(port)); 80 | portLineEdit->setMaximumWidth(80); 81 | QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)), 82 | this, SLOT(updated())); 83 | horizontalLayout_2->addWidget(portLineEdit); 84 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 85 | horizontalLayout_2->addItem(horizontalSpacer); 86 | tunnelGridLayout->addLayout(horizontalLayout_2); 87 | } 88 | { 89 | std::string keys = tunnelConfig->getkeys(); 90 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 91 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 92 | ui.keysLabel = new QLabel(gridLayoutWidget_2); 93 | keysLabel->setObjectName(QStringLiteral("keysLabel")); 94 | horizontalLayout_2->addWidget(keysLabel); 95 | ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2); 96 | keysLineEdit->setObjectName(QStringLiteral("keysLineEdit")); 97 | keysLineEdit->setText(keys.c_str()); 98 | QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)), 99 | this, SLOT(updated())); 100 | horizontalLayout_2->addWidget(keysLineEdit); 101 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 102 | horizontalLayout_2->addItem(horizontalSpacer); 103 | tunnelGridLayout->addLayout(horizontalLayout_2); 104 | } 105 | { 106 | int inPort = tunnelConfig->getinPort(); 107 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 108 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 109 | ui.inPortLabel = new QLabel(gridLayoutWidget_2); 110 | inPortLabel->setObjectName(QStringLiteral("inPortLabel")); 111 | horizontalLayout_2->addWidget(inPortLabel); 112 | ui.inPortLineEdit = new QLineEdit(gridLayoutWidget_2); 113 | inPortLineEdit->setObjectName(QStringLiteral("inPortLineEdit")); 114 | inPortLineEdit->setText(QString::number(inPort)); 115 | inPortLineEdit->setMaximumWidth(80); 116 | QObject::connect(inPortLineEdit, SIGNAL(textChanged(const QString &)), 117 | this, SLOT(updated())); 118 | horizontalLayout_2->addWidget(inPortLineEdit); 119 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 120 | horizontalLayout_2->addItem(horizontalSpacer); 121 | tunnelGridLayout->addLayout(horizontalLayout_2); 122 | } 123 | { 124 | std::string accessList = tunnelConfig->getaccessList(); 125 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 126 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 127 | ui.accessListLabel = new QLabel(gridLayoutWidget_2); 128 | accessListLabel->setObjectName(QStringLiteral("accessListLabel")); 129 | horizontalLayout_2->addWidget(accessListLabel); 130 | ui.accessListLineEdit = new QLineEdit(gridLayoutWidget_2); 131 | accessListLineEdit->setObjectName(QStringLiteral("accessListLineEdit")); 132 | accessListLineEdit->setText(accessList.c_str()); 133 | QObject::connect(accessListLineEdit, SIGNAL(textChanged(const QString &)), 134 | this, SLOT(updated())); 135 | horizontalLayout_2->addWidget(accessListLineEdit); 136 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 137 | horizontalLayout_2->addItem(horizontalSpacer); 138 | tunnelGridLayout->addLayout(horizontalLayout_2); 139 | } 140 | 141 | { 142 | std::string hostOverride = tunnelConfig->gethostOverride(); 143 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 144 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 145 | ui.hostOverrideLabel = new QLabel(gridLayoutWidget_2); 146 | hostOverrideLabel->setObjectName(QStringLiteral("hostOverrideLabel")); 147 | horizontalLayout_2->addWidget(hostOverrideLabel); 148 | hostOverrideLabel->setEnabled(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP); 149 | ui.hostOverrideLineEdit = new QLineEdit(gridLayoutWidget_2); 150 | hostOverrideLineEdit->setObjectName(QStringLiteral("hostOverrideLineEdit")); 151 | hostOverrideLineEdit->setText(hostOverride.c_str()); 152 | QObject::connect(hostOverrideLineEdit, SIGNAL(textChanged(const QString &)), 153 | this, SLOT(updated())); 154 | horizontalLayout_2->addWidget(hostOverrideLineEdit); 155 | hostOverrideLineEdit->setEnabled(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP); 156 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 157 | horizontalLayout_2->addItem(horizontalSpacer); 158 | tunnelGridLayout->addLayout(horizontalLayout_2); 159 | } 160 | { 161 | std::string webIRCPass = tunnelConfig->getwebircpass(); 162 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 163 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 164 | ui.webIRCPassLabel = new QLabel(gridLayoutWidget_2); 165 | webIRCPassLabel->setObjectName(QStringLiteral("webIRCPassLabel")); 166 | horizontalLayout_2->addWidget(webIRCPassLabel); 167 | ui.webIRCPassLineEdit = new QLineEdit(gridLayoutWidget_2); 168 | webIRCPassLineEdit->setObjectName(QStringLiteral("webIRCPassLineEdit")); 169 | webIRCPassLineEdit->setText(webIRCPass.c_str()); 170 | QObject::connect(webIRCPassLineEdit, SIGNAL(textChanged(const QString &)), 171 | this, SLOT(updated())); 172 | horizontalLayout_2->addWidget(webIRCPassLineEdit); 173 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 174 | horizontalLayout_2->addItem(horizontalSpacer); 175 | tunnelGridLayout->addLayout(horizontalLayout_2); 176 | } 177 | { 178 | bool gzip = tunnelConfig->getgzip(); 179 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 180 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 181 | ui.gzipCheckBox = new QCheckBox(gridLayoutWidget_2); 182 | gzipCheckBox->setObjectName(QStringLiteral("gzipCheckBox")); 183 | gzipCheckBox->setChecked(gzip); 184 | QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)), 185 | this, SLOT(updated())); 186 | horizontalLayout_2->addWidget(gzipCheckBox); 187 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 188 | horizontalLayout_2->addItem(horizontalSpacer); 189 | tunnelGridLayout->addLayout(horizontalLayout_2); 190 | } 191 | { 192 | i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); 193 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 194 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 195 | ui.sigTypeLabel = new QLabel(gridLayoutWidget_2); 196 | sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel")); 197 | horizontalLayout_2->addWidget(sigTypeLabel); 198 | ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType); 199 | sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox")); 200 | QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)), 201 | this, SLOT(updated())); 202 | horizontalLayout_2->addWidget(sigTypeComboBox); 203 | QPushButton * lockButton2 = new QPushButton(gridLayoutWidget_2); 204 | horizontalLayout_2->addWidget(lockButton2); 205 | widgetlocks.add(new widgetlock(sigTypeComboBox, lockButton2)); 206 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 207 | horizontalLayout_2->addItem(horizontalSpacer); 208 | tunnelGridLayout->addLayout(horizontalLayout_2); 209 | } 210 | { 211 | std::string address = tunnelConfig->getaddress(); 212 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 213 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 214 | ui.addressLabel = new QLabel(gridLayoutWidget_2); 215 | addressLabel->setObjectName(QStringLiteral("addressLabel")); 216 | horizontalLayout_2->addWidget(addressLabel); 217 | ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2); 218 | addressLineEdit->setObjectName(QStringLiteral("addressLineEdit")); 219 | addressLineEdit->setText(address.c_str()); 220 | QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)), 221 | this, SLOT(updated())); 222 | horizontalLayout_2->addWidget(addressLineEdit); 223 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 224 | horizontalLayout_2->addItem(horizontalSpacer); 225 | tunnelGridLayout->addLayout(horizontalLayout_2); 226 | } 227 | { 228 | bool isUniqueLocal = tunnelConfig->getisUniqueLocal(); 229 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 230 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 231 | ui.isUniqueLocalCheckBox = new QCheckBox(gridLayoutWidget_2); 232 | isUniqueLocalCheckBox->setObjectName(QStringLiteral("isUniqueLocalCheckBox")); 233 | isUniqueLocalCheckBox->setChecked(isUniqueLocal); 234 | QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)), 235 | this, SLOT(updated())); 236 | horizontalLayout_2->addWidget(isUniqueLocalCheckBox); 237 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 238 | horizontalLayout_2->addItem(horizontalSpacer); 239 | tunnelGridLayout->addLayout(horizontalLayout_2); 240 | } 241 | { 242 | int cryptoType = tunnelConfig->getcryptoType(); 243 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 244 | ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2); 245 | cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel")); 246 | horizontalLayout_2->addWidget(cryptoTypeLabel); 247 | ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2); 248 | cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit")); 249 | cryptoTypeLineEdit->setText(QString::number(cryptoType)); 250 | cryptoTypeLineEdit->setMaximumWidth(80); 251 | QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)), 252 | this, SLOT(updated())); 253 | horizontalLayout_2->addWidget(cryptoTypeLineEdit); 254 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 255 | horizontalLayout_2->addItem(horizontalSpacer); 256 | tunnelGridLayout->addLayout(horizontalLayout_2); 257 | } 258 | { 259 | I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); 260 | appendControlsForI2CPParameters(i2cpParameters, gridIndex); 261 | } 262 | 263 | retranslateServerTunnelForm(ui); 264 | 265 | tunnelGridLayout->invalidate(); 266 | 267 | return h; 268 | } 269 | 270 | void ServerTunnelPane::deleteServerTunnelForm() { 271 | TunnelPane::deleteTunnelForm(); 272 | delete serverTunnelNameGroupBox;//->deleteLater(); 273 | serverTunnelNameGroupBox=nullptr; 274 | 275 | //gridLayoutWidget_2->deleteLater(); 276 | //gridLayoutWidget_2=nullptr; 277 | } 278 | 279 | 280 | ServerTunnelPane* ServerTunnelPane::asServerTunnelPane(){return this;} 281 | ClientTunnelPane* ServerTunnelPane::asClientTunnelPane(){return nullptr;} 282 | -------------------------------------------------------------------------------- /src/ServerTunnelPane.h: -------------------------------------------------------------------------------- 1 | #ifndef SERVERTUNNELPANE_H 2 | #define SERVERTUNNELPANE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "QVBoxLayout" 19 | #include "QCheckBox" 20 | 21 | #include "assert.h" 22 | 23 | #include "TunnelPane.h" 24 | #include "TunnelsPageUpdateListener.h" 25 | 26 | class ServerTunnelConfig; 27 | 28 | class ClientTunnelPane; 29 | 30 | class ServerTunnelPane : public TunnelPane { 31 | Q_OBJECT 32 | 33 | public: 34 | ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow); 35 | virtual ~ServerTunnelPane(){} 36 | 37 | virtual ServerTunnelPane* asServerTunnelPane(); 38 | virtual ClientTunnelPane* asClientTunnelPane(); 39 | 40 | int appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, 41 | int tunnelsRow, int height); 42 | void deleteServerTunnelForm(); 43 | 44 | private: 45 | QGroupBox *serverTunnelNameGroupBox; 46 | 47 | //tunnel 48 | QWidget *gridLayoutWidget_2; 49 | 50 | //host 51 | QHBoxLayout *horizontalLayout_2; 52 | QLabel *hostLabel; 53 | QLineEdit *hostLineEdit; 54 | QSpacerItem *hostHorizontalSpacer; 55 | 56 | //port 57 | QLabel * portLabel; 58 | QLineEdit * portLineEdit; 59 | 60 | //keys 61 | QLabel * keysLabel; 62 | QLineEdit * keysLineEdit; 63 | 64 | //inPort 65 | QLabel * inPortLabel; 66 | QLineEdit * inPortLineEdit; 67 | 68 | //cryptoType 69 | QLabel * cryptoTypeLabel; 70 | QLineEdit * cryptoTypeLineEdit; 71 | 72 | //accessList 73 | QLabel * accessListLabel; 74 | QLineEdit * accessListLineEdit; 75 | 76 | //hostOverride 77 | QLabel * hostOverrideLabel; 78 | QLineEdit * hostOverrideLineEdit; 79 | 80 | //webIRCPass 81 | QLabel * webIRCPassLabel; 82 | QLineEdit * webIRCPassLineEdit; 83 | 84 | //address 85 | QLabel * addressLabel; 86 | QLineEdit * addressLineEdit; 87 | 88 | //gzip 89 | QCheckBox * gzipCheckBox; 90 | 91 | //isUniqueLocal 92 | QCheckBox * isUniqueLocalCheckBox; 93 | 94 | //sigType 95 | QLabel * sigTypeLabel; 96 | QComboBox * sigTypeComboBox; 97 | 98 | protected slots: 99 | virtual void setGroupBoxTitle(const QString & title); 100 | 101 | private: 102 | void retranslateServerTunnelForm(ServerTunnelPane& /*ui*/) { 103 | typeLabel->setText(QApplication::translate("srvTunForm", "Server tunnel type:", 0)); 104 | hostLabel->setText(QApplication::translate("srvTunForm", "Host:", 0)); 105 | portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0)); 106 | keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0)); 107 | inPortLabel->setText(QApplication::translate("srvTunForm", "InPort:", 0)); 108 | cryptoTypeLabel->setText(QApplication::translate("srvTunForm", "Crypto type:", 0)); 109 | accessListLabel->setText(QApplication::translate("srvTunForm", "Access list:", 0)); 110 | hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0)); 111 | webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0)); 112 | addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0)); 113 | 114 | gzipCheckBox->setText(QApplication::translate("srvTunForm", "GZip", 0)); 115 | isUniqueLocalCheckBox->setText(QApplication::translate("srvTunForm", "Is unique local", 0)); 116 | 117 | sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0)); 118 | } 119 | 120 | protected: 121 | virtual bool applyDataFromUIToTunnelConfig() { 122 | QString cannotSaveSettings = QApplication::tr("Cannot save settings."); 123 | bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); 124 | if(!ok)return false; 125 | ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig(); 126 | assert(stc!=nullptr); 127 | 128 | if(!isValidSingleLine(hostLineEdit))return false; 129 | if(!isValidSingleLine(portLineEdit))return false; 130 | if(!isValidSingleLine(cryptoTypeLineEdit))return false; 131 | if(!isValidSingleLine(keysLineEdit))return false; 132 | if(!isValidSingleLine(inPortLineEdit))return false; 133 | if(!isValidSingleLine(accessListLineEdit))return false; 134 | if(stc->getType()==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP) { 135 | if(!isValidSingleLine(hostOverrideLineEdit))return false; 136 | } 137 | if(!isValidSingleLine(webIRCPassLineEdit))return false; 138 | if(!isValidSingleLine(addressLineEdit))return false; 139 | 140 | stc->sethost(hostLineEdit->text().toStdString()); 141 | 142 | auto portStr=portLineEdit->text(); 143 | int portInt=portStr.toInt(&ok); 144 | if(!ok){ 145 | highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit); 146 | return false; 147 | } 148 | stc->setport(portInt); 149 | 150 | auto cryptoTypeStr=cryptoTypeLineEdit->text(); 151 | int cryptoTypeInt=cryptoTypeStr.toInt(&ok); 152 | if(!ok){ 153 | highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit); 154 | return false; 155 | } 156 | stc->setcryptoType(cryptoTypeInt); 157 | 158 | stc->setkeys(keysLineEdit->text().toStdString()); 159 | 160 | auto str=inPortLineEdit->text(); 161 | int inPortInt=str.toInt(&ok); 162 | if(!ok){ 163 | highlightWrongInput(QApplication::tr("Bad inPort, must be int.")+" "+cannotSaveSettings,inPortLineEdit); 164 | return false; 165 | } 166 | stc->setinPort(inPortInt); 167 | 168 | stc->setaccessList(accessListLineEdit->text().toStdString()); 169 | 170 | if(stc->getType()==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP) { 171 | stc->sethostOverride(hostOverrideLineEdit->text().toStdString()); 172 | } 173 | 174 | stc->setwebircpass(webIRCPassLineEdit->text().toStdString()); 175 | 176 | stc->setaddress(addressLineEdit->text().toStdString()); 177 | 178 | stc->setgzip(gzipCheckBox->isChecked()); 179 | 180 | stc->setisUniqueLocal(isUniqueLocalCheckBox->isChecked()); 181 | 182 | stc->setsigType(readSigTypeComboboxUI(sigTypeComboBox)); 183 | 184 | hostOverrideLabel->setEnabled(stc->getType()==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP); 185 | hostOverrideLineEdit->setEnabled(stc->getType()==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP); 186 | 187 | return true; 188 | } 189 | }; 190 | 191 | #endif // SERVERTUNNELPANE_H 192 | -------------------------------------------------------------------------------- /src/SignatureTypeComboboxFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "SignatureTypeComboboxFactory.h" 2 | 3 | -------------------------------------------------------------------------------- /src/SignatureTypeComboboxFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef SIGNATURETYPECOMBOBOXFACTORY_H 2 | #define SIGNATURETYPECOMBOBOXFACTORY_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "Identity.h" 8 | 9 | class SignatureTypeComboBoxFactory 10 | { 11 | static const QVariant createUserData(const uint16_t sigType) { 12 | return QVariant::fromValue((uint)sigType); 13 | } 14 | 15 | static void addItem(QComboBox* signatureTypeCombobox, QString text, const uint16_t sigType) { 16 | const QVariant userData = createUserData(sigType); 17 | signatureTypeCombobox->addItem(text, userData); 18 | } 19 | 20 | public: 21 | static uint16_t getSigType(const QVariant& var) { 22 | return (uint16_t)var.toInt(); 23 | } 24 | 25 | static void fillComboBox(QComboBox* signatureTypeCombobox, uint16_t selectedSigType) { 26 | /* 27 | https://geti2p.net/spec/common-structures#certificate 28 | все коды перечислены 29 | это таблица "The defined Signing Public Key types are:" ? 30 | да 31 | 32 | see also: Identity.h line 55 33 | */ 34 | int index=0; 35 | bool foundSelected=false; 36 | 37 | using namespace i2p::data; 38 | 39 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "DSA_SHA1", 0), SIGNING_KEY_TYPE_DSA_SHA1); //0 40 | if(selectedSigType==SIGNING_KEY_TYPE_DSA_SHA1){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 41 | ++index; 42 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA256_P256", 0), SIGNING_KEY_TYPE_ECDSA_SHA256_P256); //1 43 | if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA256_P256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 44 | ++index; 45 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA384_P384", 0), SIGNING_KEY_TYPE_ECDSA_SHA384_P384); //2 46 | if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA384_P384){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 47 | ++index; 48 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA512_P521", 0), SIGNING_KEY_TYPE_ECDSA_SHA512_P521); //3 49 | if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA512_P521){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 50 | ++index; 51 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA256_2048", 0), SIGNING_KEY_TYPE_RSA_SHA256_2048); //4 52 | if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA256_2048){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 53 | ++index; 54 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA384_3072", 0), SIGNING_KEY_TYPE_RSA_SHA384_3072); //5 55 | if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA384_3072){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 56 | ++index; 57 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA512_4096", 0), SIGNING_KEY_TYPE_RSA_SHA512_4096); //6 58 | if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA512_4096){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 59 | ++index; 60 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); //7 61 | if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 62 | ++index; 63 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519PH", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph); //8 64 | if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 65 | ++index; 66 | // the following signature type should never appear in netid=2 67 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256", 0), SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256); //9 68 | if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 69 | ++index; 70 | addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512); //10 71 | if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} 72 | ++index; 73 | if(!foundSelected){ 74 | addItem(signatureTypeCombobox, QString::number(selectedSigType), selectedSigType); //unknown sigtype 75 | signatureTypeCombobox->setCurrentIndex(index); 76 | } 77 | } 78 | 79 | static QComboBox* createSignatureTypeComboBox(QWidget* parent, uint16_t selectedSigType) { 80 | QComboBox* signatureTypeCombobox = new QComboBox(parent); 81 | fillComboBox(signatureTypeCombobox, selectedSigType); 82 | return signatureTypeCombobox; 83 | } 84 | }; 85 | 86 | #endif // SIGNATURETYPECOMBOBOXFACTORY_H 87 | -------------------------------------------------------------------------------- /src/TunnelConfig.cpp: -------------------------------------------------------------------------------- 1 | #include "TunnelConfig.h" 2 | 3 | void TunnelConfig::saveHeaderToStringStream(std::stringstream& out) { 4 | out << "[" << name << "]\n" 5 | << "type=" << type.toStdString() << "\n"; 6 | } 7 | 8 | void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) { 9 | if (i2cpParameters.getInbound_length().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNEL_LENGTH) 10 | out << i2p::client::I2CP_PARAM_INBOUND_TUNNEL_LENGTH << "=" 11 | << i2cpParameters.getInbound_length().toStdString() << "\n"; 12 | if (i2cpParameters.getOutbound_length().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNEL_LENGTH) 13 | out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH << "=" 14 | << i2cpParameters.getOutbound_length().toStdString() << "\n"; 15 | if (i2cpParameters.getInbound_quantity().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNELS_QUANTITY) 16 | out << i2p::client::I2CP_PARAM_INBOUND_TUNNELS_QUANTITY << "=" 17 | << i2cpParameters.getInbound_quantity().toStdString() << "\n"; 18 | if (i2cpParameters.getOutbound_quantity().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNELS_QUANTITY) 19 | out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY << "=" 20 | << i2cpParameters.getOutbound_quantity().toStdString() << "\n"; 21 | if (i2cpParameters.getCrypto_tagsToSend().toUShort() != i2p::client::DEFAULT_TAGS_TO_SEND) 22 | out << i2p::client::I2CP_PARAM_TAGS_TO_SEND << "=" 23 | << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n"; 24 | if (!i2cpParameters.getExplicitPeers().isEmpty()) //todo #947 25 | out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "=" 26 | << i2cpParameters.getExplicitPeers().toStdString() << "\n"; 27 | out << i2p::client::I2CP_PARAM_LEASESET_AUTH_TYPE << "=" 28 | << i2cpParameters.get_i2cp_leaseSetAuthType().toStdString() << "\n"; 29 | out << i2p::client::I2CP_PARAM_LEASESET_ENCRYPTION_TYPE << "=" 30 | << i2cpParameters.get_i2cp_leaseSetEncType().toStdString() << "\n"; 31 | out << i2p::client::I2CP_PARAM_LEASESET_PRIV_KEY << "=" 32 | << i2cpParameters.get_i2cp_leaseSetPrivKey().toStdString() << "\n"; 33 | out << i2p::client::I2CP_PARAM_LEASESET_TYPE << "=" 34 | << i2cpParameters.get_i2cp_leaseSetType().toStdString() << "\n"; 35 | out << i2p::client::I2CP_PARAM_STREAMING_ANSWER_PINGS << "=" 36 | << (i2cpParameters.get_i2p_streaming_answerPings() ? "true" : "false") << "\n"; 37 | out << i2p::client::I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY << "=" 38 | << i2cpParameters.get_i2p_streaming_initialAckDelay().toStdString() << "\n"; 39 | out << "\n"; 40 | } 41 | 42 | void ClientTunnelConfig::saveToStringStream(std::stringstream& out) { 43 | out << "address=" << address << "\n" 44 | << "port=" << port << "\n" 45 | << "destination=" << dest << "\n" 46 | << "destinationport=" << destinationPort << "\n" 47 | << "cryptoType=" << getcryptoType() << "\n" 48 | << "signaturetype=" << sigType << "\n"; 49 | if(!keys.empty()) out << "keys=" << keys << "\n"; 50 | } 51 | 52 | 53 | void ServerTunnelConfig::saveToStringStream(std::stringstream& out) { 54 | out << "host=" << host << "\n" 55 | << "port=" << port << "\n" 56 | << "signaturetype=" << sigType << "\n" 57 | << "inport=" << inPort << "\n"; 58 | if(accessList.size()>0) { out << "accesslist=" << accessList << "\n"; } 59 | out << "gzip=" << (gzip?"true":"false") << "\n" 60 | << "cryptoType=" << getcryptoType() << "\n" 61 | << "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n" 62 | << "address=" << address << "\n" 63 | << "hostoverride=" << hostOverride << "\n" 64 | << "webircpassword=" << webircpass << "\n"; 65 | if(!keys.empty()) out << "keys=" << keys << "\n"; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/TunnelConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef TUNNELCONFIG_H 2 | #define TUNNELCONFIG_H 3 | 4 | #include "QString" 5 | #include 6 | 7 | #include "ClientContext.h" 8 | #include "Destination.h" 9 | #include "TunnelsPageUpdateListener.h" 10 | 11 | 12 | class I2CPParameters{ 13 | QString inbound_length;//number of hops of an inbound tunnel. 3 by default; lower value is faster but dangerous 14 | QString outbound_length;//number of hops of an outbound tunnel. 3 by default; lower value is faster but dangerous 15 | QString inbound_quantity; //number of inbound tunnels. 5 by default 16 | QString outbound_quantity; //number of outbound tunnels. 5 by default 17 | QString crypto_tagsToSend; //number of ElGamal/AES tags to send. 40 by default; too low value may cause problems with tunnel building 18 | QString explicitPeers; //list of comma-separated b64 addresses of peers to use, default: unset 19 | QString i2p_streaming_initialAckDelay; //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default 20 | bool i2p_streaming_answerPings; //i2p.streaming.answerPings -- enable sending pongs. true by default 21 | QString i2cp_leaseSetType; //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default 22 | QString i2cp_leaseSetEncType; //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default 23 | QString i2cp_leaseSetPrivKey; //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH 24 | QString i2cp_leaseSetAuthType; //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK 25 | public: 26 | I2CPParameters(): inbound_length(), 27 | outbound_length(), 28 | inbound_quantity(), 29 | outbound_quantity(), 30 | crypto_tagsToSend(), 31 | explicitPeers(), 32 | i2p_streaming_initialAckDelay(), 33 | i2p_streaming_answerPings(true), 34 | i2cp_leaseSetType(), 35 | i2cp_leaseSetEncType(), 36 | i2cp_leaseSetPrivKey(), 37 | i2cp_leaseSetAuthType() {} 38 | const QString& getInbound_length(){return inbound_length;} 39 | const QString& getOutbound_length(){return outbound_length;} 40 | const QString& getInbound_quantity(){return inbound_quantity;} 41 | const QString& getOutbound_quantity(){return outbound_quantity;} 42 | const QString& getCrypto_tagsToSend(){return crypto_tagsToSend;} 43 | const QString& getExplicitPeers(){return explicitPeers;} 44 | const QString& get_i2p_streaming_initialAckDelay(){return i2p_streaming_initialAckDelay;} 45 | bool get_i2p_streaming_answerPings(){return i2p_streaming_answerPings;} 46 | const QString& get_i2cp_leaseSetType(){return i2cp_leaseSetType;} 47 | const QString& get_i2cp_leaseSetEncType(){return i2cp_leaseSetEncType;} 48 | const QString& get_i2cp_leaseSetPrivKey(){return i2cp_leaseSetPrivKey;} 49 | const QString& get_i2cp_leaseSetAuthType(){return i2cp_leaseSetAuthType;} 50 | void setInbound_length(QString inbound_length_){inbound_length=inbound_length_;} 51 | void setOutbound_length(QString outbound_length_){outbound_length=outbound_length_;} 52 | void setInbound_quantity(QString inbound_quantity_){inbound_quantity=inbound_quantity_;} 53 | void setOutbound_quantity(QString outbound_quantity_){outbound_quantity=outbound_quantity_;} 54 | void setCrypto_tagsToSend(QString crypto_tagsToSend_){crypto_tagsToSend=crypto_tagsToSend_;} 55 | void setExplicitPeers(QString explicitPeers_){explicitPeers=explicitPeers_;} 56 | void set_i2p_streaming_initialAckDelay(QString i2p_streaming_initialAckDelay_){i2p_streaming_initialAckDelay=i2p_streaming_initialAckDelay_;} 57 | void set_i2p_streaming_answerPings(bool i2p_streaming_answerPings_){i2p_streaming_answerPings=i2p_streaming_answerPings_;} 58 | void set_i2cp_leaseSetType(QString i2cp_leaseSetType_){i2cp_leaseSetType=i2cp_leaseSetType_;} 59 | void set_i2cp_leaseSetEncType(QString i2cp_leaseSetEncType_){i2cp_leaseSetEncType=i2cp_leaseSetEncType_;} 60 | void set_i2cp_leaseSetPrivKey(QString i2cp_leaseSetPrivKey_){i2cp_leaseSetPrivKey=i2cp_leaseSetPrivKey_;} 61 | void set_i2cp_leaseSetAuthType(QString i2cp_leaseSetAuthType_){i2cp_leaseSetAuthType=i2cp_leaseSetAuthType_;} 62 | }; 63 | 64 | 65 | class ClientTunnelConfig; 66 | class ServerTunnelConfig; 67 | 68 | class TunnelPane; 69 | 70 | class TunnelConfig { 71 | /* 72 | const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client"; 73 | const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server"; 74 | const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http"; 75 | const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc"; 76 | const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient"; 77 | const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver"; 78 | const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks"; 79 | const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks"; 80 | const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy"; 81 | */ 82 | QString type; 83 | std::string name; 84 | TunnelPane* tunnelPane; 85 | int cryptoType; 86 | public: 87 | TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_, int cryptoType_): 88 | type(type_), name(name_), cryptoType(cryptoType_), i2cpParameters(i2cpParameters_) {} 89 | virtual ~TunnelConfig(){} 90 | const QString& getType(){return type;} 91 | const std::string& getName(){return name;} 92 | int getcryptoType(){return cryptoType;} 93 | void setType(const QString& type_){type=type_;} 94 | void setName(const std::string& name_){name=name_;} 95 | I2CPParameters& getI2cpParameters(){return i2cpParameters;} 96 | void saveHeaderToStringStream(std::stringstream& out); 97 | void saveI2CPParametersToStringStream(std::stringstream& out); 98 | virtual void saveToStringStream(std::stringstream& out)=0; 99 | virtual ClientTunnelConfig* asClientTunnelConfig()=0; 100 | virtual ServerTunnelConfig* asServerTunnelConfig()=0; 101 | void setTunnelPane(TunnelPane* tp){this->tunnelPane = tp;} 102 | TunnelPane* getTunnelPane() {return tunnelPane;} 103 | void setcryptoType(int cryptoType_){cryptoType=cryptoType_;} 104 | private: 105 | I2CPParameters i2cpParameters; 106 | }; 107 | 108 | /* 109 | # mandatory parameters: 110 | std::string dest; 111 | if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) 112 | dest = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION); 113 | int port = section.second.get (I2P_CLIENT_TUNNEL_PORT); 114 | # optional parameters (may be omitted) 115 | std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); 116 | std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); 117 | int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); 118 | i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); 119 | # * keys -- our identity, if unset, will be generated on every startup, 120 | # if set and file missing, keys will be generated and placed to this file 121 | # * address -- local interface to bind 122 | # * signaturetype -- signature type for new destination. 0 (DSA/SHA1), 1 (EcDSA/SHA256) or 7 (EdDSA/SHA512) 123 | [somelabel] 124 | type = client 125 | address = 127.0.0.1 126 | port = 6668 127 | destination = irc.postman.i2p 128 | keys = irc-keys.dat 129 | */ 130 | class ClientTunnelConfig : public TunnelConfig { 131 | std::string dest; 132 | int port; 133 | std::string keys; 134 | std::string address; 135 | int destinationPort; 136 | i2p::data::SigningKeyType sigType; 137 | public: 138 | ClientTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_, 139 | std::string dest_, 140 | int port_, 141 | std::string keys_, 142 | std::string address_, 143 | int destinationPort_, 144 | i2p::data::SigningKeyType sigType_, 145 | int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_), 146 | dest(dest_), 147 | port(port_), 148 | keys(keys_), 149 | address(address_), 150 | destinationPort(destinationPort_), 151 | sigType(sigType_) {} 152 | std::string& getdest(){return dest;} 153 | int getport(){return port;} 154 | std::string & getkeys(){return keys;} 155 | std::string & getaddress(){return address;} 156 | int getdestinationPort(){return destinationPort;} 157 | i2p::data::SigningKeyType getsigType(){return sigType;} 158 | void setdest(const std::string& dest_){dest=dest_;} 159 | void setport(int port_){port=port_;} 160 | void setkeys(const std::string & keys_){keys=keys_;} 161 | void setaddress(const std::string & address_){address=address_;} 162 | void setdestinationPort(int destinationPort_){destinationPort=destinationPort_;} 163 | void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} 164 | virtual void saveToStringStream(std::stringstream& out); 165 | virtual ClientTunnelConfig* asClientTunnelConfig(){return this;} 166 | virtual ServerTunnelConfig* asServerTunnelConfig(){return nullptr;} 167 | }; 168 | 169 | /* 170 | # mandatory parameters: 171 | # * host -- ip address of our service 172 | # * port -- port of our service 173 | # * keys -- file with LeaseSet of address in i2p 174 | std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST); 175 | int port = section.second.get (I2P_SERVER_TUNNEL_PORT); 176 | std::string keys = section.second.get (I2P_SERVER_TUNNEL_KEYS); 177 | # optional parameters (may be omitted) 178 | int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0); 179 | std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); 180 | std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, ""); 181 | std::string webircpass = section.second.get (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, ""); 182 | bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true); 183 | i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); 184 | std::string address = section.second.get (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); 185 | bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); 186 | # * inport -- optional, i2p service port, if unset - the same as 'port' 187 | # * accesslist -- comma-separated list of i2p addresses, allowed to connect 188 | # every address is b32 without '.b32.i2p' part 189 | [somelabel] 190 | type = server 191 | host = 127.0.0.1 192 | port = 6667 193 | keys = irc.dat 194 | */ 195 | class ServerTunnelConfig : public TunnelConfig { 196 | std::string host; 197 | int port; 198 | std::string keys; 199 | int inPort; 200 | std::string accessList; 201 | std::string hostOverride; 202 | std::string webircpass; 203 | bool gzip; 204 | i2p::data::SigningKeyType sigType; 205 | std::string address; 206 | bool isUniqueLocal; 207 | public: 208 | ServerTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_, 209 | std::string host_, 210 | int port_, 211 | std::string keys_, 212 | int inPort_, 213 | std::string accessList_, 214 | std::string hostOverride_, 215 | std::string webircpass_, 216 | bool gzip_, 217 | i2p::data::SigningKeyType sigType_, 218 | std::string address_, 219 | bool isUniqueLocal_, 220 | int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_), 221 | host(host_), 222 | port(port_), 223 | keys(keys_), 224 | inPort(inPort_), 225 | accessList(accessList_), 226 | hostOverride(hostOverride_), 227 | webircpass(webircpass_), 228 | gzip(gzip_), 229 | sigType(sigType_), 230 | address(address_), 231 | isUniqueLocal(isUniqueLocal_) {} 232 | std::string& gethost(){return host;} 233 | int getport(){return port;} 234 | std::string& getkeys(){return keys;} 235 | int getinPort(){return inPort;} 236 | std::string& getaccessList(){return accessList;} 237 | std::string& gethostOverride(){return hostOverride;} 238 | std::string& getwebircpass(){return webircpass;} 239 | bool getgzip(){return gzip;} 240 | i2p::data::SigningKeyType getsigType(){return sigType;} 241 | std::string& getaddress(){return address;} 242 | bool getisUniqueLocal(){return isUniqueLocal;} 243 | void sethost(const std::string& host_){host=host_;} 244 | void setport(int port_){port=port_;} 245 | void setkeys(const std::string& keys_){keys=keys_;} 246 | void setinPort(int inPort_){inPort=inPort_;} 247 | void setaccessList(const std::string& accessList_){accessList=accessList_;} 248 | void sethostOverride(const std::string& hostOverride_){hostOverride=hostOverride_;} 249 | void setwebircpass(const std::string& webircpass_){webircpass=webircpass_;} 250 | void setgzip(bool gzip_){gzip=gzip_;} 251 | void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} 252 | void setaddress(const std::string& address_){address=address_;} 253 | void setisUniqueLocal(bool isUniqueLocal_){isUniqueLocal=isUniqueLocal_;} 254 | virtual void saveToStringStream(std::stringstream& out); 255 | virtual ClientTunnelConfig* asClientTunnelConfig(){return nullptr;} 256 | virtual ServerTunnelConfig* asServerTunnelConfig(){return this;} 257 | }; 258 | 259 | 260 | #endif // TUNNELCONFIG_H 261 | -------------------------------------------------------------------------------- /src/TunnelPane.cpp: -------------------------------------------------------------------------------- 1 | #include "TunnelPane.h" 2 | 3 | #include "QMessageBox" 4 | #include "mainwindow.h" 5 | #include "ui_mainwindow.h" 6 | 7 | #include "I2pdQtUtil.h" 8 | 9 | TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_): 10 | QObject(), 11 | mainWindow(mainWindow_), 12 | wrongInputPane(wrongInputPane_), 13 | wrongInputLabel(wrongInputLabel_), 14 | tunnelConfig(tunnelConfig_), 15 | tunnelsPageUpdateListener(tunnelsPageUpdateListener_), 16 | gridLayoutWidget_2(nullptr) {} 17 | 18 | void TunnelPane::setupTunnelPane( 19 | TunnelConfig* tunnelConfig, 20 | QGroupBox *tunnelGroupBox, 21 | QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, 22 | QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h) { 23 | tunnelGroupBox->setGeometry(0, tunnelsFormGridLayoutWidget->height(), gridLayoutWidget_2->width(), h); 24 | tunnelsFormGridLayoutWidget->resize(527, tunnelsFormGridLayoutWidget->height()+h); 25 | 26 | QObject::connect(tunnelTypeComboBox, SIGNAL(currentIndexChanged(int)), 27 | this, SLOT(updated())); 28 | 29 | 30 | this->tunnelGroupBox=tunnelGroupBox; 31 | 32 | gridLayoutWidget_2->setObjectName(QStringLiteral("gridLayoutWidget_2")); 33 | this->gridLayoutWidget_2=gridLayoutWidget_2; 34 | tunnelGridLayout = new QVBoxLayout(gridLayoutWidget_2); 35 | tunnelGridLayout->setObjectName(QStringLiteral("tunnelGridLayout")); 36 | tunnelGridLayout->setContentsMargins(10, 25, 10, 10); 37 | tunnelGridLayout->setSpacing(5); 38 | 39 | //header 40 | QHBoxLayout *headerHorizontalLayout = new QHBoxLayout(); 41 | headerHorizontalLayout->setObjectName(QStringLiteral("headerHorizontalLayout")); 42 | 43 | nameLabel = new QLabel(gridLayoutWidget_2); 44 | nameLabel->setObjectName(QStringLiteral("nameLabel")); 45 | headerHorizontalLayout->addWidget(nameLabel); 46 | nameLineEdit = new QLineEdit(gridLayoutWidget_2); 47 | nameLineEdit->setObjectName(QStringLiteral("nameLineEdit")); 48 | const QString& tunnelName=tunnelConfig->getName().c_str(); 49 | nameLineEdit->setText(tunnelName); 50 | setGroupBoxTitle(tunnelName); 51 | 52 | QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)), 53 | this, SLOT(updated())); 54 | 55 | headerHorizontalLayout->addWidget(nameLineEdit); 56 | headerHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 57 | headerHorizontalLayout->addItem(headerHorizontalSpacer); 58 | deletePushButton = new QPushButton(gridLayoutWidget_2); 59 | deletePushButton->setObjectName(QStringLiteral("deletePushButton")); 60 | QObject::connect(deletePushButton, SIGNAL(released()), 61 | this, SLOT(deleteButtonReleased()));//MainWindow::DeleteTunnelNamed(std::string name) { 62 | headerHorizontalLayout->addWidget(deletePushButton); 63 | tunnelGridLayout->addLayout(headerHorizontalLayout); 64 | 65 | //type 66 | { 67 | //const QString& type = tunnelConfig->getType(); 68 | QHBoxLayout * horizontalLayout_ = new QHBoxLayout(); 69 | horizontalLayout_->setObjectName(QStringLiteral("horizontalLayout_")); 70 | typeLabel = new QLabel(gridLayoutWidget_2); 71 | typeLabel->setObjectName(QStringLiteral("typeLabel")); 72 | horizontalLayout_->addWidget(typeLabel); 73 | horizontalLayout_->addWidget(tunnelTypeComboBox); 74 | QPushButton * lockButton1 = new QPushButton(gridLayoutWidget_2); 75 | horizontalLayout_->addWidget(lockButton1); 76 | widgetlocks.add(new widgetlock(tunnelTypeComboBox, lockButton1)); 77 | this->tunnelTypeComboBox=tunnelTypeComboBox; 78 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 79 | horizontalLayout_->addItem(horizontalSpacer); 80 | tunnelGridLayout->addLayout(horizontalLayout_); 81 | } 82 | 83 | retranslateTunnelForm(*this); 84 | } 85 | 86 | void TunnelPane::deleteWidget() { 87 | //gridLayoutWidget_2->deleteLater(); 88 | tunnelGroupBox->deleteLater(); 89 | } 90 | 91 | void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex) { 92 | { 93 | //number of hops of an inbound tunnel 94 | const QString& inbound_length=i2cpParameters.getInbound_length(); 95 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 96 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 97 | inbound_lengthLabel = new QLabel(gridLayoutWidget_2); 98 | inbound_lengthLabel->setObjectName(QStringLiteral("inbound_lengthLabel")); 99 | horizontalLayout_2->addWidget(inbound_lengthLabel); 100 | inbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2); 101 | inbound_lengthLineEdit->setObjectName(QStringLiteral("inbound_lengthLineEdit")); 102 | inbound_lengthLineEdit->setText(inbound_length); 103 | inbound_lengthLineEdit->setMaximumWidth(80); 104 | QObject::connect(inbound_lengthLineEdit, SIGNAL(textChanged(const QString &)), 105 | this, SLOT(updated())); 106 | horizontalLayout_2->addWidget(inbound_lengthLineEdit); 107 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 108 | horizontalLayout_2->addItem(horizontalSpacer); 109 | tunnelGridLayout->addLayout(horizontalLayout_2); 110 | } 111 | { 112 | //number of hops of an outbound tunnel 113 | const QString& outbound_length=i2cpParameters.getOutbound_length(); 114 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 115 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 116 | outbound_lengthLabel = new QLabel(gridLayoutWidget_2); 117 | outbound_lengthLabel->setObjectName(QStringLiteral("outbound_lengthLabel")); 118 | horizontalLayout_2->addWidget(outbound_lengthLabel); 119 | outbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2); 120 | outbound_lengthLineEdit->setObjectName(QStringLiteral("outbound_lengthLineEdit")); 121 | outbound_lengthLineEdit->setText(outbound_length); 122 | outbound_lengthLineEdit->setMaximumWidth(80); 123 | QObject::connect(outbound_lengthLineEdit, SIGNAL(textChanged(const QString &)), 124 | this, SLOT(updated())); 125 | horizontalLayout_2->addWidget(outbound_lengthLineEdit); 126 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 127 | horizontalLayout_2->addItem(horizontalSpacer); 128 | tunnelGridLayout->addLayout(horizontalLayout_2); 129 | } 130 | { 131 | //number of inbound tunnels 132 | const QString& inbound_quantity=i2cpParameters.getInbound_quantity(); 133 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 134 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 135 | inbound_quantityLabel = new QLabel(gridLayoutWidget_2); 136 | inbound_quantityLabel->setObjectName(QStringLiteral("inbound_quantityLabel")); 137 | horizontalLayout_2->addWidget(inbound_quantityLabel); 138 | inbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2); 139 | inbound_quantityLineEdit->setObjectName(QStringLiteral("inbound_quantityLineEdit")); 140 | inbound_quantityLineEdit->setText(inbound_quantity); 141 | inbound_quantityLineEdit->setMaximumWidth(80); 142 | QObject::connect(inbound_quantityLineEdit, SIGNAL(textChanged(const QString &)), 143 | this, SLOT(updated())); 144 | horizontalLayout_2->addWidget(inbound_quantityLineEdit); 145 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 146 | horizontalLayout_2->addItem(horizontalSpacer); 147 | tunnelGridLayout->addLayout(horizontalLayout_2); 148 | } 149 | { 150 | //number of outbound tunnels 151 | const QString& outbound_quantity=i2cpParameters.getOutbound_quantity(); 152 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 153 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 154 | outbound_quantityLabel = new QLabel(gridLayoutWidget_2); 155 | outbound_quantityLabel->setObjectName(QStringLiteral("outbound_quantityLabel")); 156 | horizontalLayout_2->addWidget(outbound_quantityLabel); 157 | outbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2); 158 | outbound_quantityLineEdit->setObjectName(QStringLiteral("outbound_quantityLineEdit")); 159 | outbound_quantityLineEdit->setText(outbound_quantity); 160 | outbound_quantityLineEdit->setMaximumWidth(80); 161 | QObject::connect(outbound_quantityLineEdit, SIGNAL(textChanged(const QString &)), 162 | this, SLOT(updated())); 163 | horizontalLayout_2->addWidget(outbound_quantityLineEdit); 164 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 165 | horizontalLayout_2->addItem(horizontalSpacer); 166 | tunnelGridLayout->addLayout(horizontalLayout_2); 167 | } 168 | { 169 | //number of ElGamal/AES tags to send 170 | const QString& crypto_tagsToSend=i2cpParameters.getCrypto_tagsToSend(); 171 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 172 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 173 | crypto_tagsToSendLabel = new QLabel(gridLayoutWidget_2); 174 | crypto_tagsToSendLabel->setObjectName(QStringLiteral("crypto_tagsToSendLabel")); 175 | horizontalLayout_2->addWidget(crypto_tagsToSendLabel); 176 | crypto_tagsToSendLineEdit = new QLineEdit(gridLayoutWidget_2); 177 | crypto_tagsToSendLineEdit->setObjectName(QStringLiteral("crypto_tagsToSendLineEdit")); 178 | crypto_tagsToSendLineEdit->setText(crypto_tagsToSend); 179 | crypto_tagsToSendLineEdit->setMaximumWidth(80); 180 | QObject::connect(crypto_tagsToSendLineEdit, SIGNAL(textChanged(const QString &)), 181 | this, SLOT(updated())); 182 | horizontalLayout_2->addWidget(crypto_tagsToSendLineEdit); 183 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 184 | horizontalLayout_2->addItem(horizontalSpacer); 185 | tunnelGridLayout->addLayout(horizontalLayout_2); 186 | } 187 | 188 | { 189 | //explicitPeers -- list of comma-separated b64 addresses of peers to use, default: unset 190 | const QString& value=i2cpParameters.getExplicitPeers(); 191 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 192 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 193 | QLabel *_Label; 194 | explicitPeersLabel = _Label = new QLabel(gridLayoutWidget_2); 195 | _Label->setObjectName(QStringLiteral("_Label")); 196 | horizontalLayout_2->addWidget(_Label); 197 | QLineEdit *_LineEdit; 198 | explicitPeersLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); 199 | _LineEdit->setObjectName(QStringLiteral("_LineEdit")); 200 | _LineEdit->setText(value); 201 | _LineEdit->setMaximumWidth(80); 202 | QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), 203 | this, SLOT(updated())); 204 | horizontalLayout_2->addWidget(_LineEdit); 205 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 206 | horizontalLayout_2->addItem(horizontalSpacer); 207 | tunnelGridLayout->addLayout(horizontalLayout_2); 208 | } 209 | 210 | { 211 | //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default 212 | const QString& value=i2cpParameters.get_i2p_streaming_initialAckDelay(); 213 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 214 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 215 | QLabel *_Label; 216 | i2p_streaming_initialAckDelayLabel = _Label = new QLabel(gridLayoutWidget_2); 217 | _Label->setObjectName(QStringLiteral("_Label")); 218 | horizontalLayout_2->addWidget(_Label); 219 | QLineEdit *_LineEdit; 220 | i2p_streaming_initialAckDelayLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); 221 | _LineEdit->setObjectName(QStringLiteral("_LineEdit")); 222 | _LineEdit->setText(value); 223 | _LineEdit->setMaximumWidth(80); 224 | QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), 225 | this, SLOT(updated())); 226 | horizontalLayout_2->addWidget(_LineEdit); 227 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 228 | horizontalLayout_2->addItem(horizontalSpacer); 229 | tunnelGridLayout->addLayout(horizontalLayout_2); 230 | } 231 | 232 | { 233 | //i2p.streaming.answerPings -- enable sending pongs. true by default 234 | const bool value=i2cpParameters.get_i2p_streaming_answerPings(); 235 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 236 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 237 | QCheckBox *_CheckBox; 238 | i2p_streaming_answerPingsCheckBox = _CheckBox = new QCheckBox(gridLayoutWidget_2); 239 | _CheckBox->setObjectName(QStringLiteral("_CheckBox")); 240 | horizontalLayout_2->addWidget(_CheckBox); 241 | _CheckBox->setChecked(value); 242 | QObject::connect(_CheckBox, SIGNAL(toggled(bool)), 243 | this, SLOT(updated())); 244 | tunnelGridLayout->addLayout(horizontalLayout_2); 245 | } 246 | 247 | { 248 | //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default 249 | const QString& value=i2cpParameters.get_i2cp_leaseSetType(); 250 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 251 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 252 | QLabel *_Label; 253 | i2cp_leaseSetTypeLabel = _Label = new QLabel(gridLayoutWidget_2); 254 | _Label->setObjectName(QStringLiteral("_Label")); 255 | horizontalLayout_2->addWidget(_Label); 256 | QLineEdit *_LineEdit; 257 | i2cp_leaseSetTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); 258 | _LineEdit->setObjectName(QStringLiteral("_LineEdit")); 259 | _LineEdit->setText(value); 260 | _LineEdit->setMaximumWidth(80); 261 | QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), 262 | this, SLOT(updated())); 263 | horizontalLayout_2->addWidget(_LineEdit); 264 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 265 | horizontalLayout_2->addItem(horizontalSpacer); 266 | tunnelGridLayout->addLayout(horizontalLayout_2); 267 | } 268 | 269 | { 270 | //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default 271 | const QString& value=i2cpParameters.get_i2cp_leaseSetEncType(); 272 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 273 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 274 | QLabel *_Label; 275 | i2cp_leaseSetEncTypeLabel = _Label = new QLabel(gridLayoutWidget_2); 276 | _Label->setObjectName(QStringLiteral("_Label")); 277 | horizontalLayout_2->addWidget(_Label); 278 | QLineEdit *_LineEdit; 279 | i2cp_leaseSetEncTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); 280 | _LineEdit->setObjectName(QStringLiteral("_LineEdit")); 281 | _LineEdit->setText(value); 282 | _LineEdit->setMaximumWidth(80); 283 | QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), 284 | this, SLOT(updated())); 285 | horizontalLayout_2->addWidget(_LineEdit); 286 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 287 | horizontalLayout_2->addItem(horizontalSpacer); 288 | tunnelGridLayout->addLayout(horizontalLayout_2); 289 | } 290 | 291 | { 292 | //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH 293 | const QString& value=i2cpParameters.get_i2cp_leaseSetPrivKey(); 294 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 295 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 296 | QLabel *_Label; 297 | i2cp_leaseSetPrivKeyLabel = _Label = new QLabel(gridLayoutWidget_2); 298 | _Label->setObjectName(QStringLiteral("_Label")); 299 | horizontalLayout_2->addWidget(_Label); 300 | QLineEdit *_LineEdit; 301 | i2cp_leaseSetPrivKeyLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); 302 | _LineEdit->setObjectName(QStringLiteral("_LineEdit")); 303 | _LineEdit->setText(value); 304 | _LineEdit->setMaximumWidth(80); 305 | QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), 306 | this, SLOT(updated())); 307 | horizontalLayout_2->addWidget(_LineEdit); 308 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 309 | horizontalLayout_2->addItem(horizontalSpacer); 310 | tunnelGridLayout->addLayout(horizontalLayout_2); 311 | } 312 | 313 | { 314 | //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK 315 | const QString& value=i2cpParameters.get_i2cp_leaseSetAuthType(); 316 | QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); 317 | horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); 318 | QLabel *_Label; 319 | i2cp_leaseSetAuthTypeLabel = _Label = new QLabel(gridLayoutWidget_2); 320 | _Label->setObjectName(QStringLiteral("_Label")); 321 | horizontalLayout_2->addWidget(_Label); 322 | QLineEdit *_LineEdit; 323 | i2cp_leaseSetAuthTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); 324 | _LineEdit->setObjectName(QStringLiteral("_LineEdit")); 325 | _LineEdit->setText(value); 326 | _LineEdit->setMaximumWidth(80); 327 | QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), 328 | this, SLOT(updated())); 329 | horizontalLayout_2->addWidget(_LineEdit); 330 | QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); 331 | horizontalLayout_2->addItem(horizontalSpacer); 332 | tunnelGridLayout->addLayout(horizontalLayout_2); 333 | } 334 | 335 | retranslateI2CPParameters(); 336 | } 337 | 338 | void TunnelPane::updated() { 339 | std::string oldName=tunnelConfig->getName(); 340 | //validate and show red if invalid 341 | hideWrongInputLabel(); 342 | if(!mainWindow->applyTunnelsUiToConfigs())return; 343 | tunnelsPageUpdateListener->updated(oldName, tunnelConfig); 344 | } 345 | 346 | void TunnelPane::deleteButtonReleased() { 347 | QMessageBox msgBox; 348 | msgBox.setText(QApplication::tr("Are you sure to delete this tunnel?")); 349 | msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); 350 | msgBox.setDefaultButton(QMessageBox::Cancel); 351 | int ret = msgBox.exec(); 352 | switch (ret) { 353 | case QMessageBox::Ok: 354 | // OK was clicked 355 | hideWrongInputLabel(); 356 | tunnelsPageUpdateListener->needsDeleting(tunnelConfig->getName()); 357 | break; 358 | case QMessageBox::Cancel: 359 | // Cancel was clicked 360 | return; 361 | } 362 | } 363 | 364 | /* 365 | const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client"; 366 | const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server"; 367 | const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http"; 368 | const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc"; 369 | const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient"; 370 | const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver"; 371 | const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks"; 372 | const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks"; 373 | const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy"; 374 | */ 375 | QString TunnelPane::readTunnelTypeComboboxData() { 376 | return tunnelTypeComboBox->currentData().toString(); 377 | } 378 | 379 | i2p::data::SigningKeyType TunnelPane::readSigTypeComboboxUI(QComboBox* sigTypeComboBox) { 380 | return (i2p::data::SigningKeyType) sigTypeComboBox->currentData().toInt(); 381 | } 382 | 383 | void TunnelPane::deleteTunnelForm() { 384 | widgetlocks.deleteListeners(); 385 | } 386 | 387 | void TunnelPane::highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) { 388 | wrongInputPane->setVisible(true); 389 | wrongInputLabel->setText(warningText); 390 | mainWindow->adjustSizesAccordingToWrongLabel(); 391 | if(controlWithWrongInput){ 392 | mainWindow->ui->tunnelsScrollArea->ensureWidgetVisible(controlWithWrongInput); 393 | controlWithWrongInput->setFocus(); 394 | } 395 | mainWindow->showTunnelsPage(); 396 | } 397 | 398 | void TunnelPane::hideWrongInputLabel() const { 399 | wrongInputPane->setVisible(false); 400 | mainWindow->adjustSizesAccordingToWrongLabel(); 401 | } 402 | 403 | bool TunnelPane::isValidSingleLine(QLineEdit* widget) { 404 | return ::isValidSingleLine(widget, WrongInputPageEnum::tunnelsSettingsPage, mainWindow); 405 | } 406 | -------------------------------------------------------------------------------- /src/TunnelPane.h: -------------------------------------------------------------------------------- 1 | #ifndef TUNNELPANE_H 2 | #define TUNNELPANE_H 3 | 4 | #include "QObject" 5 | #include "QWidget" 6 | #include "QComboBox" 7 | #include "QGridLayout" 8 | #include "QLabel" 9 | #include "QPushButton" 10 | #include "QApplication" 11 | #include "QLineEdit" 12 | #include "QGroupBox" 13 | #include "QVBoxLayout" 14 | #include "QCheckBox" 15 | 16 | #include "TunnelConfig.h" 17 | 18 | #include 19 | #include 20 | 21 | class ServerTunnelPane; 22 | class ClientTunnelPane; 23 | 24 | class TunnelConfig; 25 | class I2CPParameters; 26 | 27 | class MainWindow; 28 | 29 | class TunnelPane : public QObject { 30 | 31 | Q_OBJECT 32 | 33 | public: 34 | TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_); 35 | virtual ~TunnelPane(){} 36 | 37 | void deleteTunnelForm(); 38 | 39 | void hideWrongInputLabel() const; 40 | void highlightWrongInput(QString warningText, QWidget* controlWithWrongInput); 41 | 42 | virtual ServerTunnelPane* asServerTunnelPane()=0; 43 | virtual ClientTunnelPane* asClientTunnelPane()=0; 44 | 45 | void deleteWidget(); 46 | 47 | protected: 48 | MainWindow* mainWindow; 49 | QWidget * wrongInputPane; 50 | QLabel* wrongInputLabel; 51 | TunnelConfig* tunnelConfig; 52 | widgetlockregistry widgetlocks; 53 | TunnelsPageUpdateListener* tunnelsPageUpdateListener; 54 | QVBoxLayout *tunnelGridLayout; 55 | QGroupBox *tunnelGroupBox; 56 | QWidget* gridLayoutWidget_2; 57 | 58 | //header 59 | QLabel *nameLabel; 60 | QLineEdit *nameLineEdit; 61 | public: 62 | QLineEdit * getNameLineEdit() { return nameLineEdit; } 63 | 64 | public slots: 65 | void updated(); 66 | void deleteButtonReleased(); 67 | 68 | protected: 69 | QSpacerItem *headerHorizontalSpacer; 70 | QPushButton *deletePushButton; 71 | 72 | //type 73 | QComboBox *tunnelTypeComboBox; 74 | QLabel *typeLabel; 75 | 76 | //i2cp 77 | 78 | QLabel * inbound_lengthLabel; 79 | QLineEdit * inbound_lengthLineEdit; 80 | 81 | QLabel * outbound_lengthLabel; 82 | QLineEdit * outbound_lengthLineEdit; 83 | 84 | QLabel * inbound_quantityLabel; 85 | QLineEdit * inbound_quantityLineEdit; 86 | 87 | QLabel * outbound_quantityLabel; 88 | QLineEdit * outbound_quantityLineEdit; 89 | 90 | QLabel * crypto_tagsToSendLabel; 91 | QLineEdit * crypto_tagsToSendLineEdit; 92 | 93 | QLabel * explicitPeersLabel; 94 | QLineEdit * explicitPeersLineEdit; 95 | 96 | QLabel * i2p_streaming_initialAckDelayLabel; 97 | QLineEdit * i2p_streaming_initialAckDelayLineEdit; 98 | 99 | QCheckBox * i2p_streaming_answerPingsCheckBox; 100 | 101 | QLabel * i2cp_leaseSetTypeLabel; 102 | QLineEdit * i2cp_leaseSetTypeLineEdit; 103 | 104 | QLabel * i2cp_leaseSetEncTypeLabel; 105 | QLineEdit * i2cp_leaseSetEncTypeLineEdit; 106 | 107 | QLabel * i2cp_leaseSetPrivKeyLabel; 108 | QLineEdit * i2cp_leaseSetPrivKeyLineEdit; 109 | 110 | QLabel * i2cp_leaseSetAuthTypeLabel; 111 | QLineEdit * i2cp_leaseSetAuthTypeLineEdit; 112 | 113 | 114 | QString readTunnelTypeComboboxData(); 115 | 116 | //should be created by factory 117 | i2p::data::SigningKeyType readSigTypeComboboxUI(QComboBox* sigTypeComboBox); 118 | 119 | public: 120 | //returns false when invalid data at UI 121 | virtual bool applyDataFromUIToTunnelConfig() { 122 | if(!isValidSingleLine(nameLineEdit)){ 123 | setGroupBoxTitle(QApplication::translate("tunPage", "invalid_tunnel_name")); 124 | return false; 125 | } 126 | if(!isValidSingleLine(inbound_lengthLineEdit))return false; 127 | if(!isValidSingleLine(inbound_quantityLineEdit))return false; 128 | if(!isValidSingleLine(outbound_lengthLineEdit))return false; 129 | if(!isValidSingleLine(outbound_quantityLineEdit))return false; 130 | if(!isValidSingleLine(crypto_tagsToSendLineEdit))return false; 131 | if(!isValidSingleLine(i2cp_leaseSetAuthTypeLineEdit))return false; 132 | if(!isValidSingleLine(i2cp_leaseSetEncTypeLineEdit))return false; 133 | if(!isValidSingleLine(i2cp_leaseSetPrivKeyLineEdit))return false; 134 | if(!isValidSingleLine(i2cp_leaseSetTypeLineEdit))return false; 135 | if(!isValidSingleLine(i2p_streaming_initialAckDelayLineEdit))return false; 136 | setGroupBoxTitle(nameLineEdit->text()); 137 | tunnelConfig->setName(nameLineEdit->text().toStdString()); 138 | tunnelConfig->setType(readTunnelTypeComboboxData()); 139 | I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters(); 140 | i2cpParams.setInbound_length(inbound_lengthLineEdit->text()); 141 | i2cpParams.setInbound_quantity(inbound_quantityLineEdit->text()); 142 | i2cpParams.setOutbound_length(outbound_lengthLineEdit->text()); 143 | i2cpParams.setOutbound_quantity(outbound_quantityLineEdit->text()); 144 | i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text()); 145 | i2cpParams.set_i2cp_leaseSetAuthType(i2cp_leaseSetAuthTypeLineEdit->text()); 146 | i2cpParams.set_i2cp_leaseSetEncType(i2cp_leaseSetEncTypeLineEdit->text()); 147 | i2cpParams.set_i2cp_leaseSetPrivKey(i2cp_leaseSetPrivKeyLineEdit->text()); 148 | i2cpParams.set_i2cp_leaseSetType(i2cp_leaseSetTypeLineEdit->text()); 149 | i2cpParams.set_i2p_streaming_answerPings(i2p_streaming_answerPingsCheckBox->isChecked()); 150 | i2cpParams.set_i2p_streaming_initialAckDelay(i2p_streaming_initialAckDelayLineEdit->text()); 151 | return true; 152 | } 153 | protected: 154 | void setupTunnelPane( 155 | TunnelConfig* tunnelConfig, 156 | QGroupBox *tunnelGroupBox, 157 | QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, 158 | QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h); 159 | void appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex); 160 | public: 161 | int height() { 162 | return gridLayoutWidget_2?gridLayoutWidget_2->height():0; 163 | } 164 | 165 | protected slots: 166 | virtual void setGroupBoxTitle(const QString & title)=0; 167 | private: 168 | void retranslateTunnelForm(TunnelPane& ui) { 169 | ui.deletePushButton->setText(QApplication::translate("tunForm", "Delete Tunnel", 0)); 170 | ui.nameLabel->setText(QApplication::translate("tunForm", "Tunnel name:", 0)); 171 | } 172 | 173 | void retranslateI2CPParameters() { 174 | inbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an inbound tunnel:", 0));; 175 | outbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an outbound tunnel:", 0));; 176 | inbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of inbound tunnels:", 0));; 177 | outbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of outbound tunnels:", 0));; 178 | crypto_tagsToSendLabel->setText(QApplication::translate("tunForm", "Number of ElGamal/AES tags to send:", 0));; 179 | explicitPeersLabel->setText(QApplication::translate("tunForm", "List of comma-separated b64 addresses of peers to use:", 0));; 180 | i2p_streaming_initialAckDelayLabel->setText(QApplication::translate("tunForm", "Milliseconds to wait before sending Ack:", 0)); 181 | i2p_streaming_answerPingsCheckBox->setText(QApplication::translate("tunForm", "Enable sending pongs", 0)); 182 | i2cp_leaseSetTypeLabel->setText(QApplication::translate("tunForm", "Type of LeaseSet to be sent. 1, 3 or 5:", 0)); 183 | i2cp_leaseSetEncTypeLabel->setText(QApplication::translate("tunForm", "Comma-separ. encr. types to be used in LeaseSet type 3 or 5:", 0)); 184 | i2cp_leaseSetPrivKeyLabel->setText(QApplication::translate("tunForm", "Decryption key for encrypted LeaseSet in base64. PSK or private DH:", 0)); 185 | i2cp_leaseSetAuthTypeLabel->setText(QApplication::translate("tunForm", "Auth type for encrypted LeaseSet. 0 - no auth, 1 - DH, 2 - PSK:", 0)); 186 | } 187 | protected: 188 | bool isValidSingleLine(QLineEdit* widget); 189 | }; 190 | 191 | #endif // TUNNELPANE_H 192 | -------------------------------------------------------------------------------- /src/TunnelsPageUpdateListener.h: -------------------------------------------------------------------------------- 1 | #ifndef TUNNELSPAGEUPDATELISTENER_H 2 | #define TUNNELSPAGEUPDATELISTENER_H 3 | 4 | class TunnelConfig; 5 | 6 | class TunnelsPageUpdateListener { 7 | public: 8 | virtual void updated(std::string oldName, TunnelConfig* tunConf)=0; 9 | virtual void needsDeleting(std::string oldName)=0; 10 | }; 11 | 12 | #endif // TUNNELSPAGEUPDATELISTENER_H 13 | -------------------------------------------------------------------------------- /src/i2pd.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | resources/icons/mask.ico 4 | resources/images/icon.png 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/i2pd.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "resources/icons/mask.ico" 2 | 3 | #include // needed for VERSIONINFO 4 | #include "i2pd/libi2pd/version.h" 5 | 6 | VS_VERSION_INFO VERSIONINFO 7 | FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH 8 | PRODUCTVERSION I2P_VERSION_MAJOR,I2P_VERSION_MINOR,I2P_VERSION_MICRO,I2P_VERSION_PATCH 9 | FILEOS VOS_NT_WINDOWS32 10 | FILETYPE VFT_APP 11 | BEGIN 12 | BLOCK "StringFileInfo" 13 | BEGIN 14 | BLOCK "040904E4" // U.S. English - multilingual (hex) 15 | BEGIN 16 | VALUE "CompanyName", "PurpleI2P" 17 | VALUE "FileDescription", "I2Pd Qt" 18 | VALUE "FileVersion", I2PD_VERSION 19 | VALUE "InternalName", "i2pd-qt" 20 | VALUE "LegalCopyright", "Copyright (C) 2013-2020, The PurpleI2P Project" 21 | VALUE "LegalTrademarks1", "Distributed under the BSD 3-Clause software license, see the accompanying file COPYING or https://opensource.org/licenses/BSD-3-Clause." 22 | VALUE "OriginalFilename", "i2pd_qt.exe" 23 | VALUE "ProductName", "i2pd-qt" 24 | VALUE "ProductVersion", I2P_VERSION 25 | END 26 | END 27 | 28 | BLOCK "VarFileInfo" 29 | BEGIN 30 | VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal) 31 | END 32 | END 33 | -------------------------------------------------------------------------------- /src/logviewermanager.cpp: -------------------------------------------------------------------------------- 1 | #include "logviewermanager.h" 2 | 3 | LogViewerManager::LogViewerManager(std::shared_ptr logStream_, 4 | QPlainTextEdit* logTextEdit_, 5 | QObject *parent) : 6 | QObject(parent), 7 | logStream(logStream_), 8 | logTextEdit(logTextEdit_), 9 | controllerForBgThread(nullptr) 10 | { 11 | assert(logTextEdit!=nullptr); 12 | controllerForBgThread=new i2pd::qt::logviewer::Controller(*this); 13 | } 14 | 15 | namespace i2pd { 16 | namespace qt { 17 | namespace logviewer { 18 | 19 | QString Worker::pollAndShootATimerForInfiniteRetries() { 20 | std::shared_ptr logStream=logViewerManager.getLogStream(); 21 | if(!logStream)return ""; 22 | std::streamsize MAX_SZ=64*1024; 23 | char*buf=(char*)malloc(MAX_SZ*sizeof(char)); 24 | if(buf==nullptr)return ""; 25 | std::streamsize read=logStream->readsome(buf, MAX_SZ); 26 | if(read<0)read=0; 27 | QString ret=QString::fromUtf8(buf, read); 28 | free(buf); 29 | return ret; 30 | } 31 | 32 | Controller::Controller(LogViewerManager ¶meter1):logViewerManager(parameter1) { 33 | Worker *worker = new Worker(parameter1); 34 | worker->moveToThread(&workerThread); 35 | connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); 36 | connect(this, &Controller::operate1, worker, &Worker::doWork1); 37 | connect(worker, &Worker::resultReady, 38 | ¶meter1, &LogViewerManager::appendPlainText_atGuiThread); 39 | workerThread.start(); 40 | timerId=startTimer(100/*millis*/); 41 | } 42 | 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/logviewermanager.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGVIEWERMANAGER_H 2 | #define LOGVIEWERMANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "FS.h" 16 | #include "Log.h" 17 | 18 | class LogViewerManager; 19 | 20 | namespace i2pd { 21 | namespace qt { 22 | namespace logviewer { 23 | 24 | class Worker : public QObject 25 | { 26 | Q_OBJECT 27 | private: 28 | LogViewerManager &logViewerManager; 29 | public: 30 | Worker(LogViewerManager ¶meter1):logViewerManager(parameter1){} 31 | private: 32 | QString pollAndShootATimerForInfiniteRetries(); 33 | 34 | public slots: 35 | void doWork1() { 36 | /* ... here is the expensive or blocking operation ... */ 37 | QString read=pollAndShootATimerForInfiniteRetries(); 38 | emit resultReady(read); 39 | } 40 | 41 | signals: 42 | void resultReady(QString read); 43 | }; 44 | 45 | class Controller : public QObject 46 | { 47 | Q_OBJECT 48 | QThread workerThread; 49 | LogViewerManager& logViewerManager; 50 | int timerId; 51 | public: 52 | Controller(LogViewerManager ¶meter1); 53 | ~Controller() { 54 | if(timerId!=0)killTimer(timerId); 55 | workerThread.quit(); 56 | workerThread.wait(); 57 | } 58 | signals: 59 | void operate1(); 60 | protected: 61 | void timerEvent(QTimerEvent */*event*/) { 62 | emit operate1(); 63 | } 64 | }; 65 | 66 | } 67 | } 68 | } 69 | 70 | class LogViewerManager : public QObject 71 | { 72 | Q_OBJECT 73 | private: 74 | std::shared_ptr logStream; 75 | QPlainTextEdit* logTextEdit; 76 | i2pd::qt::logviewer::Controller* controllerForBgThread; 77 | public: 78 | //also starts a bg thread (QTimer) polling logStream->readsome(buf, n) 79 | explicit LogViewerManager(std::shared_ptr logStream_, 80 | QPlainTextEdit* logTextEdit_, 81 | QObject *parent); 82 | //also deallocs the bg thread (QTimer) 83 | virtual ~LogViewerManager(){} 84 | const i2pd::qt::logviewer::Controller& getControllerForBgThread() { 85 | assert(controllerForBgThread!=nullptr); 86 | return *controllerForBgThread; 87 | } 88 | const QPlainTextEdit* getLogTextEdit(){ return logTextEdit; } 89 | const std::shared_ptr getLogStream(){ return logStream; } 90 | signals: 91 | 92 | public slots: 93 | //void appendFromNonGuiThread(std::string read) { 94 | //} 95 | public slots: 96 | void appendPlainText_atGuiThread(QString plainText) { 97 | if(plainText.length()==0)return; 98 | assert(logTextEdit!=nullptr); 99 | int scrollPosVert =logTextEdit->verticalScrollBar()->value(); 100 | int scrollPosHoriz=logTextEdit->horizontalScrollBar()->value(); 101 | int scrollPosVertMax =logTextEdit->verticalScrollBar()->maximum(); 102 | const int MAX_LINES=10*1024; 103 | logTextEdit->setMaximumBlockCount(MAX_LINES); 104 | //logTextEdit->appendPlainText(plainText); 105 | //navigate the window to the end 106 | //QTextCursor cursor = logTextEdit->textCursor(); 107 | //cursor.movePosition(QTextCursor::MoveOperation::End); 108 | //logTextEdit->setTextCursor(cursor); 109 | //QTextCursor prev_cursor = logTextEdit->textCursor(); 110 | logTextEdit->moveCursor(QTextCursor::End); 111 | logTextEdit->insertPlainText(plainText); 112 | if(/*prev_cursor.atEnd()*/scrollPosVert==scrollPosVertMax){ 113 | //logTextEdit->moveCursor(QTextCursor::End); 114 | scrollPosVert =logTextEdit->verticalScrollBar()->maximum(); 115 | scrollPosHoriz=logTextEdit->horizontalScrollBar()->minimum(); 116 | } 117 | //else 118 | // logTextEdit->setTextCursor(prev_cursor); 119 | logTextEdit->verticalScrollBar()->setValue(scrollPosVert); 120 | logTextEdit->horizontalScrollBar()->setValue(scrollPosHoriz); 121 | } 122 | /* 123 | void replaceText_atGuiThread() { 124 | assert(logTextEdit!=nullptr); 125 | logTextEdit->setText(QString::fromStdString(nav.getContent())); 126 | } 127 | */ 128 | }; 129 | 130 | #endif // LOGVIEWERMANAGER_H 131 | -------------------------------------------------------------------------------- /src/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 908 10 | 604 11 | 12 | 13 | 14 | 15 | 908 16 | 0 17 | 18 | 19 | 20 | 21 | 908 22 | 16777215 23 | 24 | 25 | 26 | MainWindow 27 | 28 | 29 | 30 | 31 | 0 32 | 0 33 | 34 | 35 | 36 | 37 | 908 38 | 600 39 | 40 | 41 | 42 | 43 | 908 44 | 600 45 | 46 | 47 | 48 | 49 | 50 | 10 51 | 10 52 | 888 53 | 596 54 | 55 | 56 | 57 | 58 | QLayout::SetMaximumSize 59 | 60 | 61 | 62 | 63 | QLayout::SetMinimumSize 64 | 65 | 66 | 67 | 0 68 | 0 69 | 170 70 | 596 71 | 72 | 73 | 74 | 75 | 76 | true 77 | 78 | 79 | Status 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 0 88 | 0 89 | 90 | 91 | 92 | 93 | 172 94 | 0 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | Log 103 | 104 | 105 | 106 | 107 | 108 | 109 | true 110 | 111 | 112 | General settings 113 | 114 | 115 | 116 | 117 | 118 | 119 | true 120 | 121 | 122 | Tunnels settings 123 | 124 | 125 | 126 | 127 | 128 | 129 | true 130 | 131 | 132 | Restart 133 | 134 | 135 | 136 | 137 | 138 | 139 | true 140 | 141 | 142 | Quit 143 | 144 | 145 | 146 | 147 | 148 | 149 | Qt::Horizontal 150 | 151 | 152 | QSizePolicy::Fixed 153 | 154 | 155 | 156 | 171 157 | 0 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | Qt::Vertical 166 | 167 | 168 | 169 | 20 170 | 40 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 9 180 | 181 | 182 | 183 | Qt::NoContextMenu 184 | 185 | 186 | Show app name, version and build date 187 | 188 | 189 | <html><head/><body><p><a href="about:i2pd_qt"><span style="text-decoration: none; color:#a0a0a0;"><span style="font-weight: 500;">i2pd_qt</span><br/>Version SHORT_VERSION · About...</span></a></p></body></html> 190 | 191 | 192 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 193 | 194 | 195 | 6 196 | 197 | 198 | 0 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | QLayout::SetMinAndMaxSize 208 | 209 | 210 | 211 | 212 | 213 | 0 214 | 30 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 0 224 | 0 225 | 0 226 | 227 | 228 | 229 | 230 | 231 | 232 | 255 233 | 0 234 | 0 235 | 236 | 237 | 238 | 239 | 240 | 241 | 255 242 | 127 243 | 127 244 | 245 | 246 | 247 | 248 | 249 | 250 | 255 251 | 63 252 | 63 253 | 254 | 255 | 256 | 257 | 258 | 259 | 127 260 | 0 261 | 0 262 | 263 | 264 | 265 | 266 | 267 | 268 | 170 269 | 0 270 | 0 271 | 272 | 273 | 274 | 275 | 276 | 277 | 0 278 | 0 279 | 0 280 | 281 | 282 | 283 | 284 | 285 | 286 | 255 287 | 255 288 | 255 289 | 290 | 291 | 292 | 293 | 294 | 295 | 0 296 | 0 297 | 0 298 | 299 | 300 | 301 | 302 | 303 | 304 | 255 305 | 255 306 | 255 307 | 308 | 309 | 310 | 311 | 312 | 313 | 255 314 | 0 315 | 0 316 | 317 | 318 | 319 | 320 | 321 | 322 | 0 323 | 0 324 | 0 325 | 326 | 327 | 328 | 329 | 330 | 331 | 255 332 | 127 333 | 127 334 | 335 | 336 | 337 | 338 | 339 | 340 | 255 341 | 255 342 | 220 343 | 344 | 345 | 346 | 347 | 348 | 349 | 0 350 | 0 351 | 0 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 0 361 | 0 362 | 0 363 | 364 | 365 | 366 | 367 | 368 | 369 | 255 370 | 0 371 | 0 372 | 373 | 374 | 375 | 376 | 377 | 378 | 255 379 | 127 380 | 127 381 | 382 | 383 | 384 | 385 | 386 | 387 | 255 388 | 63 389 | 63 390 | 391 | 392 | 393 | 394 | 395 | 396 | 127 397 | 0 398 | 0 399 | 400 | 401 | 402 | 403 | 404 | 405 | 170 406 | 0 407 | 0 408 | 409 | 410 | 411 | 412 | 413 | 414 | 0 415 | 0 416 | 0 417 | 418 | 419 | 420 | 421 | 422 | 423 | 255 424 | 255 425 | 255 426 | 427 | 428 | 429 | 430 | 431 | 432 | 0 433 | 0 434 | 0 435 | 436 | 437 | 438 | 439 | 440 | 441 | 255 442 | 255 443 | 255 444 | 445 | 446 | 447 | 448 | 449 | 450 | 255 451 | 0 452 | 0 453 | 454 | 455 | 456 | 457 | 458 | 459 | 0 460 | 0 461 | 0 462 | 463 | 464 | 465 | 466 | 467 | 468 | 255 469 | 127 470 | 127 471 | 472 | 473 | 474 | 475 | 476 | 477 | 255 478 | 255 479 | 220 480 | 481 | 482 | 483 | 484 | 485 | 486 | 0 487 | 0 488 | 0 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 127 498 | 0 499 | 0 500 | 501 | 502 | 503 | 504 | 505 | 506 | 255 507 | 0 508 | 0 509 | 510 | 511 | 512 | 513 | 514 | 515 | 255 516 | 127 517 | 127 518 | 519 | 520 | 521 | 522 | 523 | 524 | 255 525 | 63 526 | 63 527 | 528 | 529 | 530 | 531 | 532 | 533 | 127 534 | 0 535 | 0 536 | 537 | 538 | 539 | 540 | 541 | 542 | 170 543 | 0 544 | 0 545 | 546 | 547 | 548 | 549 | 550 | 551 | 127 552 | 0 553 | 0 554 | 555 | 556 | 557 | 558 | 559 | 560 | 255 561 | 255 562 | 255 563 | 564 | 565 | 566 | 567 | 568 | 569 | 127 570 | 0 571 | 0 572 | 573 | 574 | 575 | 576 | 577 | 578 | 255 579 | 0 580 | 0 581 | 582 | 583 | 584 | 585 | 586 | 587 | 255 588 | 0 589 | 0 590 | 591 | 592 | 593 | 594 | 595 | 596 | 0 597 | 0 598 | 0 599 | 600 | 601 | 602 | 603 | 604 | 605 | 255 606 | 0 607 | 0 608 | 609 | 610 | 611 | 612 | 613 | 614 | 255 615 | 255 616 | 220 617 | 618 | 619 | 620 | 621 | 622 | 623 | 0 624 | 0 625 | 0 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | wrongInputMessageLabel 634 | 635 | 636 | true 637 | 638 | 639 | 10 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 0 648 | 0 649 | 650 | 651 | 652 | 653 | 0 654 | 0 655 | 656 | 657 | 658 | 659 | 707 660 | 713 661 | 662 | 663 | 664 | 1 665 | 666 | 667 | 668 | 669 | 0 670 | 0 671 | 672 | 673 | 674 | 675 | 676 | 0 677 | 0 678 | 707 679 | 586 680 | 681 | 682 | 683 | 684 | QLayout::SetMaximumSize 685 | 686 | 687 | 688 | 689 | 690 | 15 691 | 692 | 693 | 694 | Status 695 | 696 | 697 | 698 | 699 | 700 | 701 | QLayout::SetMaximumSize 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 0 712 | 0 713 | 714 | 715 | 716 | 717 | 718 | 0 719 | 0 720 | 707 721 | 586 722 | 723 | 724 | 725 | 726 | QLayout::SetMinAndMaxSize 727 | 728 | 729 | 730 | 731 | 732 | 15 733 | 734 | 735 | 736 | Log 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 0 745 | 0 746 | 747 | 748 | 749 | Qt::ScrollBarAlwaysOn 750 | 751 | 752 | Qt::ScrollBarAsNeeded 753 | 754 | 755 | QAbstractScrollArea::AdjustIgnored 756 | 757 | 758 | 10000 759 | 760 | 761 | false 762 | 763 | 764 | true 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 0 775 | 0 776 | 777 | 778 | 779 | 780 | 781 | 0 782 | 0 783 | 707 784 | 586 785 | 786 | 787 | 788 | 789 | QLayout::SetMinAndMaxSize 790 | 791 | 792 | 793 | 794 | 795 | 15 796 | 797 | 798 | 799 | General settings 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 0 808 | 0 809 | 810 | 811 | 812 | Qt::ScrollBarAlwaysOn 813 | 814 | 815 | Qt::ScrollBarAsNeeded 816 | 817 | 818 | QAbstractScrollArea::AdjustIgnored 819 | 820 | 821 | true 822 | 823 | 824 | 825 | 826 | 0 827 | 0 828 | 693 829 | 498 830 | 831 | 832 | 833 | 834 | 0 835 | 0 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 0 849 | 0 850 | 707 851 | 586 852 | 853 | 854 | 855 | 856 | QLayout::SetMinAndMaxSize 857 | 858 | 859 | 860 | 861 | 862 | 15 863 | 864 | 865 | 866 | Tunnels settings 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | Add Client Tunnel 876 | 877 | 878 | 879 | 880 | 881 | 882 | Add Server Tunnel 883 | 884 | 885 | 886 | 887 | 888 | 889 | Qt::Horizontal 890 | 891 | 892 | 893 | 40 894 | 20 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | Qt::ScrollBarAlwaysOn 905 | 906 | 907 | false 908 | 909 | 910 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 911 | 912 | 913 | 914 | 915 | 0 916 | 0 917 | 699 918 | 425 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 0 932 | 0 933 | 707 934 | 586 935 | 936 | 937 | 938 | 939 | QLayout::SetMinAndMaxSize 940 | 941 | 942 | 943 | 944 | 945 | 15 946 | 947 | 948 | 949 | Restart 950 | 951 | 952 | 953 | 954 | 955 | 956 | Restart i2pd 957 | 958 | 959 | 960 | 961 | 962 | 963 | Qt::Vertical 964 | 965 | 966 | 967 | 20 968 | 40 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 0 980 | 0 981 | 982 | 983 | 984 | 985 | 986 | 0 987 | 0 988 | 707 989 | 531 990 | 991 | 992 | 993 | 994 | QLayout::SetMinAndMaxSize 995 | 996 | 997 | 998 | 999 | 1000 | 15 1001 | 1002 | 1003 | 1004 | Quit 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | Quit Now 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | Graceful Quit 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | Qt::Vertical 1026 | 1027 | 1028 | 1029 | 20 1030 | 40 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | handleQuitButton() 1051 | handleGracefulQuitButton() 1052 | 1053 | 1054 | -------------------------------------------------------------------------------- /src/pagewithbackbutton.cpp: -------------------------------------------------------------------------------- 1 | #include "pagewithbackbutton.h" 2 | #include "QVBoxLayout" 3 | #include "QHBoxLayout" 4 | #include "QPushButton" 5 | 6 | PageWithBackButton::PageWithBackButton(QWidget *parent, QWidget* child) : QWidget(parent) 7 | { 8 | QVBoxLayout * layout = new QVBoxLayout(); 9 | setLayout(layout); 10 | QWidget * topBar = new QWidget(); 11 | QHBoxLayout * topBarLayout = new QHBoxLayout(); 12 | topBar->setLayout(topBarLayout); 13 | layout->addWidget(topBar); 14 | layout->addWidget(child); 15 | 16 | QPushButton * backButton = new QPushButton(topBar); 17 | backButton->setText("< Back"); 18 | topBarLayout->addWidget(backButton); 19 | connect(backButton, SIGNAL(released()), this, SLOT(backReleasedSlot())); 20 | } 21 | 22 | void PageWithBackButton::backReleasedSlot() { 23 | emit backReleased(); 24 | } 25 | -------------------------------------------------------------------------------- /src/pagewithbackbutton.h: -------------------------------------------------------------------------------- 1 | #ifndef PAGEWITHBACKBUTTON_H 2 | #define PAGEWITHBACKBUTTON_H 3 | 4 | #include 5 | 6 | class PageWithBackButton : public QWidget 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit PageWithBackButton(QWidget *parent, QWidget* child); 11 | 12 | signals: 13 | 14 | void backReleased(); 15 | 16 | private slots: 17 | 18 | void backReleasedSlot(); 19 | }; 20 | 21 | #endif // PAGEWITHBACKBUTTON_H 22 | -------------------------------------------------------------------------------- /src/resources/icons/mask.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/src/resources/icons/mask.ico -------------------------------------------------------------------------------- /src/resources/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PurpleI2P/i2pd-qt/111e95c8890e5722f78f1993c2781a390ef920f1/src/resources/images/icon.png -------------------------------------------------------------------------------- /src/routercommandswidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | routerCommandsWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 707 10 | 300 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | Form 21 | 22 | 23 | 24 | 25 | 0 26 | 0 27 | 707 28 | 301 29 | 30 | 31 | 32 | 33 | QLayout::SetMaximumSize 34 | 35 | 36 | 37 | 38 | 39 | 0 40 | 0 41 | 42 | 43 | 44 | 45 | 75 46 | true 47 | 48 | 49 | 50 | Router Commands 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 0 59 | 0 60 | 61 | 62 | 63 | Run peer test 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 0 72 | 0 73 | 74 | 75 | 76 | Decline transit tunnels 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 0 85 | 0 86 | 87 | 88 | 89 | Accept transit tunnels 90 | 91 | 92 | 93 | 94 | 95 | 96 | false 97 | 98 | 99 | 100 | 0 101 | 0 102 | 103 | 104 | 105 | Cancel graceful quit 106 | 107 | 108 | 109 | 110 | 111 | 112 | Qt::Vertical 113 | 114 | 115 | 116 | 20 117 | 40 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /src/statusbuttons.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | StatusButtonsForm 4 | 5 | 6 | 7 | 0 8 | 0 9 | 171 10 | 295 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 171 22 | 295 23 | 24 | 25 | 26 | Form 27 | 28 | 29 | 30 | 31 | 21 32 | 0 33 | 171 34 | 300 35 | 36 | 37 | 38 | 39 | QLayout::SetDefaultConstraint 40 | 41 | 42 | 43 | 44 | 45 | 150 46 | 16777215 47 | 48 | 49 | 50 | Main page 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 150 59 | 16777215 60 | 61 | 62 | 63 | Router commands 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 150 72 | 16777215 73 | 74 | 75 | 76 | Local destinations 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 150 85 | 16777215 86 | 87 | 88 | 89 | Leasesets 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 150 98 | 16777215 99 | 100 | 101 | 102 | Tunnels 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 150 111 | 16777215 112 | 113 | 114 | 115 | Transit tunnels 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 150 124 | 16777215 125 | 126 | 127 | 128 | Transports 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 150 137 | 16777215 138 | 139 | 140 | 141 | I2P tunnels 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 150 | 16777215 151 | 152 | 153 | 154 | SAM sessions 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /src/textbrowsertweaked1.cpp: -------------------------------------------------------------------------------- 1 | #include "textbrowsertweaked1.h" 2 | 3 | TextBrowserTweaked1::TextBrowserTweaked1(QWidget * parent): QTextBrowser(parent) 4 | { 5 | } 6 | 7 | /*void TextBrowserTweaked1::setSource(const QUrl & url) { 8 | emit navigatedTo(url); 9 | }*/ 10 | -------------------------------------------------------------------------------- /src/textbrowsertweaked1.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXTBROWSERTWEAKED1_H 2 | #define TEXTBROWSERTWEAKED1_H 3 | 4 | #include 5 | #include 6 | 7 | class TextBrowserTweaked1 : public QTextBrowser 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | TextBrowserTweaked1(QWidget * parent); 13 | //virtual void setSource(const QUrl & url); 14 | 15 | signals: 16 | void mouseReleased(); 17 | //void navigatedTo(const QUrl & link); 18 | 19 | protected: 20 | void mouseReleaseEvent(QMouseEvent *event) { 21 | QTextBrowser::mouseReleaseEvent(event); 22 | emit mouseReleased(); 23 | } 24 | }; 25 | 26 | #endif // TEXTBROWSERTWEAKED1_H 27 | -------------------------------------------------------------------------------- /src/tunnelform.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 527 10 | 452 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 0 20 | 0 21 | 521 22 | 451 23 | 24 | 25 | 26 | 27 | 28 | 29 | server_tunnel_name 30 | 31 | 32 | 33 | 34 | 0 35 | 20 36 | 511 37 | 421 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Qt::Horizontal 50 | 51 | 52 | 53 | 40 54 | 20 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | Delete 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | Host: 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | Qt::Horizontal 84 | 85 | 86 | 87 | 40 88 | 20 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /src/widgetlock.cpp: -------------------------------------------------------------------------------- 1 | #include "widgetlock.h" 2 | -------------------------------------------------------------------------------- /src/widgetlock.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGETLOCK_H 2 | #define WIDGETLOCK_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class widgetlock : public QObject { 10 | Q_OBJECT 11 | 12 | private: 13 | QWidget* widget; 14 | QPushButton* lockButton; 15 | 16 | public slots: 17 | void lockButtonClicked(bool) { 18 | bool wasEnabled = widget->isEnabled(); 19 | widget->setEnabled(!wasEnabled); 20 | lockButton->setText(widget->isEnabled()?lockButton->tr("Lock"):lockButton->tr("Edit")); 21 | } 22 | 23 | public: 24 | widgetlock(QWidget* widget_, QPushButton* lockButton_): widget(widget_),lockButton(lockButton_) { 25 | widget->setEnabled(false); 26 | lockButton->setText(lockButton->tr("Edit")); 27 | QObject::connect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool))); 28 | } 29 | virtual ~widgetlock() {} 30 | void deleteListener() { 31 | QObject::disconnect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool))); 32 | } 33 | }; 34 | 35 | #endif // WIDGETLOCK_H 36 | -------------------------------------------------------------------------------- /src/widgetlockregistry.cpp: -------------------------------------------------------------------------------- 1 | #include "widgetlockregistry.h" 2 | 3 | -------------------------------------------------------------------------------- /src/widgetlockregistry.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGETLOCKREGISTRY_H 2 | #define WIDGETLOCKREGISTRY_H 3 | 4 | #include 5 | #include 6 | 7 | class widgetlockregistry { 8 | std::vector locks; 9 | 10 | public: 11 | widgetlockregistry() : locks() {} 12 | virtual ~widgetlockregistry() {} 13 | void add(widgetlock* lock) { 14 | locks.push_back(lock); 15 | } 16 | 17 | void deleteListeners() { 18 | while(!locks.empty()) { 19 | widgetlock* lock = locks.back(); 20 | lock->deleteListener(); 21 | delete lock; 22 | locks.pop_back(); 23 | } 24 | } 25 | }; 26 | 27 | #endif // WIDGETLOCKREGISTRY_H 28 | --------------------------------------------------------------------------------