From a1c72be2a9e33aa9c3e731d94c9589792eb8031f Mon Sep 17 00:00:00 2001 From: Darknet Villain Date: Sun, 4 Jun 2017 02:47:27 -0400 Subject: [PATCH 01/23] Add updated Dockerfile --- contrib/docker/Dockerfile | 54 ++++++++++++++++++++++++++++++++++++ contrib/docker/entrypoint.sh | 16 +++++++++++ 2 files changed, 70 insertions(+) create mode 100644 contrib/docker/Dockerfile create mode 100644 contrib/docker/entrypoint.sh diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile new file mode 100644 index 00000000..2c2c4a03 --- /dev/null +++ b/contrib/docker/Dockerfile @@ -0,0 +1,54 @@ +FROM alpine:latest +LABEL authors "Mikal Villa , Darknet Villain " + +# Expose git branch, tag and URL variables as arguments +ARG GIT_BRANCH="master" +ENV GIT_BRANCH=${GIT_BRANCH} +ARG GIT_TAG="" +ENV GIT_TAG=${GIT_TAG} +ARG REPO_URL="https://github.com/PurpleI2P/i2pd.git" +ENV REPO_URL=${REPO_URL} + +ENV I2PD_HOME="/home/i2pd" +ENV DATA_DIR="${I2PD_HOME}/data" + +RUN mkdir -p "$I2PD_HOME" \ + && adduser -S -h "$I2PD_HOME" i2pd \ + && chown -R i2pd:nobody "$I2PD_HOME" + +# +# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the +# image under 20mb we need to remove all the build dependencies in the same "RUN" / layer. +# + +# 1. install deps, clone and build. +# 2. strip binaries. +# 3. Purge all dependencies and other unrelated packages, including build directory. +RUN apk --no-cache --virtual build-dependendencies add make gcc g++ libtool boost-dev build-base openssl-dev openssl git \ + && mkdir -p /tmp/build \ + && cd /tmp/build && git clone -b ${GIT_BRANCH} ${REPO_URL} \ + && cd i2pd \ + && if [ -n "${GIT_TAG}" ]; then git checkout tags/${GIT_TAG}; fi \ + && make \ + && cp -R contrib/certificates /i2pd_certificates \ + && mkdir -p /usr/local/bin \ + && mv i2pd /usr/local/bin \ + && cd /usr/local/bin \ + && strip i2pd \ + && rm -fr /tmp/build && apk --purge del build-dependendencies build-base fortify-headers boost-dev zlib-dev openssl-dev \ + boost-python3 python3 gdbm boost-unit_test_framework boost-python linux-headers boost-prg_exec_monitor \ + boost-serialization boost-signals boost-wave boost-wserialization boost-math boost-graph boost-regex git pcre \ + libtool g++ gcc pkgconfig + +# 2. Adding required libraries to run i2pd to ensure it will run. +RUN apk --no-cache add boost-filesystem boost-system boost-program_options boost-date_time boost-thread boost-iostreams openssl musl-utils libstdc++ + +COPY entrypoint.sh /entrypoint.sh +RUN chmod a+x /entrypoint.sh + +RUN echo "export DATA_DIR=${DATA_DIR}" >> /etc/profile +VOLUME "$DATA_DIR" +EXPOSE 7070 4444 4447 7656 2827 7654 7650 +USER i2pd + +ENTRYPOINT [ "/entrypoint.sh" ] diff --git a/contrib/docker/entrypoint.sh b/contrib/docker/entrypoint.sh new file mode 100644 index 00000000..670ff577 --- /dev/null +++ b/contrib/docker/entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/sh +COMMAND=/usr/local/bin/i2pd +# To make ports exposeable +# Note: $DATA_DIR is defined in /etc/profile +DEFAULT_ARGS=" --datadir=$DATA_DIR --reseed.verify=true --upnp.enabled=false --http.enabled=true --http.address=0.0.0.0 --httpproxy.enabled=true --httpproxy.address=0.0.0.0 --socksproxy.enabled=true --socksproxy.address=0.0.0.0 --sam.enabled=true --sam.address=0.0.0.0" + +if [ "$1" = "--help" ]; then + set -- $COMMAND --help +else + # Create datadir + mkdir -p "$DATA_DIR" + ln -s /i2pd_certificates "$DATA_DIR"/certificates + set -- $COMMAND $DEFAULT_ARGS $@ +fi + +exec "$@" From 83c5131b672df82142b7b7d86689fce2a4aab0e1 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 7 Jun 2017 10:53:50 -0400 Subject: [PATCH 02/23] skip expired introducer --- libi2pd/SSU.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libi2pd/SSU.cpp b/libi2pd/SSU.cpp index 1edeb3bd..eabdd8c4 100644 --- a/libi2pd/SSU.cpp +++ b/libi2pd/SSU.cpp @@ -445,12 +445,14 @@ namespace transport int numIntroducers = address->ssu->introducers.size (); if (numIntroducers > 0) { + uint32_t ts = i2p::util::GetSecondsSinceEpoch (); std::shared_ptr introducerSession; const i2p::data::RouterInfo::Introducer * introducer = nullptr; // we might have a session to introducer already for (int i = 0; i < numIntroducers; i++) { auto intr = &(address->ssu->introducers[i]); + if (intr->iExp > 0 && ts > intr->iExp) continue; // skip expired introducer boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort); if (ep.address ().is_v4 ()) // ipv4 only { @@ -465,7 +467,7 @@ namespace transport } if (!introducer) { - LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no ipv4 introducers present"); + LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no ipv4 non-expired introducers presented"); return; } From 629261c4bea07bc16d3e103280c92c03916dad32 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 11 Jun 2017 09:29:31 +0300 Subject: [PATCH 03/23] remove msvc and NSIS project files fix some windows build warnings --- Win32/.gitignore | 14 -- Win32/DaemonWin32.cpp | 17 +- Win32/Itoopie.cmd | 14 -- Win32/PurpleI2P.nsi | 282 ------------------------ Win32/Resource.rc | 49 +---- Win32/Resource.rc2 | 11 +- Win32/Win32App.cpp | 2 +- Win32/Win32Service.h | 4 +- Win32/i2pd.sln | 30 --- Win32/i2pd.vcxproj | 292 ------------------------- Win32/i2pd.vcxproj.filters | 302 -------------------------- Win32/ictoopie.bmp | Bin 25818 -> 0 bytes Win32/ictoopie.ico | Bin 180626 -> 0 bytes Win32/install_service.bat | 1 - Win32/installer.iss | 41 ---- Win32/nsi/helper_readme.nsh | 57 ----- Win32/nsi/servicelib.nsh | 419 ------------------------------------ Win32/resource.h | 15 +- Win32/uninstall_service.bat | 1 - libi2pd/FS.cpp | 2 +- 20 files changed, 23 insertions(+), 1530 deletions(-) delete mode 100644 Win32/.gitignore delete mode 100644 Win32/Itoopie.cmd delete mode 100644 Win32/PurpleI2P.nsi delete mode 100644 Win32/i2pd.sln delete mode 100644 Win32/i2pd.vcxproj delete mode 100644 Win32/i2pd.vcxproj.filters delete mode 100644 Win32/ictoopie.bmp delete mode 100644 Win32/ictoopie.ico delete mode 100644 Win32/install_service.bat delete mode 100644 Win32/installer.iss delete mode 100644 Win32/nsi/helper_readme.nsh delete mode 100644 Win32/nsi/servicelib.nsh delete mode 100644 Win32/uninstall_service.bat diff --git a/Win32/.gitignore b/Win32/.gitignore deleted file mode 100644 index 5aa0538d..00000000 --- a/Win32/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -* -!*/ - -!*.h -!*.cpp - -!*.bat - -!*.sln -!*.vcproj -!*.vcxproj -!*.vcxproj.filters -!*.iss -!.gitignore diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index 6eb43dc0..698cf390 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -60,7 +60,6 @@ namespace i2p } else LogPrint(eLogDebug, "Daemon: running as user"); - return true; } @@ -71,10 +70,10 @@ namespace i2p SetConsoleOutputCP(1251); setlocale(LC_ALL, "Russian"); #ifdef WIN32_APP - if (!i2p::win32::StartWin32App ()) return false; + if (!i2p::win32::StartWin32App ()) return false; - // override log - i2p::config::SetOption("log", std::string ("file")); + // override log + i2p::config::SetOption("log", std::string ("file")); #endif bool ret = Daemon_Singleton::start(); if (ret && i2p::log::Logger().GetLogType() == eLogFile) @@ -92,24 +91,22 @@ namespace i2p bool DaemonWin32::stop() { #ifdef WIN32_APP - i2p::win32::StopWin32App (); + i2p::win32::StopWin32App (); #endif return Daemon_Singleton::stop(); } void DaemonWin32::run () - { + { #ifdef WIN32_APP - i2p::win32::RunWin32App (); + i2p::win32::RunWin32App (); #else while (running) { std::this_thread::sleep_for (std::chrono::seconds(1)); } - #endif - } + } } } - #endif diff --git a/Win32/Itoopie.cmd b/Win32/Itoopie.cmd deleted file mode 100644 index f7d895c8..00000000 --- a/Win32/Itoopie.cmd +++ /dev/null @@ -1,14 +0,0 @@ -@echo off -convert Itoopie.svg ^ - -fuzz 90%% -fill transparent -floodfill 2x2 white -fuzz 20%% -fill #AE0E99 -opaque red ^ - -fill #FBBC11 -opaque yellow ^ - ( -clone 0 -resize 256x256 ) ^ - ( -clone 0 -resize 128x128 ) ^ - ( -clone 0 -resize 64x64 ) ^ - ( -clone 0 -resize 48x48 ) ^ - ( -clone 0 -resize 32x32 ) ^ - ( -clone 0 -resize 24x24 ) ^ - ( -clone 0 -resize 16x16 ) ^ - ( -size 150x57 xc:white -clone 0 -geometry 57x57+46+0 -composite -gravity center -write BMP3:ictoopie.bmp +delete ) ^ - ( -clone 0 -write Itoopie_purple.png +delete ) ^ - -delete 0 ictoopie.ico diff --git a/Win32/PurpleI2P.nsi b/Win32/PurpleI2P.nsi deleted file mode 100644 index 7aa69daf..00000000 --- a/Win32/PurpleI2P.nsi +++ /dev/null @@ -1,282 +0,0 @@ -# NSIS Installer script. (Tested with NSIS 2.64 on Windows 7) -# Author: Mikal Villa (Meeh) -# Version: 1.1 -Name PurpleI2P - -RequestExecutionLevel highest -SetCompressor /SOLID lzma -ShowInstDetails show - -# General Symbol Definitions -!define REGKEY "SOFTWARE\$(^Name)" -!define VERSION 0.3.0.0 -!define COMPANY "The Privacy Solutions Project" -!define URL "https://i2p.io" - -# MUI Symbol Definitions -!define MUI_ICON "mask.ico" -#!define MUI_WELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp" -!define MUI_HEADERIMAGE -!define MUI_HEADERIMAGE_RIGHT -#!define MUI_HEADERIMAGE_BITMAP "../share/pixmaps/nsis-header.bmp" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM -!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} -!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup -!define MUI_STARTMENUPAGE_DEFAULTFOLDER PurpleI2P -!define MUI_FINISHPAGE_RUN $INSTDIR\i2pd.exe -!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\Readme.txt - - -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp" -!define MUI_UNFINISHPAGE_NOAUTOCLOSE - -# Included files -!include Sections.nsh -!include MUI2.nsh -!include nsDialogs.nsh -!include winmessages.nsh -!include logiclib.nsh -# Local included files -!include nsi\helper_readme.nsh -;!include nsi\servicelib.nsh - -# Variables -Var StartMenuGroup - -# Installer pages -# Execution flow of installer windows -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_README "../Readme.md" -!insertmacro MUI_PAGE_DIRECTORY -# Disabled for now. Use the bat -;Page custom mode_selection # Meeh's hack for installing and starting service. -!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH - -# Uninstall pages -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -# Installer languages -!insertmacro MUI_LANGUAGE English - -# Installer attributes -OutFile PurpleI2P-0.3.0.0-win32-setup.exe -InstallDir $PROGRAMFILES\PurpleI2P -CRCCheck on -XPStyle on -BrandingText " " -ShowInstDetails show -VIProductVersion 0.3.0.0 -VIAddVersionKey ProductName PurpleI2P -VIAddVersionKey ProductVersion "${VERSION}" -VIAddVersionKey CompanyName "${COMPANY}" -VIAddVersionKey CompanyWebsite "${URL}" -VIAddVersionKey FileVersion "${VERSION}" -VIAddVersionKey FileDescription "" -VIAddVersionKey LegalCopyright "" -InstallDirRegKey HKCU "${REGKEY}" Path -ShowUninstDetails show - -# Readme definitions - -;-------------------------------- -;Languages - ;Set up install lang strings for 1st lang - ${ReadmeLanguage} "${LANG_ENGLISH}" \ - "Read Me" \ - "Please review the following important information." \ - "About $(^name):" \ - "$\n Click on scrollbar arrows or press Page Down to review the entire text." - - ;Add 2nd language - !insertmacro MUI_LANGUAGE "Norwegian" - - ;set up install lang strings for second lang - ${ReadmeLanguage} "${LANG_NORWEGIAN}" \ - "Les meg!" \ - "Vennligst les informasjonen om hvordan du skal bruke PurpleI2P." \ - "Om $(^name):" \ - "$\n Klikk på scrollbaren til høyre for å se hele innholdet." - -;-------------------------------- - -# Installer sections -Section -Main SEC0000 - SetOutPath $INSTDIR - SetOverwrite on - File /oname=i2pd.exe Release\i2pd.exe - File /oname=install_service.bat install_service.bat - File /oname=uninstall_service.bat uninstall_service.bat - File /oname=LICENSE.txt ..\LICENSE - File /oname=Readme.txt ..\README.md - SetOutPath $INSTDIR\src - File /r /x *.nsi /x *.rc /x *.exe /x *.obj /x *.nsh /x *.sln /x *.vcxproj /x *.tlog /x *.log /x *.res /x *.pdb /x *.suo /x *.opensdf /x *.filters /x *.sdf /x *.iss /x *.aps /x .gitignore /x *.o ../\*.* - SetOutPath $INSTDIR - RMDir /r /REBOOTOK $INSTDIR\src\.git # Remove git directory - RMDir /r /REBOOTOK $INSTDIR\src\Win32\Release # Removing release directory - RMDir /r /REBOOTOK $INSTDIR\src\Win32\nsi - WriteRegStr HKCU "${REGKEY}\Components" Main 1 -SectionEnd - -Section -post SEC0001 - WriteRegStr HKCU "${REGKEY}" Path $INSTDIR - SetOutPath $INSTDIR - WriteUninstaller $INSTDIR\uninstall.exe - !insertmacro MUI_STARTMENU_WRITE_BEGIN Application - CreateDirectory $SMPROGRAMS\$StartMenuGroup - CreateShortcut "$SMPROGRAMS\$StartMenuGroup\PurpleI2P.lnk" $INSTDIR\i2pd.exe - CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Install PurpleI2P Service.lnk" $INSTDIR\install_service.bat - CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P Service.lnk" $INSTDIR\uninstall_service.bat - CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P.lnk" $INSTDIR\uninstall.exe - !insertmacro MUI_STARTMENU_WRITE_END - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe - WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 - WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 - WriteRegStr HKCR "i2pd" "URL Protocol" "" - WriteRegStr HKCR "i2pd" "" "URL:i2pd" # TODO: if a instance of own is found, relaunch with a proxyfied browser to open webage. (e.g i2pd://meeh.i2p) - WriteRegStr HKCR "i2pd\DefaultIcon" "" $INSTDIR\i2pd.exe - WriteRegStr HKCR "i2pd\shell\open\command" "" '"$INSTDIR\i2pd.exe" "%1"' -SectionEnd - -# Macro for selecting uninstaller sections -!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID - Push $R0 - ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}" - StrCmp $R0 1 0 next${UNSECTION_ID} - !insertmacro SelectSection "${UNSECTION_ID}" - GoTo done${UNSECTION_ID} -next${UNSECTION_ID}: - !insertmacro UnselectSection "${UNSECTION_ID}" -done${UNSECTION_ID}: - Pop $R0 -!macroend - - -# Uninstaller sections -Section /o -un.Main UNSEC0000 - Delete /REBOOTOK $INSTDIR\i2pd.exe - Delete /REBOOTOK $INSTDIR\LICENSE.txt - Delete /REBOOTOK $INSTDIR\Readme.txt - Delete /REBOOTOK $INSTDIR\install_service.bat - Delete /REBOOTOK $INSTDIR\uninstall_service.bat - RMDir /r /REBOOTOK $INSTDIR\src - DeleteRegValue HKCU "${REGKEY}\Components" Main -SectionEnd - -Section -un.post UNSEC0001 - DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" - Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall PurpleI2P.lnk" - Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\PurpleI2P.lnk" - Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Install PurpleI2P Service.lnk" - Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\UnInstall PurpleI2P Service.lnk" - Delete /REBOOTOK "$SMSTARTUP\PurpleI2P.lnk" - Delete /REBOOTOK $INSTDIR\uninstall.exe - Delete /REBOOTOK $INSTDIR\debug.log - DeleteRegValue HKCU "${REGKEY}" StartMenuGroup - DeleteRegValue HKCU "${REGKEY}" Path - DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components" - DeleteRegKey /IfEmpty HKCU "${REGKEY}" - DeleteRegKey HKCR "i2pd" - RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup - RmDir /REBOOTOK $INSTDIR - Push $R0 - StrCpy $R0 $StartMenuGroup 1 - StrCmp $R0 ">" no_smgroup -no_smgroup: - Pop $R0 -SectionEnd - -; var hwndExecModeRadio -; var hwndRunServiceNowRadio - -; Function mode_selection -; nsDialogs::Create 1018 -; Pop $0 -; ${NSD_CreateLabel} 0 10 75% 20u "How would you like PurpleI2P (i2pd) to run?" -; Pop $0 - -; ${NSD_CreateRadioButton} 20 60 80% 25u "Service Mode" -; Pop $hwndExecModeRadio -; ${NSD_AddStyle} $hwndExecModeRadio ${WS_GROUP} - -; ${NSD_CreateRadioButton} 20 90 80% 25u "Command line Mode" -; Pop $0 - -; ${NSD_CreateButton} 20 150 -40 14u "Do it!" -; Pop $0 -; ${NSD_OnClick} $0 perform_mode - -; nsDialogs::Show -; FunctionEnd - -; Function start_now_selection -; nsDialogs::Create 1018 -; Pop $0 -; ${NSD_CreateLabel} 0 10 75% 20u "Enable the service now?" -; Pop $0 - -; ${NSD_CreateRadioButton} 20 60 80% 25u "Yes" -; Pop $hwndRunServiceNowRadio -; ${NSD_AddStyle} $hwndRunServiceNowRadio ${WS_GROUP} - -; ${NSD_CreateRadioButton} 20 90 80% 25u "No" -; Pop $0 - -; ${NSD_CreateButton} 20 150 -40 14u "Do it!" -; Pop $0 -; ${NSD_OnClick} $0 perform_mode - -; nsDialogs::Show -; FunctionEnd - -; Function perform_mode -; ${NSD_GetState} $hwndExecModeRadio $0 -; ${If} $0 = ${BST_CHECKED} -; Call service_mode -; ${EndIF} -; FunctionEnd - -; Function start_now -; ${NSD_GetState} $hwndRunServiceNowRadio $0 -; ${If} $0 = ${BST_CHECKED} -; Call start_now_selection -; ${EndIF} -; FunctionEnd - -; Function service_mode -; Push "create" -; Push "PurpleI2P Service" -; Push "$INSTDIR\i2pd.exe;autostart=1;display=PurpleI2P" -; Call Service -; Pop $0 ; Actually more to write than !insertmacro, but much more fun :D -; Push "start" -; Push "PurpleI2P Service" -; Call Service -; Pop $0 -; Call start_now -; !define MUI_FINISHPAGE_RUN_NOTCHECKED -; !define MUI_FINISHPAGE_RUN_TEXT "No need to run now since we already installed and launched it as a Windows service!" -; FunctionEnd - -# Installer functions -Function .onInit - InitPluginsDir - !insertmacro MUI_LANGDLL_DISPLAY -FunctionEnd - -# Uninstaller functions -Function un.onInit - ReadRegStr $INSTDIR HKCU "${REGKEY}" Path - !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup - !insertmacro SELECT_UNSECTION Main ${UNSEC0000} - !insertmacro MUI_UNGETLANGUAGE -FunctionEnd \ No newline at end of file diff --git a/Win32/Resource.rc b/Win32/Resource.rc index cca1c16e..5d394d1a 100644 --- a/Win32/Resource.rc +++ b/Win32/Resource.rc @@ -1,73 +1,36 @@ -// Microsoft Visual C++ generated resource script. -// #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// #include "winres.h" - -///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - 1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN "#include ""winres.h""\r\n" "\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN "\r\n" "\0" END +#endif // APSTUDIO_INVOKED -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -MAINICON ICON "mask.ico" -//MAINICON ICON "anke.ico" - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - +MAINICON ICON "mask.ico" +#endif // English (United States) resources #ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - #include "Resource.rc2" - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED +#endif // not APSTUDIO_INVOKED diff --git a/Win32/Resource.rc2 b/Win32/Resource.rc2 index b001be82..6a4f481d 100644 --- a/Win32/Resource.rc2 +++ b/Win32/Resource.rc2 @@ -1,18 +1,9 @@ -// -// Resource.RC2 - resources Microsoft Visual C++ does not edit directly -// - #ifdef APSTUDIO_INVOKED #error this file is not editable by Microsoft Visual C++ #endif //APSTUDIO_INVOKED #include "../libi2pd/version.h" -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - VS_VERSION_INFO VERSIONINFO FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH PRODUCTVERSION I2P_VERSION_MAJOR,I2P_VERSION_MINOR,I2P_VERSION_MICRO,I2P_VERSION_PATCH @@ -34,7 +25,7 @@ BEGIN VALUE "FileDescription", "C++ I2P daemon" VALUE "FileVersion", I2PD_VERSION VALUE "InternalName", CODENAME - VALUE "LegalCopyright", "Copyright (C) 2013-2015, The PurpleI2P Project" + VALUE "LegalCopyright", "Copyright (C) 2013-2017, The PurpleI2P Project" VALUE "OriginalFilename", "i2pd" VALUE "ProductName", "Purple I2P" VALUE "ProductVersion", I2P_VERSION diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index 8f0f7abd..e66b5f08 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -38,7 +38,7 @@ namespace win32 InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_CONSOLE, "Open &console"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About..."); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit"); SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE); diff --git a/Win32/Win32Service.h b/Win32/Win32Service.h index 097cb111..95cad3b5 100644 --- a/Win32/Win32Service.h +++ b/Win32/Win32Service.h @@ -7,10 +7,10 @@ #ifdef _WIN32 // Internal name of the service -#define SERVICE_NAME "i2pService" +#define SERVICE_NAME "i2pdService" // Displayed name of the service -#define SERVICE_DISPLAY_NAME "i2p router service" +#define SERVICE_DISPLAY_NAME "i2pd router service" // Service start options. #define SERVICE_START_TYPE SERVICE_DEMAND_START diff --git a/Win32/i2pd.sln b/Win32/i2pd.sln deleted file mode 100644 index 4606b24b..00000000 --- a/Win32/i2pd.sln +++ /dev/null @@ -1,30 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30723.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "i2pd", "i2pd.vcxproj", "{930568EC-31C9-406A-AD1C-9636DF5D8FAA}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.ActiveCfg = Debug|Win32 - {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.Build.0 = Debug|Win32 - {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|Win32.Deploy.0 = Debug|Win32 - {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|x64.ActiveCfg = Debug|x64 - {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Debug|x64.Build.0 = Debug|x64 - {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.ActiveCfg = Release|Win32 - {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.Build.0 = Release|Win32 - {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|Win32.Deploy.0 = Release|Win32 - {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|x64.ActiveCfg = Release|x64 - {930568EC-31C9-406A-AD1C-9636DF5D8FAA}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Win32/i2pd.vcxproj b/Win32/i2pd.vcxproj deleted file mode 100644 index 6426af09..00000000 --- a/Win32/i2pd.vcxproj +++ /dev/null @@ -1,292 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {930568EC-31C9-406A-AD1C-9636DF5D8FAA} - i2pd - - - - Application - true - v120_xp - NotSet - - - Application - true - v120_xp - NotSet - - - Application - false - v120_xp - true - NotSet - - - Application - false - v120_xp - true - NotSet - - - - - - - - - - - - - - - - - - - ./..;$(IncludePath);$(BOOST);$(CRYPTOPP);C:\build-lib\cryptopp;C:\build-lib\boost_1_57_0\ - $(BOOST)\stage\lib;C:\build-lib\cryptopp;C:\build-lib\boost_1_57_0\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath) - ./..;$(VC_SourcePath); - $(ProjectName)_d - - - ./..;$(IncludePath);$(BOOST);$(CRYPTOPP) - $(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath) - ./..;$(VC_SourcePath); - $(ProjectName)_d - - - ./..;$(IncludePath);$(BOOST);C:\build-lib\boost_1_57_0\;C:\build-lib - C:\build-lib\boost_1_57_0\stage\lib;C:\build-lib\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath) - ./..;$(VC_SourcePath); - - - ./..;$(IncludePath);$(BOOST);$(CRYPTOPP) - $(BOOST)\stage\lib;$(CRYPTOPP)\cryptopp\$(Platform)\Output\$(Configuration);$(LibraryPath) - ./..;$(VC_SourcePath); - - - - Level3 - Disabled - true - MultiThreadedDebug - _MBCS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) - - - true - cryptlib.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - AsInvoker - 0.2 - Console - - - - - Level3 - Disabled - true - MultiThreadedDebug - _MBCS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions) - - - true - cryptlib.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - AsInvoker - 0.2 - Console - - - - - Level2 - MaxSpeed - true - true - MultiThreaded - _WIN32_WINNT=0x0501;%(PreprocessorDefinitions) - true - true - - - false - true - false - cryptlib.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - AsInvoker - - - Console - 5.01 - NoErrorReport - - - - - - - - - - - Level3 - MaxSpeed - true - true - MultiThreaded - _WIN32_WINNT=0x0502;%(PreprocessorDefinitions) - true - true - - - false - true - false - cryptlib.lib;%(AdditionalDependencies) - $(OutDir)$(TargetName)$(TargetExt) - AsInvoker - - - Console - 5.02 - NoErrorReport - - - - - - - - - - - - diff --git a/Win32/i2pd.vcxproj.filters b/Win32/i2pd.vcxproj.filters deleted file mode 100644 index 4402ec7a..00000000 --- a/Win32/i2pd.vcxproj.filters +++ /dev/null @@ -1,302 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {a880a08c-16b8-4243-82ea-6bfc63bb7dab} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Win32 - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Win32 - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Source Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/Win32/ictoopie.bmp b/Win32/ictoopie.bmp deleted file mode 100644 index c92f7c583975d802536ed3def0ae5a733f891137..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25818 zcmeI53s4kS*2n3d?wOvR>7EB5Gs8n*1{72fQ49uxKtu}+5ky2I8>6CY%;y`0l}JPZ z18RH$A_O79tH5;wG%u5qv);IF~n>G_dTsO5fPI*)5YP))R zntP|uum9(sd+zNv?uj##TsoErY4(z2)KI(S>4X|I+0ve7yg+`T6;OGIXv5?%cVvXwf1_OJ=2D6e_if*Ybiv z&>3}FQOhb>nVY=j)SO?iUuaZluZUiz?k1&538eDhVjCYH|HT(yIQI%1RvWQ8gay!u z*=#nTFnSpKME3ErdbwNNJ^eg``Ugc1kB&==3w<;cJaK|rqsEcZ(?=)%B{6Dv)X*_Q zV^d>2{XOMd0Dkq&H{W!aNu6F0$qbJkJ?if64*3Oz2bsH@K`cHkK5k@O->AM8UkeVV zOi76!6^|33y^I+dj|_dpC(s9{L6A5n>FK19K_QTts}Vi{h!awR!A z8A9?2@bR*FW#wm89j$uh#4A{_Q&3kBIV{pY*gqj7LGPv?GI~ht$k>3;fO%`@tvR@6 zVa>v*q$ubXY78G7&ag~KNC=`+hgsFR1rf_|-@bi3&l|cKyaT*5rf10XYTvGv*A0K) zP|;igjBaK(FdUpR7yxH3pIOmTQFgctU#;H1Ix{;H?iAw0SMay9X3cW0=^a)ZnG6xo zOrAWMqA4_YVbNjbP32%{2WZFm{L9a4L=D0hG?EkZCYCps1K{1YNg_FQ@l-hB0r3M6 z3=JGO@P{9MaF}78SP+>EFI~FSzkh$klW6N^l+J+aYL4Gkpq(VBmLD$n3-W`;lKztP z3q3o=!)1UU^JI**x7EYj!)mpD{`u!lG`+*BB9kGEEk~rbJ~qIyi?HT+P0i2l6fi4W zD|>|XaP@Fq+_3mpBK#R6TV*=;-L5e)`FYrgvCXWHP*Z^=e#P92i1H zb??+|IJp7t6x-Spzj#y}nX__^icQi%`l6(3SCQLvx>oCJQu^=)T z!q`Y@%M8~XSX1z7!GiS*mNYCum?HB8*wwGEM#mrLAVV|zrP;uRZ|!QtPU())!i|OF z=8jV+6u|h{V~-(^?nKi&tST}Y;_~NaXHyg{CuX!djY_Q)4MNX;Jx4t|DyKYW=CYZg zgF+FwV#o$dL_)-@RWozf=ae*-$nwiwmy1wF?w7 zW+Y85nmRCHAjb(&gU3cjk1~4($bV=unLha71814uVfB#75Lq@17$IfdBY4o9ylpG1 z|F3Mrx$OK#lSN9ODk!EG(?3f+Z?U#wrLeJF+_p~KQ6X$!D{Lv|tEX}cBKTN_W(Euz zQNQcz#=SRI*PIQDNW>o^>r-1>>oD6os~`dy9y!t)9NY_f<2AY$N?Ug{w}V5$@;CcM zB%x)aDJDUc3Ut-tuJvLg)=F`QeZ|LWad)w{+SR4o(Bx;g>~Gur`t7X;?hH$Q4h&Id zUS6KFOz*IIh+>FP=D_{~0Re$hD@VDoO4ZOOre$W8!XJvF8z5i_VEViy)OSH=XNVnq zg%dm}-_QX=H|)3!DbCE@tT##%9l&tXq)865t+NUuhau)lR904+Ef$(m1TuZY*eHf# zJFrO`N;I&8l3Xl4k1(;FiQRL5owz+lnZ$A&+-dm0;b=(pl)IARz%V5xg}AVW5QY~o zUPMls*YFIbj8#6lT&P8GDMOF@pQhXjV-e*5jXaZ)c%L9>af(PiRRv}x1%#cEmr zKxt7ZG&wbfH`>LT4;XjvN!;8jao0T+Xg^pb?gVOA+5~PUh2L_aA%puXN>VD7TefU* zjBTA&%0tia#*G`(r%y-32xEt^gH{Whp)nActtsYd5eKE!#YH(d)o}1Cq{zgLj8-Jr zS>0!6jj$z%>5o6RD6A`lhUc}b1X_=enVFgByEqGg1L}F`8J<0RwtM&PPzbCW!9HFl zZj=3Fg}7}j_nf=J;-)Zr(N@N27AxO@6xBJ^X4bz%TYGd}KtyT++EXBnuQB)r6*OWpP-GWFZECe#dug2u16)RTwTdiojV0aa!<|z%W zZSvu>*Xv*ZQ3BX>>));|Z9pp4e#pe7sThqLZQ?ro zCvF7H6kfM(9a##L?LaKUAAkH&8ba(KsIc}CR<}xeyFWlX+m<`}z29?VvXM5Ik^~fm zd!eeTs;#X}whCEWVi}f|l_4(%0tzpiPU76eJ0g0Y>au{Uw!oz zS?KJ)mQ049eDVqAwE-Z_3z~%+B?bN-Ze7l4Zqx7lhK)=_Ie0*^uCC5*6|#27WLQ{O zD0@-W@Ck;4*9=YfZ3DZY>-_P^9cY+#H31_YU%PzyGFkNGUrQjvZ@&2^JUmOesKZsOR!NSOVWe^2E};zK(%%`H+A%iY*6;g)4I2!GF)=YDPW2{`A%+uS zZ!}`)=KbPG5!M{KuHXHge$PdWB6b}Abt4J3QkNh7!!~ILaj6|+OB*+4F3R-v^~JNr z4pzy7FOD>Z=)z%80rqAB`y#5mtGdHCwWSA`xOApxI1?P996VC9;8p$pE5B$GA?Th< zn*2>%`YbMO2C@OV&F3VTGR7nAI09)K42E~#efPl|-N7}G#t`FBiHTBg0Nzi^%5+4e z{Jiy?n}^lUm%*(2j)8qjsp6i_yW3hex9PTjp?rKa)zPEJOBl3*pslOK}1~X>Glp&dkK1 z621)!3%hXP0v?a)-Mg3S*;2z1DLalt0VY;q?)aHAXB=$d2VWe43>Pk32!^zWx1^%h zc4qXfxR}TAG#i@A?c29!Wo1E--+lL8Tucl*Zh-+q!o_=ghJ>C!cW&p-onVW%e8H?z zyE-~uF>JilW*%u*PcA~4m@0rtkPqJI4z7VfhL}4j`Ak-+E!YM`%E`t3`t}91&Xz$Q zAT%^YHDir5tiQN1s87g+Uq9oEb~QOEQIR-7VtDA9GByni)6>)c9JlCf#s{{4`t)gU zZ*Q1fHGHBp+*|%OZ}!>n$}62KtgWe0d-@7h??R~9s?FXT8|pisfcO)hlbgOua<+9J zDNH^n5Mz>^&mm=>Kpoz^c~cs7!iYsTFR|u*L-Q?F=HJYoo+V3{o;vm3sZ*zxm6UjT zT2y1_VSW^3ra$m6X2?^4HY;XWT)TD+O8du09}P+}q5;Qq|hAq~64kyaFw&q)sgO$^5hp(%%3Xu)K zq+q;)kD~d()dSOS{hzj)aB+T z=p)Gt(R@Ka=+R4Rw1sGw?&;9jeaG~rtjrzV#(%1kCsQg8e>im5Fw8zCh}ds`D#;9S zHHb6uQfRyZ6EtYih!97t{$Hsvlszhl$t%1ojx^uaz4jSDyMnQWAP_|-6AC09AdEmb zLtFvcv4aN>Mn*=WS;I6%8bRrhvHZL$q5Qb6;jHepPj#C<0a(qV*DwPLjVHyh0B$y$ zmn>QG{rBJh_O>SO2>A?UlVeuevSrIKJq`1}fe5cXp|v{n+!a0n3X31Dcf+uRbX@8O zn$V3va+Ta5rpsOSM`0*m7LwV>#NoXN$b3R+f>z7pE&4p~=H`ldaH*-O$i%$={`-XX u1G}KJfBa)HlrIaJ801UA>d>J>yLa!#+iLNjSYV(6Ia2#||B-fFT>c;WrJH{M diff --git a/Win32/ictoopie.ico b/Win32/ictoopie.ico deleted file mode 100644 index 077479a2ab8c7304f6dca1ac1770176394134cc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180626 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 iJmHh&v-Y;wb diff --git a/Win32/install_service.bat b/Win32/install_service.bat deleted file mode 100644 index b03c11b6..00000000 --- a/Win32/install_service.bat +++ /dev/null @@ -1 +0,0 @@ -i2pd --service=install \ No newline at end of file diff --git a/Win32/installer.iss b/Win32/installer.iss deleted file mode 100644 index 95c2bf42..00000000 --- a/Win32/installer.iss +++ /dev/null @@ -1,41 +0,0 @@ -#define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.14.0" -#define I2Pd_Publisher "PurpleI2P" - -[Setup] -AppName={#I2Pd_AppName} -AppVersion={#I2Pd_ver} -AppPublisher={#I2Pd_Publisher} -DefaultDirName={pf}\I2Pd -DefaultGroupName=I2Pd -UninstallDisplayIcon={app}\I2Pd.exe -OutputDir=. -LicenseFile=../LICENSE -OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver} -SetupIconFile=mask.ico -InternalCompressLevel=ultra64 -Compression=lzma/ultra64 -SolidCompression=true -ArchitecturesInstallIn64BitMode=x64 -AppVerName={#I2Pd_AppName} -ExtraDiskSpaceRequired=15 -AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2} -AppPublisherURL=http://i2pd.website/ -AppSupportURL=https://github.com/PurpleI2P/i2pd/issues -AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases - -[Files] -Source: ..\i2pd_x86.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64 -Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64 -Source: ..\README.md; DestDir: {app}; DestName: Readme.txt; Flags: onlyifdoesntexist -Source: ..\contrib\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist -Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist -Source: ..\contrib\tunnels.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist -Source: ..\contrib\certificates\*; DestDir: {userappdata}\i2pd\certificates; Flags: onlyifdoesntexist recursesubdirs createallsubdirs - -[Icons] -Name: {group}\I2Pd; Filename: {app}\i2pd.exe -Name: {group}\Readme; Filename: {app}\Readme.txt - -[UninstallDelete] -Type: filesandordirs; Name: {app} diff --git a/Win32/nsi/helper_readme.nsh b/Win32/nsi/helper_readme.nsh deleted file mode 100644 index a3baaca1..00000000 --- a/Win32/nsi/helper_readme.nsh +++ /dev/null @@ -1,57 +0,0 @@ -!verbose push -!verbose 3 - -!ifndef _MUI_EXTRAPAGES_NSH -!define _MUI_EXTRAPAGES_NSH - -!ifmacrondef MUI_EXTRAPAGE_README & MUI_PAGE_README & MUI_UNPAGE_README & ReadmeLangStrings - -!macro MUI_EXTRAPAGE_README UN ReadmeFile -!verbose push -!verbose 3 - !define MUI_PAGE_HEADER_TEXT "$(${UN}ReadmeHeader)" - !define MUI_PAGE_HEADER_SUBTEXT "$(${UN}ReadmeSubHeader)" - !define MUI_LICENSEPAGE_TEXT_TOP "$(${UN}ReadmeTextTop)" - !define MUI_LICENSEPAGE_TEXT_BOTTOM "$(${UN}ReadmeTextBottom)" - !define MUI_LICENSEPAGE_BUTTON "$(^NextBtn)" - !insertmacro MUI_${UN}PAGE_LICENSE "${ReadmeFile}" -!verbose pop -!macroend - -!define ReadmeRun "!insertmacro MUI_EXTRAPAGE_README" - - -!macro MUI_PAGE_README ReadmeFile -!verbose push -!verbose 3 - ${ReadmeRun} "" "${ReadmeFile}" -!verbose pop -!macroend - - -!macro MUI_UNPAGE_README ReadmeFile -!verbose push -!verbose 3 - ${ReadmeRun} "UN" "${ReadmeFile}" -!verbose pop -!macroend - - -!macro ReadmeLangStrings UN MUI_LANG ReadmeHeader ReadmeSubHeader ReadmeTextTop ReadmeTextBottom -!verbose push -!verbose 3 - LangString ${UN}ReadmeHeader ${MUI_LANG} "${ReadmeHeader}" - LangString ${UN}ReadmeSubHeader ${MUI_LANG} "${ReadmeSubHeader}" - LangString ${UN}ReadmeTextTop ${MUI_LANG} "${ReadmeTextTop}" - LangString ${UN}ReadmeTextBottom ${MUI_LANG} "${ReadmeTextBottom}" -!verbose pop -!macroend - -!define ReadmeLanguage `!insertmacro ReadmeLangStrings ""` - -!define Un.ReadmeLanguage `!insertmacro ReadmeLangStrings "UN"` - -!endif -!endif - -!verbose pop \ No newline at end of file diff --git a/Win32/nsi/servicelib.nsh b/Win32/nsi/servicelib.nsh deleted file mode 100644 index 7f4b5861..00000000 --- a/Win32/nsi/servicelib.nsh +++ /dev/null @@ -1,419 +0,0 @@ -; NSIS SERVICE LIBRARY - servicelib.nsh -; Version 1.8.1 - Jun 21th, 2013 -; Questions/Comments - dselkirk@hotmail.com -; -; Description: -; Provides an interface to window services -; -; Inputs: -; action - systemlib action ie. create, delete, start, stop, pause, -; continue, installed, running, status -; name - name of service to manipulate -; param - action parameters; usage: var1=value1;var2=value2;...etc. -; (don't forget to add a ';' after the last value!) -; -; Actions: -; create - creates a new windows service -; Parameters: -; path - path to service executable -; autostart - automatically start with system ie. 1|0 -; interact - interact with the desktop ie. 1|0 -; depend - service dependencies -; user - user that runs the service -; password - password of the above user -; display - display name in service's console -; description - Description of service -; starttype - start type (supersedes autostart) -; servicetype - service type (supersedes interact) -; -; delete - deletes a windows service -; start - start a stopped windows service -; stop - stops a running windows service -; pause - pauses a running windows service -; continue - continues a paused windows service -; installed - is the provided service installed -; Parameters: -; action - if true then invokes the specified action -; running - is the provided service running -; Parameters: -; action - if true then invokes the specified action -; status - check the status of the provided service -; -; Usage: -; Method 1: -; Push "action" -; Push "name" -; Push "param" -; Call Service -; Pop $0 ;response -; -; Method 2: -; !insertmacro SERVICE "action" "name" "param" -; -; History: -; 1.0 - 09/15/2003 - Initial release -; 1.1 - 09/16/2003 - Changed &l to i, thx brainsucker -; 1.2 - 02/29/2004 - Fixed documentation. -; 1.3 - 01/05/2006 - Fixed interactive flag and pop order (Kichik) -; 1.4 - 12/07/2006 - Added display and depend, fixed datatypes (Vitoco) -; 1.5 - 06/25/2008 - Added description of service.(DeSafe.com/liuqixing#gmail.com) -; 1.5.1 - 06/12/2009 - Added use of __UNINSTALL__ -; 1.6 - 08/02/2010 - Fixed description implementation (Anders) -; 1.7 - 04/11/2010 - Added get running service process id (Nico) -; 1.8 - 24/03/2011 - Added starttype and servicetype (Sergius) -; 1.8.1 - 21/06/2013 - Added dynamic ASCII & Unicode support (Zinthose) - -!ifndef SERVICELIB - !define SERVICELIB - - !define SC_MANAGER_ALL_ACCESS 0x3F - !define SC_STATUS_PROCESS_INFO 0x0 - !define SERVICE_ALL_ACCESS 0xF01FF - - !define SERVICE_CONTROL_STOP 1 - !define SERVICE_CONTROL_PAUSE 2 - !define SERVICE_CONTROL_CONTINUE 3 - - !define SERVICE_STOPPED 0x1 - !define SERVICE_START_PENDING 0x2 - !define SERVICE_STOP_PENDING 0x3 - !define SERVICE_RUNNING 0x4 - !define SERVICE_CONTINUE_PENDING 0x5 - !define SERVICE_PAUSE_PENDING 0x6 - !define SERVICE_PAUSED 0x7 - - !define SERVICE_KERNEL_DRIVER 0x00000001 - !define SERVICE_FILE_SYSTEM_DRIVER 0x00000002 - !define SERVICE_WIN32_OWN_PROCESS 0x00000010 - !define SERVICE_WIN32_SHARE_PROCESS 0x00000020 - !define SERVICE_INTERACTIVE_PROCESS 0x00000100 - - - !define SERVICE_BOOT_START 0x00000000 - !define SERVICE_SYSTEM_START 0x00000001 - !define SERVICE_AUTO_START 0x00000002 - !define SERVICE_DEMAND_START 0x00000003 - !define SERVICE_DISABLED 0x00000004 - - ## Added by Zinthose for Native Unicode Support - !ifdef NSIS_UNICODE - !define APITAG "W" - !else - !define APITAG "A" - !endif - - !macro SERVICE ACTION NAME PARAM - Push '${ACTION}' - Push '${NAME}' - Push '${PARAM}' - !ifdef __UNINSTALL__ - Call un.Service - !else - Call Service - !endif - !macroend - - !macro FUNC_GETPARAM - Push $0 - Push $1 - Push $2 - Push $3 - Push $4 - Push $5 - Push $6 - Push $7 - Exch 8 - Pop $1 ;name - Exch 8 - Pop $2 ;source - StrCpy $0 "" - StrLen $7 $2 - StrCpy $3 0 - lbl_loop: - IntCmp $3 $7 0 0 lbl_done - StrLen $4 "$1=" - StrCpy $5 $2 $4 $3 - StrCmp $5 "$1=" 0 lbl_next - IntOp $5 $3 + $4 - StrCpy $3 $5 - lbl_loop2: - IntCmp $3 $7 0 0 lbl_done - StrCpy $6 $2 1 $3 - StrCmp $6 ";" 0 lbl_next2 - IntOp $6 $3 - $5 - StrCpy $0 $2 $6 $5 - Goto lbl_done - lbl_next2: - IntOp $3 $3 + 1 - Goto lbl_loop2 - lbl_next: - IntOp $3 $3 + 1 - Goto lbl_loop - lbl_done: - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Exch 2 - Pop $6 - Pop $7 - Exch $0 - !macroend - - !macro CALL_GETPARAM VAR NAME DEFAULT LABEL - Push $1 - Push ${NAME} - Call ${UN}GETPARAM - Pop $6 - StrCpy ${VAR} "${DEFAULT}" - StrCmp $6 "" "${LABEL}" 0 - StrCpy ${VAR} $6 - !macroend - - !macro FUNC_SERVICE UN - Push $0 - Push $1 - Push $2 - Push $3 - Push $4 - Push $5 - Push $6 - Push $7 - Exch 8 - Pop $1 ;param - Exch 8 - Pop $2 ;name - Exch 8 - Pop $3 ;action - ;$0 return - ;$4 OpenSCManager - ;$5 OpenService - - StrCpy $0 "false" - System::Call 'advapi32::OpenSCManager${APITAG}(n, n, i ${SC_MANAGER_ALL_ACCESS}) i.r4' - IntCmp $4 0 lbl_done - StrCmp $3 "create" lbl_create - System::Call 'advapi32::OpenService${APITAG}(i r4, t r2, i ${SERVICE_ALL_ACCESS}) i.r5' - IntCmp $5 0 lbl_done - - lbl_select: - StrCmp $3 "delete" lbl_delete - StrCmp $3 "start" lbl_start - StrCmp $3 "stop" lbl_stop - StrCmp $3 "pause" lbl_pause - StrCmp $3 "continue" lbl_continue - StrCmp $3 "installed" lbl_installed - StrCmp $3 "running" lbl_running - StrCmp $3 "status" lbl_status - StrCmp $3 "processid" lbl_processid - Goto lbl_done - - ; create service - lbl_create: - Push $R1 ;depend - Push $R2 ;user - Push $R3 ;password - Push $R4 ;servicetype/interact - Push $R5 ;starttype/autostart - Push $R6 ;path - Push $R7 ;display - Push $R8 ;description - - !insertmacro CALL_GETPARAM $R1 "depend" "n" "lbl_depend" - StrCpy $R1 't "$R1"' - lbl_depend: - StrCmp $R1 "n" 0 lbl_machine ;old name of depend param - !insertmacro CALL_GETPARAM $R1 "machine" "n" "lbl_machine" - StrCpy $R1 't "$R1"' - lbl_machine: - - !insertmacro CALL_GETPARAM $R2 "user" "n" "lbl_user" - StrCpy $R2 't "$R2"' - lbl_user: - - !insertmacro CALL_GETPARAM $R3 "password" "n" "lbl_password" - StrCpy $R3 't "$R3"' - lbl_password: - - !insertmacro CALL_GETPARAM $R4 "interact" "${SERVICE_WIN32_OWN_PROCESS}" "lbl_interact" - StrCpy $6 ${SERVICE_WIN32_OWN_PROCESS} - IntCmp $R4 0 +2 - IntOp $6 $6 | ${SERVICE_INTERACTIVE_PROCESS} - StrCpy $R4 $6 - lbl_interact: - - !insertmacro CALL_GETPARAM $R4 "servicetype" "$R4" "lbl_servicetype" - lbl_servicetype: - - !insertmacro CALL_GETPARAM $R5 "autostart" "${SERVICE_DEMAND_START}" "lbl_autostart" - StrCpy $6 ${SERVICE_DEMAND_START} - IntCmp $R5 0 +2 - StrCpy $6 ${SERVICE_AUTO_START} - StrCpy $R5 $6 - lbl_autostart: - - !insertmacro CALL_GETPARAM $R5 "starttype" "$R5" "lbl_starttype" - lbl_starttype: - - !insertmacro CALL_GETPARAM $R6 "path" "n" "lbl_path" - lbl_path: - - !insertmacro CALL_GETPARAM $R7 "display" "$2" "lbl_display" - lbl_display: - - !insertmacro CALL_GETPARAM $R8 "description" "$2" "lbl_description" - lbl_description: - - System::Call 'advapi32::CreateService${APITAG}(i r4, t r2, t R7, i ${SERVICE_ALL_ACCESS}, \ - i R4, i R5, i 0, t R6, n, n, $R1, $R2, $R3) i.r6' - - ; write description of service (SERVICE_CONFIG_DESCRIPTION) - System::Call 'advapi32::ChangeServiceConfig2${APITAG}(ir6,i1,*t "$R8")i.R7' - strcmp $R7 "error" 0 lbl_descriptioncomplete - WriteRegStr HKLM "SYSTEM\CurrentControlSet\Services\$2" "Description" $R8 - lbl_descriptioncomplete: - - Pop $R8 - Pop $R7 - Pop $R6 - Pop $R5 - Pop $R4 - Pop $R3 - Pop $R2 - Pop $R1 - StrCmp $6 0 lbl_done lbl_good - - ; delete service - lbl_delete: - System::Call 'advapi32::DeleteService(i r5) i.r6' - StrCmp $6 0 lbl_done lbl_good - - ; start service - lbl_start: - System::Call 'advapi32::StartService${APITAG}(i r5, i 0, i 0) i.r6' - StrCmp $6 0 lbl_done lbl_good - - ; stop service - lbl_stop: - Push $R1 - System::Call '*(i,i,i,i,i,i,i) i.R1' - System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_STOP}, i $R1) i' - System::Free $R1 - Pop $R1 - StrCmp $6 0 lbl_done lbl_good - - ; pause service - lbl_pause: - Push $R1 - System::Call '*(i,i,i,i,i,i,i) i.R1' - System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_PAUSE}, i $R1) i' - System::Free $R1 - Pop $R1 - StrCmp $6 0 lbl_done lbl_good - - ; continue service - lbl_continue: - Push $R1 - System::Call '*(i,i,i,i,i,i,i) i.R1' - System::Call 'advapi32::ControlService(i r5, i ${SERVICE_CONTROL_CONTINUE}, i $R1) i' - System::Free $R1 - Pop $R1 - StrCmp $6 0 lbl_done lbl_good - - ; is installed - lbl_installed: - !insertmacro CALL_GETPARAM $7 "action" "" "lbl_good" - StrCpy $3 $7 - Goto lbl_select - - ; is service running - lbl_running: - Push $R1 - System::Call '*(i,i,i,i,i,i,i) i.R1' - System::Call 'advapi32::QueryServiceStatus(i r5, i $R1) i' - System::Call '*$R1(i, i.r6)' - System::Free $R1 - Pop $R1 - IntFmt $6 "0x%X" $6 - StrCmp $6 ${SERVICE_RUNNING} 0 lbl_done - !insertmacro CALL_GETPARAM $7 "action" "" "lbl_good" - StrCpy $3 $7 - Goto lbl_select - - lbl_status: - Push $R1 - System::Call '*(i,i,i,i,i,i,i) i.R1' - System::Call 'advapi32::QueryServiceStatus(i r5, i $R1) i' - System::Call '*$R1(i, i .r6)' - System::Free $R1 - Pop $R1 - IntFmt $6 "0x%X" $6 - StrCpy $0 "running" - IntCmp $6 ${SERVICE_RUNNING} lbl_done - StrCpy $0 "stopped" - IntCmp $6 ${SERVICE_STOPPED} lbl_done - StrCpy $0 "start_pending" - IntCmp $6 ${SERVICE_START_PENDING} lbl_done - StrCpy $0 "stop_pending" - IntCmp $6 ${SERVICE_STOP_PENDING} lbl_done - StrCpy $0 "running" - IntCmp $6 ${SERVICE_RUNNING} lbl_done - StrCpy $0 "continue_pending" - IntCmp $6 ${SERVICE_CONTINUE_PENDING} lbl_done - StrCpy $0 "pause_pending" - IntCmp $6 ${SERVICE_PAUSE_PENDING} lbl_done - StrCpy $0 "paused" - IntCmp $6 ${SERVICE_PAUSED} lbl_done - StrCpy $0 "unknown" - Goto lbl_done - - lbl_processid: - Push $R1 - Push $R2 - System::Call '*(i,i,i,i,i,i,i,i,i) i.R1' - System::Call '*(i 0) i.R2' - System::Call "advapi32::QueryServiceStatusEx(i r5, i ${SC_STATUS_PROCESS_INFO}, i $R1, i 36, i $R2) i" - System::Call "*$R1(i,i,i,i,i,i,i, i .r0)" - System::Free $R2 - System::Free $R1 - Pop $R2 - Pop $R1 - Goto lbl_done - - lbl_good: - StrCpy $0 "true" - lbl_done: - IntCmp $5 0 +2 - System::Call 'advapi32::CloseServiceHandle(i r5) n' - IntCmp $4 0 +2 - System::Call 'advapi32::CloseServiceHandle(i r4) n' - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Exch 3 - Pop $5 - Pop $7 - Pop $6 - Exch $0 - !macroend - - Function Service - !insertmacro FUNC_SERVICE "" - FunctionEnd - - Function un.Service - !insertmacro FUNC_SERVICE "un." - FunctionEnd - - Function GetParam - !insertmacro FUNC_GETPARAM - FunctionEnd - - Function un.GetParam - !insertmacro FUNC_GETPARAM - FunctionEnd - - !undef APITAG -!endif \ No newline at end of file diff --git a/Win32/resource.h b/Win32/resource.h index a8309c8b..3b188481 100644 --- a/Win32/resource.h +++ b/Win32/resource.h @@ -1,16 +1,11 @@ //{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Resource.rc -// -#define MAINICON 101 +#define MAINICON 101 -// Next default values for new objects -// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/Win32/uninstall_service.bat b/Win32/uninstall_service.bat deleted file mode 100644 index 0289c24a..00000000 --- a/Win32/uninstall_service.bat +++ /dev/null @@ -1 +0,0 @@ -i2pd --service=remove \ No newline at end of file diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index 713d6ca6..bceda568 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -56,7 +56,7 @@ namespace fs { else { // otherwise %appdata% - SHGetFolderPath(NULL, CSIDL_APPDATA, 0, NULL, localAppData); + SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, localAppData); dataDir = std::string(localAppData) + "\\" + appName; } return; From a1e9c3d2705e12071f0c2cf9f2ed05ce9825879c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 11 Jun 2017 09:34:19 +0300 Subject: [PATCH 04/23] remove NSIS template --- build/cmake_modules/NSIS.template.in | 978 --------------------------- 1 file changed, 978 deletions(-) delete mode 100644 build/cmake_modules/NSIS.template.in diff --git a/build/cmake_modules/NSIS.template.in b/build/cmake_modules/NSIS.template.in deleted file mode 100644 index f7d5a7f7..00000000 --- a/build/cmake_modules/NSIS.template.in +++ /dev/null @@ -1,978 +0,0 @@ -; CPack install script designed for a nmake build - -;-------------------------------- -; You must define these values - - !define VERSION "@CPACK_PACKAGE_VERSION@" - !define PATCH "@CPACK_PACKAGE_VERSION_PATCH@" - !define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@" - -;-------------------------------- -;Variables - - Var MUI_TEMP - Var STARTMENU_FOLDER - Var SV_ALLUSERS - Var START_MENU - Var DO_NOT_ADD_TO_PATH - Var ADD_TO_PATH_ALL_USERS - Var ADD_TO_PATH_CURRENT_USER - Var INSTALL_DESKTOP - Var IS_DEFAULT_INSTALLDIR -;-------------------------------- -;Include Modern UI - - !include "MUI.nsh" - - ;Default installation folder - InstallDir "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" - -;-------------------------------- -;General - - ;Name and file - Name "@CPACK_NSIS_PACKAGE_NAME@" - OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" - - ;Set compression - SetCompressor @CPACK_NSIS_COMPRESSOR@ - - ;Require administrator access - RequestExecutionLevel admin - -@CPACK_NSIS_DEFINES@ - - !include Sections.nsh - -;--- Component support macros: --- -; The code for the add/remove functionality is from: -; http://nsis.sourceforge.net/Add/Remove_Functionality -; It has been modified slightly and extended to provide -; inter-component dependencies. -Var AR_SecFlags -Var AR_RegFlags -@CPACK_NSIS_SECTION_SELECTED_VARS@ - -; Loads the "selected" flag for the section named SecName into the -; variable VarName. -!macro LoadSectionSelectedIntoVar SecName VarName - SectionGetFlags ${${SecName}} $${VarName} - IntOp $${VarName} $${VarName} & ${SF_SELECTED} ;Turn off all other bits -!macroend - -; Loads the value of a variable... can we get around this? -!macro LoadVar VarName - IntOp $R0 0 + $${VarName} -!macroend - -; Sets the value of a variable -!macro StoreVar VarName IntValue - IntOp $${VarName} 0 + ${IntValue} -!macroend - -!macro InitSection SecName - ; This macro reads component installed flag from the registry and - ;changes checked state of the section on the components page. - ;Input: section index constant name specified in Section command. - - ClearErrors - ;Reading component status from registry - ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" "Installed" - IfErrors "default_${SecName}" - ;Status will stay default if registry value not found - ;(component was never installed) - IntOp $AR_RegFlags $AR_RegFlags & ${SF_SELECTED} ;Turn off all other bits - SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading default section flags - IntOp $AR_SecFlags $AR_SecFlags & 0xFFFE ;Turn lowest (enabled) bit off - IntOp $AR_SecFlags $AR_RegFlags | $AR_SecFlags ;Change lowest bit - - ; Note whether this component was installed before - !insertmacro StoreVar ${SecName}_was_installed $AR_RegFlags - IntOp $R0 $AR_RegFlags & $AR_RegFlags - - ;Writing modified flags - SectionSetFlags ${${SecName}} $AR_SecFlags - - "default_${SecName}:" - !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected -!macroend - -!macro FinishSection SecName - ; This macro reads section flag set by user and removes the section - ;if it is not selected. - ;Then it writes component installed flag to registry - ;Input: section index constant name specified in Section command. - - SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading section flags - ;Checking lowest bit: - IntOp $AR_SecFlags $AR_SecFlags & ${SF_SELECTED} - IntCmp $AR_SecFlags 1 "leave_${SecName}" - ;Section is not selected: - ;Calling Section uninstall macro and writing zero installed flag - !insertmacro "Remove_${${SecName}}" - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \ - "Installed" 0 - Goto "exit_${SecName}" - - "leave_${SecName}:" - ;Section is selected: - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \ - "Installed" 1 - - "exit_${SecName}:" -!macroend - -!macro RemoveSection_CPack SecName - ; This macro is used to call section's Remove_... macro - ;from the uninstaller. - ;Input: section index constant name specified in Section command. - - !insertmacro "Remove_${${SecName}}" -!macroend - -; Determine whether the selection of SecName changed -!macro MaybeSelectionChanged SecName - !insertmacro LoadVar ${SecName}_selected - SectionGetFlags ${${SecName}} $R1 - IntOp $R1 $R1 & ${SF_SELECTED} ;Turn off all other bits - - ; See if the status has changed: - IntCmp $R0 $R1 "${SecName}_unchanged" - !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected - - IntCmp $R1 ${SF_SELECTED} "${SecName}_was_selected" - !insertmacro "Deselect_required_by_${SecName}" - goto "${SecName}_unchanged" - - "${SecName}_was_selected:" - !insertmacro "Select_${SecName}_depends" - - "${SecName}_unchanged:" -!macroend -;--- End of Add/Remove macros --- - -;-------------------------------- -;Interface Settings - - !define MUI_HEADERIMAGE - !define MUI_ABORTWARNING - -;-------------------------------- -; path functions - -!verbose 3 -!include "WinMessages.NSH" -!verbose 4 - -;---------------------------------------- -; based upon a script of "Written by KiCHiK 2003-01-18 05:57:02" -;---------------------------------------- -!verbose 3 -!include "WinMessages.NSH" -!verbose 4 -;==================================================== -; get_NT_environment -; Returns: the selected environment -; Output : head of the stack -;==================================================== -!macro select_NT_profile UN -Function ${UN}select_NT_profile - StrCmp $ADD_TO_PATH_ALL_USERS "1" 0 environment_single - DetailPrint "Selected environment for all users" - Push "all" - Return - environment_single: - DetailPrint "Selected environment for current user only." - Push "current" - Return -FunctionEnd -!macroend -!insertmacro select_NT_profile "" -!insertmacro select_NT_profile "un." -;---------------------------------------------------- -!define NT_current_env 'HKCU "Environment"' -!define NT_all_env 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' - -!ifndef WriteEnvStr_RegKey - !ifdef ALL_USERS - !define WriteEnvStr_RegKey \ - 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' - !else - !define WriteEnvStr_RegKey 'HKCU "Environment"' - !endif -!endif - -; AddToPath - Adds the given dir to the search path. -; Input - head of the stack -; Note - Win9x systems requires reboot - -Function AddToPath - Exch $0 - Push $1 - Push $2 - Push $3 - - # don't add if the path doesn't exist - IfFileExists "$0\*.*" "" AddToPath_done - - ReadEnvStr $1 PATH - ; if the path is too long for a NSIS variable NSIS will return a 0 - ; length string. If we find that, then warn and skip any path - ; modification as it will trash the existing path. - StrLen $2 $1 - IntCmp $2 0 CheckPathLength_ShowPathWarning CheckPathLength_Done CheckPathLength_Done - CheckPathLength_ShowPathWarning: - Messagebox MB_OK|MB_ICONEXCLAMATION "Warning! PATH too long installer unable to modify PATH!" - Goto AddToPath_done - CheckPathLength_Done: - Push "$1;" - Push "$0;" - Call StrStr - Pop $2 - StrCmp $2 "" "" AddToPath_done - Push "$1;" - Push "$0\;" - Call StrStr - Pop $2 - StrCmp $2 "" "" AddToPath_done - GetFullPathName /SHORT $3 $0 - Push "$1;" - Push "$3;" - Call StrStr - Pop $2 - StrCmp $2 "" "" AddToPath_done - Push "$1;" - Push "$3\;" - Call StrStr - Pop $2 - StrCmp $2 "" "" AddToPath_done - - Call IsNT - Pop $1 - StrCmp $1 1 AddToPath_NT - ; Not on NT - StrCpy $1 $WINDIR 2 - FileOpen $1 "$1\autoexec.bat" a - FileSeek $1 -1 END - FileReadByte $1 $2 - IntCmp $2 26 0 +2 +2 # DOS EOF - FileSeek $1 -1 END # write over EOF - FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n" - FileClose $1 - SetRebootFlag true - Goto AddToPath_done - - AddToPath_NT: - StrCmp $ADD_TO_PATH_ALL_USERS "1" ReadAllKey - ReadRegStr $1 ${NT_current_env} "PATH" - Goto DoTrim - ReadAllKey: - ReadRegStr $1 ${NT_all_env} "PATH" - DoTrim: - StrCmp $1 "" AddToPath_NTdoIt - Push $1 - Call Trim - Pop $1 - StrCpy $0 "$1;$0" - AddToPath_NTdoIt: - StrCmp $ADD_TO_PATH_ALL_USERS "1" WriteAllKey - WriteRegExpandStr ${NT_current_env} "PATH" $0 - Goto DoSend - WriteAllKey: - WriteRegExpandStr ${NT_all_env} "PATH" $0 - DoSend: - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - AddToPath_done: - Pop $3 - Pop $2 - Pop $1 - Pop $0 -FunctionEnd - - -; RemoveFromPath - Remove a given dir from the path -; Input: head of the stack - -Function un.RemoveFromPath - Exch $0 - Push $1 - Push $2 - Push $3 - Push $4 - Push $5 - Push $6 - - IntFmt $6 "%c" 26 # DOS EOF - - Call un.IsNT - Pop $1 - StrCmp $1 1 unRemoveFromPath_NT - ; Not on NT - StrCpy $1 $WINDIR 2 - FileOpen $1 "$1\autoexec.bat" r - GetTempFileName $4 - FileOpen $2 $4 w - GetFullPathName /SHORT $0 $0 - StrCpy $0 "SET PATH=%PATH%;$0" - Goto unRemoveFromPath_dosLoop - - unRemoveFromPath_dosLoop: - FileRead $1 $3 - StrCpy $5 $3 1 -1 # read last char - StrCmp $5 $6 0 +2 # if DOS EOF - StrCpy $3 $3 -1 # remove DOS EOF so we can compare - StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine - StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine - StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine - StrCmp $3 "" unRemoveFromPath_dosLoopEnd - FileWrite $2 $3 - Goto unRemoveFromPath_dosLoop - unRemoveFromPath_dosLoopRemoveLine: - SetRebootFlag true - Goto unRemoveFromPath_dosLoop - - unRemoveFromPath_dosLoopEnd: - FileClose $2 - FileClose $1 - StrCpy $1 $WINDIR 2 - Delete "$1\autoexec.bat" - CopyFiles /SILENT $4 "$1\autoexec.bat" - Delete $4 - Goto unRemoveFromPath_done - - unRemoveFromPath_NT: - StrCmp $ADD_TO_PATH_ALL_USERS "1" unReadAllKey - ReadRegStr $1 ${NT_current_env} "PATH" - Goto unDoTrim - unReadAllKey: - ReadRegStr $1 ${NT_all_env} "PATH" - unDoTrim: - StrCpy $5 $1 1 -1 # copy last char - StrCmp $5 ";" +2 # if last char != ; - StrCpy $1 "$1;" # append ; - Push $1 - Push "$0;" - Call un.StrStr ; Find `$0;` in $1 - Pop $2 ; pos of our dir - StrCmp $2 "" unRemoveFromPath_done - ; else, it is in path - # $0 - path to add - # $1 - path var - StrLen $3 "$0;" - StrLen $4 $2 - StrCpy $5 $1 -$4 # $5 is now the part before the path to remove - StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove - StrCpy $3 $5$6 - - StrCpy $5 $3 1 -1 # copy last char - StrCmp $5 ";" 0 +2 # if last char == ; - StrCpy $3 $3 -1 # remove last char - - StrCmp $ADD_TO_PATH_ALL_USERS "1" unWriteAllKey - WriteRegExpandStr ${NT_current_env} "PATH" $3 - Goto unDoSend - unWriteAllKey: - WriteRegExpandStr ${NT_all_env} "PATH" $3 - unDoSend: - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - unRemoveFromPath_done: - Pop $6 - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Pop $0 -FunctionEnd - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Uninstall sutff -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -########################################### -# Utility Functions # -########################################### - -;==================================================== -; IsNT - Returns 1 if the current system is NT, 0 -; otherwise. -; Output: head of the stack -;==================================================== -; IsNT -; no input -; output, top of the stack = 1 if NT or 0 if not -; -; Usage: -; Call IsNT -; Pop $R0 -; ($R0 at this point is 1 or 0) - -!macro IsNT un -Function ${un}IsNT - Push $0 - ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion - StrCmp $0 "" 0 IsNT_yes - ; we are not NT. - Pop $0 - Push 0 - Return - - IsNT_yes: - ; NT!!! - Pop $0 - Push 1 -FunctionEnd -!macroend -!insertmacro IsNT "" -!insertmacro IsNT "un." - -; StrStr -; input, top of stack = string to search for -; top of stack-1 = string to search in -; output, top of stack (replaces with the portion of the string remaining) -; modifies no other variables. -; -; Usage: -; Push "this is a long ass string" -; Push "ass" -; Call StrStr -; Pop $R0 -; ($R0 at this point is "ass string") - -!macro StrStr un -Function ${un}StrStr -Exch $R1 ; st=haystack,old$R1, $R1=needle - Exch ; st=old$R1,haystack - Exch $R2 ; st=old$R1,old$R2, $R2=haystack - Push $R3 - Push $R4 - Push $R5 - StrLen $R3 $R1 - StrCpy $R4 0 - ; $R1=needle - ; $R2=haystack - ; $R3=len(needle) - ; $R4=cnt - ; $R5=tmp - loop: - StrCpy $R5 $R2 $R3 $R4 - StrCmp $R5 $R1 done - StrCmp $R5 "" done - IntOp $R4 $R4 + 1 - Goto loop -done: - StrCpy $R1 $R2 "" $R4 - Pop $R5 - Pop $R4 - Pop $R3 - Pop $R2 - Exch $R1 -FunctionEnd -!macroend -!insertmacro StrStr "" -!insertmacro StrStr "un." - -Function Trim ; Added by Pelaca - Exch $R1 - Push $R2 -Loop: - StrCpy $R2 "$R1" 1 -1 - StrCmp "$R2" " " RTrim - StrCmp "$R2" "$\n" RTrim - StrCmp "$R2" "$\r" RTrim - StrCmp "$R2" ";" RTrim - GoTo Done -RTrim: - StrCpy $R1 "$R1" -1 - Goto Loop -Done: - Pop $R2 - Exch $R1 -FunctionEnd - -Function ConditionalAddToRegisty - Pop $0 - Pop $1 - StrCmp "$0" "" ConditionalAddToRegisty_EmptyString - WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \ - "$1" "$0" - ;MessageBox MB_OK "Set Registry: '$1' to '$0'" - DetailPrint "Set install registry entry: '$1' to '$0'" - ConditionalAddToRegisty_EmptyString: -FunctionEnd - -;-------------------------------- - -!ifdef CPACK_USES_DOWNLOAD -Function DownloadFile - IfFileExists $INSTDIR\* +2 - CreateDirectory $INSTDIR - Pop $0 - - ; Skip if already downloaded - IfFileExists $INSTDIR\$0 0 +2 - Return - - StrCpy $1 "@CPACK_DOWNLOAD_SITE@" - - try_again: - NSISdl::download "$1/$0" "$INSTDIR\$0" - - Pop $1 - StrCmp $1 "success" success - StrCmp $1 "Cancelled" cancel - MessageBox MB_OK "Download failed: $1" - cancel: - Return - success: -FunctionEnd -!endif - -;-------------------------------- -; Installation types -@CPACK_NSIS_INSTALLATION_TYPES@ - -;-------------------------------- -; Component sections -@CPACK_NSIS_COMPONENT_SECTIONS@ - -;-------------------------------- -; Define some macro setting for the gui -@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@ -@CPACK_NSIS_INSTALLER_ICON_CODE@ -@CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@ -@CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@ - -;-------------------------------- -;Pages - !insertmacro MUI_PAGE_WELCOME - - !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@" - Page custom InstallOptionsPage - !insertmacro MUI_PAGE_DIRECTORY - - ;Start Menu Folder Page Configuration - !define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX" - !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" - !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" - !define MUI_STARTMENUPAGE_DEFAULTFOLDER "Purple I2P" - !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER - - @CPACK_NSIS_PAGE_COMPONENTS@ - - !insertmacro MUI_PAGE_INSTFILES - !insertmacro MUI_PAGE_FINISH - - !insertmacro MUI_UNPAGE_CONFIRM - !insertmacro MUI_UNPAGE_INSTFILES - -;-------------------------------- -;Languages - - !insertmacro MUI_LANGUAGE "English" ;first language is the default language - !insertmacro MUI_LANGUAGE "Albanian" - !insertmacro MUI_LANGUAGE "Arabic" - !insertmacro MUI_LANGUAGE "Basque" - !insertmacro MUI_LANGUAGE "Belarusian" - !insertmacro MUI_LANGUAGE "Bosnian" - !insertmacro MUI_LANGUAGE "Breton" - !insertmacro MUI_LANGUAGE "Bulgarian" - !insertmacro MUI_LANGUAGE "Croatian" - !insertmacro MUI_LANGUAGE "Czech" - !insertmacro MUI_LANGUAGE "Danish" - !insertmacro MUI_LANGUAGE "Dutch" - !insertmacro MUI_LANGUAGE "Estonian" - !insertmacro MUI_LANGUAGE "Farsi" - !insertmacro MUI_LANGUAGE "Finnish" - !insertmacro MUI_LANGUAGE "French" - !insertmacro MUI_LANGUAGE "German" - !insertmacro MUI_LANGUAGE "Greek" - !insertmacro MUI_LANGUAGE "Hebrew" - !insertmacro MUI_LANGUAGE "Hungarian" - !insertmacro MUI_LANGUAGE "Icelandic" - !insertmacro MUI_LANGUAGE "Indonesian" - !insertmacro MUI_LANGUAGE "Irish" - !insertmacro MUI_LANGUAGE "Italian" - !insertmacro MUI_LANGUAGE "Japanese" - !insertmacro MUI_LANGUAGE "Korean" - !insertmacro MUI_LANGUAGE "Kurdish" - !insertmacro MUI_LANGUAGE "Latvian" - !insertmacro MUI_LANGUAGE "Lithuanian" - !insertmacro MUI_LANGUAGE "Luxembourgish" - !insertmacro MUI_LANGUAGE "Macedonian" - !insertmacro MUI_LANGUAGE "Malay" - !insertmacro MUI_LANGUAGE "Mongolian" - !insertmacro MUI_LANGUAGE "Norwegian" - !insertmacro MUI_LANGUAGE "Polish" - !insertmacro MUI_LANGUAGE "Portuguese" - !insertmacro MUI_LANGUAGE "PortugueseBR" - !insertmacro MUI_LANGUAGE "Romanian" - !insertmacro MUI_LANGUAGE "Russian" - !insertmacro MUI_LANGUAGE "Serbian" - !insertmacro MUI_LANGUAGE "SerbianLatin" - !insertmacro MUI_LANGUAGE "SimpChinese" - !insertmacro MUI_LANGUAGE "Slovak" - !insertmacro MUI_LANGUAGE "Slovenian" - !insertmacro MUI_LANGUAGE "Spanish" - !insertmacro MUI_LANGUAGE "Swedish" - !insertmacro MUI_LANGUAGE "Thai" - !insertmacro MUI_LANGUAGE "TradChinese" - !insertmacro MUI_LANGUAGE "Turkish" - !insertmacro MUI_LANGUAGE "Ukrainian" - !insertmacro MUI_LANGUAGE "Welsh" - - -;-------------------------------- -;Reserve Files - - ;These files should be inserted before other files in the data block - ;Keep these lines before any File command - ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA) - - ReserveFile "NSIS.InstallOptions.ini" - !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS - -;-------------------------------- -;Installer Sections - -Section "-Core installation" - ;Use the entire tree produced by the INSTALL target. Keep the - ;list of directories here in sync with the RMDir commands below. - SetOutPath "$INSTDIR" - @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@ - @CPACK_NSIS_FULL_INSTALL@ - - ;Store installation folder - WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR - - ;Create uninstaller - WriteUninstaller "$INSTDIR\Uninstall.exe" - Push "DisplayName" - Push "@CPACK_NSIS_DISPLAY_NAME@" - Call ConditionalAddToRegisty - Push "DisplayVersion" - Push "@CPACK_PACKAGE_VERSION@" - Call ConditionalAddToRegisty - Push "Publisher" - Push "@CPACK_PACKAGE_VENDOR@" - Call ConditionalAddToRegisty - Push "UninstallString" - Push "$INSTDIR\Uninstall.exe" - Call ConditionalAddToRegisty - Push "NoRepair" - Push "1" - Call ConditionalAddToRegisty - - !ifdef CPACK_NSIS_ADD_REMOVE - ;Create add/remove functionality - Push "ModifyPath" - Push "$INSTDIR\AddRemove.exe" - Call ConditionalAddToRegisty - !else - Push "NoModify" - Push "1" - Call ConditionalAddToRegisty - !endif - - ; Optional registration - Push "DisplayIcon" - Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@" - Call ConditionalAddToRegisty - Push "HelpLink" - Push "@CPACK_NSIS_HELP_LINK@" - Call ConditionalAddToRegisty - Push "URLInfoAbout" - Push "@CPACK_NSIS_URL_INFO_ABOUT@" - Call ConditionalAddToRegisty - Push "Contact" - Push "@CPACK_NSIS_CONTACT@" - Call ConditionalAddToRegisty - !insertmacro MUI_INSTALLOPTIONS_READ $INSTALL_DESKTOP "NSIS.InstallOptions.ini" "Field 5" "State" - !insertmacro MUI_STARTMENU_WRITE_BEGIN Application - - ;Create shortcuts - CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" -@CPACK_NSIS_CREATE_ICONS@ -@CPACK_NSIS_CREATE_ICONS_EXTRA@ - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe" - - ;Read a value from an InstallOptions INI file - !insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State" - !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_ALL_USERS "NSIS.InstallOptions.ini" "Field 3" "State" - !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_CURRENT_USER "NSIS.InstallOptions.ini" "Field 4" "State" - - ; Write special uninstall registry entries - Push "StartMenu" - Push "$STARTMENU_FOLDER" - Call ConditionalAddToRegisty - Push "DoNotAddToPath" - Push "$DO_NOT_ADD_TO_PATH" - Call ConditionalAddToRegisty - Push "AddToPathAllUsers" - Push "$ADD_TO_PATH_ALL_USERS" - Call ConditionalAddToRegisty - Push "AddToPathCurrentUser" - Push "$ADD_TO_PATH_CURRENT_USER" - Call ConditionalAddToRegisty - Push "InstallToDesktop" - Push "$INSTALL_DESKTOP" - Call ConditionalAddToRegisty - - !insertmacro MUI_STARTMENU_WRITE_END - -@CPACK_NSIS_EXTRA_INSTALL_COMMANDS@ - -SectionEnd - -Section "-Add to path" - Push $INSTDIR\bin - StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 doNotAddToPath - StrCmp $DO_NOT_ADD_TO_PATH "1" doNotAddToPath 0 - Call AddToPath - doNotAddToPath: -SectionEnd - -;-------------------------------- -; Create custom pages -Function InstallOptionsPage - !insertmacro MUI_HEADER_TEXT "Install Options" "Choose options for installing @CPACK_NSIS_PACKAGE_NAME@" - !insertmacro MUI_INSTALLOPTIONS_DISPLAY "NSIS.InstallOptions.ini" - -FunctionEnd - -;-------------------------------- -; determine admin versus local install -Function un.onInit - - ClearErrors - UserInfo::GetName - IfErrors noLM - Pop $0 - UserInfo::GetAccountType - Pop $1 - StrCmp $1 "Admin" 0 +3 - SetShellVarContext all - ;MessageBox MB_OK 'User "$0" is in the Admin group' - Goto done - StrCmp $1 "Power" 0 +3 - SetShellVarContext all - ;MessageBox MB_OK 'User "$0" is in the Power Users group' - Goto done - - noLM: - ;Get installation folder from registry if available - - done: - -FunctionEnd - -;--- Add/Remove callback functions: --- -!macro SectionList MacroName - ;This macro used to perform operation on multiple sections. - ;List all of your components in following manner here. -@CPACK_NSIS_COMPONENT_SECTION_LIST@ -!macroend - -Section -FinishComponents - ;Removes unselected components and writes component status to registry - !insertmacro SectionList "FinishSection" - -!ifdef CPACK_NSIS_ADD_REMOVE - ; Get the name of the installer executable - System::Call 'kernel32::GetModuleFileNameA(i 0, t .R0, i 1024) i r1' - StrCpy $R3 $R0 - - ; Strip off the last 13 characters, to see if we have AddRemove.exe - StrLen $R1 $R0 - IntOp $R1 $R0 - 13 - StrCpy $R2 $R0 13 $R1 - StrCmp $R2 "AddRemove.exe" addremove_installed - - ; We're not running AddRemove.exe, so install it - CopyFiles $R3 $INSTDIR\AddRemove.exe - - addremove_installed: -!endif -SectionEnd -;--- End of Add/Remove callback functions --- - -;-------------------------------- -; Component dependencies -Function .onSelChange - !insertmacro SectionList MaybeSelectionChanged -FunctionEnd - -;-------------------------------- -;Uninstaller Section - -Section "Uninstall" - ReadRegStr $START_MENU SHCTX \ - "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu" - ;MessageBox MB_OK "Start menu is in: $START_MENU" - ReadRegStr $DO_NOT_ADD_TO_PATH SHCTX \ - "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "DoNotAddToPath" - ReadRegStr $ADD_TO_PATH_ALL_USERS SHCTX \ - "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathAllUsers" - ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \ - "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathCurrentUser" - ;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS" - ReadRegStr $INSTALL_DESKTOP SHCTX \ - "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "InstallToDesktop" - ;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP " - -@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@ - - ;Remove files we installed. - ;Keep the list of directories here in sync with the File commands above. -@CPACK_NSIS_DELETE_FILES@ -@CPACK_NSIS_DELETE_DIRECTORIES@ - -!ifdef CPACK_NSIS_ADD_REMOVE - ;Remove the add/remove program - Delete "$INSTDIR\AddRemove.exe" -!endif - - ;Remove the uninstaller itself. - Delete "$INSTDIR\Uninstall.exe" - DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" - - ;Remove the installation directory if it is empty. - RMDir "$INSTDIR" - - ; Remove the registry entries. - DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" - - ; Removes all optional components - !insertmacro SectionList "RemoveSection_CPack" - - !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP - - Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" -@CPACK_NSIS_DELETE_ICONS@ -@CPACK_NSIS_DELETE_ICONS_EXTRA@ - - ;Delete empty start menu parent diretories - StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" - - startMenuDeleteLoop: - ClearErrors - RMDir $MUI_TEMP - GetFullPathName $MUI_TEMP "$MUI_TEMP\.." - - IfErrors startMenuDeleteLoopDone - - StrCmp "$MUI_TEMP" "$SMPROGRAMS" startMenuDeleteLoopDone startMenuDeleteLoop - startMenuDeleteLoopDone: - - ; If the user changed the shortcut, then untinstall may not work. This should - ; try to fix it. - StrCpy $MUI_TEMP "$START_MENU" - Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" -@CPACK_NSIS_DELETE_ICONS_EXTRA@ - - ;Delete empty start menu parent diretories - StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" - - secondStartMenuDeleteLoop: - ClearErrors - RMDir $MUI_TEMP - GetFullPathName $MUI_TEMP "$MUI_TEMP\.." - - IfErrors secondStartMenuDeleteLoopDone - - StrCmp "$MUI_TEMP" "$SMPROGRAMS" secondStartMenuDeleteLoopDone secondStartMenuDeleteLoop - secondStartMenuDeleteLoopDone: - - DeleteRegKey /ifempty SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" - - Push $INSTDIR\bin - StrCmp $DO_NOT_ADD_TO_PATH_ "1" doNotRemoveFromPath 0 - Call un.RemoveFromPath - doNotRemoveFromPath: -SectionEnd - -;-------------------------------- -; determine admin versus local install -; Is install for "AllUsers" or "JustMe"? -; Default to "JustMe" - set to "AllUsers" if admin or on Win9x -; This function is used for the very first "custom page" of the installer. -; This custom page does not show up visibly, but it executes prior to the -; first visible page and sets up $INSTDIR properly... -; Choose different default installation folder based on SV_ALLUSERS... -; "Program Files" for AllUsers, "My Documents" for JustMe... - -Function .onInit - StrCmp "@CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL@" "ON" 0 inst - - ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "UninstallString" - StrCmp $0 "" inst - - MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \ - "@CPACK_NSIS_PACKAGE_NAME@ is already installed. $\n$\nDo you want to uninstall the old version before installing the new one?" \ - IDYES uninst IDNO inst - Abort - -;Run the uninstaller -uninst: - ClearErrors - StrLen $2 "\Uninstall.exe" - StrCpy $3 $0 -$2 # remove "\Uninstall.exe" from UninstallString to get path - ExecWait '$0 _?=$3' ;Do not copy the uninstaller to a temp file - - IfErrors uninst_failed inst -uninst_failed: - MessageBox MB_OK|MB_ICONSTOP "Uninstall failed." - Abort - - -inst: - ; Reads components status for registry - !insertmacro SectionList "InitSection" - - ; check to see if /D has been used to change - ; the install directory by comparing it to the - ; install directory that is expected to be the - ; default - StrCpy $IS_DEFAULT_INSTALLDIR 0 - StrCmp "$INSTDIR" "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" 0 +2 - StrCpy $IS_DEFAULT_INSTALLDIR 1 - - StrCpy $SV_ALLUSERS "JustMe" - ; if default install dir then change the default - ; if it is installed for JustMe - StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2 - StrCpy $INSTDIR "$DOCUMENTS\@CPACK_PACKAGE_INSTALL_DIRECTORY@" - - ClearErrors - UserInfo::GetName - IfErrors noLM - Pop $0 - UserInfo::GetAccountType - Pop $1 - StrCmp $1 "Admin" 0 +4 - SetShellVarContext all - ;MessageBox MB_OK 'User "$0" is in the Admin group' - StrCpy $SV_ALLUSERS "AllUsers" - Goto done - StrCmp $1 "Power" 0 +4 - SetShellVarContext all - ;MessageBox MB_OK 'User "$0" is in the Power Users group' - StrCpy $SV_ALLUSERS "AllUsers" - Goto done - - noLM: - StrCpy $SV_ALLUSERS "AllUsers" - ;Get installation folder from registry if available - - done: - StrCmp $SV_ALLUSERS "AllUsers" 0 +3 - StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2 - StrCpy $INSTDIR "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" - - StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 noOptionsPage - !insertmacro MUI_INSTALLOPTIONS_EXTRACT "NSIS.InstallOptions.ini" - - noOptionsPage: -FunctionEnd From 193fc343fe52806aeb3182e758a03b8235821334 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 11 Jun 2017 09:38:07 +0300 Subject: [PATCH 05/23] reupload mistakenly deleted iss project --- Win32/inno_installer.iss | 149 --------------------------------------- Win32/installer.iss | 41 +++++++++++ 2 files changed, 41 insertions(+), 149 deletions(-) delete mode 100644 Win32/inno_installer.iss create mode 100644 Win32/installer.iss diff --git a/Win32/inno_installer.iss b/Win32/inno_installer.iss deleted file mode 100644 index 67acc431..00000000 --- a/Win32/inno_installer.iss +++ /dev/null @@ -1,149 +0,0 @@ - -#define I2Pd_AppName "i2pd" -#define I2Pd_ver "0.2" - -[Setup] -AppName={#I2Pd_AppName} -AppVersion={#I2Pd_ver} -DefaultDirName={pf}\I2Pd -DefaultGroupName=I2Pd -UninstallDisplayIcon={app}\I2Pd.exe -Compression=lzma2 -SolidCompression=yes -OutputDir=. -LicenseFile=.\..\LICENSE -OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver} -ArchitecturesInstallIn64BitMode=x64 - - -[Files] -Source: "x64\Release\i2pd.exe"; DestDir: "{app}"; DestName: "i2pd.exe"; Check: Is64BitInstallMode -Source: "Release\i2pd.exe"; DestDir: "{app}"; Check: not Is64BitInstallMode -Source: "..\README.md"; DestDir: "{app}"; DestName: "Readme.txt"; AfterInstall: ConvertLineEndings - -[Icons] -Name: "{group}\I2Pd"; Filename: "{app}\i2pd.exe" -Name: "{group}\Readme"; Filename: "{app}\Readme.txt" - - -[Registry] -Root: HKCU; Subkey: "Environment"; ValueName: "Path"; ValueType: "string"; ValueData: "{app};{olddata}"; Check: NotOnPathAlready(); Flags: preservestringtype; - -[Code] - -var - DefaultTop, - DefaultLeft, - DefaultHeight, - DefaultBackTop, - DefaultNextTop, - DefaultCancelTop, - DefaultBevelTop, - DefaultOuterHeight: Integer; - -const - LicenseHeight = 400; - LF = #10; - CR = #13; - CRLF = CR + LF; - -procedure ConvertLineEndings(); - var - FilePath : String; - FileContents : String; -begin - FilePath := ExpandConstant(CurrentFileName) - LoadStringFromFile(FilePath, FileContents); - StringChangeEx(FileContents, LF, CRLF, False); - SaveStringToFile(FilePath, FileContents, False); -end; - -procedure InitializeWizard(); -begin - DefaultTop := WizardForm.Top; - DefaultLeft := WizardForm.Left; - DefaultHeight := WizardForm.Height; - DefaultBackTop := WizardForm.BackButton.Top; - DefaultNextTop := WizardForm.NextButton.Top; - DefaultCancelTop := WizardForm.CancelButton.Top; - DefaultBevelTop := WizardForm.Bevel.Top; - DefaultOuterHeight := WizardForm.OuterNotebook.Height; - - WizardForm.InnerPage.Height := WizardForm.InnerPage.Height + (LicenseHeight - DefaultHeight); - WizardForm.InnerNotebook.Height := WizardForm.InnerNotebook.Height + (LicenseHeight - DefaultHeight); - WizardForm.LicensePage.Height := WizardForm.LicensePage.Height + (LicenseHeight - DefaultHeight); - WizardForm.LicenseMemo.Height := WizardForm.LicenseMemo.Height + (LicenseHeight - DefaultHeight); - WizardForm.LicenseNotAcceptedRadio.Top := WizardForm.LicenseNotAcceptedRadio.Top + (LicenseHeight - DefaultHeight); - WizardForm.LicenseAcceptedRadio.Top := WizardForm.LicenseAcceptedRadio.Top + (LicenseHeight - DefaultHeight); - -end; - -procedure CurPageChanged(CurPageID: Integer); -begin - if CurPageID = wpLicense then - begin - WizardForm.Top := DefaultTop - (LicenseHeight - DefaultHeight) div 2; - WizardForm.Height := LicenseHeight; - WizardForm.OuterNotebook.Height := WizardForm.OuterNotebook.Height + (LicenseHeight - DefaultHeight); - WizardForm.CancelButton.Top := DefaultCancelTop + (LicenseHeight - DefaultHeight); - WizardForm.NextButton.Top := DefaultNextTop + (LicenseHeight - DefaultHeight); - WizardForm.BackButton.Top := DefaultBackTop + (LicenseHeight - DefaultHeight); - WizardForm.Bevel.Top := DefaultBevelTop + (LicenseHeight - DefaultHeight); - end - else - begin - WizardForm.Top := DefaultTop; - WizardForm.Left := DefaultLeft; - WizardForm.Height := DefaultHeight; - WizardForm.OuterNotebook.Height := DefaultOuterHeight; - WizardForm.CancelButton.Top := DefaultCancelTop; - WizardForm.NextButton.Top := DefaultNextTop; - WizardForm.BackButton.Top := DefaultBackTop; - WizardForm.Bevel.Top := DefaultBevelTop; - end; -end; - -function NotOnPathAlready(): Boolean; -var - BinDir, Path: String; -begin - Log('Checking if i2pd dir is already in the %PATH%'); - if RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'Path', Path) then - begin // Successfully read the value - Log('HKCUEnvironmentPATH = ' + Path); - BinDir := ExpandConstant('{app}'); - Log('Looking for i2pd dir in %PATH%: ' + BinDir + ' in ' + Path); - if Pos(LowerCase(BinDir), Lowercase(Path)) = 0 then - begin - Log('Did not find i2pd dir in %PATH% so I will add it'); - Result := True; - end - else - begin - Log('Found i2pd dir in %PATH% so will not add it again'); - Result := False; - end - end - else // The key probably doesn't exist - begin - Log('Could not access HKCUEnvironmentPATH so I assume that it is OK to add it'); - Result := True; - end; -end; - - -procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); -var - BinDir, Path: String; -begin - if (CurUninstallStep = usPostUninstall) - and (RegQueryStringValue(HKEY_CURRENT_USER, 'Environment', 'PATH', Path)) then - begin - BinDir := ExpandConstant('{app}'); - if Pos(LowerCase(BinDir) + ';', Lowercase(Path)) <> 0 then - begin - StringChange(Path, BinDir + ';', ''); - RegWriteStringValue(HKEY_CURRENT_USER, 'Environment', 'PATH', Path); - end; - end; -end; diff --git a/Win32/installer.iss b/Win32/installer.iss new file mode 100644 index 00000000..95c2bf42 --- /dev/null +++ b/Win32/installer.iss @@ -0,0 +1,41 @@ +#define I2Pd_AppName "i2pd" +#define I2Pd_ver "2.14.0" +#define I2Pd_Publisher "PurpleI2P" + +[Setup] +AppName={#I2Pd_AppName} +AppVersion={#I2Pd_ver} +AppPublisher={#I2Pd_Publisher} +DefaultDirName={pf}\I2Pd +DefaultGroupName=I2Pd +UninstallDisplayIcon={app}\I2Pd.exe +OutputDir=. +LicenseFile=../LICENSE +OutputBaseFilename=setup_{#I2Pd_AppName}_v{#I2Pd_ver} +SetupIconFile=mask.ico +InternalCompressLevel=ultra64 +Compression=lzma/ultra64 +SolidCompression=true +ArchitecturesInstallIn64BitMode=x64 +AppVerName={#I2Pd_AppName} +ExtraDiskSpaceRequired=15 +AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2} +AppPublisherURL=http://i2pd.website/ +AppSupportURL=https://github.com/PurpleI2P/i2pd/issues +AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases + +[Files] +Source: ..\i2pd_x86.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64 +Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64 +Source: ..\README.md; DestDir: {app}; DestName: Readme.txt; Flags: onlyifdoesntexist +Source: ..\contrib\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist +Source: ..\contrib\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist +Source: ..\contrib\tunnels.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist +Source: ..\contrib\certificates\*; DestDir: {userappdata}\i2pd\certificates; Flags: onlyifdoesntexist recursesubdirs createallsubdirs + +[Icons] +Name: {group}\I2Pd; Filename: {app}\i2pd.exe +Name: {group}\Readme; Filename: {app}\Readme.txt + +[UninstallDelete] +Type: filesandordirs; Name: {app} From 8e266058ae8756ffec8a6d4207ffb49f894b01a2 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Thu, 2 Feb 2017 03:06:32 +0800 Subject: [PATCH 06/23] more of SAM debug logging --- libi2pd_client/SAM.cpp | 59 ++++++++++++++++++++++-------------------- libi2pd_client/SAM.h | 5 ++-- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 42968c7a..66b81ab2 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -24,22 +24,23 @@ namespace client SAMSocket::~SAMSocket () { - Terminate (); - } + Terminate ("~SAMSocket()"); + } - void SAMSocket::CloseStream () + void SAMSocket::CloseStream (const char* reason) { + LogPrint (eLogDebug, "SAMSocket::CloseStream, reason: ", reason); if (m_Stream) { m_Stream->Close (); m_Stream.reset (); - } - } - - void SAMSocket::Terminate () + } + } + + void SAMSocket::Terminate (const char* reason) { - CloseStream (); - + CloseStream (reason); + switch (m_SocketType) { case eSAMSocketTypeSession: @@ -82,7 +83,7 @@ namespace client { LogPrint (eLogError, "SAM: handshake read error: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) - Terminate (); + Terminate ("SAM: handshake read error"); } else { @@ -130,7 +131,7 @@ namespace client else { LogPrint (eLogError, "SAM: handshake mismatch"); - Terminate (); + Terminate ("SAM: handshake mismatch"); } } } @@ -141,7 +142,7 @@ namespace client { LogPrint (eLogError, "SAM: handshake reply send error: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) - Terminate (); + Terminate ("SAM: handshake reply send error"); } else { @@ -153,6 +154,8 @@ namespace client void SAMSocket::SendMessageReply (const char * msg, size_t len, bool close) { + LogPrint (eLogDebug, "SAMSocket::SendMessageReply, close=",close?"true":"false", " reason: ", msg); + if (!m_IsSilent) boost::asio::async_write (m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (), std::bind(&SAMSocket::HandleMessageReplySent, shared_from_this (), @@ -160,7 +163,7 @@ namespace client else { if (close) - Terminate (); + Terminate ("SAMSocket::SendMessageReply(close=true)"); else Receive (); } @@ -172,12 +175,12 @@ namespace client { LogPrint (eLogError, "SAM: reply send error: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) - Terminate (); + Terminate ("SAM: reply send error"); } else { if (close) - Terminate (); + Terminate ("SAMSocket::HandleMessageReplySent(close=true)"); else Receive (); } @@ -189,7 +192,7 @@ namespace client { LogPrint (eLogError, "SAM: read error: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) - Terminate (); + Terminate ("SAM: read error"); } else if (m_SocketType == eSAMSocketTypeStream) HandleReceived (ecode, bytes_transferred); @@ -243,13 +246,13 @@ namespace client else { LogPrint (eLogError, "SAM: unexpected message ", m_Buffer); - Terminate (); + Terminate ("SAM: unexpected message"); } } else { LogPrint (eLogError, "SAM: malformed message ", m_Buffer); - Terminate (); + Terminate ("malformed message"); } } @@ -603,7 +606,7 @@ namespace client if (m_BufferOffset >= SAM_SOCKET_BUFFER_SIZE) { LogPrint (eLogError, "SAM: Buffer is full, terminate"); - Terminate (); + Terminate ("Buffer is full"); return; } m_Socket.async_read_some (boost::asio::buffer(m_Buffer + m_BufferOffset, SAM_SOCKET_BUFFER_SIZE - m_BufferOffset), @@ -617,7 +620,7 @@ namespace client { LogPrint (eLogError, "SAM: read error: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) - Terminate (); + Terminate ("read error"); } else { @@ -631,8 +634,8 @@ namespace client { if (!ecode) s->Receive (); - else - s->m_Owner.GetService ().post ([s] { s->Terminate (); }); + else + s->m_Owner.GetService ().post ([s] { s->Terminate ("AsyncSend failed"); }); }); } } @@ -660,8 +663,8 @@ namespace client std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1)); } else // no more data - Terminate (); - } + Terminate ("no more data"); + } } } @@ -678,14 +681,14 @@ namespace client else { auto s = shared_from_this (); - m_Owner.GetService ().post ([s] { s->Terminate (); }); + m_Owner.GetService ().post ([s] { s->Terminate ("stream read error"); }); } } else { auto s = shared_from_this (); - m_Owner.GetService ().post ([s] { s->Terminate (); }); - } + m_Owner.GetService ().post ([s] { s->Terminate ("stream read error (op aborted)"); }); + } } else { @@ -700,7 +703,7 @@ namespace client { LogPrint (eLogError, "SAM: socket write error: ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) - Terminate (); + Terminate ("socket write error at HandleWriteI2PData"); } else I2PReceive (); diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index d8a6ca1a..5a6de143 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -79,8 +79,8 @@ namespace client public: SAMSocket (SAMBridge& owner); - ~SAMSocket (); - void CloseStream (); // TODO: implement it better + ~SAMSocket (); + void CloseStream (const char* reason); // TODO: implement it better boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; }; void ReceiveHandshake (); @@ -90,6 +90,7 @@ namespace client void Terminate (); private: + void Terminate (const char* reason); void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleMessage (const boost::system::error_code& ecode, std::size_t bytes_transferred); From 5b769869d051965e205335d4dbf9dd8346fcb85a Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Thu, 2 Feb 2017 03:09:57 +0800 Subject: [PATCH 07/23] fixed qt .pro file --- qt/i2pd_qt/DaemonQT.cpp | 40 +- qt/i2pd_qt/DaemonQT.h | 10 +- qt/i2pd_qt/i2pd_qt.pro | 179 +++ qt/i2pd_qt/mainwindow.cpp | 56 +- qt/i2pd_qt/mainwindow.h | 11 +- qt/i2pd_qt/mainwindow.ui | 2383 ++++++++++++++++++++++++++++++++++++- 6 files changed, 2559 insertions(+), 120 deletions(-) diff --git a/qt/i2pd_qt/DaemonQT.cpp b/qt/i2pd_qt/DaemonQT.cpp index 585bd56c..accd69b1 100644 --- a/qt/i2pd_qt/DaemonQT.cpp +++ b/qt/i2pd_qt/DaemonQT.cpp @@ -18,23 +18,41 @@ namespace qt void Worker::startDaemon() { qDebug("Performing daemon start..."); - m_Daemon.start(); - qDebug("Daemon started."); - emit resultReady(); + //try{ + m_Daemon.start(); + qDebug("Daemon started."); + emit resultReady(false, ""); + /*}catch(std::exception ex){ + emit resultReady(true, ex.what()); + }catch(...){ + emit resultReady(true, QObject::tr("Error: unknown exception")); + }*/ } void Worker::restartDaemon() { qDebug("Performing daemon restart..."); - m_Daemon.restart(); - qDebug("Daemon restarted."); - emit resultReady(); - } + //try{ + m_Daemon.restart(); + qDebug("Daemon restarted."); + emit resultReady(false, ""); + /*}catch(std::exception ex){ + emit resultReady(true, ex.what()); + }catch(...){ + emit resultReady(true, QObject::tr("Error: unknown exception")); + }*/ + } void Worker::stopDaemon() { qDebug("Performing daemon stop..."); - m_Daemon.stop(); - qDebug("Daemon stopped."); - emit resultReady(); - } + //try{ + m_Daemon.stop(); + qDebug("Daemon stopped."); + emit resultReady(false, ""); + /*}catch(std::exception ex){ + emit resultReady(true, ex.what()); + }catch(...){ + emit resultReady(true, QObject::tr("Error: unknown exception")); + }*/ + } Controller::Controller(DaemonQTImpl& daemon): m_Daemon (daemon) diff --git a/qt/i2pd_qt/DaemonQT.h b/qt/i2pd_qt/DaemonQT.h index 98e8b4e6..fc874f34 100644 --- a/qt/i2pd_qt/DaemonQT.h +++ b/qt/i2pd_qt/DaemonQT.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace i2p { @@ -32,6 +33,7 @@ namespace qt bool isRunning(); private: void setRunning(bool running); + void showError(std::string errorMsg); private: QMutex* mutex; bool m_IsRunning; @@ -55,7 +57,7 @@ namespace qt void stopDaemon(); signals: - void resultReady(); + void resultReady(bool failed, QString failureMessage); }; class Controller : public QObject @@ -69,7 +71,11 @@ namespace qt DaemonQTImpl& m_Daemon; public slots: - void handleResults(){} + void handleResults(bool failed, QString failureMessage){ + if(failed){ + QMessageBox::critical(0, QObject::tr("Error"), failureMessage); + } + } signals: void startDaemon(); void stopDaemon(); diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 229d3f2e..54a8bbcc 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -138,3 +138,182 @@ linux:!android { QT += xml #INSTALLS += sources } + +DISTFILES += \ + ../../android/bin/classes.dex \ + ../../android/bin/I2PD.apk \ + ../../android/bin/AndroidManifest.xml \ + ../../android/AndroidManifest.xml \ + ../../libi2pd.a \ + ../../libi2pdclient.a \ + ../../i2pd \ + ../../android/bin/classes/org/purplei2p/i2pd/BuildConfig.class \ + ../../android/bin/classes/org/purplei2p/i2pd/DaemonSingleton$1.class \ + ../../android/bin/classes/org/purplei2p/i2pd/DaemonSingleton$State.class \ + ../../android/bin/classes/org/purplei2p/i2pd/DaemonSingleton$StateChangeListener.class \ + ../../android/bin/classes/org/purplei2p/i2pd/DaemonSingleton.class \ + ../../android/bin/classes/org/purplei2p/i2pd/ForegroundService$LocalBinder.class \ + ../../android/bin/classes/org/purplei2p/i2pd/ForegroundService.class \ + ../../android/bin/classes/org/purplei2p/i2pd/I2PD$1$1.class \ + ../../android/bin/classes/org/purplei2p/i2pd/I2PD$1.class \ + ../../android/bin/classes/org/purplei2p/i2pd/I2PD$2.class \ + ../../android/bin/classes/org/purplei2p/i2pd/I2PD$3$1.class \ + ../../android/bin/classes/org/purplei2p/i2pd/I2PD$3.class \ + ../../android/bin/classes/org/purplei2p/i2pd/I2PD.class \ + ../../android/bin/classes/org/purplei2p/i2pd/I2PD_JNI.class \ + ../../android/bin/classes/org/purplei2p/i2pd/NetworkStateChangeReceiver.class \ + ../../android/bin/classes/org/purplei2p/i2pd/R$attr.class \ + ../../android/bin/classes/org/purplei2p/i2pd/R$drawable.class \ + ../../android/bin/classes/org/purplei2p/i2pd/R$id.class \ + ../../android/bin/classes/org/purplei2p/i2pd/R$menu.class \ + ../../android/bin/classes/org/purplei2p/i2pd/R$string.class \ + ../../android/bin/classes/org/purplei2p/i2pd/R.class \ + ../../android/bin/dexedLibs/android-support-v4-bddf40bf5b9bc79d6d6d4419e6234206.jar \ + ../../android/libs/android-support-v4.jar \ + android/libs/android-support-v4.jar \ + ../../debian/i2pd.init \ + ../../debian/postinst \ + ../../debian/postrm \ + ../../entrypoint.sh \ + ../../contrib/certificates/family/i2p-dev.crt \ + ../../contrib/certificates/family/i2pd-dev.crt \ + ../../contrib/certificates/family/mca2-i2p.crt \ + ../../contrib/certificates/family/volatile.crt \ + ../../contrib/certificates/reseed/atomike_at_mail.i2p.crt \ + ../../contrib/certificates/reseed/backup_at_mail.i2p.crt \ + ../../contrib/certificates/reseed/bugme_at_mail.i2p.crt \ + ../../contrib/certificates/reseed/echelon_at_mail.i2p.crt \ + ../../contrib/certificates/reseed/hottuna_at_mail.i2p.crt \ + ../../contrib/certificates/reseed/meeh_at_mail.i2p.crt \ + ../../contrib/certificates/reseed/parg_at_mail.i2p.crt \ + ../../contrib/certificates/reseed/r4sas_at_mail.i2p.crt \ + ../../contrib/certificates/reseed/zmx_at_mail.i2p.crt \ + ../../contrib/certificates/router/killyourtv_at_mail.i2p.crt \ + ../../contrib/certificates/router/orignal_at_mail.i2p.crt \ + ../../contrib/certificates/router/str4d_at_mail.i2p.crt \ + ../../contrib/certificates/router/zzz_at_mail.i2p.crt \ + ../../build/fig.yml \ + ../../appveyor.yml \ + ../../android/res/menu/options_main.xml \ + ../../android/res/values/strings.xml \ + ../../android/build.xml \ + android/res/layout/splash.xml \ + android/res/values/libs.xml \ + android/res/values/strings.xml \ + android/res/values-de/strings.xml \ + android/res/values-el/strings.xml \ + android/res/values-es/strings.xml \ + android/res/values-et/strings.xml \ + android/res/values-fa/strings.xml \ + android/res/values-fr/strings.xml \ + android/res/values-id/strings.xml \ + android/res/values-it/strings.xml \ + android/res/values-ja/strings.xml \ + android/res/values-ms/strings.xml \ + android/res/values-nb/strings.xml \ + android/res/values-nl/strings.xml \ + android/res/values-pl/strings.xml \ + android/res/values-pt-rBR/strings.xml \ + android/res/values-ro/strings.xml \ + android/res/values-rs/strings.xml \ + android/res/values-ru/strings.xml \ + android/res/values-zh-rCN/strings.xml \ + android/res/values-zh-rTW/strings.xml \ + ../../android/bin/resources.ap_ \ + ../../Win32/ictoopie.bmp \ + ../../Win32/mask.bmp \ + ../../android/bin/res/crunch/drawable/icon.png \ + ../../android/bin/res/crunch/drawable/itoopie_notification_icon.png \ + ../../android/res/drawable/icon.png \ + ../../android/res/drawable/itoopie_notification_icon.png \ + ../../docs/itoopieImage.png \ + android/res/drawable/itoopie_notification_icon.png \ + android/res/drawable-hdpi/icon.png \ + ../../Win32/ictoopie.ico \ + ../../Win32/mask.ico \ + docs/patch_openssl_so_libs.html \ + ../../android/bin/jarlist.cache \ + ../../android/jni/Android.mk \ + ../../android/jni/Application.mk \ + ../../android/proguard-project.txt \ + ../../android/project.properties \ + ../../build/cmake_modules/NSIS.template.in \ + ../../build/docker/old-ubuntu-based/Dockerfile \ + ../../contrib/debian/i2pd.service \ + ../../contrib/debian/i2pd.tmpfile \ + ../../contrib/rpm/i2pd.service \ + ../../debian/patches/series \ + ../../debian/source/format \ + ../../debian/compat \ + ../../debian/control \ + ../../debian/copyright \ + ../../debian/docs \ + ../../debian/i2pd.1 \ + ../../debian/i2pd.default \ + ../../debian/i2pd.dirs \ + ../../debian/i2pd.install \ + ../../debian/i2pd.links \ + ../../debian/i2pd.manpages \ + ../../debian/i2pd.openrc \ + ../../debian/i2pd.upstart \ + ../../debian/logrotate \ + ../../debian/watch \ + ../../docs/Doxyfile \ + ../../docs/index.rst \ + ../../docs/subscriptions.txt \ + ../../docs/tunnels.conf \ + android/src/org/kde/necessitas/ministro/IMinistro.aidl \ + android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl \ + android/build.gradle \ + android/project.properties \ + ../../Win32/nsi/helper_readme.nsh \ + ../../Win32/nsi/servicelib.nsh \ + ../../Win32/i2pd.sln \ + ../../Win32/i2pd.vcxproj \ + ../../Win32/i2pd.vcxproj.filters \ + ../../Win32/inno_installer.iss \ + ../../Win32/install_service.bat \ + ../../Win32/installer.iss \ + ../../Win32/Itoopie.cmd \ + ../../Win32/PurpleI2P.nsi \ + ../../Win32/uninstall_service.bat \ + ../../Dockerfile \ + ../../filelist.mk \ + ../../LICENSE \ + ../../debian/changelog \ + ../../ChangeLog \ + ../../build/cmake_modules/FindMiniUPnPc.cmake \ + ../../build/CMakeLists.txt \ + ../../android/gen/org/purplei2p/i2pd/BuildConfig.java \ + ../../android/gen/org/purplei2p/i2pd/R.java \ + ../../android/src/org/purplei2p/i2pd/DaemonSingleton.java \ + ../../android/src/org/purplei2p/i2pd/ForegroundService.java \ + ../../android/src/org/purplei2p/i2pd/I2PD.java \ + ../../android/src/org/purplei2p/i2pd/I2PD_JNI.java \ + ../../android/src/org/purplei2p/i2pd/NetworkStateChangeReceiver.java \ + android/src/org/purplei2p/i2pd/I2PDMainActivity.java \ + android/src/org/purplei2p/i2pd/LocalService.java \ + android/src/org/qtproject/qt5/android/bindings/QtActivity.java \ + android/src/org/qtproject/qt5/android/bindings/QtApplication.java \ + ../../debian/rules \ + ../../build/docker/README.md \ + ../../docs/building/android.md \ + ../../docs/building/cross.md \ + ../../docs/building/ios.md \ + ../../docs/building/requirements.md \ + ../../docs/building/unix.md \ + ../../docs/building/windows.md \ + ../../docs/config_opts_after_2.3.0.md \ + ../../docs/configuration.md \ + ../../docs/family.md \ + ../../docs/hacking.md \ + ../../docs/usage.md \ + README.md \ + ../../README.md \ + ../../docs/i2pd.conf \ + ../../build/cmake-zlib-amd64.patch \ + ../../build/cmake-zlib-static.patch \ + ../../debian/patches/01-tune-build-opts.patch \ + ../../docs/conf.py \ + ../../contrib/debian/README \ + ../../contrib/rpm/i2pd.spec diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 4b749473..340832f0 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1,5 +1,5 @@ #include "mainwindow.h" -//#include "ui_mainwindow.h" +#include "ui_mainwindow.h" #include #include #include "RouterContext.h" @@ -8,56 +8,24 @@ #endif MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent)/*, - ui(new Ui::MainWindow)*/ + QMainWindow(parent), + ui(new Ui::MainWindow) #ifndef ANDROID ,quitting(false) #endif { - //ui->setupUi(this); - if (objectName().isEmpty()) - setObjectName(QStringLiteral("MainWindow")); + ui->setupUi(this); resize(800, 480); - centralWidget = new QWidget(this); - centralWidget->setObjectName(QStringLiteral("centralWidget")); - verticalLayoutWidget = new QWidget(centralWidget); - verticalLayoutWidget->setObjectName(QStringLiteral("verticalLayoutWidget")); - //verticalLayoutWidget->setGeometry(QRect(10, 20, 771, 441)); - verticalLayout1 = new QVBoxLayout(verticalLayoutWidget); - verticalLayout1->setSpacing(6); - verticalLayout1->setContentsMargins(11, 11, 11, 11); - verticalLayout1->setObjectName(QStringLiteral("verticalLayout1")); - verticalLayout1->setContentsMargins(0, 0, 0, 0); - quitButton = new QPushButton(verticalLayoutWidget); - quitButton->setObjectName(QStringLiteral("quitButton")); - QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - sizePolicy.setHorizontalStretch(1); - //sizePolicy.setVerticalStretch(1); - sizePolicy.setHeightForWidth(quitButton->sizePolicy().hasHeightForWidth()); - quitButton->setSizePolicy(sizePolicy); - verticalLayout1->addWidget(quitButton); - gracefulQuitButton = new QPushButton(verticalLayoutWidget); - gracefulQuitButton->setObjectName(QStringLiteral("gracefulQuitButton")); - QSizePolicy sizePolicy2(QSizePolicy::Maximum, QSizePolicy::Maximum); - sizePolicy2.setHorizontalStretch(1); - //sizePolicy2.setVerticalStretch(1); - sizePolicy2.setHeightForWidth(gracefulQuitButton->sizePolicy().hasHeightForWidth()); - gracefulQuitButton->setSizePolicy(sizePolicy2); - verticalLayout1->addWidget(gracefulQuitButton); - - setCentralWidget(centralWidget); - - setWindowTitle(QApplication::translate("MainWindow", "i2pd", 0)); - quitButton->setText(QApplication::translate("MainWindow", "Quit", 0)); - gracefulQuitButton->setText(QApplication::translate("MainWindow", "Graceful Quit", 0)); + //ui->stackedWidget->setCurrentIndex(4);//quit page + ui->stackedWidget->setCurrentIndex(1);//sett. page #ifndef ANDROID createActions(); createTrayIcon(); #endif - QObject::connect(quitButton, SIGNAL(released()), this, SLOT(handleQuitButton())); - QObject::connect(gracefulQuitButton, SIGNAL(released()), this, SLOT(handleGracefulQuitButton())); + QObject::connect(ui->fastQuitPushButton, SIGNAL(released()), this, SLOT(handleQuitButton())); + QObject::connect(ui->gracefulQuitPushButton, SIGNAL(released()), this, SLOT(handleGracefulQuitButton())); #ifndef ANDROID QObject::connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), @@ -138,10 +106,10 @@ void MainWindow::handleQuitButton() { void MainWindow::handleGracefulQuitButton() { qDebug("Graceful Quit pressed."); - gracefulQuitButton->setText(QApplication::translate("MainWindow", "Graceful quit is in progress", 0)); - gracefulQuitButton->setEnabled(false); - gracefulQuitButton->adjustSize(); - verticalLayoutWidget->adjustSize(); + ui->gracefulQuitPushButton->setText(QApplication::translate("MainWindow", "Graceful quit is in progress", 0)); + ui->gracefulQuitPushButton->setEnabled(false); + ui->gracefulQuitPushButton->adjustSize(); + ui->quitPage->adjustSize(); i2p::context.SetAcceptsTunnels (false); // stop accpting tunnels QTimer::singleShot(10*60*1000/*millis*/, this, SLOT(handleGracefulQuitTimerEvent())); } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 349eadec..5e1c0d8b 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -48,21 +48,14 @@ private: #ifndef ANDROID void createActions(); void createTrayIcon(); -#endif - - QWidget *centralWidget; - QWidget *verticalLayoutWidget; - QVBoxLayout *verticalLayout1; - QPushButton *quitButton; - QPushButton *gracefulQuitButton; - -#ifndef ANDROID bool quitting; QAction *toggleWindowVisibleAction; QSystemTrayIcon *trayIcon; QMenu *trayIconMenu; #endif + Ui::MainWindow* ui; + protected: #ifndef ANDROID void closeEvent(QCloseEvent *event); diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index d73e7743..b2382173 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -7,41 +7,2349 @@ 0 0 800 - 480 + 3200 MainWindow - + 10 - 20 - 771 - 441 + 10 + 781 + 3181 - + + + QLayout::SetMaximumSize + - - - - 0 - 0 - + + + QLayout::SetMinimumSize - - Quit - - + + + + false + + + Status + + + + + + + false + + + Settings + + + + + + + false + + + Tunnels + + + + + + + false + + + Restart + + + + + + + false + + + Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + - - - Graceful Quit - + + + + + + 10 + 0 + 661 + 491 + + + + + + + + 15 + + + + Status + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 0 + 0 + 681 + 3171 + + + + + + + + 15 + + + + Settings + + + + + + + true + + + + + 0 + 0 + 677 + 3138 + + + + + 0 + 0 + + + + + + 10 + 11 + 661 + 3121 + + + + + + + + 0 + 0 + + + + + 0 + 202 + + + + + 16777215 + 202 + + + + Router options + + + + + 0 + 20 + 661 + 185 + + + + + + + Enable communication through ipv6 + + + + + + + Router will not accept transit tunnels at startup + + + + + + + Router will be floodfill + + + + + + + + + Bandwidth limit (integer): + + + + + + + + + + KBps + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Family (name of a family router belongs to): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMaximumSize + + + + + NetID (network ID router belongs to. The main I2P ID is 2): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 46 + + + + + 16777215 + 46 + + + + Configuration file: + + + + + 0 + 18 + 661 + 31 + + + + + QLayout::SetMinimumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Pid file: + + + + + 0 + 20 + 661 + 31 + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 309 + + + + + 16777215 + 309 + + + + Socks proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 250 + 661 + 31 + + + + + + + Outproxy address: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 280 + 661 + 31 + + + + + + + Outproxy port: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Ports + + + + + + + + 0 + 22 + + + + + 16777215 + 22 + + + + Insomnia (prevent system from sleeping) + + + + + + + + 0 + 0 + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Router external address (for incoming connections) + + + Qt::AlignJustify|Qt::AlignTop + + + + + 0 + 20 + 661 + 81 + + + + + QLayout::SetMinAndMaxSize + + + + + QLayout::SetMinAndMaxSize + + + + + Host: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMinAndMaxSize + + + + + Port (leave empty to auto-assign): + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Tunnels configuration file: + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Data folder (for storage of i2pd data — RI, keys, peer profiles, …): + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 249 + + + + + 16777215 + 249 + + + + HTTP proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Windows-specific options + + + + + + + + 0 + 179 + + + + + 16777215 + 179 + + + + HTTP webconsole + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 321 + 22 + + + + Enable basic HTTP auth + + + + + + 60 + 120 + 601 + 31 + + + + + + + Username: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 60 + 150 + 601 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + General options + + + + + + + + 0 + 107 + + + + + 16777215 + 107 + + + + Logging + + + Qt::AlignJustify|Qt::AlignTop + + + + + -1 + 19 + 661 + 91 + + + + + QLayout::SetMinimumSize + + + + + QLayout::SetMaximumSize + + + + + Log file: + + + + + + + + + + Browse… + + + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + Log level: + + + + + + + + Error + + + + + Warn + + + + + Info + + + + + Debug + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 20 + 40 + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + SAM interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + BOB interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + I2CP interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 200 + + + + + 16777215 + 200 + + + + I2PControl interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + 0 + 10 + 681 + 931 + + + + + QLayout::SetMaximumSize + + + + + + 15 + + + + Tunnels + + + + + + + true + + + + + 0 + 0 + 98 + 28 + + + + + + 0 + 10 + 661 + 881 + + + + + + + + + + + + + + + 0 + 0 + 681 + 451 + + + + + + + + 15 + + + + Restart + + + + + + + Restart i2pd + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 10 + 671 + 931 + + + + + QLayout::SetMaximumSize + + + + + + 15 + + + + Quit + + + + + + + Quit Now + + + + + + + Graceful Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + @@ -50,40 +2358,7 @@ - - - quitButton - released() - MainWindow - handleQuitButton() - - - 384 - 244 - - - 373 - 419 - - - - - gracefulShutdownButton - released() - MainWindow - handleGracefulQuitButton() - - - 395 - 319 - - - 399 - 239 - - - - + handleQuitButton() handleGracefulQuitButton() From f202fb9af6bd45b8ad3498c356a595a84bd9681f Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sat, 28 Jan 2017 16:01:34 +0800 Subject: [PATCH 08/23] qt forms now work! --- qt/i2pd_qt/DaemonQT.cpp | 2 +- qt/i2pd_qt/mainwindow.cpp | 69 ++- qt/i2pd_qt/mainwindow.h | 7 + qt/i2pd_qt/mainwindow.ui | 935 +++++++++++++++++++++++++++++--------- 4 files changed, 794 insertions(+), 219 deletions(-) diff --git a/qt/i2pd_qt/DaemonQT.cpp b/qt/i2pd_qt/DaemonQT.cpp index accd69b1..c51e88e3 100644 --- a/qt/i2pd_qt/DaemonQT.cpp +++ b/qt/i2pd_qt/DaemonQT.cpp @@ -162,7 +162,7 @@ namespace qt { i2p::qt::Controller daemonQtController(daemon); qDebug("Starting the daemon..."); - emit daemonQtController.startDaemon(); + //DEBUG //emit daemonQtController.startDaemon(); //daemon.start (); qDebug("Starting GUI event loop..."); result = app.exec(); diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 340832f0..03a2f8ea 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -6,6 +6,7 @@ #ifndef ANDROID #include #endif +#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), @@ -15,17 +16,46 @@ MainWindow::MainWindow(QWidget *parent) : #endif { ui->setupUi(this); - resize(800, 480); - //ui->stackedWidget->setCurrentIndex(4);//quit page - ui->stackedWidget->setCurrentIndex(1);//sett. page + setFixedSize(width(), 480); + onResize(); + + ui->stackedWidget->setCurrentIndex(0); + ui->settingsScrollArea->resize(ui->settingsContentsGridLayout->sizeHint().width()+10,ui->settingsScrollArea->height()); + QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); + //QSize szSettContents = ui->settingsContentsGridLayout->minimumSize(); + int w = 683; + int h = 3000; + ui->settingsContents->setFixedSize(w, h); + ui->settingsContents->resize(w, h); + //ui->settingsContents->adjustSize(); + + /* + QPalette pal(palette()); + pal.setColor(QPalette::Background, Qt::red); + ui->settingsContents->setAutoFillBackground(true); + ui->settingsContents->setPalette(pal); + */ + + //ui->settingsScrollArea->adjustSize(); + ui->tunnelsScrollAreaWidgetContents->setFixedSize( + ui->tunnelsScrollArea->width() - barSett->width(), 0); #ifndef ANDROID createActions(); createTrayIcon(); #endif + QObject::connect(ui->statusPagePushButton, SIGNAL(released()), this, SLOT(showStatusPage())); + QObject::connect(ui->settingsPagePushButton, SIGNAL(released()), this, SLOT(showSettingsPage())); + + QObject::connect(ui->tunnelsPagePushButton, SIGNAL(released()), this, SLOT(showTunnelsPage())); + QObject::connect(ui->restartPagePushButton, SIGNAL(released()), this, SLOT(showRestartPage())); + QObject::connect(ui->quitPagePushButton, SIGNAL(released()), this, SLOT(showQuitPage())); + + /* QObject::connect(ui->fastQuitPushButton, SIGNAL(released()), this, SLOT(handleQuitButton())); QObject::connect(ui->gracefulQuitPushButton, SIGNAL(released()), this, SLOT(handleGracefulQuitButton())); +*/ #ifndef ANDROID QObject::connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), @@ -38,6 +68,34 @@ MainWindow::MainWindow(QWidget *parent) : //QMetaObject::connectSlotsByName(this); } +void MainWindow::showStatusPage(){ui->stackedWidget->setCurrentIndex(0);} +void MainWindow::showSettingsPage(){ui->stackedWidget->setCurrentIndex(1);} +void MainWindow::showTunnelsPage(){ui->stackedWidget->setCurrentIndex(2);} +void MainWindow::showRestartPage(){ui->stackedWidget->setCurrentIndex(3);} +void MainWindow::showQuitPage(){ui->stackedWidget->setCurrentIndex(4);} + +void MainWindow::resizeEvent(QResizeEvent *event) +{ + QMainWindow::resizeEvent(event); + onResize(); +} + +void MainWindow::onResize() +{ + if(isVisible()){ + ui->horizontalLayoutWidget->resize(ui->horizontalLayoutWidget->width(), height()); + + //status + ui->statusPage->resize(ui->statusPage->width(), height()); + + //tunnels + ui->tunnelsPage->resize(ui->tunnelsPage->width(), height()); + ui->verticalLayoutWidget_6->resize(ui->verticalLayoutWidget_6->width(), height()-20); + /*ui->tunnelsScrollArea->resize(ui->tunnelsScrollArea->width(), + ui->verticalLayoutWidget_6->height()-ui->label_5->height());*/ + } +} + #ifndef ANDROID void MainWindow::createActions() { toggleWindowVisibleAction = new QAction(tr("&Toggle the window"), this); @@ -106,12 +164,15 @@ void MainWindow::handleQuitButton() { void MainWindow::handleGracefulQuitButton() { qDebug("Graceful Quit pressed."); + /* ui->gracefulQuitPushButton->setText(QApplication::translate("MainWindow", "Graceful quit is in progress", 0)); ui->gracefulQuitPushButton->setEnabled(false); ui->gracefulQuitPushButton->adjustSize(); ui->quitPage->adjustSize(); i2p::context.SetAcceptsTunnels (false); // stop accpting tunnels - QTimer::singleShot(10*60*1000/*millis*/, this, SLOT(handleGracefulQuitTimerEvent())); + QTimer::singleShot(10*60*1000//millis + , this, SLOT(handleGracefulQuitTimerEvent())); + */ } void MainWindow::handleGracefulQuitTimerEvent() { diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 5e1c0d8b..2af82467 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -43,6 +43,11 @@ private slots: void iconActivated(QSystemTrayIcon::ActivationReason reason); void toggleVisibilitySlot(); #endif + void showStatusPage(); + void showSettingsPage(); + void showTunnelsPage(); + void showRestartPage(); + void showQuitPage(); private: #ifndef ANDROID @@ -60,6 +65,8 @@ protected: #ifndef ANDROID void closeEvent(QCloseEvent *event); #endif + void resizeEvent(QResizeEvent* event); + void onResize(); }; #endif // MAINWINDOW_H diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index b2382173..8b006b5c 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -6,26 +6,32 @@ 0 0 - 800 - 3200 + 816 + 3000 MainWindow + + + 0 + 0 + + 10 10 - 781 - 3181 + 801 + 491 - QLayout::SetMaximumSize + QLayout::SetDefaultConstraint @@ -35,7 +41,7 @@ - false + true Status @@ -45,7 +51,7 @@ - false + true Settings @@ -55,7 +61,7 @@ - false + true Tunnels @@ -65,7 +71,7 @@ - false + true Restart @@ -75,7 +81,7 @@ - false + true Quit @@ -99,17 +105,35 @@ + + + 0 + 0 + + + + + 16777215 + 516 + + + + 1 + - 10 + 0 0 - 661 + 671 491 + + QLayout::SetMinAndMaxSize + @@ -139,18 +163,27 @@ + + + 0 + 0 + + 0 0 - 681 - 3171 + 701 + 460 + + QLayout::SetMinAndMaxSize + - + 15 @@ -163,6 +196,15 @@ + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustIgnored + true @@ -171,8 +213,8 @@ 0 0 - 677 - 3138 + 684 + 427 @@ -187,10 +229,60 @@ 10 11 661 - 3121 + 3000 - + + + + + + 0 + 0 + + + + + 0 + 46 + + + + + 16777215 + 46 + + + + Configuration file: + + + + + 0 + 18 + 661 + 31 + + + + + QLayout::SetMinimumSize + + + + + + + + Browse… + + + + + + + @@ -340,97 +432,6 @@ - - - - - 0 - 0 - - - - - 0 - 46 - - - - - 16777215 - 46 - - - - Configuration file: - - - - - 0 - 18 - 661 - 31 - - - - - QLayout::SetMinimumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Pid file: - - - - - 0 - 20 - 661 - 31 - - - - - - - - - - Browse… - - - - - - - @@ -814,49 +815,6 @@ - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Ports - - - - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Insomnia (prevent system from sleeping) - - - @@ -1367,30 +1325,6 @@ - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Windows-specific options - - - @@ -1725,22 +1659,6 @@ - - - - Qt::Vertical - - - QSizePolicy::Preferred - - - - 20 - 40 - - - - @@ -2073,13 +1991,13 @@ 0 - 200 + 189 16777215 - 200 + 189 @@ -2175,6 +2093,600 @@ + + + + 0 + 100 + 661 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Certificate file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Key file: + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 108 + + + + + 16777215 + 108 + + + + Limits + + + + + 0 + 20 + 661 + 31 + + + + + + + Maximum number of transit tunnels: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Maximum number of open files (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 80 + 661 + 31 + + + + + + + Maximum size of core file in Kb (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Ports + + + + + + + + 0 + 22 + + + + + 16777215 + 22 + + + + Insomnia (prevent system from sleeping) + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Pid file: + + + + + 0 + 20 + 661 + 31 + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 44 + + + + + 16777215 + 44 + + + + Cryptography + + + + + 0 + 20 + 661 + 22 + + + + Use ElGamal precomputed tables + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Windows-specific options + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Reseeding + + + + + 0 + 20 + 661 + 22 + + + + Request SU3 signature verification + + + + + + 0 + 40 + 661 + 31 + + + + + + + SU3 file to reseed from: + + + + + + + + + + Browse… + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Reseed URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 78 + + + + + 16777215 + 78 + + + + Addressbook settings + + + + + 0 + 20 + 661 + 31 + + + + + + + Addressbook default subscription URL for initial setup: + + + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Addressbook subscriptions URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Various options + + + + + + + + 0 + 68 + + + + + 16777215 + 68 + + + + UPnP + + + + + 0 + 20 + 97 + 22 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Name i2pd appears in UPnP forwardings list: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -2190,14 +2702,14 @@ 0 - 10 + 0 681 - 931 + 460 - QLayout::SetMaximumSize + QLayout::SetMinAndMaxSize @@ -2213,6 +2725,9 @@ + + Qt::ScrollBarAlwaysOn + true @@ -2221,21 +2736,10 @@ 0 0 - 98 - 28 + 664 + 427 - - - - 0 - 10 - 661 - 881 - - - - @@ -2253,6 +2757,9 @@ + + QLayout::SetMinAndMaxSize + @@ -2299,14 +2806,14 @@ 0 - 10 + 0 671 - 931 + 480 - QLayout::SetMaximumSize + QLayout::SetMinAndMaxSize From 5df77eb474c4a86293361a75b7b7705e475b10db Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sat, 28 Jan 2017 16:26:54 +0800 Subject: [PATCH 09/23] qt forms now work even better! --- qt/i2pd_qt/mainwindow.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 8b006b5c..24a8184b 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -294,13 +294,13 @@ 0 - 202 + 215 16777215 - 202 + 215 @@ -312,7 +312,7 @@ 0 20 661 - 185 + 188 From f2b0f64138f0be96d7689ba72744845b0ae0696b Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Thu, 2 Feb 2017 03:03:09 +0800 Subject: [PATCH 10/23] tmp --- .gitignore | 9 ++++- qt/i2pd_qt/mainwindow.cpp | 75 +++++++++++++++++++++++++++++++++++++-- qt/i2pd_qt/mainwindow.ui | 8 ++--- 3 files changed, 85 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index c472d88e..5424262f 100644 --- a/.gitignore +++ b/.gitignore @@ -254,4 +254,11 @@ docs/generated build/Makefile # debian stuff -.pc/ \ No newline at end of file +.pc/ + +# qt + +qt/i2pd_qt/*.ui.autosave +qt/i2pd_qt/*.ui.bk* +qt/i2pd_qt/*.ui_* + diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 03a2f8ea..7c545a4c 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -16,6 +16,8 @@ MainWindow::MainWindow(QWidget *parent) : #endif { ui->setupUi(this); + + //TODO handle resizes and change the below into resize() call setFixedSize(width(), 480); onResize(); @@ -52,10 +54,77 @@ MainWindow::MainWindow(QWidget *parent) : QObject::connect(ui->restartPagePushButton, SIGNAL(released()), this, SLOT(showRestartPage())); QObject::connect(ui->quitPagePushButton, SIGNAL(released()), this, SLOT(showQuitPage())); - /* QObject::connect(ui->fastQuitPushButton, SIGNAL(released()), this, SLOT(handleQuitButton())); QObject::connect(ui->gracefulQuitPushButton, SIGNAL(released()), this, SLOT(handleGracefulQuitButton())); -*/ + + initFileChooser(configFileLineEdit, configFileBrowsePushButton); + initFileChooser(tunnelsConfigFileLineEdit, tunnelsConfigFileBrowsePushButton); + initFileChooser(pidFileLineEdit, pidFileBrowsePushButton); + initFileChooser(logFileLineEdit, logFileBrowsePushButton); + initFileChooser(httpProxyKeyFileLineEdit, httpProxyKeyFilePushButton); + initFileChooser(socksProxyKeyFileLineEdit, socksProxyKeyFilePushButton); + initFileChooser(i2pControlCertFileLineEdit, i2pControlCertFileBrowsePushButton); + initFileChooser(i2pControlKeyFileLineEdit, i2pControlKeyFileBrowsePushButton); + initFileChooser(reseedFileLineEdit, reseedFileBrowsePushButton); + + initFolderChooser(dataFolderLineEdit, dataFolderBrowsePushButton); + + initCombobox(logLevelComboBox); + + initIPAddressBox(routerExternalHostLineEdit, tr("Router external address -> Host")); + initTCPPortBox(routerExternalPortLineEdit, tr("Router external address -> Port")); + + initCheckBox(ipv6CheckBox); + initCheckBox(notransitCheckBox); + initCheckBox(floodfillCheckBox); + initIntegerBox(bandwidthLineEdit); + initStringBox(familyLineEdit); + initIntegerBox(netIdLineEdit); + + initCheckBox(insomniaCheckBox); + + initCheckBox(webconsoleEnabledCheckBox); + initIPAddressBox(webconsoleAddrLineEdit, tr("HTTP webconsole -> IP address")); + initTCPPortBox(webconsolePortLineEdit, tr("HTTP webconsole -> Port")); + initCheckBox(webconsoleBasicAuthCheckBox); + initStringBox(webconsoleUserNameLineEditBasicAuth); + initStringBox(webconsolePasswordLineEditBasicAuth); + + initCheckBox(httpProxyEnabledCheckBox); + initIPAddressBox(httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); + initTCPPortBox(httpProxyPortLineEdit, tr("HTTP proxy -> Port")); + initIntegerBox(httpProxyInboundTunnelsLenLineEdit); + initIntegerBox(httpProxyInboundTunnQuantityLineEdit); + initIntegerBox(httpProxyOutBoundTunnLenLineEdit); + initIntegerBox(httpProxyOutboundTunnQuantityLineEdit); + + initCheckBox(socksProxyEnabledCheckBox); + initIPAddressBox(socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); + initTCPPortBox(socksProxyPortLineEdit, tr("Socks proxy -> Port")); + initIntegerBox(socksProxyInboundTunnelsLenLineEdit); + initIntegerBox(socksProxyInboundTunnQuantityLineEdit); + initIntegerBox(socksProxyOutBoundTunnLenLineEdit); + initIntegerBox(socksProxyOutboundTunnQuantityLineEdit); + initIPAddressBox(outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); + initTCPPortBox(outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); + + initCheckBox(socksProxyEnabledCheckBox); + initIPAddressBox(socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); + initTCPPortBox(socksProxyPortLineEdit, tr("Socks proxy -> Port")); + + initCheckBox(socksProxyEnabledCheckBox); + initIPAddressBox(socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); + initTCPPortBox(socksProxyPortLineEdit, tr("Socks proxy -> Port")); + + initCheckBox(socksProxyEnabledCheckBox); + initIPAddressBox(socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); + initTCPPortBox(socksProxyPortLineEdit, tr("Socks proxy -> Port")); + + initCheckBox(socksProxyEnabledCheckBox); + initIPAddressBox(socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); + initTCPPortBox(socksProxyPortLineEdit, tr("Socks proxy -> Port")); + + loadAllConfigs(); #ifndef ANDROID QObject::connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), @@ -74,12 +143,14 @@ void MainWindow::showTunnelsPage(){ui->stackedWidget->setCurrentIndex(2);} void MainWindow::showRestartPage(){ui->stackedWidget->setCurrentIndex(3);} void MainWindow::showQuitPage(){ui->stackedWidget->setCurrentIndex(4);} +//TODO void MainWindow::resizeEvent(QResizeEvent *event) { QMainWindow::resizeEvent(event); onResize(); } +//TODO void MainWindow::onResize() { if(isVisible()){ diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 24a8184b..8bfbfe39 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -26,7 +26,7 @@ 10 10 801 - 491 + 3000 @@ -114,7 +114,7 @@ 16777215 - 516 + 3000 @@ -127,7 +127,7 @@ 0 0 671 - 491 + 3000 @@ -175,7 +175,7 @@ 0 0 701 - 460 + 3000 From 59b3daabc5fe5e5ce7df75537155f8d2ff64543e Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Thu, 2 Feb 2017 23:13:44 +0800 Subject: [PATCH 11/23] qt gui preliminary results --- qt/i2pd_qt/mainwindow.cpp | 138 +- qt/i2pd_qt/mainwindow.h | 15 + qt/i2pd_qt/mainwindow.ui | 22 +- qt/i2pd_qt/mainwindow.ui.backup_workingOK | 2873 +++++++++++++++++++++ qt/i2pd_qt/mainwindow.ui_expandedForm_old | 2873 +++++++++++++++++++++ 5 files changed, 5854 insertions(+), 67 deletions(-) create mode 100644 qt/i2pd_qt/mainwindow.ui.backup_workingOK create mode 100644 qt/i2pd_qt/mainwindow.ui_expandedForm_old diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 7c545a4c..cc4dd0b3 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -57,72 +57,88 @@ MainWindow::MainWindow(QWidget *parent) : QObject::connect(ui->fastQuitPushButton, SIGNAL(released()), this, SLOT(handleQuitButton())); QObject::connect(ui->gracefulQuitPushButton, SIGNAL(released()), this, SLOT(handleGracefulQuitButton())); - initFileChooser(configFileLineEdit, configFileBrowsePushButton); - initFileChooser(tunnelsConfigFileLineEdit, tunnelsConfigFileBrowsePushButton); - initFileChooser(pidFileLineEdit, pidFileBrowsePushButton); - initFileChooser(logFileLineEdit, logFileBrowsePushButton); - initFileChooser(httpProxyKeyFileLineEdit, httpProxyKeyFilePushButton); - initFileChooser(socksProxyKeyFileLineEdit, socksProxyKeyFilePushButton); - initFileChooser(i2pControlCertFileLineEdit, i2pControlCertFileBrowsePushButton); - initFileChooser(i2pControlKeyFileLineEdit, i2pControlKeyFileBrowsePushButton); - initFileChooser(reseedFileLineEdit, reseedFileBrowsePushButton); + initFileChooser(ui->configFileLineEdit, ui->configFileBrowsePushButton); + initFileChooser(ui->tunnelsConfigFileLineEdit, ui->tunnelsConfigFileBrowsePushButton); + initFileChooser(ui->pidFileLineEdit, ui->pidFileBrowsePushButton); + initFileChooser(ui->logFileLineEdit, ui->logFileBrowsePushButton); + initFileChooser(ui->httpProxyKeyFileLineEdit, ui->httpProxyKeyFilePushButton); + initFileChooser(ui->socksProxyKeyFileLineEdit, ui->socksProxyKeyFilePushButton); + initFileChooser(ui->i2pControlCertFileLineEdit, ui->i2pControlCertFileBrowsePushButton); + initFileChooser(ui->i2pControlKeyFileLineEdit, ui->i2pControlKeyFileBrowsePushButton); + initFileChooser(ui->reseedFileLineEdit, ui->reseedFileBrowsePushButton); - initFolderChooser(dataFolderLineEdit, dataFolderBrowsePushButton); + initFolderChooser(ui->dataFolderLineEdit, ui->dataFolderBrowsePushButton); - initCombobox(logLevelComboBox); + initCombobox(ui->logLevelComboBox); - initIPAddressBox(routerExternalHostLineEdit, tr("Router external address -> Host")); - initTCPPortBox(routerExternalPortLineEdit, tr("Router external address -> Port")); + initIPAddressBox(ui->routerExternalHostLineEdit, tr("Router external address -> Host")); + initTCPPortBox(ui->routerExternalPortLineEdit, tr("Router external address -> Port")); - initCheckBox(ipv6CheckBox); - initCheckBox(notransitCheckBox); - initCheckBox(floodfillCheckBox); - initIntegerBox(bandwidthLineEdit); - initStringBox(familyLineEdit); - initIntegerBox(netIdLineEdit); + initCheckBox(ui->ipv6CheckBox); + initCheckBox(ui->notransitCheckBox); + initCheckBox(ui->floodfillCheckBox); + initIntegerBox(ui->bandwidthLineEdit); + initStringBox(ui->familyLineEdit); + initIntegerBox(ui->netIdLineEdit); - initCheckBox(insomniaCheckBox); + initCheckBox(ui->insomniaCheckBox); - initCheckBox(webconsoleEnabledCheckBox); - initIPAddressBox(webconsoleAddrLineEdit, tr("HTTP webconsole -> IP address")); - initTCPPortBox(webconsolePortLineEdit, tr("HTTP webconsole -> Port")); - initCheckBox(webconsoleBasicAuthCheckBox); - initStringBox(webconsoleUserNameLineEditBasicAuth); - initStringBox(webconsolePasswordLineEditBasicAuth); + initCheckBox(ui->webconsoleEnabledCheckBox); + initIPAddressBox(ui->webconsoleAddrLineEdit, tr("HTTP webconsole -> IP address")); + initTCPPortBox(ui->webconsolePortLineEdit, tr("HTTP webconsole -> Port")); + initCheckBox(ui->webconsoleBasicAuthCheckBox); + initStringBox(ui->webconsoleUserNameLineEditBasicAuth); + initStringBox(ui->webconsolePasswordLineEditBasicAuth); - initCheckBox(httpProxyEnabledCheckBox); - initIPAddressBox(httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); - initTCPPortBox(httpProxyPortLineEdit, tr("HTTP proxy -> Port")); - initIntegerBox(httpProxyInboundTunnelsLenLineEdit); - initIntegerBox(httpProxyInboundTunnQuantityLineEdit); - initIntegerBox(httpProxyOutBoundTunnLenLineEdit); - initIntegerBox(httpProxyOutboundTunnQuantityLineEdit); + initCheckBox(ui->httpProxyEnabledCheckBox); + initIPAddressBox(ui->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); + initTCPPortBox(ui->httpProxyPortLineEdit, tr("HTTP proxy -> Port")); + initIntegerBox(ui->httpProxyInboundTunnelsLenLineEdit); + initIntegerBox(ui->httpProxyInboundTunnQuantityLineEdit); + initIntegerBox(ui->httpProxyOutBoundTunnLenLineEdit); + initIntegerBox(ui->httpProxyOutboundTunnQuantityLineEdit); - initCheckBox(socksProxyEnabledCheckBox); - initIPAddressBox(socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); - initTCPPortBox(socksProxyPortLineEdit, tr("Socks proxy -> Port")); - initIntegerBox(socksProxyInboundTunnelsLenLineEdit); - initIntegerBox(socksProxyInboundTunnQuantityLineEdit); - initIntegerBox(socksProxyOutBoundTunnLenLineEdit); - initIntegerBox(socksProxyOutboundTunnQuantityLineEdit); - initIPAddressBox(outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); - initTCPPortBox(outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); + initCheckBox(ui->socksProxyEnabledCheckBox); + initIPAddressBox(ui->socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); + initTCPPortBox(ui->socksProxyPortLineEdit, tr("Socks proxy -> Port")); + initIntegerBox(ui->socksProxyInboundTunnelsLenLineEdit); + initIntegerBox(ui->socksProxyInboundTunnQuantityLineEdit); + initIntegerBox(ui->socksProxyOutBoundTunnLenLineEdit); + initIntegerBox(ui->socksProxyOutboundTunnQuantityLineEdit); + initIPAddressBox(ui->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); + initTCPPortBox(ui->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); - initCheckBox(socksProxyEnabledCheckBox); - initIPAddressBox(socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); - initTCPPortBox(socksProxyPortLineEdit, tr("Socks proxy -> Port")); + initCheckBox(ui->samEnabledCheckBox); + initIPAddressBox(ui->samAddressLineEdit, tr("SAM -> IP address")); + initTCPPortBox(ui->samPortLineEdit, tr("SAM -> Port")); - initCheckBox(socksProxyEnabledCheckBox); - initIPAddressBox(socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); - initTCPPortBox(socksProxyPortLineEdit, tr("Socks proxy -> Port")); + initCheckBox(ui->bobEnabledCheckBox); + initIPAddressBox(ui->bobAddressLineEdit, tr("BOB -> IP address")); + initTCPPortBox(ui->bobPortLineEdit, tr("BOB -> Port")); - initCheckBox(socksProxyEnabledCheckBox); - initIPAddressBox(socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); - initTCPPortBox(socksProxyPortLineEdit, tr("Socks proxy -> Port")); + initCheckBox(ui->i2cpEnabledCheckBox); + initIPAddressBox(ui->i2cpAddressLineEdit, tr("I2CP -> IP address")); + initTCPPortBox(ui->i2cpPortLineEdit, tr("I2CP -> Port")); - initCheckBox(socksProxyEnabledCheckBox); - initIPAddressBox(socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); - initTCPPortBox(socksProxyPortLineEdit, tr("Socks proxy -> Port")); + initCheckBox(ui->i2pControlEnabledCheckBox); + initIPAddressBox(ui->i2pControlAddressLineEdit, tr("I2PControl -> IP address")); + initTCPPortBox(ui->i2pControlPortLineEdit, tr("I2PControl -> Port")); + initStringBox(ui->i2pControlPasswordLineEdit); + + initCheckBox(ui->enableUPnPCheckBox); + initStringBox(ui->upnpNameLineEdit); + + initCheckBox(ui->useElGamalPrecomputedTablesCheckBox); + + initCheckBox(ui->reseedVerifyCheckBox); + initStringBox(ui->reseedURLsLineEdit); + + initStringBox(ui->addressbookDefaultURLLineEdit); + initStringBox(ui->addressbookSubscriptionsURLslineEdit); + + initIntegerBox(ui->maxNumOfTransitTunnelsLineEdit); + initIntegerBox(ui->maxNumOfOpenFilesLineEdit); + initIntegerBox(ui->coreFileMaxSizeNumberLineEdit); loadAllConfigs(); @@ -235,7 +251,6 @@ void MainWindow::handleQuitButton() { void MainWindow::handleGracefulQuitButton() { qDebug("Graceful Quit pressed."); - /* ui->gracefulQuitPushButton->setText(QApplication::translate("MainWindow", "Graceful quit is in progress", 0)); ui->gracefulQuitPushButton->setEnabled(false); ui->gracefulQuitPushButton->adjustSize(); @@ -243,7 +258,6 @@ void MainWindow::handleGracefulQuitButton() { i2p::context.SetAcceptsTunnels (false); // stop accpting tunnels QTimer::singleShot(10*60*1000//millis , this, SLOT(handleGracefulQuitTimerEvent())); - */ } void MainWindow::handleGracefulQuitTimerEvent() { @@ -263,3 +277,15 @@ MainWindow::~MainWindow() //delete ui; //QMessageBox::information(0, "Debug", "mw destructor 2"); } + +void MainWindow::initFileChooser(QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton){} +void MainWindow::initFolderChooser(QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton){} +void MainWindow::initCombobox(QComboBox* comboBox){} +void MainWindow::initIPAddressBox(QLineEdit* addressLineEdit, QString fieldNameTranslated){} +void MainWindow::initTCPPortBox(QLineEdit* portLineEdit, QString fieldNameTranslated){} +void MainWindow::initCheckBox(QCheckBox* checkBox){} +void MainWindow::initIntegerBox(QLineEdit* numberLineEdit){} +void MainWindow::initStringBox(QLineEdit* lineEdit){} + +void MainWindow::loadAllConfigs(){} +void MainWindow::saveAllConfigs(){} diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 2af82467..5ef1ae22 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -12,6 +12,8 @@ #include #include #include +#include +#include #ifndef ANDROID #include #include @@ -67,6 +69,19 @@ protected: #endif void resizeEvent(QResizeEvent* event); void onResize(); + + void initFileChooser(QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton); + void initFolderChooser(QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton); + void initCombobox(QComboBox* comboBox); + void initIPAddressBox(QLineEdit* addressLineEdit, QString fieldNameTranslated); + void initTCPPortBox(QLineEdit* portLineEdit, QString fieldNameTranslated); + void initCheckBox(QCheckBox* checkBox); + void initIntegerBox(QLineEdit* numberLineEdit); + void initStringBox(QLineEdit* lineEdit); + + void loadAllConfigs(); + void saveAllConfigs(); + }; #endif // MAINWINDOW_H diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 8bfbfe39..825fb0e6 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -26,7 +26,7 @@ 10 10 801 - 3000 + 491 @@ -114,7 +114,7 @@ 16777215 - 3000 + 516 @@ -127,7 +127,7 @@ 0 0 671 - 3000 + 491 @@ -175,7 +175,7 @@ 0 0 701 - 3000 + 460 @@ -213,8 +213,8 @@ 0 0 - 684 - 427 + 683 + 426 @@ -2223,7 +2223,7 @@ - + @@ -2258,7 +2258,7 @@ - + @@ -2293,7 +2293,7 @@ - + @@ -2736,8 +2736,8 @@ 0 0 - 664 - 427 + 84 + 28 diff --git a/qt/i2pd_qt/mainwindow.ui.backup_workingOK b/qt/i2pd_qt/mainwindow.ui.backup_workingOK new file mode 100644 index 00000000..825fb0e6 --- /dev/null +++ b/qt/i2pd_qt/mainwindow.ui.backup_workingOK @@ -0,0 +1,2873 @@ + + + MainWindow + + + + 0 + 0 + 816 + 3000 + + + + MainWindow + + + + + 0 + 0 + + + + + + 10 + 10 + 801 + 491 + + + + + QLayout::SetDefaultConstraint + + + + + QLayout::SetMinimumSize + + + + + true + + + Status + + + + + + + true + + + Settings + + + + + + + true + + + Tunnels + + + + + + + true + + + Restart + + + + + + + true + + + Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 516 + + + + 1 + + + + + + 0 + 0 + 671 + 491 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Status + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 0 + 701 + 460 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Settings + + + + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustIgnored + + + true + + + + + 0 + 0 + 683 + 426 + + + + + 0 + 0 + + + + + + 10 + 11 + 661 + 3000 + + + + + + + + 0 + 0 + + + + + 0 + 46 + + + + + 16777215 + 46 + + + + Configuration file: + + + + + 0 + 18 + 661 + 31 + + + + + QLayout::SetMinimumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 0 + + + + + 0 + 215 + + + + + 16777215 + 215 + + + + Router options + + + + + 0 + 20 + 661 + 188 + + + + + + + Enable communication through ipv6 + + + + + + + Router will not accept transit tunnels at startup + + + + + + + Router will be floodfill + + + + + + + + + Bandwidth limit (integer): + + + + + + + + + + KBps + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Family (name of a family router belongs to): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMaximumSize + + + + + NetID (network ID router belongs to. The main I2P ID is 2): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 309 + + + + + 16777215 + 309 + + + + Socks proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 250 + 661 + 31 + + + + + + + Outproxy address: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 280 + 661 + 31 + + + + + + + Outproxy port: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Router external address (for incoming connections) + + + Qt::AlignJustify|Qt::AlignTop + + + + + 0 + 20 + 661 + 81 + + + + + QLayout::SetMinAndMaxSize + + + + + QLayout::SetMinAndMaxSize + + + + + Host: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMinAndMaxSize + + + + + Port (leave empty to auto-assign): + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Tunnels configuration file: + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Data folder (for storage of i2pd data — RI, keys, peer profiles, …): + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 249 + + + + + 16777215 + 249 + + + + HTTP proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 179 + + + + + 16777215 + 179 + + + + HTTP webconsole + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 321 + 22 + + + + Enable basic HTTP auth + + + + + + 60 + 120 + 601 + 31 + + + + + + + Username: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 60 + 150 + 601 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + General options + + + + + + + + 0 + 107 + + + + + 16777215 + 107 + + + + Logging + + + Qt::AlignJustify|Qt::AlignTop + + + + + -1 + 19 + 661 + 91 + + + + + QLayout::SetMinimumSize + + + + + QLayout::SetMaximumSize + + + + + Log file: + + + + + + + + + + Browse… + + + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + Log level: + + + + + + + + Error + + + + + Warn + + + + + Info + + + + + Debug + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + SAM interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + BOB interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + I2CP interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 189 + + + + + 16777215 + 189 + + + + I2PControl interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Certificate file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Key file: + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 108 + + + + + 16777215 + 108 + + + + Limits + + + + + 0 + 20 + 661 + 31 + + + + + + + Maximum number of transit tunnels: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Maximum number of open files (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 80 + 661 + 31 + + + + + + + Maximum size of core file in Kb (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Ports + + + + + + + + 0 + 22 + + + + + 16777215 + 22 + + + + Insomnia (prevent system from sleeping) + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Pid file: + + + + + 0 + 20 + 661 + 31 + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 44 + + + + + 16777215 + 44 + + + + Cryptography + + + + + 0 + 20 + 661 + 22 + + + + Use ElGamal precomputed tables + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Windows-specific options + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Reseeding + + + + + 0 + 20 + 661 + 22 + + + + Request SU3 signature verification + + + + + + 0 + 40 + 661 + 31 + + + + + + + SU3 file to reseed from: + + + + + + + + + + Browse… + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Reseed URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 78 + + + + + 16777215 + 78 + + + + Addressbook settings + + + + + 0 + 20 + 661 + 31 + + + + + + + Addressbook default subscription URL for initial setup: + + + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Addressbook subscriptions URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Various options + + + + + + + + 0 + 68 + + + + + 16777215 + 68 + + + + UPnP + + + + + 0 + 20 + 97 + 22 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Name i2pd appears in UPnP forwardings list: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 681 + 460 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Tunnels + + + + + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 84 + 28 + + + + + + + + + + + + + 0 + 0 + 681 + 451 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Restart + + + + + + + Restart i2pd + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 0 + 671 + 480 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Quit + + + + + + + Quit Now + + + + + + + Graceful Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + handleQuitButton() + handleGracefulQuitButton() + + diff --git a/qt/i2pd_qt/mainwindow.ui_expandedForm_old b/qt/i2pd_qt/mainwindow.ui_expandedForm_old new file mode 100644 index 00000000..feb3b738 --- /dev/null +++ b/qt/i2pd_qt/mainwindow.ui_expandedForm_old @@ -0,0 +1,2873 @@ + + + MainWindow + + + + 0 + 0 + 816 + 5000 + + + + MainWindow + + + + + 0 + 0 + + + + + + 10 + 10 + 801 + 5000 + + + + + QLayout::SetDefaultConstraint + + + + + QLayout::SetMinimumSize + + + + + true + + + Status + + + + + + + true + + + Settings + + + + + + + true + + + Tunnels + + + + + + + true + + + Restart + + + + + + + true + + + Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 5000 + + + + 1 + + + + + + 0 + 0 + 671 + 5000 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Status + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 0 + 701 + 5000 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Settings + + + + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustIgnored + + + true + + + + + 0 + 0 + 684 + 427 + + + + + 0 + 0 + + + + + + 10 + 11 + 661 + 5000 + + + + + + + + 0 + 0 + + + + + 0 + 46 + + + + + 16777215 + 46 + + + + Configuration file: + + + + + 0 + 18 + 661 + 31 + + + + + QLayout::SetMinimumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 0 + + + + + 0 + 215 + + + + + 16777215 + 215 + + + + Router options + + + + + 0 + 20 + 661 + 188 + + + + + + + Enable communication through ipv6 + + + + + + + Router will not accept transit tunnels at startup + + + + + + + Router will be floodfill + + + + + + + + + Bandwidth limit (integer): + + + + + + + + + + KBps + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Family (name of a family router belongs to): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMaximumSize + + + + + NetID (network ID router belongs to. The main I2P ID is 2): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 309 + + + + + 16777215 + 309 + + + + Socks proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 250 + 661 + 31 + + + + + + + Outproxy address: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 280 + 661 + 31 + + + + + + + Outproxy port: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Router external address (for incoming connections) + + + Qt::AlignJustify|Qt::AlignTop + + + + + 0 + 20 + 661 + 81 + + + + + QLayout::SetMinAndMaxSize + + + + + QLayout::SetMinAndMaxSize + + + + + Host: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMinAndMaxSize + + + + + Port (leave empty to auto-assign): + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Tunnels configuration file: + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Data folder (for storage of i2pd data — RI, keys, peer profiles, …): + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 249 + + + + + 16777215 + 249 + + + + HTTP proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 179 + + + + + 16777215 + 179 + + + + HTTP webconsole + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 321 + 22 + + + + Enable basic HTTP auth + + + + + + 60 + 120 + 601 + 31 + + + + + + + Username: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 60 + 150 + 601 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + General options + + + + + + + + 0 + 107 + + + + + 16777215 + 107 + + + + Logging + + + Qt::AlignJustify|Qt::AlignTop + + + + + -1 + 19 + 661 + 91 + + + + + QLayout::SetMinimumSize + + + + + QLayout::SetMaximumSize + + + + + Log file: + + + + + + + + + + Browse… + + + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + Log level: + + + + + + + + Error + + + + + Warn + + + + + Info + + + + + Debug + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + SAM interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + BOB interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + I2CP interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 189 + + + + + 16777215 + 189 + + + + I2PControl interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Certificate file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Key file: + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 108 + + + + + 16777215 + 108 + + + + Limits + + + + + 0 + 20 + 661 + 31 + + + + + + + Maximum number of transit tunnels: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Maximum number of open files (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 80 + 661 + 31 + + + + + + + Maximum size of core file in Kb (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Ports + + + + + + + + 0 + 22 + + + + + 16777215 + 22 + + + + Insomnia (prevent system from sleeping) + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Pid file: + + + + + 0 + 20 + 661 + 31 + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 44 + + + + + 16777215 + 44 + + + + Cryptography + + + + + 0 + 20 + 661 + 22 + + + + Use ElGamal precomputed tables + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Windows-specific options + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Reseeding + + + + + 0 + 20 + 661 + 22 + + + + Request SU3 signature verification + + + + + + 0 + 40 + 661 + 31 + + + + + + + SU3 file to reseed from: + + + + + + + + + + Browse… + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Reseed URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 78 + + + + + 16777215 + 78 + + + + Addressbook settings + + + + + 0 + 20 + 661 + 31 + + + + + + + Addressbook default subscription URL for initial setup: + + + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Addressbook subscriptions URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Various options + + + + + + + + 0 + 68 + + + + + 16777215 + 68 + + + + UPnP + + + + + 0 + 20 + 97 + 22 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Name i2pd appears in UPnP forwardings list: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 681 + 460 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Tunnels + + + + + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 664 + 427 + + + + + + + + + + + + + 0 + 0 + 681 + 451 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Restart + + + + + + + Restart i2pd + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 0 + 671 + 480 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Quit + + + + + + + Quit Now + + + + + + + Graceful Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + handleQuitButton() + handleGracefulQuitButton() + + From 9925e2732ac337579fe0307e53c21de58688267b Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 24 Feb 2017 16:30:47 +0800 Subject: [PATCH 12/23] rework + now restarts after app kill event --- android/res/values/strings.xml | 2 + .../org/purplei2p/i2pd/DaemonSingleton.java | 98 ++++++++++--------- .../org/purplei2p/i2pd/ForegroundService.java | 20 +++- android/src/org/purplei2p/i2pd/I2PD.java | 26 ++--- 4 files changed, 81 insertions(+), 65 deletions(-) diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index 8c78e88b..0b8bef38 100755 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -2,6 +2,8 @@ i2pd i2pd started + i2pd service started + i2pd service stopped Quit Graceful Quit Graceful quit is already in progress diff --git a/android/src/org/purplei2p/i2pd/DaemonSingleton.java b/android/src/org/purplei2p/i2pd/DaemonSingleton.java index 5e0ac4d0..e1ebc269 100644 --- a/android/src/org/purplei2p/i2pd/DaemonSingleton.java +++ b/android/src/org/purplei2p/i2pd/DaemonSingleton.java @@ -8,20 +8,20 @@ import android.util.Log; public class DaemonSingleton { private static final String TAG="i2pd"; private static final DaemonSingleton instance = new DaemonSingleton(); - public static interface StateChangeListener { void daemonStateChanged(); } - private final Set stateChangeListeners = new HashSet(); + public static interface StateUpdateListener { void daemonStateUpdate(); } + private final Set stateUpdateListeners = new HashSet(); public static DaemonSingleton getInstance() { return instance; } - public synchronized void addStateChangeListener(StateChangeListener listener) { stateChangeListeners.add(listener); } - public synchronized void removeStateChangeListener(StateChangeListener listener) { stateChangeListeners.remove(listener); } + public synchronized void addStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.add(listener); } + public synchronized void removeStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.remove(listener); } public synchronized void stopAcceptingTunnels() { if(isStartedOkay()){ state=State.gracefulShutdownInProgress; - fireStateChange(); + fireStateUpdate(); I2PD_JNI.stopAcceptingTunnels(); } } @@ -32,61 +32,63 @@ public class DaemonSingleton { private boolean startedOkay; - public static enum State {starting,jniLibraryLoaded,startedOkay,startFailed,gracefulShutdownInProgress}; + public static enum State {uninitialized,starting,jniLibraryLoaded,startedOkay,startFailed,gracefulShutdownInProgress}; - private State state = State.starting; + private State state = State.uninitialized; public State getState() { return state; } - { - synchronized(this){ - fireStateChange(); - new Thread(new Runnable(){ - - @Override - public void run() { - try { - I2PD_JNI.loadLibraries(); - synchronized (DaemonSingleton.this) { - state = State.jniLibraryLoaded; - fireStateChange(); - } - } catch (Throwable tr) { - lastThrowable=tr; - synchronized (DaemonSingleton.this) { - state = State.startFailed; - fireStateChange(); - } - return; + public synchronized void start() { + if(state != State.uninitialized)return; + state = State.starting; + fireStateUpdate(); + new Thread(new Runnable(){ + + @Override + public void run() { + try { + I2PD_JNI.loadLibraries(); + synchronized (DaemonSingleton.this) { + state = State.jniLibraryLoaded; + fireStateUpdate(); } - try { - synchronized (DaemonSingleton.this) { - daemonStartResult = I2PD_JNI.startDaemon(); - if("ok".equals(daemonStartResult)){state=State.startedOkay;setStartedOkay(true);} - else state=State.startFailed; - fireStateChange(); - } - } catch (Throwable tr) { - lastThrowable=tr; - synchronized (DaemonSingleton.this) { - state = State.startFailed; - fireStateChange(); - } - return; - } + } catch (Throwable tr) { + lastThrowable=tr; + synchronized (DaemonSingleton.this) { + state = State.startFailed; + fireStateUpdate(); + } + return; } - - }, "i2pdDaemonStart").start(); - } + try { + synchronized (DaemonSingleton.this) { + daemonStartResult = I2PD_JNI.startDaemon(); + if("ok".equals(daemonStartResult)){ + state=State.startedOkay; + setStartedOkay(true); + }else state=State.startFailed; + fireStateUpdate(); + } + } catch (Throwable tr) { + lastThrowable=tr; + synchronized (DaemonSingleton.this) { + state = State.startFailed; + fireStateUpdate(); + } + return; + } + } + + }, "i2pdDaemonStart").start(); } private Throwable lastThrowable; private String daemonStartResult="N/A"; - private synchronized void fireStateChange() { + private synchronized void fireStateUpdate() { Log.i(TAG, "daemon state change: "+state); - for(StateChangeListener listener : stateChangeListeners) { + for(StateUpdateListener listener : stateUpdateListeners) { try { - listener.daemonStateChanged(); + listener.daemonStateUpdate(); } catch (Throwable tr) { Log.e(TAG, "exception in listener ignored", tr); } diff --git a/android/src/org/purplei2p/i2pd/ForegroundService.java b/android/src/org/purplei2p/i2pd/ForegroundService.java index 16155651..d25d0a88 100644 --- a/android/src/org/purplei2p/i2pd/ForegroundService.java +++ b/android/src/org/purplei2p/i2pd/ForegroundService.java @@ -1,15 +1,17 @@ package org.purplei2p.i2pd; import android.app.Notification; +import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; +import android.widget.Toast; public class ForegroundService extends Service { -// private NotificationManager mNM; + private NotificationManager notificationManager; // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. @@ -28,26 +30,31 @@ public class ForegroundService extends Service { @Override public void onCreate() { -// mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); + notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); // Display a notification about us starting. We put an icon in the status bar. showNotification(); + daemon.start(); + // Tell the user we started. + Toast.makeText(this, R.string.i2pd_service_started, Toast.LENGTH_SHORT).show(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("ForegroundService", "Received start id " + startId + ": " + intent); - return START_NOT_STICKY; + daemon.start(); + return START_STICKY; } @Override public void onDestroy() { // Cancel the persistent notification. - //mNM.cancel(NOTIFICATION); + notificationManager.cancel(NOTIFICATION); + stopForeground(true); // Tell the user we stopped. - //Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); + Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show(); } @Override @@ -84,4 +91,7 @@ public class ForegroundService extends Service { //mNM.notify(NOTIFICATION, notification); startForeground(NOTIFICATION, notification); } + + private final DaemonSingleton daemon = DaemonSingleton.getInstance(); } + diff --git a/android/src/org/purplei2p/i2pd/I2PD.java b/android/src/org/purplei2p/i2pd/I2PD.java index 0397cf03..86b877ac 100755 --- a/android/src/org/purplei2p/i2pd/I2PD.java +++ b/android/src/org/purplei2p/i2pd/I2PD.java @@ -22,12 +22,16 @@ import android.widget.Toast; public class I2PD extends Activity { private static final String TAG = "i2pd"; - private DaemonSingleton daemon = DaemonSingleton.getInstance(); - private DaemonSingleton.StateChangeListener daemonStateChangeListener = - new DaemonSingleton.StateChangeListener() { + + private TextView textView; + + private final DaemonSingleton daemon = DaemonSingleton.getInstance(); + + private DaemonSingleton.StateUpdateListener daemonStateUpdatedListener = + new DaemonSingleton.StateUpdateListener() { @Override - public void daemonStateChanged() { + public void daemonStateUpdate() { runOnUiThread(new Runnable(){ @Override @@ -50,19 +54,17 @@ public class I2PD extends Activity { } }; - private TextView textView; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - //set the app be foreground (do not unload when RAM needed) - doBindService(); - textView = new TextView(this); setContentView(textView); - daemonStateChangeListener.daemonStateChanged(); - daemon.addStateChangeListener(daemonStateChangeListener); + DaemonSingleton.getInstance().addStateChangeListener(daemonStateUpdatedListener); + daemonStateUpdatedListener.daemonStateUpdate(); + + //set the app be foreground + doBindService(); } @Override @@ -73,7 +75,7 @@ public class I2PD extends Activity { private void localDestroy() { textView = null; - daemon.removeStateChangeListener(daemonStateChangeListener); + DaemonSingleton.getInstance().removeStateChangeListener(daemonStateUpdatedListener); Timer gracefulQuitTimer = getGracefulQuitTimer(); if(gracefulQuitTimer!=null) { gracefulQuitTimer.cancel(); From 275da075e0ec732bc5a8de0c31350b3d7a79f801 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Tue, 14 Mar 2017 20:34:01 +0800 Subject: [PATCH 13/23] various qt work --- libi2pd/Config.cpp | 14 + libi2pd/Config.h | 3 + qt/i2pd_qt/ClientTunnelPane.cpp | 22 + qt/i2pd_qt/ClientTunnelPane.h | 21 + qt/i2pd_qt/MainWindowItems.cpp | 2 + qt/i2pd_qt/MainWindowItems.h | 17 + qt/i2pd_qt/ServerTunnelPane.cpp | 239 ++ qt/i2pd_qt/ServerTunnelPane.h | 110 + qt/i2pd_qt/TunnelConfig.cpp | 2 + qt/i2pd_qt/TunnelConfig.h | 221 ++ qt/i2pd_qt/TunnelPane.cpp | 149 + qt/i2pd_qt/TunnelPane.h | 94 + qt/i2pd_qt/i2pd_qt.pro | 5 +- qt/i2pd_qt/mainwindow.cpp | 459 ++- qt/i2pd_qt/mainwindow.h | 510 ++- qt/i2pd_qt/mainwindow.ui | 3372 +++++++++-------- ...dForm_old => mainwindow.ui.bk_26_feb_2017} | 26 +- qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn2 | 2964 +++++++++++++++ qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn3 | 3161 +++++++++++++++ qt/i2pd_qt/mainwindow.ui_expandedForm_old4 | 3231 ++++++++++++++++ qt/i2pd_qt/tunnelform.ui | 104 + 21 files changed, 13078 insertions(+), 1648 deletions(-) create mode 100644 qt/i2pd_qt/ClientTunnelPane.cpp create mode 100644 qt/i2pd_qt/ClientTunnelPane.h create mode 100644 qt/i2pd_qt/MainWindowItems.cpp create mode 100644 qt/i2pd_qt/MainWindowItems.h create mode 100644 qt/i2pd_qt/ServerTunnelPane.cpp create mode 100644 qt/i2pd_qt/ServerTunnelPane.h create mode 100644 qt/i2pd_qt/TunnelConfig.cpp create mode 100644 qt/i2pd_qt/TunnelConfig.h create mode 100644 qt/i2pd_qt/TunnelPane.cpp create mode 100644 qt/i2pd_qt/TunnelPane.h rename qt/i2pd_qt/{mainwindow.ui_expandedForm_old => mainwindow.ui.bk_26_feb_2017} (99%) create mode 100644 qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn2 create mode 100644 qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn3 create mode 100644 qt/i2pd_qt/mainwindow.ui_expandedForm_old4 create mode 100644 qt/i2pd_qt/tunnelform.ui diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 309c0e9c..a0ec3e69 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -301,5 +301,19 @@ namespace config { return true; return false; } + + bool GetOptionAsAny(const char *name, boost::any& value) { + if (!m_Options.count(name)) + return false; + value = m_Options[name]; + return true; + } + + bool GetOptionAsAny(const std::string& name, boost::any& value) + { + return GetOptionAsAny (name.c_str (), value); + } + } // namespace config } // namespace i2p + diff --git a/libi2pd/Config.h b/libi2pd/Config.h index 1895da55..754618d7 100644 --- a/libi2pd/Config.h +++ b/libi2pd/Config.h @@ -84,6 +84,9 @@ namespace config { return GetOption (name.c_str (), value); } + bool GetOptionAsAny(const char *name, boost::any& value); + bool GetOptionAsAny(const std::string& name, boost::any& value); + /** * @brief Set value of given parameter * @param name Name of settable parameter diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp new file mode 100644 index 00000000..92c7bb5f --- /dev/null +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -0,0 +1,22 @@ +#include "ClientTunnelPane.h" + +ClientTunnelPane::ClientTunnelPane() +{ + +} + +void ClientTunnelPane::deleteClientTunnelForm(QGridLayout *tunnelsFormGridLayout) { + throw "TODO"; + /*TODO + tunnelsFormGridLayout->removeWidget(clientTunnelNameGroupBox); + + clientTunnelNameGroupBox->deleteLater(); + clientTunnelNameGroupBox=nullptr; + + gridLayoutWidget_2->deleteLater(); + gridLayoutWidget_2=nullptr; + */ +} + +ServerTunnelPane* ClientTunnelPane::asServerTunnelPane(){return nullptr;} +ClientTunnelPane* ClientTunnelPane::asClientTunnelPane(){return this;} diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h new file mode 100644 index 00000000..d4486540 --- /dev/null +++ b/qt/i2pd_qt/ClientTunnelPane.h @@ -0,0 +1,21 @@ +#ifndef CLIENTTUNNELPANE_H +#define CLIENTTUNNELPANE_H + +#include "QGridLayout" + +#include "TunnelPane.h" + +class ServerTunnelPane; +class TunnelPane; + +class ClientTunnelPane : public TunnelPane { +public: + ClientTunnelPane(); + virtual ServerTunnelPane* asServerTunnelPane(); + virtual ClientTunnelPane* asClientTunnelPane(); + void deleteClientTunnelForm(QGridLayout *tunnelsFormGridLayout); +protected slots: + virtual void setGroupBoxTitle(const QString & title){}//TODO +}; + +#endif // CLIENTTUNNELPANE_H diff --git a/qt/i2pd_qt/MainWindowItems.cpp b/qt/i2pd_qt/MainWindowItems.cpp new file mode 100644 index 00000000..c1e1ab0a --- /dev/null +++ b/qt/i2pd_qt/MainWindowItems.cpp @@ -0,0 +1,2 @@ +#include "MainWindowItems.h" + diff --git a/qt/i2pd_qt/MainWindowItems.h b/qt/i2pd_qt/MainWindowItems.h new file mode 100644 index 00000000..a4be5fe0 --- /dev/null +++ b/qt/i2pd_qt/MainWindowItems.h @@ -0,0 +1,17 @@ +#ifndef MAINWINDOWITEMS_H +#define MAINWINDOWITEMS_H + +#include +#include +#include +#include +#include + +#include +#include + +#include "mainwindow.h" + +class MainWindow; + +#endif // MAINWINDOWITEMS_H diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp new file mode 100644 index 00000000..c9b09e7e --- /dev/null +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -0,0 +1,239 @@ +#include "ServerTunnelPane.h" +#include "../../ClientContext.h" + +ServerTunnelPane::ServerTunnelPane(): TunnelPane() {} + +void ServerTunnelPane::setGroupBoxTitle(const QString & title) { + serverTunnelNameGroupBox->setTitle(title); +} + +void ServerTunnelPane::appendServerTunnelForm( + ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout) { + + tunnelsFormGridLayoutWidget->resize(527, 452); + + ServerTunnelPane& ui = *this; + + serverTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget); + serverTunnelNameGroupBox->setObjectName(QStringLiteral("serverTunnelNameGroupBox")); + + //tunnel + ui.gridLayoutWidget_2 = new QWidget(serverTunnelNameGroupBox); + + QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2); + tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox")); + tunnelTypeComboBox->addItem("Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER); + tunnelTypeComboBox->addItem("HTTP", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP); + tunnelTypeComboBox->addItem("IRC", i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC); + tunnelTypeComboBox->addItem("UDP Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER); + + gridLayoutWidget_2->setGeometry(QRect(0, 10, 561, 18*40+10)); + + setupTunnelPane(tunnelConfig, + serverTunnelNameGroupBox, + gridLayoutWidget_2, tunnelTypeComboBox, + tunnelsFormGridLayoutWidget, tunnelsFormGridLayout); + + { + const QString& type = tunnelConfig->getType(); + int index=0; + if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER)tunnelTypeComboBox->setCurrentIndex(index); + ++index; + if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP)tunnelTypeComboBox->setCurrentIndex(index); + ++index; + if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC)tunnelTypeComboBox->setCurrentIndex(index); + ++index; + if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER)tunnelTypeComboBox->setCurrentIndex(index); + ++index; + } + + //host + ui.horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.hostLabel = new QLabel(gridLayoutWidget_2); + hostLabel->setObjectName(QStringLiteral("hostLabel")); + horizontalLayout_2->addWidget(hostLabel); + ui.hostLineEdit = new QLineEdit(gridLayoutWidget_2); + hostLineEdit->setObjectName(QStringLiteral("hostLineEdit")); + hostLineEdit->setText(tunnelConfig->gethost().c_str()); + horizontalLayout_2->addWidget(hostLineEdit); + ui.hostHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(hostHorizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, 2, 0, 1, 1); + + int gridIndex = 2; + { + int port = tunnelConfig->getport(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.portLabel = new QLabel(gridLayoutWidget_2); + portLabel->setObjectName(QStringLiteral("portLabel")); + horizontalLayout_2->addWidget(portLabel); + ui.portLineEdit = new QLineEdit(gridLayoutWidget_2); + portLineEdit->setObjectName(QStringLiteral("portLineEdit")); + portLineEdit->setText(QString::number(port)); + portLineEdit->setMaximumWidth(80); + horizontalLayout_2->addWidget(portLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + std::string keys = tunnelConfig->getkeys(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.keysLabel = new QLabel(gridLayoutWidget_2); + keysLabel->setObjectName(QStringLiteral("keysLabel")); + horizontalLayout_2->addWidget(keysLabel); + ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2); + keysLineEdit->setObjectName(QStringLiteral("keysLineEdit")); + keysLineEdit->setText(keys.c_str()); + horizontalLayout_2->addWidget(keysLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + int inPort = tunnelConfig->getinPort(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.inPortLabel = new QLabel(gridLayoutWidget_2); + inPortLabel->setObjectName(QStringLiteral("inPortLabel")); + horizontalLayout_2->addWidget(inPortLabel); + ui.inPortLineEdit = new QLineEdit(gridLayoutWidget_2); + inPortLineEdit->setObjectName(QStringLiteral("inPortLineEdit")); + inPortLineEdit->setText(QString::number(inPort)); + inPortLineEdit->setMaximumWidth(80); + horizontalLayout_2->addWidget(inPortLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + std::string accessList = tunnelConfig->getaccessList(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.accessListLabel = new QLabel(gridLayoutWidget_2); + accessListLabel->setObjectName(QStringLiteral("accessListLabel")); + horizontalLayout_2->addWidget(accessListLabel); + ui.accessListLineEdit = new QLineEdit(gridLayoutWidget_2); + accessListLineEdit->setObjectName(QStringLiteral("accessListLineEdit")); + accessListLineEdit->setText(accessList.c_str()); + horizontalLayout_2->addWidget(accessListLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + std::string hostOverride = tunnelConfig->gethostOverride(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.hostOverrideLabel = new QLabel(gridLayoutWidget_2); + hostOverrideLabel->setObjectName(QStringLiteral("hostOverrideLabel")); + horizontalLayout_2->addWidget(hostOverrideLabel); + ui.hostOverrideLineEdit = new QLineEdit(gridLayoutWidget_2); + hostOverrideLineEdit->setObjectName(QStringLiteral("hostOverrideLineEdit")); + hostOverrideLineEdit->setText(hostOverride.c_str()); + horizontalLayout_2->addWidget(hostOverrideLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + std::string webIRCPass = tunnelConfig->getwebircpass(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.webIRCPassLabel = new QLabel(gridLayoutWidget_2); + webIRCPassLabel->setObjectName(QStringLiteral("webIRCPassLabel")); + horizontalLayout_2->addWidget(webIRCPassLabel); + ui.webIRCPassLineEdit = new QLineEdit(gridLayoutWidget_2); + webIRCPassLineEdit->setObjectName(QStringLiteral("webIRCPassLineEdit")); + webIRCPassLineEdit->setText(webIRCPass.c_str()); + horizontalLayout_2->addWidget(webIRCPassLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + bool gzip = tunnelConfig->getgzip(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.gzipCheckBox = new QCheckBox(gridLayoutWidget_2); + gzipCheckBox->setObjectName(QStringLiteral("gzipCheckBox")); + gzipCheckBox->setChecked(gzip); + horizontalLayout_2->addWidget(gzipCheckBox); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); + //combo box + //TODO sigtype + } + { + uint32_t maxConns = tunnelConfig->getmaxConns(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.maxConnsLabel = new QLabel(gridLayoutWidget_2); + maxConnsLabel->setObjectName(QStringLiteral("maxConnsLabel")); + horizontalLayout_2->addWidget(maxConnsLabel); + ui.maxConnsLineEdit = new QLineEdit(gridLayoutWidget_2); + maxConnsLineEdit->setObjectName(QStringLiteral("maxConnsLineEdit")); + maxConnsLineEdit->setText(QString::number(maxConns)); + maxConnsLineEdit->setMaximumWidth(80); + horizontalLayout_2->addWidget(maxConnsLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + std::string address = tunnelConfig->getaddress(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.addressLabel = new QLabel(gridLayoutWidget_2); + addressLabel->setObjectName(QStringLiteral("addressLabel")); + horizontalLayout_2->addWidget(addressLabel); + ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2); + addressLineEdit->setObjectName(QStringLiteral("addressLineEdit")); + addressLineEdit->setText(address.c_str()); + horizontalLayout_2->addWidget(addressLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + bool isUniqueLocal = tunnelConfig->getisUniqueLocal(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.isUniqueLocalCheckBox = new QCheckBox(gridLayoutWidget_2); + isUniqueLocalCheckBox->setObjectName(QStringLiteral("isUniqueLocalCheckBox")); + isUniqueLocalCheckBox->setChecked(isUniqueLocal); + horizontalLayout_2->addWidget(isUniqueLocalCheckBox); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); + appendControlsForI2CPParameters(i2cpParameters, gridIndex); + } + + tunnelsFormGridLayout->addWidget(serverTunnelNameGroupBox, 0, 0, 1, 1); + + retranslateServerTunnelForm(ui); +} + +void ServerTunnelPane::deleteServerTunnelForm(QGridLayout *tunnelsFormGridLayout) { + tunnelsFormGridLayout->removeWidget(tunnelGroupBox); + + tunnelGroupBox->deleteLater(); + tunnelGroupBox=nullptr; + + gridLayoutWidget_2->deleteLater(); + gridLayoutWidget_2=nullptr; +} + + +ServerTunnelPane* ServerTunnelPane::asServerTunnelPane(){return this;} +ClientTunnelPane* ServerTunnelPane::asClientTunnelPane(){return nullptr;} diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h new file mode 100644 index 00000000..d4ed549d --- /dev/null +++ b/qt/i2pd_qt/ServerTunnelPane.h @@ -0,0 +1,110 @@ +#ifndef SERVERTUNNELPANE_H +#define SERVERTUNNELPANE_H + +#include "TunnelPane.h" +#include "mainwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ServerTunnelConfig; + +class ClientTunnelPane; + +class ServerTunnelPane : public TunnelPane { + Q_OBJECT + +public: + ServerTunnelPane(); + virtual ~ServerTunnelPane(){} + + virtual ServerTunnelPane* asServerTunnelPane(); + virtual ClientTunnelPane* asClientTunnelPane(); + + void appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout); + void deleteServerTunnelForm(QGridLayout *tunnelsFormGridLayout); + +private: + QGroupBox *serverTunnelNameGroupBox; + + //tunnel + QWidget *gridLayoutWidget_2; + + //host + QHBoxLayout *horizontalLayout_2; + QLabel *hostLabel; + QLineEdit *hostLineEdit; + QSpacerItem *hostHorizontalSpacer; + + //port + QLabel * portLabel; + QLineEdit * portLineEdit; + + //keys + QLabel * keysLabel; + QLineEdit * keysLineEdit; + + //inPort + QLabel * inPortLabel; + QLineEdit * inPortLineEdit; + + //accessList + QLabel * accessListLabel; + QLineEdit * accessListLineEdit; + + //hostOverride + QLabel * hostOverrideLabel; + QLineEdit * hostOverrideLineEdit; + + //webIRCPass + QLabel * webIRCPassLabel; + QLineEdit * webIRCPassLineEdit; + + //address + QLabel * addressLabel; + QLineEdit * addressLineEdit; + + //maxConns + QLabel * maxConnsLabel; + QLineEdit * maxConnsLineEdit; + + //gzip + QCheckBox * gzipCheckBox; + + //isUniqueLocal + QCheckBox * isUniqueLocalCheckBox; + +protected slots: + virtual void setGroupBoxTitle(const QString & title); + +private: + void retranslateServerTunnelForm(ServerTunnelPane& /*ui*/) { + hostLabel->setText(QApplication::translate("srvTunForm", "Host:", 0)); + portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0)); + keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0)); + inPortLabel->setText(QApplication::translate("srvTunForm", "InPort:", 0)); + accessListLabel->setText(QApplication::translate("srvTunForm", "Access list:", 0)); + hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0)); + webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0)); + addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0)); + maxConnsLabel->setText(QApplication::translate("srvTunForm", "Max connections:", 0)); + + gzipCheckBox->setText(QApplication::translate("srvTunForm", "GZip", 0)); + isUniqueLocalCheckBox->setText(QApplication::translate("srvTunForm", "Is unique local", 0)); + } + +}; + +#endif // SERVERTUNNELPANE_H diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp new file mode 100644 index 00000000..fbd8a2ab --- /dev/null +++ b/qt/i2pd_qt/TunnelConfig.cpp @@ -0,0 +1,2 @@ +#include "TunnelConfig.h" + diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h new file mode 100644 index 00000000..f37809d9 --- /dev/null +++ b/qt/i2pd_qt/TunnelConfig.h @@ -0,0 +1,221 @@ +#ifndef TUNNELCONFIG_H +#define TUNNELCONFIG_H + +#include "QString" +#include + +#include "../../ClientContext.h" + + +class I2CPParameters{ + QString inbound_length;//number of hops of an inbound tunnel. 3 by default; lower value is faster but dangerous + QString outbound_length;//number of hops of an outbound tunnel. 3 by default; lower value is faster but dangerous + QString inbound_quantity; //number of inbound tunnels. 5 by default + QString outbound_quantity; //number of outbound tunnels. 5 by default + QString crypto_tagsToSend; //number of ElGamal/AES tags to send. 40 by default; too low value may cause problems with tunnel building + QString explicitPeers; //list of comma-separated b64 addresses of peers to use, default: unset +public: + I2CPParameters(): inbound_length(), + outbound_length(), + inbound_quantity(), + outbound_quantity(), + crypto_tagsToSend(), + explicitPeers() {} + const QString& getInbound_length(){return inbound_length;} + const QString& getOutbound_length(){return outbound_length;} + const QString& getInbound_quantity(){return inbound_quantity;} + const QString& getOutbound_quantity(){return outbound_quantity;} + const QString& getCrypto_tagsToSend(){return crypto_tagsToSend;} + const QString& getExplicitPeers(){return explicitPeers;} + void setInbound_length(QString inbound_length_){inbound_length=inbound_length_;} + void setOutbound_length(QString outbound_length_){outbound_length=outbound_length_;} + void setInbound_quantity(QString inbound_quantity_){inbound_quantity=inbound_quantity_;} + void setOutbound_quantity(QString outbound_quantity_){outbound_quantity=outbound_quantity_;} + void setCrypto_tagsToSend(QString crypto_tagsToSend_){crypto_tagsToSend=crypto_tagsToSend_;} + void setExplicitPeers(QString explicitPeers_){explicitPeers=explicitPeers_;} +}; + + +class ClientTunnelConfig; +class ServerTunnelConfig; +class TunnelConfig { + /* + const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client"; + const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server"; + const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http"; + const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc"; + const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient"; + const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver"; + const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks"; + const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks"; + const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy"; + */ + QString type; + std::string name; +public: + TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_): type(type_), name(name_), i2cpParameters(i2cpParameters_) {} + const QString& getType(){return type;} + const std::string& getName(){return name;} + void setType(const QString& type_){type=type_;} + void setName(const std::string& name_){name=name_;} + I2CPParameters& getI2cpParameters(){return i2cpParameters;} + virtual ClientTunnelConfig* asClientTunnelConfig()=0; + virtual ServerTunnelConfig* asServerTunnelConfig()=0; + +private: + I2CPParameters i2cpParameters; +}; + +/* +# mandatory parameters: + std::string dest; + if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) + dest = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION); + int port = section.second.get (I2P_CLIENT_TUNNEL_PORT); +# optional parameters (may be omitted) + std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); + std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); + int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); + i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); +# * keys -- our identity, if unset, will be generated on every startup, +# if set and file missing, keys will be generated and placed to this file +# * address -- local interface to bind +# * signaturetype -- signature type for new destination. 0 (DSA/SHA1), 1 (EcDSA/SHA256) or 7 (EdDSA/SHA512) +[somelabel] +type = client +address = 127.0.0.1 +port = 6668 +destination = irc.postman.i2p +keys = irc-keys.dat +*/ +class ClientTunnelConfig : public TunnelConfig { + std::string dest; + int port; + std::string keys; + std::string address; + int destinationPort; + i2p::data::SigningKeyType sigType; +public: + ClientTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_, + std::string dest_, + int port_, + std::string keys_, + std::string address_, + int destinationPort_, + i2p::data::SigningKeyType sigType_): TunnelConfig(name_, type_, i2cpParameters_), + dest(dest_), + port(port_), + keys(keys_), + address(address_), + destinationPort(destinationPort_) {} + std::string& getdest(){return dest;} + int getport(){return port;} + std::string & getkeys(){return keys;} + std::string & getaddress(){return address;} + int getdestinationPort(){return destinationPort;} + i2p::data::SigningKeyType getsigType(){return sigType;} + void setdest(std::string& dest_){dest=dest_;} + void setport(int port_){port=port_;} + void setkeys(std::string & keys_){keys=keys_;} + void setaddress(std::string & address_){address=address_;} + void setdestinationPort(int destinationPort_){destinationPort=destinationPort_;} + void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} + virtual ClientTunnelConfig* asClientTunnelConfig(){return this;} + virtual ServerTunnelConfig* asServerTunnelConfig(){return nullptr;} +}; + +/* +# mandatory parameters: +# * host -- ip address of our service +# * port -- port of our service +# * keys -- file with LeaseSet of address in i2p + std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST); + int port = section.second.get (I2P_SERVER_TUNNEL_PORT); + std::string keys = section.second.get (I2P_SERVER_TUNNEL_KEYS); +# optional parameters (may be omitted) + int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0); + std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); + std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, ""); + std::string webircpass = section.second.get (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, ""); + bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true); + i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); + uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN); + std::string address = section.second.get (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); + bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); +# * inport -- optional, i2p service port, if unset - the same as 'port' +# * accesslist -- comma-separated list of i2p addresses, allowed to connect +# every address is b32 without '.b32.i2p' part +[somelabel] +type = server +host = 127.0.0.1 +port = 6667 +keys = irc.dat +*/ +class ServerTunnelConfig : public TunnelConfig { + std::string host; + int port; + std::string keys; + int inPort; + std::string accessList; + std::string hostOverride; + std::string webircpass; + bool gzip; + i2p::data::SigningKeyType sigType; + uint32_t maxConns; + std::string address; + bool isUniqueLocal; +public: + ServerTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_, + std::string host_, + int port_, + std::string keys_, + int inPort_, + std::string accessList_, + std::string hostOverride_, + std::string webircpass_, + bool gzip_, + i2p::data::SigningKeyType sigType_, + uint32_t maxConns_, + std::string address_, + bool isUniqueLocal_): TunnelConfig(name_, type_, i2cpParameters_), + host(host_), + port(port_), + keys(keys_), + inPort(inPort_), + accessList(accessList_), + hostOverride(hostOverride_), + webircpass(webircpass_), + gzip(gzip_), + sigType(sigType_), + maxConns(maxConns_), + address(address_) {} + std::string& gethost(){return host;} + int getport(){return port;} + std::string& getkeys(){return keys;} + int getinPort(){return inPort;} + std::string& getaccessList(){return accessList;} + std::string& gethostOverride(){return hostOverride;} + std::string& getwebircpass(){return webircpass;} + bool getgzip(){return gzip;} + i2p::data::SigningKeyType getsigType(){return sigType;} + uint32_t getmaxConns(){return maxConns;} + std::string& getaddress(){return address;} + bool getisUniqueLocal(){return isUniqueLocal;} + void sethost(std::string& host_){host=host_;} + void setport(int port_){port=port_;} + void setkeys(std::string& keys_){keys=keys_;} + void setinPort(int inPort_){inPort=inPort_;} + void setaccessList(std::string& accessList_){accessList=accessList_;} + void sethostOverride(std::string& hostOverride_){hostOverride=hostOverride_;} + void setwebircpass(std::string& webircpass_){webircpass=webircpass_;} + void setgzip(bool gzip_){gzip=gzip_;} + void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} + void setmaxConns(uint32_t maxConns_){maxConns=maxConns_;} + void setaddress(std::string& address_){address=address_;} + void setisUniqueLocal(bool isUniqueLocal_){isUniqueLocal=isUniqueLocal_;} + virtual ClientTunnelConfig* asClientTunnelConfig(){return nullptr;} + virtual ServerTunnelConfig* asServerTunnelConfig(){return this;} +}; + + +#endif // TUNNELCONFIG_H diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp new file mode 100644 index 00000000..3b76a124 --- /dev/null +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -0,0 +1,149 @@ +#include "TunnelPane.h" + +TunnelPane::TunnelPane(): QObject(),gridLayoutWidget_2(nullptr) { +} + +void TunnelPane::setupTunnelPane( + TunnelConfig* tunnelConfig, + QGroupBox *tunnelGroupBox, + QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, + QWidget */*tunnelsFormGridLayoutWidget*/, QGridLayout */*tunnelsFormGridLayout*/) { + this->tunnelGroupBox=tunnelGroupBox; + gridLayoutWidget_2->setObjectName(QStringLiteral("gridLayoutWidget_2")); + this->gridLayoutWidget_2=gridLayoutWidget_2; + tunnelGridLayout = new QGridLayout(gridLayoutWidget_2); + tunnelGridLayout->setObjectName(QStringLiteral("tunnelGridLayout")); + tunnelGridLayout->setContentsMargins(5, 5, 5, 5); + tunnelGridLayout->setVerticalSpacing(5); + + //header + QHBoxLayout *headerHorizontalLayout = new QHBoxLayout(); + headerHorizontalLayout->setObjectName(QStringLiteral("headerHorizontalLayout")); + + nameLabel = new QLabel(gridLayoutWidget_2); + nameLabel->setObjectName(QStringLiteral("nameLabel")); + headerHorizontalLayout->addWidget(nameLabel); + nameLineEdit = new QLineEdit(gridLayoutWidget_2); + nameLineEdit->setObjectName(QStringLiteral("nameLineEdit")); + const QString& tunnelName=tunnelConfig->getName().c_str(); + nameLineEdit->setText(tunnelName); + setGroupBoxTitle(tunnelName); + + QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(setGroupBoxTitle(const QString &))); + + headerHorizontalLayout->addWidget(nameLineEdit); + headerHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + headerHorizontalLayout->addItem(headerHorizontalSpacer); + deletePushButton = new QPushButton(gridLayoutWidget_2);//TODO handle it + deletePushButton->setObjectName(QStringLiteral("deletePushButton")); + headerHorizontalLayout->addWidget(deletePushButton); + tunnelGridLayout->addLayout(headerHorizontalLayout, 0, 0, 1, 1); + + //type + { + const QString& type = tunnelConfig->getType(); + QHBoxLayout * horizontalLayout_ = new QHBoxLayout(); + horizontalLayout_->setObjectName(QStringLiteral("horizontalLayout_")); + typeLabel = new QLabel(gridLayoutWidget_2); + typeLabel->setObjectName(QStringLiteral("typeLabel")); + horizontalLayout_->addWidget(typeLabel); + horizontalLayout_->addWidget(tunnelTypeComboBox); + this->tunnelTypeComboBox=tunnelTypeComboBox; + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_, 1, 0, 1, 1); + } + + retranslateTunnelForm(*this); +} + +void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex) { + { + //number of hops of an inbound tunnel + const QString& inbound_length=i2cpParameters.getInbound_length(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + inbound_lengthLabel = new QLabel(gridLayoutWidget_2); + inbound_lengthLabel->setObjectName(QStringLiteral("inbound_lengthLabel")); + horizontalLayout_2->addWidget(inbound_lengthLabel); + inbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2); + inbound_lengthLineEdit->setObjectName(QStringLiteral("inbound_lengthLineEdit")); + inbound_lengthLineEdit->setText(inbound_length); + inbound_lengthLineEdit->setMaximumWidth(80); + horizontalLayout_2->addWidget(inbound_lengthLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + //number of hops of an outbound tunnel + const QString& outbound_length=i2cpParameters.getOutbound_length(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + outbound_lengthLabel = new QLabel(gridLayoutWidget_2); + outbound_lengthLabel->setObjectName(QStringLiteral("outbound_lengthLabel")); + horizontalLayout_2->addWidget(outbound_lengthLabel); + outbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2); + outbound_lengthLineEdit->setObjectName(QStringLiteral("outbound_lengthLineEdit")); + outbound_lengthLineEdit->setText(outbound_length); + outbound_lengthLineEdit->setMaximumWidth(80); + horizontalLayout_2->addWidget(outbound_lengthLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + //number of inbound tunnels + const QString& inbound_quantity=i2cpParameters.getInbound_quantity(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + inbound_quantityLabel = new QLabel(gridLayoutWidget_2); + inbound_quantityLabel->setObjectName(QStringLiteral("inbound_quantityLabel")); + horizontalLayout_2->addWidget(inbound_quantityLabel); + inbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2); + inbound_quantityLineEdit->setObjectName(QStringLiteral("inbound_quantityLineEdit")); + inbound_quantityLineEdit->setText(inbound_quantity); + inbound_quantityLineEdit->setMaximumWidth(80); + horizontalLayout_2->addWidget(inbound_quantityLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + //number of outbound tunnels + const QString& outbound_quantity=i2cpParameters.getOutbound_quantity(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + outbound_quantityLabel = new QLabel(gridLayoutWidget_2); + outbound_quantityLabel->setObjectName(QStringLiteral("outbound_quantityLabel")); + horizontalLayout_2->addWidget(outbound_quantityLabel); + outbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2); + outbound_quantityLineEdit->setObjectName(QStringLiteral("outbound_quantityLineEdit")); + outbound_quantityLineEdit->setText(outbound_quantity); + outbound_quantityLineEdit->setMaximumWidth(80); + horizontalLayout_2->addWidget(outbound_quantityLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + //number of ElGamal/AES tags to send + const QString& crypto_tagsToSend=i2cpParameters.getCrypto_tagsToSend(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + crypto_tagsToSendLabel = new QLabel(gridLayoutWidget_2); + crypto_tagsToSendLabel->setObjectName(QStringLiteral("crypto_tagsToSendLabel")); + horizontalLayout_2->addWidget(crypto_tagsToSendLabel); + crypto_tagsToSendLineEdit = new QLineEdit(gridLayoutWidget_2); + crypto_tagsToSendLineEdit->setObjectName(QStringLiteral("crypto_tagsToSendLineEdit")); + crypto_tagsToSendLineEdit->setText(crypto_tagsToSend); + crypto_tagsToSendLineEdit->setMaximumWidth(80); + horizontalLayout_2->addWidget(crypto_tagsToSendLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + + retranslateI2CPParameters(); +} diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h new file mode 100644 index 00000000..19021ca5 --- /dev/null +++ b/qt/i2pd_qt/TunnelPane.h @@ -0,0 +1,94 @@ +#ifndef TUNNELPANE_H +#define TUNNELPANE_H + +#include "QObject" +#include "QWidget" +#include "QComboBox" +#include "QGridLayout" +#include "QLabel" +#include "QPushButton" +#include "QApplication" +#include "QLineEdit" +#include "QGroupBox" + +#include "TunnelConfig.h" + +class ServerTunnelPane; +class ClientTunnelPane; + +class TunnelConfig; +class I2CPParameters; + +class TunnelPane : public QObject { + + Q_OBJECT + +public: + TunnelPane(); + virtual ~TunnelPane(){} + + virtual ServerTunnelPane* asServerTunnelPane()=0; + virtual ClientTunnelPane* asClientTunnelPane()=0; + +protected: + QGridLayout *tunnelGridLayout; + QGroupBox *tunnelGroupBox; + QWidget* gridLayoutWidget_2; + + //header + QLabel *nameLabel; + QLineEdit *nameLineEdit; + QSpacerItem *headerHorizontalSpacer; + QPushButton *deletePushButton; + + //type + QComboBox *tunnelTypeComboBox; + QLabel *typeLabel; + + //i2cp + + QLabel * inbound_lengthLabel; + QLineEdit * inbound_lengthLineEdit; + + QLabel * outbound_lengthLabel; + QLineEdit * outbound_lengthLineEdit; + + QLabel * inbound_quantityLabel; + QLineEdit * inbound_quantityLineEdit; + + QLabel * outbound_quantityLabel; + QLineEdit * outbound_quantityLineEdit; + + QLabel * crypto_tagsToSendLabel; + QLineEdit * crypto_tagsToSendLineEdit; + + void setupTunnelPane( + TunnelConfig* tunnelConfig, + QGroupBox *tunnelGroupBox, + QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, + QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout); + void appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex); +public: + int height() { + return gridLayoutWidget_2?gridLayoutWidget_2->height():0; + } + +protected slots: + virtual void setGroupBoxTitle(const QString & title)=0; +private: + void retranslateTunnelForm(TunnelPane& ui) { + ui.deletePushButton->setText(QApplication::translate("tunForm", "Delete Tunnel", 0)); + ui.nameLabel->setText(QApplication::translate("tunForm", "Tunnel name:", 0)); + ui.typeLabel->setText(QApplication::translate("tunForm", "Server tunnel type:", 0)); + } + + void retranslateI2CPParameters() { + inbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an inbound tunnel:", 0));; + outbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an outbound tunnel:", 0));; + inbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of inbound tunnels:", 0));; + outbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of outbound tunnels:", 0));; + crypto_tagsToSendLabel->setText(QApplication::translate("tunForm", "Number of ElGamal/AES tags to send:", 0));; + } +}; + +#endif // TUNNELPANE_H diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 54a8bbcc..6ce21726 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -42,6 +42,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp SOURCES += $$files(../../libi2pd/*.cpp) SOURCES += $$files(../../libi2pd_client/*.cpp) SOURCES += $$files(../../daemon/*.cpp) +SOURCES += $$files(./*.cpp) SOURCES -= ../../daemon/UnixDaemon.cpp @@ -63,8 +64,10 @@ HEADERS += DaemonQT.h mainwindow.h INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client INCLUDEPATH += ../../daemon +INCLUDEPATH += . -FORMS += mainwindow.ui +FORMS += mainwindow.ui \ + tunnelform.ui CONFIG += mobility diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index cc4dd0b3..136dae07 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -2,33 +2,52 @@ #include "ui_mainwindow.h" #include #include -#include "RouterContext.h" +#include +#include +#include "../../RouterContext.h" +#include "../../Config.h" +#include "../../FS.h" +#include "../../Log.h" + #ifndef ANDROID -#include +# include #endif + #include +#include + +std::string programOptionsWriterCurrentSection; + MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow) + QMainWindow(parent) #ifndef ANDROID ,quitting(false) #endif + ,ui(new Ui::MainWindow) + ,configItems() + ,datadir() + ,confpath() + ,tunconfpath() + { ui->setupUi(this); + setWindowTitle(QApplication::translate("AppTitle","I2PD")); //TODO handle resizes and change the below into resize() call setFixedSize(width(), 480); + ui->centralWidget->setMinimumHeight(480); + ui->centralWidget->setMaximumHeight(480); onResize(); ui->stackedWidget->setCurrentIndex(0); - ui->settingsScrollArea->resize(ui->settingsContentsGridLayout->sizeHint().width()+10,ui->settingsScrollArea->height()); + ui->settingsScrollArea->resize(ui->settingsContentsGridLayout->sizeHint().width()+10,380); QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); //QSize szSettContents = ui->settingsContentsGridLayout->minimumSize(); int w = 683; - int h = 3000; + int h = 3060; ui->settingsContents->setFixedSize(w, h); - ui->settingsContents->resize(w, h); + //ui->settingsContents->resize(w, h); //ui->settingsContents->adjustSize(); /* @@ -39,8 +58,8 @@ MainWindow::MainWindow(QWidget *parent) : */ //ui->settingsScrollArea->adjustSize(); - ui->tunnelsScrollAreaWidgetContents->setFixedSize( - ui->tunnelsScrollArea->width() - barSett->width(), 0); + /*ui->tunnelsScrollAreaWidgetContents->setFixedSize( + ui->tunnelsScrollArea->width() - barSett->width(), 0);*/ #ifndef ANDROID createActions(); @@ -57,91 +76,141 @@ MainWindow::MainWindow(QWidget *parent) : QObject::connect(ui->fastQuitPushButton, SIGNAL(released()), this, SLOT(handleQuitButton())); QObject::connect(ui->gracefulQuitPushButton, SIGNAL(released()), this, SLOT(handleGracefulQuitButton())); - initFileChooser(ui->configFileLineEdit, ui->configFileBrowsePushButton); - initFileChooser(ui->tunnelsConfigFileLineEdit, ui->tunnelsConfigFileBrowsePushButton); - initFileChooser(ui->pidFileLineEdit, ui->pidFileBrowsePushButton); - initFileChooser(ui->logFileLineEdit, ui->logFileBrowsePushButton); - initFileChooser(ui->httpProxyKeyFileLineEdit, ui->httpProxyKeyFilePushButton); - initFileChooser(ui->socksProxyKeyFileLineEdit, ui->socksProxyKeyFilePushButton); - initFileChooser(ui->i2pControlCertFileLineEdit, ui->i2pControlCertFileBrowsePushButton); - initFileChooser(ui->i2pControlKeyFileLineEdit, ui->i2pControlKeyFileBrowsePushButton); - initFileChooser(ui->reseedFileLineEdit, ui->reseedFileBrowsePushButton); +# define OPTION(section,option,defaultValueGetter) ConfigOption(QString(section),QString(option)) - initFolderChooser(ui->dataFolderLineEdit, ui->dataFolderBrowsePushButton); + initFileChooser( OPTION("","conf",[](){return "";}), ui->configFileLineEdit, ui->configFileBrowsePushButton); + initFolderChooser( OPTION("","datadir",[]{return "";}), ui->dataFolderLineEdit, ui->dataFolderBrowsePushButton); + initFileChooser( OPTION("","tunconf",[](){return "";}), ui->tunnelsConfigFileLineEdit, ui->tunnelsConfigFileBrowsePushButton); - initCombobox(ui->logLevelComboBox); + initFileChooser( OPTION("","pidfile",[]{return "";}), ui->pidFileLineEdit, ui->pidFileBrowsePushButton); + logOption=initNonGUIOption( OPTION("","log",[]{return "";})); + daemonOption=initNonGUIOption( OPTION("","daemon",[]{return "";})); + serviceOption=initNonGUIOption( OPTION("","service",[]{return "";})); - initIPAddressBox(ui->routerExternalHostLineEdit, tr("Router external address -> Host")); - initTCPPortBox(ui->routerExternalPortLineEdit, tr("Router external address -> Port")); + logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), ui->logFileLineEdit, ui->logFileBrowsePushButton); + initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), ui->logLevelComboBox); - initCheckBox(ui->ipv6CheckBox); - initCheckBox(ui->notransitCheckBox); - initCheckBox(ui->floodfillCheckBox); - initIntegerBox(ui->bandwidthLineEdit); - initStringBox(ui->familyLineEdit); - initIntegerBox(ui->netIdLineEdit); + initIPAddressBox( OPTION("","host",[]{return "";}), ui->routerExternalHostLineEdit, tr("Router external address -> Host")); + initTCPPortBox( OPTION("","port",[]{return "";}), ui->routerExternalPortLineEdit, tr("Router external address -> Port")); + + initCheckBox( OPTION("","ipv6",[]{return "false";}), ui->ipv6CheckBox); + initCheckBox( OPTION("","notransit",[]{return "false";}), ui->notransitCheckBox); + initCheckBox( OPTION("","floodfill",[]{return "false";}), ui->floodfillCheckBox); + initStringBox( OPTION("","bandwidth",[]{return "";}), ui->bandwidthLineEdit); + initStringBox( OPTION("","family",[]{return "";}), ui->familyLineEdit); + initIntegerBox( OPTION("","netid",[]{return "2";}), ui->netIdLineEdit, tr("NetID")); + +#ifdef Q_OS_WIN + initCheckBox( OPTION("","insomnia",[]{return "";}), ui->insomniaCheckBox); + initNonGUIOption( OPTION("","svcctl",[]{return "";})); + initNonGUIOption( OPTION("","close",[]{return "";})); +#else + ui->insomniaCheckBox->setEnabled(false); +#endif + + initCheckBox( OPTION("http","enabled",[]{return "true";}), ui->webconsoleEnabledCheckBox); + initIPAddressBox( OPTION("http","address",[]{return "";}), ui->webconsoleAddrLineEdit, tr("HTTP webconsole -> IP address")); + initTCPPortBox( OPTION("http","port",[]{return "7070";}), ui->webconsolePortLineEdit, tr("HTTP webconsole -> Port")); + initCheckBox( OPTION("http","auth",[]{return "";}), ui->webconsoleBasicAuthCheckBox); + initStringBox( OPTION("http","user",[]{return "i2pd";}), ui->webconsoleUserNameLineEditBasicAuth); + initStringBox( OPTION("http","pass",[]{return "";}), ui->webconsolePasswordLineEditBasicAuth); + + initCheckBox( OPTION("httpproxy","enabled",[]{return "";}), ui->httpProxyEnabledCheckBox); + initIPAddressBox( OPTION("httpproxy","address",[]{return "";}), ui->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); + initTCPPortBox( OPTION("httpproxy","port",[]{return "4444";}), ui->httpProxyPortLineEdit, tr("HTTP proxy -> Port")); + initFileChooser( OPTION("httpproxy","keys",[]{return "";}), ui->httpProxyKeyFileLineEdit, ui->httpProxyKeyFilePushButton); + initSignatureTypeCombobox(OPTION("httpproxy","signaturetype",[]{return "7";}), ui->comboBox_httpPorxySignatureType); + initStringBox( OPTION("httpproxy","inbound.length",[]{return "3";}), ui->httpProxyInboundTunnelsLenLineEdit); + initStringBox( OPTION("httpproxy","inbound.quantity",[]{return "5";}), ui->httpProxyInboundTunnQuantityLineEdit); + initStringBox( OPTION("httpproxy","outbound.length",[]{return "3";}), ui->httpProxyOutBoundTunnLenLineEdit); + initStringBox( OPTION("httpproxy","outbound.quantity",[]{return "5";}), ui->httpProxyOutboundTunnQuantityLineEdit); + + initCheckBox( OPTION("socksproxy","enabled",[]{return "";}), ui->socksProxyEnabledCheckBox); + initIPAddressBox( OPTION("socksproxy","address",[]{return "";}), ui->socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); + initTCPPortBox( OPTION("socksproxy","port",[]{return "4447";}), ui->socksProxyPortLineEdit, tr("Socks proxy -> Port")); + initFileChooser( OPTION("socksproxy","keys",[]{return "";}), ui->socksProxyKeyFileLineEdit, ui->socksProxyKeyFilePushButton); + initSignatureTypeCombobox(OPTION("socksproxy","signaturetype",[]{return "7";}), ui->comboBox_socksProxySignatureType); + initStringBox( OPTION("socksproxy","inbound.length",[]{return "";}), ui->socksProxyInboundTunnelsLenLineEdit); + initStringBox( OPTION("socksproxy","inbound.quantity",[]{return "";}), ui->socksProxyInboundTunnQuantityLineEdit); + initStringBox( OPTION("socksproxy","outbound.length",[]{return "";}), ui->socksProxyOutBoundTunnLenLineEdit); + initStringBox( OPTION("socksproxy","outbound.quantity",[]{return "";}), ui->socksProxyOutboundTunnQuantityLineEdit); + initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "";}), ui->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); + initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "";}), ui->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); + + initCheckBox( OPTION("sam","enabled",[]{return "false";}), ui->samEnabledCheckBox); + initIPAddressBox( OPTION("sam","address",[]{return "";}), ui->samAddressLineEdit, tr("SAM -> IP address")); + initTCPPortBox( OPTION("sam","port",[]{return "7656";}), ui->samPortLineEdit, tr("SAM -> Port")); + + initCheckBox( OPTION("bob","enabled",[]{return "false";}), ui->bobEnabledCheckBox); + initIPAddressBox( OPTION("bob","address",[]{return "";}), ui->bobAddressLineEdit, tr("BOB -> IP address")); + initTCPPortBox( OPTION("bob","port",[]{return "2827";}), ui->bobPortLineEdit, tr("BOB -> Port")); + + initCheckBox( OPTION("i2cp","enabled",[]{return "false";}), ui->i2cpEnabledCheckBox); + initIPAddressBox( OPTION("i2cp","address",[]{return "";}), ui->i2cpAddressLineEdit, tr("I2CP -> IP address")); + initTCPPortBox( OPTION("i2cp","port",[]{return "7654";}), ui->i2cpPortLineEdit, tr("I2CP -> Port")); + + initCheckBox( OPTION("i2pcontrol","enabled",[]{return "false";}), ui->i2pControlEnabledCheckBox); + initIPAddressBox( OPTION("i2pcontrol","address",[]{return "";}), ui->i2pControlAddressLineEdit, tr("I2PControl -> IP address")); + initTCPPortBox( OPTION("i2pcontrol","port",[]{return "7650";}), ui->i2pControlPortLineEdit, tr("I2PControl -> Port")); + initStringBox( OPTION("i2pcontrol","password",[]{return "";}), ui->i2pControlPasswordLineEdit); + initFileChooser( OPTION("i2pcontrol","cert",[]{return "i2pcontrol.crt.pem";}), ui->i2pControlCertFileLineEdit, ui->i2pControlCertFileBrowsePushButton); + initFileChooser( OPTION("i2pcontrol","key",[]{return "i2pcontrol.key.pem";}), ui->i2pControlKeyFileLineEdit, ui->i2pControlKeyFileBrowsePushButton); + + initCheckBox( OPTION("upnp","enabled",[]{return "true";}), ui->enableUPnPCheckBox); + initStringBox( OPTION("upnp","name",[]{return "I2Pd";}), ui->upnpNameLineEdit); - initCheckBox(ui->insomniaCheckBox); - - initCheckBox(ui->webconsoleEnabledCheckBox); - initIPAddressBox(ui->webconsoleAddrLineEdit, tr("HTTP webconsole -> IP address")); - initTCPPortBox(ui->webconsolePortLineEdit, tr("HTTP webconsole -> Port")); - initCheckBox(ui->webconsoleBasicAuthCheckBox); - initStringBox(ui->webconsoleUserNameLineEditBasicAuth); - initStringBox(ui->webconsolePasswordLineEditBasicAuth); - - initCheckBox(ui->httpProxyEnabledCheckBox); - initIPAddressBox(ui->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); - initTCPPortBox(ui->httpProxyPortLineEdit, tr("HTTP proxy -> Port")); - initIntegerBox(ui->httpProxyInboundTunnelsLenLineEdit); - initIntegerBox(ui->httpProxyInboundTunnQuantityLineEdit); - initIntegerBox(ui->httpProxyOutBoundTunnLenLineEdit); - initIntegerBox(ui->httpProxyOutboundTunnQuantityLineEdit); - - initCheckBox(ui->socksProxyEnabledCheckBox); - initIPAddressBox(ui->socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); - initTCPPortBox(ui->socksProxyPortLineEdit, tr("Socks proxy -> Port")); - initIntegerBox(ui->socksProxyInboundTunnelsLenLineEdit); - initIntegerBox(ui->socksProxyInboundTunnQuantityLineEdit); - initIntegerBox(ui->socksProxyOutBoundTunnLenLineEdit); - initIntegerBox(ui->socksProxyOutboundTunnQuantityLineEdit); - initIPAddressBox(ui->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); - initTCPPortBox(ui->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); - - initCheckBox(ui->samEnabledCheckBox); - initIPAddressBox(ui->samAddressLineEdit, tr("SAM -> IP address")); - initTCPPortBox(ui->samPortLineEdit, tr("SAM -> Port")); - - initCheckBox(ui->bobEnabledCheckBox); - initIPAddressBox(ui->bobAddressLineEdit, tr("BOB -> IP address")); - initTCPPortBox(ui->bobPortLineEdit, tr("BOB -> Port")); - - initCheckBox(ui->i2cpEnabledCheckBox); - initIPAddressBox(ui->i2cpAddressLineEdit, tr("I2CP -> IP address")); - initTCPPortBox(ui->i2cpPortLineEdit, tr("I2CP -> Port")); - - initCheckBox(ui->i2pControlEnabledCheckBox); - initIPAddressBox(ui->i2pControlAddressLineEdit, tr("I2PControl -> IP address")); - initTCPPortBox(ui->i2pControlPortLineEdit, tr("I2PControl -> Port")); - initStringBox(ui->i2pControlPasswordLineEdit); + initCheckBox( OPTION("precomputation","elgamal",[]{return "false";}), ui->useElGamalPrecomputedTablesCheckBox); - initCheckBox(ui->enableUPnPCheckBox); - initStringBox(ui->upnpNameLineEdit); + initCheckBox( OPTION("reseed","verify",[]{return "";}), ui->reseedVerifyCheckBox); + initFileChooser( OPTION("reseed","file",[]{return "";}), ui->reseedFileLineEdit, ui->reseedFileBrowsePushButton); + initStringBox( OPTION("reseed","urls",[]{return "";}), ui->reseedURLsLineEdit); - initCheckBox(ui->useElGamalPrecomputedTablesCheckBox); + initStringBox( OPTION("addressbook","defaulturl",[]{return "";}), ui->addressbookDefaultURLLineEdit); + initStringBox( OPTION("addressbook","subscriptions",[]{return "";}), ui->addressbookSubscriptionsURLslineEdit); - initCheckBox(ui->reseedVerifyCheckBox); - initStringBox(ui->reseedURLsLineEdit); - - initStringBox(ui->addressbookDefaultURLLineEdit); - initStringBox(ui->addressbookSubscriptionsURLslineEdit); - - initIntegerBox(ui->maxNumOfTransitTunnelsLineEdit); - initIntegerBox(ui->maxNumOfOpenFilesLineEdit); - initIntegerBox(ui->coreFileMaxSizeNumberLineEdit); + initUInt16Box( OPTION("limits","transittunnels",[]{return "2500";}), ui->maxNumOfTransitTunnelsLineEdit, tr("maxNumberOfTransitTunnels")); + initUInt16Box( OPTION("limits","openfiles",[]{return "0";}), ui->maxNumOfOpenFilesLineEdit, tr("maxNumberOfOpenFiles")); + initUInt32Box( OPTION("limits","coresize",[]{return "0";}), ui->coreFileMaxSizeNumberLineEdit, tr("coreFileMaxSize")); + + initCheckBox( OPTION("trust","enabled",[]{return "false";}), ui->checkBoxTrustEnable); + initStringBox( OPTION("trust","family",[]{return "";}), ui->lineEditTrustFamily); + initStringBox( OPTION("trust","routers",[]{return "";}), ui->lineEditTrustRouters); + initCheckBox( OPTION("trust","hidden",[]{return "false";}), ui->checkBoxTrustHidden); + + initCheckBox( OPTION("websockets","enabled",[]{return "false";}), ui->checkBoxWebsocketsEnable); + initIPAddressBox( OPTION("websockets","address",[]{return "127.0.0.1";}), ui->lineEdit_webSock_addr, tr("Websocket server -> IP address")); + initTCPPortBox( OPTION("websockets","port",[]{return "7666";}), ui->lineEdit_webSock_port, tr("Websocket server -> Port")); + +# undef OPTION loadAllConfigs(); + tunnelsFormGridLayoutWidget = new QWidget(ui->tunnelsScrollAreaWidgetContents); + tunnelsFormGridLayoutWidget->setObjectName(QStringLiteral("tunnelsFormGridLayoutWidget")); + tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, 451)); + ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, 451)); + tunnelsFormGridLayout = new QGridLayout(tunnelsFormGridLayoutWidget); + tunnelsFormGridLayout->setObjectName(QStringLiteral("tunnelsFormGridLayout")); + tunnelsFormGridLayout->setContentsMargins(5, 5, 5, 5); + tunnelsFormGridLayout->setVerticalSpacing(5); + + appendTunnelForms(); + + ui->configFileLineEdit->setEnabled(false); + ui->configFileBrowsePushButton->setEnabled(false); + ui->configFileLineEdit->setText(confpath); + ui->tunnelsConfigFileLineEdit->setText(tunconfpath); + + for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { + MainWindowItem* item = *it; + item->installListeners(this); + } + + QObject::connect(ui->tunnelsConfigFileLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(reloadTunnelsConfigAndUI())); + + + #ifndef ANDROID QObject::connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); @@ -273,19 +342,223 @@ void MainWindow::handleGracefulQuitTimerEvent() { MainWindow::~MainWindow() { qDebug("Destroying main window"); + for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { + MainWindowItem* item = *it; + item->deleteLater(); + } + configItems.clear(); //QMessageBox::information(0, "Debug", "mw destructor 1"); //delete ui; //QMessageBox::information(0, "Debug", "mw destructor 2"); } -void MainWindow::initFileChooser(QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton){} -void MainWindow::initFolderChooser(QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton){} -void MainWindow::initCombobox(QComboBox* comboBox){} -void MainWindow::initIPAddressBox(QLineEdit* addressLineEdit, QString fieldNameTranslated){} -void MainWindow::initTCPPortBox(QLineEdit* portLineEdit, QString fieldNameTranslated){} -void MainWindow::initCheckBox(QCheckBox* checkBox){} -void MainWindow::initIntegerBox(QLineEdit* numberLineEdit){} -void MainWindow::initStringBox(QLineEdit* lineEdit){} +FileChooserItem* MainWindow::initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton){ + FileChooserItem* retVal; + retVal=new FileChooserItem(option, fileNameLineEdit, fileBrowsePushButton); + MainWindowItem* super=retVal; + configItems.append(super); + return retVal; +} +void MainWindow::initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton){ + configItems.append(new FolderChooserItem(option, folderLineEdit, folderBrowsePushButton)); +} +/*void MainWindow::initCombobox(ConfigOption option, QComboBox* comboBox){ + configItems.append(new ComboBoxItem(option, comboBox)); + QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAllConfigs())); +}*/ +void MainWindow::initLogLevelCombobox(ConfigOption option, QComboBox* comboBox){ + configItems.append(new LogLevelComboBoxItem(option, comboBox)); +} +void MainWindow::initSignatureTypeCombobox(ConfigOption option, QComboBox* comboBox){ + configItems.append(new SignatureTypeComboBoxItem(option, comboBox)); +} +void MainWindow::initIPAddressBox(ConfigOption option, QLineEdit* addressLineEdit, QString fieldNameTranslated){ + configItems.append(new IPAddressStringItem(option, addressLineEdit, fieldNameTranslated)); +} +void MainWindow::initTCPPortBox(ConfigOption option, QLineEdit* portLineEdit, QString fieldNameTranslated){ + configItems.append(new TCPPortStringItem(option, portLineEdit, fieldNameTranslated)); +} +void MainWindow::initCheckBox(ConfigOption option, QCheckBox* checkBox) { + configItems.append(new CheckBoxItem(option, checkBox)); +} +void MainWindow::initIntegerBox(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){ + configItems.append(new IntegerStringItem(option, numberLineEdit, fieldNameTranslated)); +} +void MainWindow::initUInt32Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){ + configItems.append(new UInt32StringItem(option, numberLineEdit, fieldNameTranslated)); +} +void MainWindow::initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated){ + configItems.append(new UInt16StringItem(option, numberLineEdit, fieldNameTranslated)); +} +void MainWindow::initStringBox(ConfigOption option, QLineEdit* lineEdit){ + configItems.append(new BaseStringItem(option, lineEdit)); +} +NonGUIOptionItem* MainWindow::initNonGUIOption(ConfigOption option) { + NonGUIOptionItem * retValue; + configItems.append(retValue=new NonGUIOptionItem(option)); + return retValue; +} -void MainWindow::loadAllConfigs(){} -void MainWindow::saveAllConfigs(){} +void MainWindow::loadAllConfigs(){ + + //BORROWED FROM ??? //TODO move this code into single location + std::string config; i2p::config::GetOption("conf", config); + std::string datadir; i2p::config::GetOption("datadir", datadir); + bool service = false; +#ifndef _WIN32 + i2p::config::GetOption("service", service); +#endif + i2p::fs::DetectDataDir(datadir, service); + i2p::fs::Init(); + + datadir = i2p::fs::GetDataDir(); + // TODO: drop old name detection in v2.8.0 + if (config == "") + { + config = i2p::fs::DataDirPath("i2p.conf"); + if (i2p::fs::Exists (config)) { + LogPrint(eLogWarning, "Daemon: please rename i2p.conf to i2pd.conf here: ", config); + } else { + config = i2p::fs::DataDirPath("i2pd.conf"); + if (!i2p::fs::Exists (config)) { + // use i2pd.conf only if exists + config = ""; /* reset */ + } + } + } + + //BORROWED FROM ClientContext.cpp //TODO move this code into single location + std::string tunConf; i2p::config::GetOption("tunconf", tunConf); + if (tunConf == "") { + // TODO: cleanup this in 2.8.0 + tunConf = i2p::fs::DataDirPath ("tunnels.cfg"); + if (i2p::fs::Exists(tunConf)) { + LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); + } else { + tunConf = i2p::fs::DataDirPath ("tunnels.conf"); + } + } + + this->confpath = config.c_str(); + this->datadir = datadir.c_str(); + this->tunconfpath = tunConf.c_str(); + + for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { + MainWindowItem* item = *it; + item->loadFromConfigOption(); + } + + ReadTunnelsConfig(); +} +/** returns false iff not valid items present and save was aborted */ +bool MainWindow::saveAllConfigs(){ + programOptionsWriterCurrentSection=""; + if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file")); + else logOption->optionValue=boost::any(std::string("stdout")); + daemonOption->optionValue=boost::any(false); + serviceOption->optionValue=boost::any(false); + + std::stringstream out; + for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { + MainWindowItem* item = *it; + if(!item->isValid()) return false; + } + + for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { + MainWindowItem* item = *it; + item->saveToStringStream(out); + } + + using namespace std; + + QString backup=confpath+"~"; + if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors + QFile::rename(confpath, backup);//TODO handle errors + ofstream outfile; + outfile.open(confpath.toStdString());//TODO handle errors + string dataToWrite = out.str(); + outfile << dataToWrite.c_str(); + outfile.close(); + + return true; +} + +void FileChooserItem::pushButtonReleased() { + QString fileName = lineEdit->text().trimmed(); + fileName = QFileDialog::getOpenFileName(nullptr, tr("Open File"), fileName, tr("All Files (*.*)")); + if(fileName.length()>0)lineEdit->setText(fileName); +} +void FolderChooserItem::pushButtonReleased() { + QString fileName = lineEdit->text().trimmed(); + fileName = QFileDialog::getExistingDirectory(nullptr, tr("Open Folder"), fileName); + if(fileName.length()>0)lineEdit->setText(fileName); +} + +void BaseStringItem::installListeners(MainWindow *mainWindow) { + QObject::connect(lineEdit, SIGNAL(textChanged(const QString &)), mainWindow, SLOT(saveAllConfigs())); +} +void ComboBoxItem::installListeners(MainWindow *mainWindow) { + QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), mainWindow, SLOT(saveAllConfigs())); +} +void CheckBoxItem::installListeners(MainWindow *mainWindow) { + QObject::connect(checkBox, SIGNAL(stateChanged(int)), mainWindow, SLOT(saveAllConfigs())); +} + + +void MainWindowItem::installListeners(MainWindow *mainWindow) {} + +void MainWindow::appendTunnelForms() { + int height=0; + for(std::list::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { + TunnelConfig* tunconf = *it; + ServerTunnelConfig* stc = tunconf->asServerTunnelConfig(); + if(stc){ + ServerTunnelPane * tunnelPane=new ServerTunnelPane(); + tunnelPane->appendServerTunnelForm(stc, tunnelsFormGridLayoutWidget, tunnelsFormGridLayout); + height+=tunnelPane->height(); + qDebug() << "tun.height:" << height; + tunnelPanes.push_back(tunnelPane); + continue; + } + ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig(); + if(ctc){ + ClientTunnelPane * tunnelPane=new ClientTunnelPane();//TODO + height+=tunnelPane->height(); + qDebug() << "tun.height:" << height; + tunnelPanes.push_back(tunnelPane); + continue; + } + throw "unknown TunnelConfig subtype"; + } + qDebug() << "tun.setting height:" << height; + tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, height)); + ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height)); +} +void MainWindow::deleteTunnelForms() { + for(std::list::iterator it = tunnelPanes.begin(); it != tunnelPanes.end(); ++it) { + TunnelPane* tp = *it; + ServerTunnelPane* stp = tp->asServerTunnelPane(); + if(stp){ + stp->deleteServerTunnelForm(tunnelsFormGridLayout); + continue; + } + ClientTunnelPane* ctp = tp->asClientTunnelPane(); + if(ctp){ + ctp->deleteClientTunnelForm(tunnelsFormGridLayout); + continue; + } + throw "unknown TunnelPane subtype"; + } + tunnelPanes.clear(); +} + +void MainWindow::reloadTunnelsConfigAndUI() { + deleteTunnelForms(); + for(std::list::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { + TunnelConfig* tunconf = *it; + delete tunconf; + } + tunnelConfigs.clear(); + ReadTunnelsConfig(); + appendTunnelForms(); +} diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 5ef1ae22..05ecaddf 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -1,6 +1,7 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +#include #include #include #include @@ -9,29 +10,313 @@ #include #include #include -#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #ifndef ANDROID -#include -#include -#include +# include +# include +# include #endif +#include + +#include + +#include "MainWindowItems.h" +#include "TunnelPane.h" +#include "ServerTunnelPane.h" +#include "ClientTunnelPane.h" +#include "TunnelConfig.h" + +#include "../../Config.h" +#include "../../FS.h" + +#include + +#include +#include + +template +bool isType(boost::any& a) { + return +#ifdef BOOST_AUX_ANY_TYPE_ID_NAME + std::strcmp(a.type().name(), typeid(ValueType).name()) == 0 +#else + a.type() == typeid(ValueType) +#endif + ; +} + +class ConfigOption { +public: + QString section; + QString option; + //MainWindow::DefaultValueGetter defaultValueGetter; + ConfigOption(QString section_, QString option_/*, DefaultValueGetter defaultValueGetter_*/): + section(section_) + , option(option_) + //, defaultValueGetter(defaultValueGetter_) + {} + +}; + +extern std::string programOptionsWriterCurrentSection; + +class MainWindow; + +class MainWindowItem : public QObject { + Q_OBJECT + ConfigOption option; +public: + MainWindowItem(ConfigOption option_) : option(option_) {} + boost::any optionValue; + virtual ~MainWindowItem(){} + virtual void installListeners(MainWindow *mainWindow); + virtual void loadFromConfigOption(){ + std::string optName=""; + if(!option.section.isEmpty())optName=option.section.toStdString()+std::string("."); + optName+=option.option.toStdString(); + qDebug() << "loadFromConfigOption[" << optName.c_str() << "]"; + boost::any programOption; + i2p::config::GetOptionAsAny(optName, programOption); + optionValue=programOption.empty()?boost::any(std::string("")) + :boost::any_cast(programOption).value(); + } + virtual void saveToStringStream(std::stringstream& out){ + if(isType(optionValue)) { + std::string v = boost::any_cast(optionValue); + if(v.empty())return; + } + if(optionValue.empty())return; + std::string rtti = optionValue.type().name(); + std::string optName=""; + if(!option.section.isEmpty())optName=option.section.toStdString()+std::string("."); + optName+=option.option.toStdString(); + qDebug() << "Writing option" << optName.c_str() << "of type" << rtti.c_str(); + std::string sectionAsStdStr = option.section.toStdString(); + if(!option.section.isEmpty() && + sectionAsStdStr!=programOptionsWriterCurrentSection) { + out << "[" << sectionAsStdStr << "]\n"; + programOptionsWriterCurrentSection=sectionAsStdStr; + } + out << option.option.toStdString() << "="; + if(isType(optionValue)) { + out << boost::any_cast(optionValue); + }else if(isType(optionValue)) { + out << (boost::any_cast(optionValue) ? "true" : "false"); + }else if(isType(optionValue)) { + out << boost::any_cast(optionValue); + }else if(isType(optionValue)) { + out << boost::any_cast(optionValue); + }else if(isType(optionValue)) { + out << boost::any_cast(optionValue); + }else if(isType(optionValue)) { + out << boost::any_cast(optionValue); + }else out << boost::any_cast(optionValue); //let it throw + out << "\n\n"; + } + virtual bool isValid(){return true;} +}; +class NonGUIOptionItem : public MainWindowItem { +public: + NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_) {}; + virtual ~NonGUIOptionItem(){} + virtual bool isValid() { return true; } +}; +class BaseStringItem : public MainWindowItem { + Q_OBJECT +public: + QLineEdit* lineEdit; + BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_) : MainWindowItem(option_), lineEdit(lineEdit_){}; + virtual ~BaseStringItem(){} + virtual void installListeners(MainWindow *mainWindow); + virtual QString toString(){ + return boost::any_cast(optionValue).c_str(); + } + virtual boost::any fromString(QString s){return boost::any(s.toStdString());} + virtual void loadFromConfigOption(){ + MainWindowItem::loadFromConfigOption(); + lineEdit->setText(toString()); + } + + virtual void saveToStringStream(std::stringstream& out){ + optionValue=fromString(lineEdit->text()); + MainWindowItem::saveToStringStream(out); + } + virtual bool isValid() { return true; } +}; +class FileOrFolderChooserItem : public BaseStringItem { +public: + QPushButton* browsePushButton; + FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) : + BaseStringItem(option_, lineEdit_), browsePushButton(browsePushButton_) {} + virtual ~FileOrFolderChooserItem(){} +}; +class FileChooserItem : public FileOrFolderChooserItem { + Q_OBJECT +private slots: + void pushButtonReleased(); +public: + FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) : + FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_) { + QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased())); + } +}; +class FolderChooserItem : public FileOrFolderChooserItem{ + Q_OBJECT +private slots: + void pushButtonReleased(); +public: + FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) : + FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_) { + QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased())); + } +}; +class ComboBoxItem : public MainWindowItem { +public: + QComboBox* comboBox; + ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_), comboBox(comboBox_){}; + virtual ~ComboBoxItem(){} + virtual void installListeners(MainWindow *mainWindow); + virtual void loadFromConfigOption()=0; + virtual void saveToStringStream(std::stringstream& out)=0; + virtual bool isValid() { return true; } +}; +class LogLevelComboBoxItem : public ComboBoxItem { +public: + LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}; + virtual ~LogLevelComboBoxItem(){} + virtual void loadFromConfigOption(){ + MainWindowItem::loadFromConfigOption(); + const char * ll = boost::any_cast(optionValue).c_str(); + comboBox->setCurrentText(QString(ll)); + } + virtual void saveToStringStream(std::stringstream& out){ + optionValue=comboBox->currentText().toStdString(); + MainWindowItem::saveToStringStream(out); + } + virtual bool isValid() { return true; } +}; +class SignatureTypeComboBoxItem : public ComboBoxItem { +public: + SignatureTypeComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}; + virtual ~SignatureTypeComboBoxItem(){} + virtual void loadFromConfigOption(){//TODO + MainWindowItem::loadFromConfigOption(); + comboBox->setCurrentText(QString::number(boost::any_cast(optionValue))); + } + virtual void saveToStringStream(std::stringstream& out){//TODO + QString txt = comboBox->currentText(); + if(txt.isEmpty()) + optionValue=std::string(); + else + optionValue=(unsigned short)std::stoi(txt.toStdString()); + MainWindowItem::saveToStringStream(out); + } + virtual bool isValid() { return true; } +}; +class CheckBoxItem : public MainWindowItem { +public: + QCheckBox* checkBox; + CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_), checkBox(checkBox_){}; + virtual ~CheckBoxItem(){} + virtual void installListeners(MainWindow *mainWindow); + virtual void loadFromConfigOption(){ + MainWindowItem::loadFromConfigOption(); + checkBox->setChecked(boost::any_cast(optionValue)); + } + virtual void saveToStringStream(std::stringstream& out){ + optionValue=checkBox->isChecked(); + MainWindowItem::saveToStringStream(out); + } + virtual bool isValid() { return true; } +}; +class BaseFormattedStringItem : public BaseStringItem { +public: + QString fieldNameTranslated; + BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : + BaseStringItem(option_, lineEdit_), fieldNameTranslated(fieldNameTranslated_) {}; + virtual ~BaseFormattedStringItem(){} + virtual bool isValid()=0; +}; +class IntegerStringItem : public BaseFormattedStringItem { +public: + IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + virtual ~IntegerStringItem(){} + virtual bool isValid(){return true;} + virtual QString toString(){return QString::number(boost::any_cast(optionValue));} + virtual boost::any fromString(QString s){return boost::any(std::stoi(s.toStdString()));} +}; +class UShortStringItem : public BaseFormattedStringItem { +public: + UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + virtual ~UShortStringItem(){} + virtual bool isValid(){return true;} + virtual QString toString(){return QString::number(boost::any_cast(optionValue));} + virtual boost::any fromString(QString s){return boost::any((unsigned short)std::stoi(s.toStdString()));} +}; +class UInt32StringItem : public BaseFormattedStringItem { +public: + UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + virtual ~UInt32StringItem(){} + virtual bool isValid(){return true;} + virtual QString toString(){return QString::number(boost::any_cast(optionValue));} + virtual boost::any fromString(QString s){return boost::any((uint32_t)std::stoi(s.toStdString()));} +}; +class UInt16StringItem : public BaseFormattedStringItem { +public: + UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + virtual ~UInt16StringItem(){} + virtual bool isValid(){return true;} + virtual QString toString(){return QString::number(boost::any_cast(optionValue));} + virtual boost::any fromString(QString s){return boost::any((uint16_t)std::stoi(s.toStdString()));} +}; +class IPAddressStringItem : public BaseFormattedStringItem { +public: + IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + virtual bool isValid(){return true;} +}; +class TCPPortStringItem : public UShortStringItem { +public: + TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : + UShortStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + virtual bool isValid(){return true;} +}; + namespace Ui { class MainWindow; } -class MainWindow : public QMainWindow -{ +using namespace i2p::client; + +class TunnelPane; + +class MainWindow : public QMainWindow { Q_OBJECT public: - explicit MainWindow(QWidget *parent = 0); + explicit MainWindow(QWidget *parent=0); ~MainWindow(); + //typedef std::function DefaultValueGetter; + //#ifndef ANDROID // void setVisible(bool visible); //#endif @@ -70,17 +355,210 @@ protected: void resizeEvent(QResizeEvent* event); void onResize(); - void initFileChooser(QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton); - void initFolderChooser(QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton); - void initCombobox(QComboBox* comboBox); - void initIPAddressBox(QLineEdit* addressLineEdit, QString fieldNameTranslated); - void initTCPPortBox(QLineEdit* portLineEdit, QString fieldNameTranslated); - void initCheckBox(QCheckBox* checkBox); - void initIntegerBox(QLineEdit* numberLineEdit); - void initStringBox(QLineEdit* lineEdit); + QList configItems; + NonGUIOptionItem* logOption; + NonGUIOptionItem* daemonOption; + NonGUIOptionItem* serviceOption; + FileChooserItem* logFileNameOption; + + FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton); + void initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton); + //void initCombobox(ConfigOption option, QComboBox* comboBox); + void initLogLevelCombobox(ConfigOption option, QComboBox* comboBox); + void initSignatureTypeCombobox(ConfigOption option, QComboBox* comboBox); + void initIPAddressBox(ConfigOption option, QLineEdit* addressLineEdit, QString fieldNameTranslated); + void initTCPPortBox(ConfigOption option, QLineEdit* portLineEdit, QString fieldNameTranslated); + void initCheckBox(ConfigOption option, QCheckBox* checkBox); + void initIntegerBox(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated); + void initUInt32Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated); + void initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated); + void initStringBox(ConfigOption option, QLineEdit* lineEdit); + NonGUIOptionItem* initNonGUIOption(ConfigOption option); void loadAllConfigs(); - void saveAllConfigs(); + +public slots: + /** returns false iff not valid items present and save was aborted */ + bool saveAllConfigs(); + void reloadTunnelsConfigAndUI(); + +private: + QString datadir; + QString confpath; + QString tunconfpath; + + std::list tunnelConfigs; + std::list tunnelPanes; + + QWidget *tunnelsFormGridLayoutWidget; + QGridLayout *tunnelsFormGridLayout; + + void appendTunnelForms(); + void deleteTunnelForms(); + + + /* + + TODO signaturetype + + https://geti2p.net/spec/common-structures#certificate + все коды перечислены + orignal_, это таблица "The defined Signing Public Key types are:" ? + да + + see also : Identity.h line 55 + + */ + + template + std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const + { + return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value)); + } + + template + void ReadI2CPOptions (const Section& section, std::map& options, I2CPParameters& param + /*TODO fill param*/) const + { + std::string _INBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH); + param.setInbound_length(QString(_INBOUND_TUNNEL_LENGTH.c_str())); + std::string _OUTBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH); + param.setOutbound_length(QString(_OUTBOUND_TUNNEL_LENGTH.c_str())); + std::string _INBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY); + param.setInbound_quantity( QString(_INBOUND_TUNNELS_QUANTITY.c_str())); + std::string _OUTBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY); + param.setOutbound_quantity(QString(_OUTBOUND_TUNNELS_QUANTITY.c_str())); + std::string _TAGS_TO_SEND = options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND); + param.setCrypto_tagsToSend(QString(_TAGS_TO_SEND.c_str())); + options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY);//TODO include into param + options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);//TODO include into param + } + + + void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels () + { + boost::property_tree::ptree pt; + std::string tunConf=tunconfpath.toStdString(); + if (tunConf == "") { + // TODO: cleanup this in 2.8.0 + tunConf = i2p::fs::DataDirPath ("tunnels.cfg"); + if (i2p::fs::Exists(tunConf)) { + LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); + } else { + tunConf = i2p::fs::DataDirPath ("tunnels.conf"); + } + } + LogPrint(eLogDebug, "tunnels config file: ", tunConf); + try + { + boost::property_tree::read_ini (tunConf, pt); + } + catch (std::exception& ex) + { + LogPrint (eLogWarning, "Clients: Can't read ", tunConf, ": ", ex.what ());//TODO show err box and disable tunn.page + return; + } + + for (auto& section: pt) + { + std::string name = section.first; + try + { + std::string type = section.second.get (I2P_TUNNELS_SECTION_TYPE); + if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT + || type == I2P_TUNNELS_SECTION_TYPE_SOCKS + || type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS + || type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY + || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) + { + // mandatory params + std::string dest; + if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) + dest = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION); + int port = section.second.get (I2P_CLIENT_TUNNEL_PORT); + // optional params + std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); + std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); + int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); + i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); + // I2CP + std::map options; + I2CPParameters i2cpParameters; + ReadI2CPOptions (section, options, i2cpParameters); + + tunnelConfigs.push_back(new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters, + dest, + port, + keys, + address, + destinationPort, + sigType)); + } + else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER + || type == I2P_TUNNELS_SECTION_TYPE_HTTP + || type == I2P_TUNNELS_SECTION_TYPE_IRC + || type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) + { + // mandatory params + std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST); + int port = section.second.get (I2P_SERVER_TUNNEL_PORT); + std::string keys = section.second.get (I2P_SERVER_TUNNEL_KEYS); + // optional params + int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0); + std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); + std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, ""); + std::string webircpass = section.second.get (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, ""); + bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true); + i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); + uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN); + std::string address = section.second.get (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); + bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); + + // I2CP + std::map options; + I2CPParameters i2cpParameters; + ReadI2CPOptions (section, options, i2cpParameters); + + /* + std::set idents; + if (accessList.length () > 0) + { + size_t pos = 0, comma; + do + { + comma = accessList.find (',', pos); + i2p::data::IdentHash ident; + ident.FromBase32 (accessList.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); + idents.insert (ident); + pos = comma + 1; + } + while (comma != std::string::npos); + } + */ + tunnelConfigs.push_back(new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters, + host, + port, + keys, + inPort, + accessList, + hostOverride, + webircpass, + gzip, + sigType, + maxConns, + address, + isUniqueLocal)); + } + else + LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf);//TODO show err box and disable the tunn gui + + } + catch (std::exception& ex) + { + LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ());//TODO show err box and disable the tunn gui + } + } + } }; diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 825fb0e6..b51f36cb 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -7,7 +7,7 @@ 0 0 816 - 3000 + 5000 @@ -20,13 +20,25 @@ 0 + + + 0 + 516 + + + + + 16777215 + 516 + + 10 10 801 - 491 + 518 @@ -111,6 +123,12 @@ 0 + + + 0 + 516 + + 16777215 @@ -118,7 +136,7 @@ - 1 + 2 @@ -127,7 +145,7 @@ 0 0 671 - 491 + 5000 @@ -175,7 +193,7 @@ 0 0 701 - 460 + 450 @@ -214,7 +232,7 @@ 0 0 683 - 426 + 416 @@ -229,12 +247,471 @@ 10 11 661 - 3000 + 3048 - - - + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + SAM interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 342 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Windows-specific options + + + + + + + + 0 + 44 + + + + + 16777215 + 44 + + + + Cryptography + + + + + 0 + 20 + 661 + 22 + + + + Use ElGamal precomputed tables + + + + + + + + + 0 + 107 + + + + + 16777215 + 107 + + + + Logging + + + Qt::AlignJustify|Qt::AlignTop + + + + + -1 + 19 + 661 + 91 + + + + + QLayout::SetMinimumSize + + + + + QLayout::SetMaximumSize + + + + + Log file: + + + + + + + + + + Browse… + + + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + Log level: + + + + + + + + Error + + + + + Warn + + + + + Info + + + + + Debug + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 68 + + + + + 16777215 + 68 + + + + UPnP + + + + + 0 + 20 + 97 + 22 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Name i2pd appears in UPnP forwardings list: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + I2CP interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 @@ -244,36 +721,751 @@ 0 - 46 + 48 16777215 - 46 + 48 - Configuration file: + Tunnels configuration file: - + 0 - 18 + 20 661 31 - + - QLayout::SetMinimumSize + QLayout::SetMaximumSize - + - + + + Browse… + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + BOB interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + General options + + + + + + + + 0 + 0 + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Router external address (for incoming connections) + + + Qt::AlignJustify|Qt::AlignTop + + + + + 0 + 20 + 661 + 81 + + + + + QLayout::SetMinAndMaxSize + + + + + QLayout::SetMinAndMaxSize + + + + + Host: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMinAndMaxSize + + + + + Port (leave empty to auto-assign): + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 78 + + + + + 16777215 + 78 + + + + Addressbook settings + + + + + 0 + 20 + 661 + 31 + + + + + + + Addressbook default subscription URL for initial setup: + + + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Addressbook subscriptions URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 280 + + + + + 16777215 + 280 + + + + HTTP proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 250 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Signature type: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Various options + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Data folder (for storage of i2pd data — RI, keys, peer profiles, …): + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + Browse… @@ -432,24 +1624,406 @@ - - + + 0 - 309 + 108 16777215 - 309 + 108 - Socks proxy + Limits - + + + + 0 + 20 + 661 + 31 + + + + + + + Maximum number of transit tunnels: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Maximum number of open files (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 80 + 661 + 31 + + + + + + + Maximum size of core file in Kb (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Pid file: + + + + + 0 + 20 + 661 + 31 + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Reseeding + + + + + 0 + 20 + 661 + 22 + + + + Request SU3 signature verification + + + + + + 0 + 40 + 661 + 31 + + + + + + + SU3 file to reseed from: + + + + + + + + + + Browse… + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Reseed URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + Trust options + + + + + 0 + 20 + 661 + 21 + + + + Enable explicit trust options + + + + + + 390 + 40 + 271 + 23 + + + + + + + 0 + 40 + 391 + 21 + + + + Make direct I2P connections only to routers in specified Family: + + + + + + 0 + 60 + 661 + 16 + + + + Make direct I2P connections only to routers specified here. Comma separated list of base64 identities: + + + + + + 0 + 80 + 661 + 23 + + + + + + + 0 + 100 + 661 + 21 + + + + Should we hide our router from other routers? + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Ports + + + + + + + + 0 + 22 + + + + + 16777215 + 22 + + + + Insomnia (prevent system from sleeping) + + + + + + + + 0 + 189 + + + + + 16777215 + 189 + + + + I2PControl interface + + 0 @@ -462,7 +2036,7 @@ Enabled - + 0 @@ -471,19 +2045,19 @@ 31 - + - + IP address to listen on: - + - + Qt::Horizontal @@ -497,7 +2071,7 @@ - + 0 @@ -506,16 +2080,16 @@ 31 - + - + Port to listen on: - + 80 @@ -525,7 +2099,7 @@ - + Qt::Horizontal @@ -539,7 +2113,7 @@ - + 0 @@ -548,27 +2122,33 @@ 31 - + - + - Keys file: + Password: - + - - - Browse… + + + Qt::Horizontal - + + + 40 + 20 + + + - + 0 @@ -577,40 +2157,27 @@ 31 - + - + - Inbound tunnels length: + Certificate file: - - - - 80 - 16777215 - - - + - - - Qt::Horizontal + + + Browse… - - - 40 - 20 - - - + - + 0 @@ -619,314 +2186,30 @@ 31 - + - + - Inbound tunnels quantity: + Key file: - - - - 80 - 16777215 - - - + - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - + - Outbound tunnels length: + Browse… - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 250 - 661 - 31 - - - - - - - Outproxy address: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 280 - 661 - 31 - - - - - - - Outproxy port: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Router external address (for incoming connections) - - - Qt::AlignJustify|Qt::AlignTop - - - - - 0 - 20 - 661 - 81 - - - - - QLayout::SetMinAndMaxSize - - - - - QLayout::SetMinAndMaxSize - - - - - Host: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMinAndMaxSize - - - - - Port (leave empty to auto-assign): - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - + + 0 @@ -936,36 +2219,36 @@ 0 - 48 + 46 16777215 - 48 + 46 - Tunnels configuration file: + Configuration file: - + 0 - 20 + 18 661 31 - + - QLayout::SetMaximumSize + QLayout::SetMinimumSize - + - + Browse… @@ -975,81 +2258,37 @@ - - + + 0 - 48 + 110 16777215 - 48 + 110 - Data folder (for storage of i2pd data — RI, keys, peer profiles, …): + Websockets server - + 0 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 249 - - - - - 16777215 - 249 - - - - HTTP proxy - - - - - 0 - 20 - 97 - 22 + 85 + 21 - Enabled + Enable - + 0 @@ -1058,19 +2297,19 @@ 31 - + - + - IP address to listen on: + Address to bind websocket server on: - + - + Qt::Horizontal @@ -1084,7 +2323,7 @@ - + 0 @@ -1093,16 +2332,16 @@ 31 - + - + - Port to listen on: + Port to bind websocket server on: - + 80 @@ -1112,204 +2351,7 @@ - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - + Qt::Horizontal @@ -1517,166 +2559,24 @@ - - + + 0 - 60 + 370 16777215 - 60 - - - - - 13 - - - - General options - - - - - - - - 0 - 107 - - - - - 16777215 - 107 + 370 - Logging + Socks proxy - - Qt::AlignJustify|Qt::AlignTop - - - - - -1 - 19 - 661 - 91 - - - - - QLayout::SetMinimumSize - - - - - QLayout::SetMaximumSize - - - - - Log file: - - - - - - - - - - Browse… - - - - - - - - - QLayout::SetMinimumSize - - - - - - 0 - 0 - - - - Log level: - - - - - - - - Error - - - - - Warn - - - - - Info - - - - - Debug - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - SAM interface - - + 0 @@ -1689,7 +2589,7 @@ Enabled - + 0 @@ -1698,19 +2598,19 @@ 31 - + - + IP address to listen on: - + - + Qt::Horizontal @@ -1724,7 +2624,7 @@ - + 0 @@ -1733,16 +2633,16 @@ 31 - + - + Port to listen on: - + 80 @@ -1752,7 +2652,7 @@ - + Qt::Horizontal @@ -1766,334 +2666,7 @@ - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - BOB interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - I2CP interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 189 - - - - - 16777215 - 189 - - - - I2PControl interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - + 0 @@ -2102,54 +2675,19 @@ 31 - + - + - Password: + Keys file: - + - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Certificate file: - - - - - - - - + Browse… @@ -2157,7 +2695,7 @@ - + 0 @@ -2166,67 +2704,26 @@ 31 - + - + - Key file: + Inbound tunnels length: - - - - - - Browse… - - - - - - - - - - - - 0 - 108 - - - - - 16777215 - 108 - - - - Limits - - - - - 0 - 20 - 661 - 31 - - - - - - - Maximum number of transit tunnels: + + + + 80 + 16777215 + - - - - + Qt::Horizontal @@ -2240,28 +2737,35 @@ - + 0 - 50 + 190 661 31 - + - + - Maximum number of open files (0 — use system limit): + Inbound tunnels quantity: - + + + + 80 + 16777215 + + + - + Qt::Horizontal @@ -2275,28 +2779,35 @@ - + 0 - 80 + 220 661 31 - + - + - Maximum size of core file in Kb (0 — use system limit): + Outbound tunnels length: - + + + + 80 + 16777215 + + + - + Qt::Horizontal @@ -2310,370 +2821,147 @@ - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Ports - - - - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Insomnia (prevent system from sleeping) - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Pid file: - - + 0 - 20 + 250 661 31 - + - - - - + - Browse… + Outbound tunnels quantity: + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - - - - - - 0 - 44 - - - - - 16777215 - 44 - - - - Cryptography - - + 0 - 20 - 661 - 22 - - - - Use ElGamal precomputed tables - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Windows-specific options - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Reseeding - - - - - 0 - 20 - 661 - 22 - - - - Request SU3 signature verification - - - - - - 0 - 40 + 280 661 31 - + - + - SU3 file to reseed from: + Outproxy address: - + - - - Browse… + + + Qt::Horizontal - + + + 40 + 20 + + + - + 0 - 70 + 310 661 31 - + - + - Reseed URLs, separated by comma: + Outproxy port: - + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + - - - - - - - 0 - 78 - - - - - 16777215 - 78 - - - - Addressbook settings - - + 0 - 20 + 130 661 31 - + - + - Addressbook default subscription URL for initial setup: + SIgnature type: - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Addressbook subscriptions URLs, separated by comma: - - + - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Various options - - - - - - - - 0 - 68 - - - - - 16777215 - 68 - - - - UPnP - - - - - 0 - 20 - 97 - 22 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Name i2pd appears in UPnP forwardings list: - - - - - - - - + Qt::Horizontal @@ -2723,21 +3011,55 @@ + + + + + + Add Client Tunnel + + + + + + + Add Server Tunnel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + Qt::ScrollBarAlwaysOn - true + false + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 0 - 84 - 28 + 663 + 395 diff --git a/qt/i2pd_qt/mainwindow.ui_expandedForm_old b/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017 similarity index 99% rename from qt/i2pd_qt/mainwindow.ui_expandedForm_old rename to qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017 index feb3b738..825fb0e6 100644 --- a/qt/i2pd_qt/mainwindow.ui_expandedForm_old +++ b/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017 @@ -7,7 +7,7 @@ 0 0 816 - 5000 + 3000 @@ -26,7 +26,7 @@ 10 10 801 - 5000 + 491 @@ -114,7 +114,7 @@ 16777215 - 5000 + 516 @@ -127,7 +127,7 @@ 0 0 671 - 5000 + 491 @@ -175,7 +175,7 @@ 0 0 701 - 5000 + 460 @@ -213,8 +213,8 @@ 0 0 - 684 - 427 + 683 + 426 @@ -229,7 +229,7 @@ 10 11 661 - 5000 + 3000 @@ -2223,7 +2223,7 @@ - + @@ -2258,7 +2258,7 @@ - + @@ -2293,7 +2293,7 @@ - + @@ -2736,8 +2736,8 @@ 0 0 - 664 - 427 + 84 + 28 diff --git a/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn2 b/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn2 new file mode 100644 index 00000000..b6bcc5ea --- /dev/null +++ b/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn2 @@ -0,0 +1,2964 @@ + + + MainWindow + + + + 0 + 0 + 816 + 5000 + + + + MainWindow + + + + + 0 + 0 + + + + + + 10 + 10 + 801 + 5000 + + + + + QLayout::SetDefaultConstraint + + + + + QLayout::SetMinimumSize + + + + + true + + + Status + + + + + + + true + + + Settings + + + + + + + true + + + Tunnels + + + + + + + true + + + Restart + + + + + + + true + + + Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 516 + + + + 1 + + + + + + 0 + 0 + 671 + 5000 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Status + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 0 + 701 + 5000 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Settings + + + + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustIgnored + + + true + + + + + 0 + 0 + 683 + 426 + + + + + 0 + 0 + + + + + + 10 + 11 + 661 + 3000 + + + + + + + + 0 + 44 + + + + + 16777215 + 44 + + + + Cryptography + + + + + 0 + 20 + 661 + 22 + + + + Use ElGamal precomputed tables + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Windows-specific options + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Reseeding + + + + + 0 + 20 + 661 + 22 + + + + Request SU3 signature verification + + + + + + 0 + 40 + 661 + 31 + + + + + + + SU3 file to reseed from: + + + + + + + + + + Browse… + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Reseed URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 78 + + + + + 16777215 + 78 + + + + Addressbook settings + + + + + 0 + 20 + 661 + 31 + + + + + + + Addressbook default subscription URL for initial setup: + + + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Addressbook subscriptions URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Various options + + + + + + + + 0 + 68 + + + + + 16777215 + 68 + + + + UPnP + + + + + 0 + 20 + 97 + 22 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Name i2pd appears in UPnP forwardings list: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 215 + + + + + 16777215 + 215 + + + + Router options + + + + + 0 + 20 + 661 + 188 + + + + + + + Enable communication through ipv6 + + + + + + + Router will not accept transit tunnels at startup + + + + + + + Router will be floodfill + + + + + + + + + Bandwidth limit (integer): + + + + + + + + + + KBps + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Family (name of a family router belongs to): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMaximumSize + + + + + NetID (network ID router belongs to. The main I2P ID is 2): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 179 + + + + + 16777215 + 179 + + + + HTTP webconsole + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 321 + 22 + + + + Enable basic HTTP auth + + + + + + 60 + 120 + 601 + 31 + + + + + + + Username: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 60 + 150 + 601 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + General options + + + + + + + + 0 + 107 + + + + + 16777215 + 107 + + + + Logging + + + Qt::AlignJustify|Qt::AlignTop + + + + + -1 + 19 + 661 + 91 + + + + + QLayout::SetMinimumSize + + + + + QLayout::SetMaximumSize + + + + + Log file: + + + + + + + + + + Browse… + + + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + Log level: + + + + + + + + Error + + + + + Warn + + + + + Info + + + + + Debug + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Tunnels configuration file: + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Data folder (for storage of i2pd data — RI, keys, peer profiles, …): + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 249 + + + + + 16777215 + 249 + + + + HTTP proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 189 + + + + + 16777215 + 189 + + + + I2PControl interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Certificate file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Key file: + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 108 + + + + + 16777215 + 108 + + + + Limits + + + + + 0 + 20 + 661 + 31 + + + + + + + Maximum number of transit tunnels: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Maximum number of open files (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 80 + 661 + 31 + + + + + + + Maximum size of core file in Kb (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Ports + + + + + + + + 0 + 22 + + + + + 16777215 + 22 + + + + Insomnia (prevent system from sleeping) + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Pid file: + + + + + 0 + 20 + 661 + 31 + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 309 + + + + + 16777215 + 309 + + + + Socks proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 250 + 661 + 31 + + + + + + + Outproxy address: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 280 + 661 + 31 + + + + + + + Outproxy port: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Router external address (for incoming connections) + + + Qt::AlignJustify|Qt::AlignTop + + + + + 0 + 20 + 661 + 81 + + + + + QLayout::SetMinAndMaxSize + + + + + QLayout::SetMinAndMaxSize + + + + + Host: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMinAndMaxSize + + + + + Port (leave empty to auto-assign): + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + SAM interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + BOB interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + I2CP interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 46 + + + + + 16777215 + 46 + + + + Configuration file: + + + + + 0 + 18 + 661 + 31 + + + + + QLayout::SetMinimumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 150 + + + + + 16777215 + 50 + + + + Trust options + + + + + 0 + 20 + 661 + 21 + + + + Enable explicit trust options + + + + + + 390 + 40 + 271 + 23 + + + + + + + 0 + 40 + 391 + 21 + + + + Make direct I2P connections only to routers in specified Family: + + + + + + 0 + 60 + 661 + 16 + + + + Make direct I2P connections only to routers specified here. Comma separated list of base64 identities: + + + + + + 0 + 80 + 661 + 23 + + + + + + + 0 + 100 + 661 + 21 + + + + Should we hide our router from other routers? + + + + + + + + + + + + + + + + + 0 + 0 + 681 + 460 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Tunnels + + + + + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 663 + 426 + + + + + + + + + + + + + 0 + 0 + 681 + 451 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Restart + + + + + + + Restart i2pd + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 0 + 671 + 480 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Quit + + + + + + + Quit Now + + + + + + + Graceful Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + handleQuitButton() + handleGracefulQuitButton() + + diff --git a/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn3 b/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn3 new file mode 100644 index 00000000..9dbaca2b --- /dev/null +++ b/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn3 @@ -0,0 +1,3161 @@ + + + MainWindow + + + + 0 + 0 + 816 + 5000 + + + + MainWindow + + + + + 0 + 0 + + + + + + 10 + 10 + 801 + 5000 + + + + + QLayout::SetDefaultConstraint + + + + + QLayout::SetMinimumSize + + + + + true + + + Status + + + + + + + true + + + Settings + + + + + + + true + + + Tunnels + + + + + + + true + + + Restart + + + + + + + true + + + Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 516 + + + + 1 + + + + + + 0 + 0 + 671 + 5000 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Status + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 0 + 701 + 5000 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Settings + + + + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustIgnored + + + true + + + + + 0 + 0 + 683 + 426 + + + + + 0 + 0 + + + + + + 10 + 11 + 661 + 3000 + + + + + + + + 0 + 68 + + + + + 16777215 + 68 + + + + UPnP + + + + + 0 + 20 + 97 + 22 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Name i2pd appears in UPnP forwardings list: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 78 + + + + + 16777215 + 78 + + + + Addressbook settings + + + + + 0 + 20 + 661 + 31 + + + + + + + Addressbook default subscription URL for initial setup: + + + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Addressbook subscriptions URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Tunnels configuration file: + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 44 + + + + + 16777215 + 44 + + + + Cryptography + + + + + 0 + 20 + 661 + 22 + + + + Use ElGamal precomputed tables + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Windows-specific options + + + + + + + + 0 + 110 + + + + + 16777215 + 110 + + + + Limits + + + + + 0 + 20 + 221 + 16 + + + + Maximum number of transit tunnels: + + + + + + 0 + 50 + 331 + 16 + + + + Maximum number of open files (0 — use system limit): + + + + + + 0 + 80 + 341 + 16 + + + + Maximum size of corefile in Kb (0 — use system limit): + + + + + + 360 + 20 + 113 + 23 + + + + + + + 360 + 50 + 113 + 23 + + + + + + + 360 + 80 + 113 + 23 + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Various options + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Reseeding + + + + + 0 + 20 + 661 + 22 + + + + Request SU3 signature verification + + + + + + 0 + 40 + 661 + 31 + + + + + + + SU3 file to reseed from: + + + + + + + + + + Browse… + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Reseed URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 179 + + + + + 16777215 + 179 + + + + HTTP webconsole + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 321 + 22 + + + + Enable basic HTTP auth + + + + + + 60 + 120 + 601 + 31 + + + + + + + Username: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 60 + 150 + 601 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Data folder (for storage of i2pd data — RI, keys, peer profiles, …): + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 107 + + + + + 16777215 + 107 + + + + Logging + + + Qt::AlignJustify|Qt::AlignTop + + + + + -1 + 19 + 661 + 91 + + + + + QLayout::SetMinimumSize + + + + + QLayout::SetMaximumSize + + + + + Log file: + + + + + + + + + + Browse… + + + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + Log level: + + + + + + + + Error + + + + + Warn + + + + + Info + + + + + Debug + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + General options + + + + + + + + 0 + 0 + + + + + 0 + 215 + + + + + 16777215 + 215 + + + + Router options + + + + + 0 + 20 + 661 + 188 + + + + + + + Enable communication through ipv6 + + + + + + + Router will not accept transit tunnels at startup + + + + + + + Router will be floodfill + + + + + + + + + Bandwidth limit (integer): + + + + + + + + + + KBps + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Family (name of a family router belongs to): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMaximumSize + + + + + NetID (network ID router belongs to. The main I2P ID is 2): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 249 + + + + + 16777215 + 249 + + + + HTTP proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 189 + + + + + 16777215 + 189 + + + + I2PControl interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Certificate file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Key file: + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 108 + + + + + 16777215 + 108 + + + + Limits + + + + + 0 + 20 + 661 + 31 + + + + + + + Maximum number of transit tunnels: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Maximum number of open files (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 80 + 661 + 31 + + + + + + + Maximum size of core file in Kb (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Ports + + + + + + + + 0 + 22 + + + + + 16777215 + 22 + + + + Insomnia (prevent system from sleeping) + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Pid file: + + + + + 0 + 20 + 661 + 31 + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 309 + + + + + 16777215 + 309 + + + + Socks proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 250 + 661 + 31 + + + + + + + Outproxy address: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 280 + 661 + 31 + + + + + + + Outproxy port: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Router external address (for incoming connections) + + + Qt::AlignJustify|Qt::AlignTop + + + + + 0 + 20 + 661 + 81 + + + + + QLayout::SetMinAndMaxSize + + + + + QLayout::SetMinAndMaxSize + + + + + Host: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMinAndMaxSize + + + + + Port (leave empty to auto-assign): + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + SAM interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + BOB interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + I2CP interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 46 + + + + + 16777215 + 46 + + + + Configuration file: + + + + + 0 + 18 + 661 + 31 + + + + + QLayout::SetMinimumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + Trust options + + + + + 0 + 20 + 661 + 21 + + + + Enable explicit trust options + + + + + + 390 + 40 + 271 + 23 + + + + + + + 0 + 40 + 391 + 21 + + + + Make direct I2P connections only to routers in specified Family: + + + + + + 0 + 60 + 661 + 16 + + + + Make direct I2P connections only to routers specified here. Comma separated list of base64 identities: + + + + + + 0 + 80 + 661 + 23 + + + + + + + 0 + 100 + 661 + 21 + + + + Should we hide our router from other routers? + + + + + + + + + 0 + 110 + + + + + 16777215 + 110 + + + + Websockets server + + + + + 0 + 20 + 85 + 21 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Address to bind websocket server on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to bind websocket server on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 681 + 460 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Tunnels + + + + + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 663 + 426 + + + + + + + + + + + + + 0 + 0 + 681 + 451 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Restart + + + + + + + Restart i2pd + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 0 + 671 + 480 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Quit + + + + + + + Quit Now + + + + + + + Graceful Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + handleQuitButton() + handleGracefulQuitButton() + + diff --git a/qt/i2pd_qt/mainwindow.ui_expandedForm_old4 b/qt/i2pd_qt/mainwindow.ui_expandedForm_old4 new file mode 100644 index 00000000..691e6a9e --- /dev/null +++ b/qt/i2pd_qt/mainwindow.ui_expandedForm_old4 @@ -0,0 +1,3231 @@ + + + MainWindow + + + + 0 + 0 + 816 + 5000 + + + + MainWindow + + + + + 0 + 0 + + + + + + 10 + 10 + 801 + 5000 + + + + + QLayout::SetDefaultConstraint + + + + + QLayout::SetMinimumSize + + + + + true + + + Status + + + + + + + true + + + Settings + + + + + + + true + + + Tunnels + + + + + + + true + + + Restart + + + + + + + true + + + Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + 16777215 + 5000 + + + + 1 + + + + + + 0 + 0 + 671 + 5000 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Status + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 0 + 701 + 5000 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Settings + + + + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustIgnored + + + true + + + + + 0 + 0 + 683 + 4966 + + + + + 0 + 0 + + + + + + 10 + 11 + 661 + 4920 + + + + + + + + 0 + 68 + + + + + 16777215 + 68 + + + + UPnP + + + + + 0 + 20 + 97 + 22 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Name i2pd appears in UPnP forwardings list: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 78 + + + + + 16777215 + 78 + + + + Addressbook settings + + + + + 0 + 20 + 661 + 31 + + + + + + + Addressbook default subscription URL for initial setup: + + + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Addressbook subscriptions URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Tunnels configuration file: + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 44 + + + + + 16777215 + 44 + + + + Cryptography + + + + + 0 + 20 + 661 + 22 + + + + Use ElGamal precomputed tables + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Windows-specific options + + + + + + + + 0 + 110 + + + + + 16777215 + 110 + + + + Limits + + + + + 0 + 20 + 221 + 16 + + + + Maximum number of transit tunnels: + + + + + + 0 + 50 + 331 + 16 + + + + Maximum number of open files (0 — use system limit): + + + + + + 0 + 80 + 341 + 16 + + + + Maximum size of corefile in Kb (0 — use system limit): + + + + + + 360 + 20 + 113 + 23 + + + + + + + 360 + 50 + 113 + 23 + + + + + + + 360 + 80 + 113 + 23 + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Various options + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Reseeding + + + + + 0 + 20 + 661 + 22 + + + + Request SU3 signature verification + + + + + + 0 + 40 + 661 + 31 + + + + + + + SU3 file to reseed from: + + + + + + + + + + Browse… + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Reseed URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 179 + + + + + 16777215 + 179 + + + + HTTP webconsole + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 321 + 22 + + + + Enable basic HTTP auth + + + + + + 60 + 120 + 601 + 31 + + + + + + + Username: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 60 + 150 + 601 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Data folder (for storage of i2pd data — RI, keys, peer profiles, …): + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 107 + + + + + 16777215 + 107 + + + + Logging + + + Qt::AlignJustify|Qt::AlignTop + + + + + -1 + 19 + 661 + 91 + + + + + QLayout::SetMinimumSize + + + + + QLayout::SetMaximumSize + + + + + Log file: + + + + + + + + + + Browse… + + + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + Log level: + + + + + + + + Error + + + + + Warn + + + + + Info + + + + + Debug + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + General options + + + + + + + + 0 + 0 + + + + + 0 + 215 + + + + + 16777215 + 215 + + + + Router options + + + + + 0 + 20 + 661 + 188 + + + + + + + Enable communication through ipv6 + + + + + + + Router will not accept transit tunnels at startup + + + + + + + Router will be floodfill + + + + + + + + + Bandwidth limit (integer): + + + + + + + + + + KBps + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Family (name of a family router belongs to): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMaximumSize + + + + + NetID (network ID router belongs to. The main I2P ID is 2): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 280 + + + + + 16777215 + 280 + + + + HTTP proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 250 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Signature type: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 189 + + + + + 16777215 + 189 + + + + I2PControl interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Certificate file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Key file: + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 108 + + + + + 16777215 + 108 + + + + Limits + + + + + 0 + 20 + 661 + 31 + + + + + + + Maximum number of transit tunnels: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Maximum number of open files (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 80 + 661 + 31 + + + + + + + Maximum size of core file in Kb (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Ports + + + + + + + + 0 + 22 + + + + + 16777215 + 22 + + + + Insomnia (prevent system from sleeping) + + + + + + + + 0 + 48 + + + + + 16777215 + 48 + + + + Pid file: + + + + + 0 + 20 + 661 + 31 + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 0 + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Router external address (for incoming connections) + + + Qt::AlignJustify|Qt::AlignTop + + + + + 0 + 20 + 661 + 81 + + + + + QLayout::SetMinAndMaxSize + + + + + QLayout::SetMinAndMaxSize + + + + + Host: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMinAndMaxSize + + + + + Port (leave empty to auto-assign): + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + SAM interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 342 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + BOB interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + I2CP interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 46 + + + + + 16777215 + 46 + + + + Configuration file: + + + + + 0 + 18 + 661 + 31 + + + + + QLayout::SetMinimumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 120 + + + + + 16777215 + 120 + + + + Trust options + + + + + 0 + 20 + 661 + 21 + + + + Enable explicit trust options + + + + + + 390 + 40 + 271 + 23 + + + + + + + 0 + 40 + 391 + 21 + + + + Make direct I2P connections only to routers in specified Family: + + + + + + 0 + 60 + 661 + 16 + + + + Make direct I2P connections only to routers specified here. Comma separated list of base64 identities: + + + + + + 0 + 80 + 661 + 23 + + + + + + + 0 + 100 + 661 + 21 + + + + Should we hide our router from other routers? + + + + + + + + + 0 + 110 + + + + + 16777215 + 110 + + + + Websockets server + + + + + 0 + 20 + 85 + 21 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Address to bind websocket server on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to bind websocket server on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 340 + + + + + 16777215 + 340 + + + + Socks proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 250 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 280 + 661 + 31 + + + + + + + Outproxy address: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 310 + 661 + 31 + + + + + + + Outproxy port: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + SIgnature type: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 681 + 460 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Tunnels + + + + + + + Qt::ScrollBarAlwaysOn + + + true + + + + + 0 + 0 + 663 + 426 + + + + + + + + + + + + + 0 + 0 + 681 + 451 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Restart + + + + + + + Restart i2pd + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + 0 + 0 + 671 + 480 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Quit + + + + + + + Quit Now + + + + + + + Graceful Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + handleQuitButton() + handleGracefulQuitButton() + + diff --git a/qt/i2pd_qt/tunnelform.ui b/qt/i2pd_qt/tunnelform.ui new file mode 100644 index 00000000..61e54770 --- /dev/null +++ b/qt/i2pd_qt/tunnelform.ui @@ -0,0 +1,104 @@ + + + Form + + + + 0 + 0 + 527 + 452 + + + + Form + + + + + 0 + 0 + 521 + 451 + + + + + + + server_tunnel_name + + + + + 0 + 20 + 511 + 421 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Delete + + + + + + + + + + + Host: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + From b3050af1a702e37ccd30b8cdc5645faae59277ca Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Mon, 3 Apr 2017 03:39:24 +0800 Subject: [PATCH 14/23] some work on desktop qt gui --- qt/i2pd_qt/ClientTunnelPane.cpp | 155 +++++++++++++++++++++++++++++++- qt/i2pd_qt/ClientTunnelPane.h | 46 +++++++++- qt/i2pd_qt/ServerTunnelPane.cpp | 12 ++- qt/i2pd_qt/ServerTunnelPane.h | 3 +- qt/i2pd_qt/TunnelConfig.h | 1 + qt/i2pd_qt/TunnelPane.cpp | 8 +- qt/i2pd_qt/TunnelPane.h | 2 +- qt/i2pd_qt/mainwindow.cpp | 11 ++- 8 files changed, 221 insertions(+), 17 deletions(-) diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp index 92c7bb5f..e03b5fd3 100644 --- a/qt/i2pd_qt/ClientTunnelPane.cpp +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -1,13 +1,16 @@ #include "ClientTunnelPane.h" +#include "../../ClientContext.h" ClientTunnelPane::ClientTunnelPane() { } +void ClientTunnelPane::setGroupBoxTitle(const QString & title) { + clientTunnelNameGroupBox->setTitle(title); +} + void ClientTunnelPane::deleteClientTunnelForm(QGridLayout *tunnelsFormGridLayout) { - throw "TODO"; - /*TODO tunnelsFormGridLayout->removeWidget(clientTunnelNameGroupBox); clientTunnelNameGroupBox->deleteLater(); @@ -15,7 +18,155 @@ void ClientTunnelPane::deleteClientTunnelForm(QGridLayout *tunnelsFormGridLayout gridLayoutWidget_2->deleteLater(); gridLayoutWidget_2=nullptr; +} + +void ClientTunnelPane::appendClientTunnelForm( + ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow) { + + ClientTunnelPane& ui = *this; + + clientTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget); + clientTunnelNameGroupBox->setObjectName(QStringLiteral("clientTunnelNameGroupBox")); + + //tunnel + ui.gridLayoutWidget_2 = new QWidget(clientTunnelNameGroupBox); + + QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2); + tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox")); + tunnelTypeComboBox->addItem("Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT); + tunnelTypeComboBox->addItem("Socks", i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS); + tunnelTypeComboBox->addItem("Websocks", i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS); + tunnelTypeComboBox->addItem("HTTP Proxy", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY); + tunnelTypeComboBox->addItem("UDP Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT); + + gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, (7+5)*40)); + + setupTunnelPane(tunnelConfig, + clientTunnelNameGroupBox, + gridLayoutWidget_2, tunnelTypeComboBox, + tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelsRow); + //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, (7+5)*40+10)); + { + const QString& type = tunnelConfig->getType(); + int index=0; + if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT)tunnelTypeComboBox->setCurrentIndex(index); + ++index; + if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS)tunnelTypeComboBox->setCurrentIndex(index); + ++index; + if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)tunnelTypeComboBox->setCurrentIndex(index); + ++index; + if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)tunnelTypeComboBox->setCurrentIndex(index); + ++index; + if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)tunnelTypeComboBox->setCurrentIndex(index); + ++index; + } + + /* + std::string destination; */ + + //host + ui.horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.destinationLabel = new QLabel(gridLayoutWidget_2); + destinationLabel->setObjectName(QStringLiteral("destinationLabel")); + horizontalLayout_2->addWidget(destinationLabel); + ui.destinationLineEdit = new QLineEdit(gridLayoutWidget_2); + destinationLineEdit->setObjectName(QStringLiteral("destinationLineEdit")); + destinationLineEdit->setText(tunnelConfig->getdest().c_str()); + horizontalLayout_2->addWidget(destinationLineEdit); + ui.destinationHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(destinationHorizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, 2, 0, 1, 1); + + /* + * int port; + */ + int gridIndex = 2; + { + int port = tunnelConfig->getport(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.portLabel = new QLabel(gridLayoutWidget_2); + portLabel->setObjectName(QStringLiteral("portLabel")); + horizontalLayout_2->addWidget(portLabel); + ui.portLineEdit = new QLineEdit(gridLayoutWidget_2); + portLineEdit->setObjectName(QStringLiteral("portLineEdit")); + portLineEdit->setText(QString::number(port)); + portLineEdit->setMaximumWidth(80); + horizontalLayout_2->addWidget(portLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + /* + * std::string keys; +*/ + { + std::string keys = tunnelConfig->getkeys(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.keysLabel = new QLabel(gridLayoutWidget_2); + keysLabel->setObjectName(QStringLiteral("keysLabel")); + horizontalLayout_2->addWidget(keysLabel); + ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2); + keysLineEdit->setObjectName(QStringLiteral("keysLineEdit")); + keysLineEdit->setText(keys.c_str()); + horizontalLayout_2->addWidget(keysLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + /* + * std::string address; + */ + { + std::string address = tunnelConfig->getaddress(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.addressLabel = new QLabel(gridLayoutWidget_2); + addressLabel->setObjectName(QStringLiteral("addressLabel")); + horizontalLayout_2->addWidget(addressLabel); + ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2); + addressLineEdit->setObjectName(QStringLiteral("addressLineEdit")); + addressLineEdit->setText(address.c_str()); + horizontalLayout_2->addWidget(addressLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + + /* + int destinationPort; + i2p::data::SigningKeyType sigType; +*/ + { + int destinationPort = tunnelConfig->getdestinationPort(); + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.destinationPortLabel = new QLabel(gridLayoutWidget_2); + destinationPortLabel->setObjectName(QStringLiteral("destinationPortLabel")); + horizontalLayout_2->addWidget(destinationPortLabel); + ui.destinationPortLineEdit = new QLineEdit(gridLayoutWidget_2); + destinationPortLineEdit->setObjectName(QStringLiteral("destinationPortLineEdit")); + destinationPortLineEdit->setText(QString::number(destinationPort)); + destinationPortLineEdit->setMaximumWidth(80); + horizontalLayout_2->addWidget(destinationPortLineEdit); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + } + { + i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); + //combo box + //TODO sigtype + } + { + I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); + appendControlsForI2CPParameters(i2cpParameters, gridIndex); + } + + retranslateClientTunnelForm(ui); } ServerTunnelPane* ClientTunnelPane::asServerTunnelPane(){return nullptr;} diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h index d4486540..0496e660 100644 --- a/qt/i2pd_qt/ClientTunnelPane.h +++ b/qt/i2pd_qt/ClientTunnelPane.h @@ -5,17 +5,61 @@ #include "TunnelPane.h" +class ClientTunnelConfig; + class ServerTunnelPane; class TunnelPane; class ClientTunnelPane : public TunnelPane { + Q_OBJECT public: ClientTunnelPane(); + virtual ~ClientTunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane(); virtual ClientTunnelPane* asClientTunnelPane(); + void appendClientTunnelForm(ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, + QGridLayout *tunnelsFormGridLayout, int tunnelsRow); void deleteClientTunnelForm(QGridLayout *tunnelsFormGridLayout); +private: + QGroupBox *clientTunnelNameGroupBox; + + //tunnel + QWidget *gridLayoutWidget_2; + + //destination + QHBoxLayout *horizontalLayout_2; + QLabel *destinationLabel; + QLineEdit *destinationLineEdit; + QSpacerItem *destinationHorizontalSpacer; + + //port + QLabel * portLabel; + QLineEdit * portLineEdit; + + //keys + QLabel * keysLabel; + QLineEdit * keysLineEdit; + + //address + QLabel * addressLabel; + QLineEdit * addressLineEdit; + + //destinationPort + QLabel * destinationPortLabel; + QLineEdit * destinationPortLineEdit; + protected slots: - virtual void setGroupBoxTitle(const QString & title){}//TODO + virtual void setGroupBoxTitle(const QString & title); + +private: + void retranslateClientTunnelForm(ClientTunnelPane& /*ui*/) { + destinationLabel->setText(QApplication::translate("srvTunForm", "Destination:", 0)); + portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0)); + keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0)); + destinationPortLabel->setText(QApplication::translate("srvTunForm", "Destination port:", 0)); + addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0)); + } + }; #endif // CLIENTTUNNELPANE_H diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp index c9b09e7e..b90b82c2 100644 --- a/qt/i2pd_qt/ServerTunnelPane.cpp +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -8,9 +8,7 @@ void ServerTunnelPane::setGroupBoxTitle(const QString & title) { } void ServerTunnelPane::appendServerTunnelForm( - ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout) { - - tunnelsFormGridLayoutWidget->resize(527, 452); + ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow) { ServerTunnelPane& ui = *this; @@ -27,12 +25,14 @@ void ServerTunnelPane::appendServerTunnelForm( tunnelTypeComboBox->addItem("IRC", i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC); tunnelTypeComboBox->addItem("UDP Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER); - gridLayoutWidget_2->setGeometry(QRect(0, 10, 561, 18*40+10)); + gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, 18*60)); + setupTunnelPane(tunnelConfig, serverTunnelNameGroupBox, gridLayoutWidget_2, tunnelTypeComboBox, - tunnelsFormGridLayoutWidget, tunnelsFormGridLayout); + tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelsRow); + //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, 18*40+10)); { const QString& type = tunnelConfig->getType(); @@ -219,8 +219,6 @@ void ServerTunnelPane::appendServerTunnelForm( appendControlsForI2CPParameters(i2cpParameters, gridIndex); } - tunnelsFormGridLayout->addWidget(serverTunnelNameGroupBox, 0, 0, 1, 1); - retranslateServerTunnelForm(ui); } diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h index d4ed549d..5b514373 100644 --- a/qt/i2pd_qt/ServerTunnelPane.h +++ b/qt/i2pd_qt/ServerTunnelPane.h @@ -33,7 +33,8 @@ public: virtual ServerTunnelPane* asServerTunnelPane(); virtual ClientTunnelPane* asClientTunnelPane(); - void appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout); + void appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, + QGridLayout *tunnelsFormGridLayout, int tunnelsRow); void deleteServerTunnelForm(QGridLayout *tunnelsFormGridLayout); private: diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h index f37809d9..2c967395 100644 --- a/qt/i2pd_qt/TunnelConfig.h +++ b/qt/i2pd_qt/TunnelConfig.h @@ -54,6 +54,7 @@ class TunnelConfig { std::string name; public: TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_): type(type_), name(name_), i2cpParameters(i2cpParameters_) {} + virtual ~TunnelConfig(){} const QString& getType(){return type;} const std::string& getName(){return name;} void setType(const QString& type_){type=type_;} diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index 3b76a124..d0d3a28e 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -7,8 +7,14 @@ void TunnelPane::setupTunnelPane( TunnelConfig* tunnelConfig, QGroupBox *tunnelGroupBox, QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, - QWidget */*tunnelsFormGridLayoutWidget*/, QGridLayout */*tunnelsFormGridLayout*/) { + QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow) { + tunnelsFormGridLayoutWidget->resize(527, tunnelsFormGridLayoutWidget->height()+gridLayoutWidget_2->height()); + tunnelGroupBox->resize(gridLayoutWidget_2->width(), gridLayoutWidget_2->height()); + tunnelsFormGridLayout->addWidget(tunnelGroupBox, tunnelsRow, 0); + + this->tunnelGroupBox=tunnelGroupBox; + gridLayoutWidget_2->setObjectName(QStringLiteral("gridLayoutWidget_2")); this->gridLayoutWidget_2=gridLayoutWidget_2; tunnelGridLayout = new QGridLayout(gridLayoutWidget_2); diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index 19021ca5..ddf546ce 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -66,7 +66,7 @@ protected: TunnelConfig* tunnelConfig, QGroupBox *tunnelGroupBox, QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, - QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout); + QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow); void appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex); public: int height() { diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 136dae07..37eea4c4 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -509,22 +509,24 @@ void MainWindowItem::installListeners(MainWindow *mainWindow) {} void MainWindow::appendTunnelForms() { int height=0; + tunnelsFormGridLayoutWidget->setGeometry(0,0,0,0); for(std::list::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { TunnelConfig* tunconf = *it; ServerTunnelConfig* stc = tunconf->asServerTunnelConfig(); if(stc){ ServerTunnelPane * tunnelPane=new ServerTunnelPane(); - tunnelPane->appendServerTunnelForm(stc, tunnelsFormGridLayoutWidget, tunnelsFormGridLayout); + tunnelPane->appendServerTunnelForm(stc, tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelPanes.size()); height+=tunnelPane->height(); - qDebug() << "tun.height:" << height; + qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); tunnelPanes.push_back(tunnelPane); continue; } ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig(); if(ctc){ - ClientTunnelPane * tunnelPane=new ClientTunnelPane();//TODO + ClientTunnelPane * tunnelPane=new ClientTunnelPane(); + tunnelPane->appendClientTunnelForm(ctc, tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelPanes.size()); height+=tunnelPane->height(); - qDebug() << "tun.height:" << height; + qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); tunnelPanes.push_back(tunnelPane); continue; } @@ -532,6 +534,7 @@ void MainWindow::appendTunnelForms() { } qDebug() << "tun.setting height:" << height; tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, height)); + tunnelsFormGridLayout->invalidate(); ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height)); } void MainWindow::deleteTunnelForms() { From 61e1e7fe8fb94070a5a81aaffe1305e88b67ae8c Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Mon, 3 Apr 2017 21:45:56 +0800 Subject: [PATCH 15/23] added one missing sigtype to Identity.h. Some work on qt gui. --- qt/i2pd_qt/ClientTunnelPane.cpp | 18 +- qt/i2pd_qt/ClientTunnelPane.h | 16 +- qt/i2pd_qt/ServerTunnelPane.cpp | 16 +- qt/i2pd_qt/ServerTunnelPane.h | 7 + qt/i2pd_qt/SignatureTypeComboboxFactory.cpp | 2 + qt/i2pd_qt/SignatureTypeComboboxFactory.h | 76 ++++++++ qt/i2pd_qt/TunnelConfig.h | 3 +- qt/i2pd_qt/TunnelPane.h | 1 - qt/i2pd_qt/i2pd_qt.pro | 190 +------------------- qt/i2pd_qt/mainwindow.h | 7 - 10 files changed, 133 insertions(+), 203 deletions(-) create mode 100644 qt/i2pd_qt/SignatureTypeComboboxFactory.cpp create mode 100644 qt/i2pd_qt/SignatureTypeComboboxFactory.h diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp index e03b5fd3..b7abb0a7 100644 --- a/qt/i2pd_qt/ClientTunnelPane.cpp +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -1,5 +1,6 @@ #include "ClientTunnelPane.h" #include "../../ClientContext.h" +#include "SignatureTypeComboboxFactory.h" ClientTunnelPane::ClientTunnelPane() { @@ -39,7 +40,7 @@ void ClientTunnelPane::appendClientTunnelForm( tunnelTypeComboBox->addItem("HTTP Proxy", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY); tunnelTypeComboBox->addItem("UDP Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT); - gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, (7+5)*40)); + gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, (7+4)*60)); setupTunnelPane(tunnelConfig, clientTunnelNameGroupBox, @@ -158,8 +159,17 @@ void ClientTunnelPane::appendClientTunnelForm( } { i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); - //combo box - //TODO sigtype + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.sigTypeLabel = new QLabel(gridLayoutWidget_2); + sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel")); + horizontalLayout_2->addWidget(sigTypeLabel); + ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType); + sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox")); + horizontalLayout_2->addWidget(sigTypeComboBox); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); } { I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); @@ -167,6 +177,8 @@ void ClientTunnelPane::appendClientTunnelForm( } retranslateClientTunnelForm(ui); + + tunnelGridLayout->invalidate(); } ServerTunnelPane* ClientTunnelPane::asServerTunnelPane(){return nullptr;} diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h index 0496e660..df4420f9 100644 --- a/qt/i2pd_qt/ClientTunnelPane.h +++ b/qt/i2pd_qt/ClientTunnelPane.h @@ -48,16 +48,22 @@ private: QLabel * destinationPortLabel; QLineEdit * destinationPortLineEdit; + //sigType + QLabel * sigTypeLabel; + QComboBox * sigTypeComboBox; + protected slots: virtual void setGroupBoxTitle(const QString & title); private: void retranslateClientTunnelForm(ClientTunnelPane& /*ui*/) { - destinationLabel->setText(QApplication::translate("srvTunForm", "Destination:", 0)); - portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0)); - keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0)); - destinationPortLabel->setText(QApplication::translate("srvTunForm", "Destination port:", 0)); - addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0)); + typeLabel->setText(QApplication::translate("cltTunForm", "Client tunnel type:", 0)); + destinationLabel->setText(QApplication::translate("cltTunForm", "Destination:", 0)); + portLabel->setText(QApplication::translate("cltTunForm", "Port:", 0)); + keysLabel->setText(QApplication::translate("cltTunForm", "Keys:", 0)); + destinationPortLabel->setText(QApplication::translate("cltTunForm", "Destination port:", 0)); + addressLabel->setText(QApplication::translate("cltTunForm", "Address:", 0)); + sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0)); } }; diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp index b90b82c2..4a1c8971 100644 --- a/qt/i2pd_qt/ServerTunnelPane.cpp +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -1,5 +1,6 @@ #include "ServerTunnelPane.h" #include "../../ClientContext.h" +#include "SignatureTypeComboboxFactory.h" ServerTunnelPane::ServerTunnelPane(): TunnelPane() {} @@ -168,8 +169,17 @@ void ServerTunnelPane::appendServerTunnelForm( } { i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); - //combo box - //TODO sigtype + QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); + ui.sigTypeLabel = new QLabel(gridLayoutWidget_2); + sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel")); + horizontalLayout_2->addWidget(sigTypeLabel); + ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType); + sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox")); + horizontalLayout_2->addWidget(sigTypeComboBox); + QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout_2->addItem(horizontalSpacer); + tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); } { uint32_t maxConns = tunnelConfig->getmaxConns(); @@ -220,6 +230,8 @@ void ServerTunnelPane::appendServerTunnelForm( } retranslateServerTunnelForm(ui); + + tunnelGridLayout->invalidate(); } void ServerTunnelPane::deleteServerTunnelForm(QGridLayout *tunnelsFormGridLayout) { diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h index 5b514373..2bab41d6 100644 --- a/qt/i2pd_qt/ServerTunnelPane.h +++ b/qt/i2pd_qt/ServerTunnelPane.h @@ -87,11 +87,16 @@ private: //isUniqueLocal QCheckBox * isUniqueLocalCheckBox; + //sigType + QLabel * sigTypeLabel; + QComboBox * sigTypeComboBox; + protected slots: virtual void setGroupBoxTitle(const QString & title); private: void retranslateServerTunnelForm(ServerTunnelPane& /*ui*/) { + typeLabel->setText(QApplication::translate("srvTunForm", "Server tunnel type:", 0)); hostLabel->setText(QApplication::translate("srvTunForm", "Host:", 0)); portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0)); keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0)); @@ -104,6 +109,8 @@ private: gzipCheckBox->setText(QApplication::translate("srvTunForm", "GZip", 0)); isUniqueLocalCheckBox->setText(QApplication::translate("srvTunForm", "Is unique local", 0)); + + sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0)); } }; diff --git a/qt/i2pd_qt/SignatureTypeComboboxFactory.cpp b/qt/i2pd_qt/SignatureTypeComboboxFactory.cpp new file mode 100644 index 00000000..9313741a --- /dev/null +++ b/qt/i2pd_qt/SignatureTypeComboboxFactory.cpp @@ -0,0 +1,2 @@ +#include "SignatureTypeComboboxFactory.h" + diff --git a/qt/i2pd_qt/SignatureTypeComboboxFactory.h b/qt/i2pd_qt/SignatureTypeComboboxFactory.h new file mode 100644 index 00000000..9c9190ed --- /dev/null +++ b/qt/i2pd_qt/SignatureTypeComboboxFactory.h @@ -0,0 +1,76 @@ +#ifndef SIGNATURETYPECOMBOBOXFACTORY_H +#define SIGNATURETYPECOMBOBOXFACTORY_H + +#include +#include +#include +#include "../../Identity.h" + +class SignatureTypeComboBoxFactory +{ + static const QVariant& createUserData(const uint16_t sigType) { + return QVariant::fromValue((uint)sigType); + } + + static void addItem(QComboBox* signatureTypeCombobox, QString text, const uint16_t sigType) { + const QVariant userData = createUserData(sigType); + signatureTypeCombobox->addItem(text, userData); + } + +public: + static QComboBox* createSignatureTypeComboBox(QWidget* parent, uint16_t selectedSigType) { + QComboBox* signatureTypeCombobox = new QComboBox(parent); + /* + https://geti2p.net/spec/common-structures#certificate + все коды перечислены + это таблица "The defined Signing Public Key types are:" ? + да + + see also: Identity.h line 55 + */ + int index=0; + bool foundSelected=false; + + using namespace i2p::data; + + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "DSA_SHA1", 0), SIGNING_KEY_TYPE_DSA_SHA1); //0 + if(selectedSigType==SIGNING_KEY_TYPE_DSA_SHA1){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA256_P256", 0), SIGNING_KEY_TYPE_ECDSA_SHA256_P256); //1 + if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA256_P256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA384_P384", 0), SIGNING_KEY_TYPE_ECDSA_SHA384_P384); //2 + if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA384_P384){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA512_P521", 0), SIGNING_KEY_TYPE_ECDSA_SHA512_P521); //3 + if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA512_P521){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA256_2048", 0), SIGNING_KEY_TYPE_RSA_SHA256_2048); //4 + if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA256_2048){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA384_3072", 0), SIGNING_KEY_TYPE_RSA_SHA384_3072); //5 + if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA384_3072){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA512_4096", 0), SIGNING_KEY_TYPE_RSA_SHA512_4096); //6 + if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA512_4096){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); //7 + if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519PH", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519PH); //8 + if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519PH){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + // the following signature type should never appear in netid=2 + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_A_GOSTR3411", 0), SIGNING_KEY_TYPE_GOSTR3410_A_GOSTR3411); //65280 + if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_A_GOSTR3411){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + if(!foundSelected){ + addItem(signatureTypeCombobox, QString::number(selectedSigType), selectedSigType); //unknown sigtype + signatureTypeCombobox->setCurrentIndex(index); + } + + return signatureTypeCombobox; + } +}; + +#endif // SIGNATURETYPECOMBOBOXFACTORY_H diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h index 2c967395..806d082c 100644 --- a/qt/i2pd_qt/TunnelConfig.h +++ b/qt/i2pd_qt/TunnelConfig.h @@ -108,7 +108,8 @@ public: port(port_), keys(keys_), address(address_), - destinationPort(destinationPort_) {} + destinationPort(destinationPort_), + sigType(sigType_){} std::string& getdest(){return dest;} int getport(){return port;} std::string & getkeys(){return keys;} diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index ddf546ce..af6c7351 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -79,7 +79,6 @@ private: void retranslateTunnelForm(TunnelPane& ui) { ui.deletePushButton->setText(QApplication::translate("tunForm", "Delete Tunnel", 0)); ui.nameLabel->setText(QApplication::translate("tunForm", "Tunnel name:", 0)); - ui.typeLabel->setText(QApplication::translate("tunForm", "Server tunnel type:", 0)); } void retranslateI2CPParameters() { diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 6ce21726..247dc8a8 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -69,18 +69,18 @@ INCLUDEPATH += . FORMS += mainwindow.ui \ tunnelform.ui -CONFIG += mobility - -MOBILITY = - LIBS += -lz android { message("Using Android settings") - DEFINES += ANDROID=1 + DEFINES += ANDROID=1 DEFINES += __ANDROID__ - INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ + CONFIG += mobility + + MOBILITY = + + INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ $$OPENSSL_PATH/openssl-1.0.2/include \ $$MINIUPNP_PATH/miniupnp-2.0/include \ $$IFADDRS_PATH @@ -142,181 +142,3 @@ linux:!android { #INSTALLS += sources } -DISTFILES += \ - ../../android/bin/classes.dex \ - ../../android/bin/I2PD.apk \ - ../../android/bin/AndroidManifest.xml \ - ../../android/AndroidManifest.xml \ - ../../libi2pd.a \ - ../../libi2pdclient.a \ - ../../i2pd \ - ../../android/bin/classes/org/purplei2p/i2pd/BuildConfig.class \ - ../../android/bin/classes/org/purplei2p/i2pd/DaemonSingleton$1.class \ - ../../android/bin/classes/org/purplei2p/i2pd/DaemonSingleton$State.class \ - ../../android/bin/classes/org/purplei2p/i2pd/DaemonSingleton$StateChangeListener.class \ - ../../android/bin/classes/org/purplei2p/i2pd/DaemonSingleton.class \ - ../../android/bin/classes/org/purplei2p/i2pd/ForegroundService$LocalBinder.class \ - ../../android/bin/classes/org/purplei2p/i2pd/ForegroundService.class \ - ../../android/bin/classes/org/purplei2p/i2pd/I2PD$1$1.class \ - ../../android/bin/classes/org/purplei2p/i2pd/I2PD$1.class \ - ../../android/bin/classes/org/purplei2p/i2pd/I2PD$2.class \ - ../../android/bin/classes/org/purplei2p/i2pd/I2PD$3$1.class \ - ../../android/bin/classes/org/purplei2p/i2pd/I2PD$3.class \ - ../../android/bin/classes/org/purplei2p/i2pd/I2PD.class \ - ../../android/bin/classes/org/purplei2p/i2pd/I2PD_JNI.class \ - ../../android/bin/classes/org/purplei2p/i2pd/NetworkStateChangeReceiver.class \ - ../../android/bin/classes/org/purplei2p/i2pd/R$attr.class \ - ../../android/bin/classes/org/purplei2p/i2pd/R$drawable.class \ - ../../android/bin/classes/org/purplei2p/i2pd/R$id.class \ - ../../android/bin/classes/org/purplei2p/i2pd/R$menu.class \ - ../../android/bin/classes/org/purplei2p/i2pd/R$string.class \ - ../../android/bin/classes/org/purplei2p/i2pd/R.class \ - ../../android/bin/dexedLibs/android-support-v4-bddf40bf5b9bc79d6d6d4419e6234206.jar \ - ../../android/libs/android-support-v4.jar \ - android/libs/android-support-v4.jar \ - ../../debian/i2pd.init \ - ../../debian/postinst \ - ../../debian/postrm \ - ../../entrypoint.sh \ - ../../contrib/certificates/family/i2p-dev.crt \ - ../../contrib/certificates/family/i2pd-dev.crt \ - ../../contrib/certificates/family/mca2-i2p.crt \ - ../../contrib/certificates/family/volatile.crt \ - ../../contrib/certificates/reseed/atomike_at_mail.i2p.crt \ - ../../contrib/certificates/reseed/backup_at_mail.i2p.crt \ - ../../contrib/certificates/reseed/bugme_at_mail.i2p.crt \ - ../../contrib/certificates/reseed/echelon_at_mail.i2p.crt \ - ../../contrib/certificates/reseed/hottuna_at_mail.i2p.crt \ - ../../contrib/certificates/reseed/meeh_at_mail.i2p.crt \ - ../../contrib/certificates/reseed/parg_at_mail.i2p.crt \ - ../../contrib/certificates/reseed/r4sas_at_mail.i2p.crt \ - ../../contrib/certificates/reseed/zmx_at_mail.i2p.crt \ - ../../contrib/certificates/router/killyourtv_at_mail.i2p.crt \ - ../../contrib/certificates/router/orignal_at_mail.i2p.crt \ - ../../contrib/certificates/router/str4d_at_mail.i2p.crt \ - ../../contrib/certificates/router/zzz_at_mail.i2p.crt \ - ../../build/fig.yml \ - ../../appveyor.yml \ - ../../android/res/menu/options_main.xml \ - ../../android/res/values/strings.xml \ - ../../android/build.xml \ - android/res/layout/splash.xml \ - android/res/values/libs.xml \ - android/res/values/strings.xml \ - android/res/values-de/strings.xml \ - android/res/values-el/strings.xml \ - android/res/values-es/strings.xml \ - android/res/values-et/strings.xml \ - android/res/values-fa/strings.xml \ - android/res/values-fr/strings.xml \ - android/res/values-id/strings.xml \ - android/res/values-it/strings.xml \ - android/res/values-ja/strings.xml \ - android/res/values-ms/strings.xml \ - android/res/values-nb/strings.xml \ - android/res/values-nl/strings.xml \ - android/res/values-pl/strings.xml \ - android/res/values-pt-rBR/strings.xml \ - android/res/values-ro/strings.xml \ - android/res/values-rs/strings.xml \ - android/res/values-ru/strings.xml \ - android/res/values-zh-rCN/strings.xml \ - android/res/values-zh-rTW/strings.xml \ - ../../android/bin/resources.ap_ \ - ../../Win32/ictoopie.bmp \ - ../../Win32/mask.bmp \ - ../../android/bin/res/crunch/drawable/icon.png \ - ../../android/bin/res/crunch/drawable/itoopie_notification_icon.png \ - ../../android/res/drawable/icon.png \ - ../../android/res/drawable/itoopie_notification_icon.png \ - ../../docs/itoopieImage.png \ - android/res/drawable/itoopie_notification_icon.png \ - android/res/drawable-hdpi/icon.png \ - ../../Win32/ictoopie.ico \ - ../../Win32/mask.ico \ - docs/patch_openssl_so_libs.html \ - ../../android/bin/jarlist.cache \ - ../../android/jni/Android.mk \ - ../../android/jni/Application.mk \ - ../../android/proguard-project.txt \ - ../../android/project.properties \ - ../../build/cmake_modules/NSIS.template.in \ - ../../build/docker/old-ubuntu-based/Dockerfile \ - ../../contrib/debian/i2pd.service \ - ../../contrib/debian/i2pd.tmpfile \ - ../../contrib/rpm/i2pd.service \ - ../../debian/patches/series \ - ../../debian/source/format \ - ../../debian/compat \ - ../../debian/control \ - ../../debian/copyright \ - ../../debian/docs \ - ../../debian/i2pd.1 \ - ../../debian/i2pd.default \ - ../../debian/i2pd.dirs \ - ../../debian/i2pd.install \ - ../../debian/i2pd.links \ - ../../debian/i2pd.manpages \ - ../../debian/i2pd.openrc \ - ../../debian/i2pd.upstart \ - ../../debian/logrotate \ - ../../debian/watch \ - ../../docs/Doxyfile \ - ../../docs/index.rst \ - ../../docs/subscriptions.txt \ - ../../docs/tunnels.conf \ - android/src/org/kde/necessitas/ministro/IMinistro.aidl \ - android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl \ - android/build.gradle \ - android/project.properties \ - ../../Win32/nsi/helper_readme.nsh \ - ../../Win32/nsi/servicelib.nsh \ - ../../Win32/i2pd.sln \ - ../../Win32/i2pd.vcxproj \ - ../../Win32/i2pd.vcxproj.filters \ - ../../Win32/inno_installer.iss \ - ../../Win32/install_service.bat \ - ../../Win32/installer.iss \ - ../../Win32/Itoopie.cmd \ - ../../Win32/PurpleI2P.nsi \ - ../../Win32/uninstall_service.bat \ - ../../Dockerfile \ - ../../filelist.mk \ - ../../LICENSE \ - ../../debian/changelog \ - ../../ChangeLog \ - ../../build/cmake_modules/FindMiniUPnPc.cmake \ - ../../build/CMakeLists.txt \ - ../../android/gen/org/purplei2p/i2pd/BuildConfig.java \ - ../../android/gen/org/purplei2p/i2pd/R.java \ - ../../android/src/org/purplei2p/i2pd/DaemonSingleton.java \ - ../../android/src/org/purplei2p/i2pd/ForegroundService.java \ - ../../android/src/org/purplei2p/i2pd/I2PD.java \ - ../../android/src/org/purplei2p/i2pd/I2PD_JNI.java \ - ../../android/src/org/purplei2p/i2pd/NetworkStateChangeReceiver.java \ - android/src/org/purplei2p/i2pd/I2PDMainActivity.java \ - android/src/org/purplei2p/i2pd/LocalService.java \ - android/src/org/qtproject/qt5/android/bindings/QtActivity.java \ - android/src/org/qtproject/qt5/android/bindings/QtApplication.java \ - ../../debian/rules \ - ../../build/docker/README.md \ - ../../docs/building/android.md \ - ../../docs/building/cross.md \ - ../../docs/building/ios.md \ - ../../docs/building/requirements.md \ - ../../docs/building/unix.md \ - ../../docs/building/windows.md \ - ../../docs/config_opts_after_2.3.0.md \ - ../../docs/configuration.md \ - ../../docs/family.md \ - ../../docs/hacking.md \ - ../../docs/usage.md \ - README.md \ - ../../README.md \ - ../../docs/i2pd.conf \ - ../../build/cmake-zlib-amd64.patch \ - ../../build/cmake-zlib-static.patch \ - ../../debian/patches/01-tune-build-opts.patch \ - ../../docs/conf.py \ - ../../contrib/debian/README \ - ../../contrib/rpm/i2pd.spec diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 05ecaddf..f94a7b9d 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -401,13 +401,6 @@ private: TODO signaturetype - https://geti2p.net/spec/common-structures#certificate - все коды перечислены - orignal_, это таблица "The defined Signing Public Key types are:" ? - да - - see also : Identity.h line 55 - */ template From 298181999d5eda338778ea59c5b791fc63e6085d Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 2 Jun 2017 22:59:13 +0800 Subject: [PATCH 16/23] qtui first draft completed --- qt/i2pd_qt/ClientTunnelPane.cpp | 64 ++++++---- qt/i2pd_qt/ClientTunnelPane.h | 34 +++++- qt/i2pd_qt/ServerTunnelPane.cpp | 88 +++++++++----- qt/i2pd_qt/ServerTunnelPane.h | 53 ++++++++- qt/i2pd_qt/SignatureTypeComboboxFactory.h | 2 +- qt/i2pd_qt/TunnelConfig.cpp | 39 ++++++ qt/i2pd_qt/TunnelConfig.h | 27 +++-- qt/i2pd_qt/TunnelPane.cpp | 94 ++++++++++++--- qt/i2pd_qt/TunnelPane.h | 34 +++++- qt/i2pd_qt/TunnelsPageUpdateListener.h | 12 ++ qt/i2pd_qt/mainwindow.cpp | 107 ++++++++++++----- qt/i2pd_qt/mainwindow.h | 137 ++++++++++++++++++++-- qt/i2pd_qt/mainwindow.ui | 54 +++++---- 13 files changed, 588 insertions(+), 157 deletions(-) create mode 100644 qt/i2pd_qt/TunnelsPageUpdateListener.h diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp index b7abb0a7..6ece1eaf 100644 --- a/qt/i2pd_qt/ClientTunnelPane.cpp +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -1,28 +1,25 @@ #include "ClientTunnelPane.h" #include "../../ClientContext.h" #include "SignatureTypeComboboxFactory.h" +#include "QVBoxLayout" -ClientTunnelPane::ClientTunnelPane() -{ - -} +ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf): + TunnelPane(tunnelsPageUpdateListener, tunconf) {} void ClientTunnelPane::setGroupBoxTitle(const QString & title) { clientTunnelNameGroupBox->setTitle(title); } -void ClientTunnelPane::deleteClientTunnelForm(QGridLayout *tunnelsFormGridLayout) { - tunnelsFormGridLayout->removeWidget(clientTunnelNameGroupBox); - - clientTunnelNameGroupBox->deleteLater(); +void ClientTunnelPane::deleteClientTunnelForm() { + delete clientTunnelNameGroupBox; clientTunnelNameGroupBox=nullptr; - gridLayoutWidget_2->deleteLater(); - gridLayoutWidget_2=nullptr; + //gridLayoutWidget_2->deleteLater(); + //gridLayoutWidget_2=nullptr; } -void ClientTunnelPane::appendClientTunnelForm( - ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow) { +int ClientTunnelPane::appendClientTunnelForm( + ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) { ClientTunnelPane& ui = *this; @@ -30,7 +27,7 @@ void ClientTunnelPane::appendClientTunnelForm( clientTunnelNameGroupBox->setObjectName(QStringLiteral("clientTunnelNameGroupBox")); //tunnel - ui.gridLayoutWidget_2 = new QWidget(clientTunnelNameGroupBox); + gridLayoutWidget_2 = new QWidget(clientTunnelNameGroupBox); QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2); tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox")); @@ -40,13 +37,10 @@ void ClientTunnelPane::appendClientTunnelForm( tunnelTypeComboBox->addItem("HTTP Proxy", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY); tunnelTypeComboBox->addItem("UDP Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT); - gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, (7+4)*60)); + int h=(7+4)*60; + gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h)); + clientTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h)); - setupTunnelPane(tunnelConfig, - clientTunnelNameGroupBox, - gridLayoutWidget_2, tunnelTypeComboBox, - tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelsRow); - //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, (7+5)*40+10)); { const QString& type = tunnelConfig->getType(); int index=0; @@ -62,6 +56,12 @@ void ClientTunnelPane::appendClientTunnelForm( ++index; } + setupTunnelPane(tunnelConfig, + clientTunnelNameGroupBox, + gridLayoutWidget_2, tunnelTypeComboBox, + tunnelsFormGridLayoutWidget, tunnelsRow, height, h); + //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, (7+5)*40+10)); + /* std::string destination; */ @@ -75,10 +75,12 @@ void ClientTunnelPane::appendClientTunnelForm( ui.destinationLineEdit = new QLineEdit(gridLayoutWidget_2); destinationLineEdit->setObjectName(QStringLiteral("destinationLineEdit")); destinationLineEdit->setText(tunnelConfig->getdest().c_str()); + QObject::connect(destinationLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(destinationLineEdit); ui.destinationHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(destinationHorizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, 2, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); /* * int port; @@ -95,10 +97,12 @@ void ClientTunnelPane::appendClientTunnelForm( portLineEdit->setObjectName(QStringLiteral("portLineEdit")); portLineEdit->setText(QString::number(port)); portLineEdit->setMaximumWidth(80); + QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(portLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } /* * std::string keys; @@ -113,10 +117,12 @@ void ClientTunnelPane::appendClientTunnelForm( ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2); keysLineEdit->setObjectName(QStringLiteral("keysLineEdit")); keysLineEdit->setText(keys.c_str()); + QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(keysLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } /* * std::string address; @@ -131,10 +137,12 @@ void ClientTunnelPane::appendClientTunnelForm( ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2); addressLineEdit->setObjectName(QStringLiteral("addressLineEdit")); addressLineEdit->setText(address.c_str()); + QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(addressLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } /* @@ -152,10 +160,12 @@ void ClientTunnelPane::appendClientTunnelForm( destinationPortLineEdit->setObjectName(QStringLiteral("destinationPortLineEdit")); destinationPortLineEdit->setText(QString::number(destinationPort)); destinationPortLineEdit->setMaximumWidth(80); + QObject::connect(destinationPortLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(destinationPortLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); @@ -166,10 +176,12 @@ void ClientTunnelPane::appendClientTunnelForm( horizontalLayout_2->addWidget(sigTypeLabel); ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType); sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox")); + QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updated())); horizontalLayout_2->addWidget(sigTypeComboBox); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); @@ -179,6 +191,8 @@ void ClientTunnelPane::appendClientTunnelForm( retranslateClientTunnelForm(ui); tunnelGridLayout->invalidate(); + + return h; } ServerTunnelPane* ClientTunnelPane::asServerTunnelPane(){return nullptr;} diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h index df4420f9..16416cd8 100644 --- a/qt/i2pd_qt/ClientTunnelPane.h +++ b/qt/i2pd_qt/ClientTunnelPane.h @@ -2,6 +2,7 @@ #define CLIENTTUNNELPANE_H #include "QGridLayout" +#include "QVBoxLayout" #include "TunnelPane.h" @@ -13,13 +14,13 @@ class TunnelPane; class ClientTunnelPane : public TunnelPane { Q_OBJECT public: - ClientTunnelPane(); + ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf); virtual ~ClientTunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane(); virtual ClientTunnelPane* asClientTunnelPane(); - void appendClientTunnelForm(ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, - QGridLayout *tunnelsFormGridLayout, int tunnelsRow); - void deleteClientTunnelForm(QGridLayout *tunnelsFormGridLayout); + int appendClientTunnelForm(ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, + int tunnelsRow, int height); + void deleteClientTunnelForm(); private: QGroupBox *clientTunnelNameGroupBox; @@ -65,7 +66,32 @@ private: addressLabel->setText(QApplication::translate("cltTunForm", "Address:", 0)); sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0)); } +protected: + virtual bool applyDataFromUIToTunnelConfig() { + bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); + if(!ok)return false; + ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig(); + assert(ctc!=nullptr); + //destination + ctc->setdest(destinationLineEdit->text().toStdString()); + + auto portStr=portLineEdit->text(); + int portInt=portStr.toInt(&ok); + if(!ok)return false; + ctc->setport(portInt); + + ctc->setkeys(keysLineEdit->text().toStdString()); + + ctc->setaddress(addressLineEdit->text().toStdString()); + + auto dportStr=portLineEdit->text(); + int dportInt=dportStr.toInt(&ok); + if(!ok)return false; + ctc->setdestinationPort(dportInt); + + ctc->setsigType(readSigTypeComboboxUI(sigTypeComboBox)); + } }; #endif // CLIENTTUNNELPANE_H diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp index 4a1c8971..7261336e 100644 --- a/qt/i2pd_qt/ServerTunnelPane.cpp +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -2,14 +2,15 @@ #include "../../ClientContext.h" #include "SignatureTypeComboboxFactory.h" -ServerTunnelPane::ServerTunnelPane(): TunnelPane() {} +ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf): + TunnelPane(tunnelsPageUpdateListener, tunconf) {} void ServerTunnelPane::setGroupBoxTitle(const QString & title) { serverTunnelNameGroupBox->setTitle(title); } -void ServerTunnelPane::appendServerTunnelForm( - ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow) { +int ServerTunnelPane::appendServerTunnelForm( + ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) { ServerTunnelPane& ui = *this; @@ -17,7 +18,7 @@ void ServerTunnelPane::appendServerTunnelForm( serverTunnelNameGroupBox->setObjectName(QStringLiteral("serverTunnelNameGroupBox")); //tunnel - ui.gridLayoutWidget_2 = new QWidget(serverTunnelNameGroupBox); + gridLayoutWidget_2 = new QWidget(serverTunnelNameGroupBox); QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2); tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox")); @@ -26,14 +27,9 @@ void ServerTunnelPane::appendServerTunnelForm( tunnelTypeComboBox->addItem("IRC", i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC); tunnelTypeComboBox->addItem("UDP Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER); - gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, 18*60)); - - - setupTunnelPane(tunnelConfig, - serverTunnelNameGroupBox, - gridLayoutWidget_2, tunnelTypeComboBox, - tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelsRow); - //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, 18*40+10)); + int h=19*60; + gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h)); + serverTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h)); { const QString& type = tunnelConfig->getType(); @@ -48,6 +44,12 @@ void ServerTunnelPane::appendServerTunnelForm( ++index; } + setupTunnelPane(tunnelConfig, + serverTunnelNameGroupBox, + gridLayoutWidget_2, tunnelTypeComboBox, + tunnelsFormGridLayoutWidget, tunnelsRow, height, h); + //this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, 18*40+10)); + //host ui.horizontalLayout_2 = new QHBoxLayout(); horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); @@ -57,10 +59,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.hostLineEdit = new QLineEdit(gridLayoutWidget_2); hostLineEdit->setObjectName(QStringLiteral("hostLineEdit")); hostLineEdit->setText(tunnelConfig->gethost().c_str()); + QObject::connect(hostLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(hostLineEdit); ui.hostHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(hostHorizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, 2, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); int gridIndex = 2; { @@ -74,10 +78,12 @@ void ServerTunnelPane::appendServerTunnelForm( portLineEdit->setObjectName(QStringLiteral("portLineEdit")); portLineEdit->setText(QString::number(port)); portLineEdit->setMaximumWidth(80); + QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(portLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { std::string keys = tunnelConfig->getkeys(); @@ -89,10 +95,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2); keysLineEdit->setObjectName(QStringLiteral("keysLineEdit")); keysLineEdit->setText(keys.c_str()); + QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(keysLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { int inPort = tunnelConfig->getinPort(); @@ -105,10 +113,12 @@ void ServerTunnelPane::appendServerTunnelForm( inPortLineEdit->setObjectName(QStringLiteral("inPortLineEdit")); inPortLineEdit->setText(QString::number(inPort)); inPortLineEdit->setMaximumWidth(80); + QObject::connect(inPortLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(inPortLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { std::string accessList = tunnelConfig->getaccessList(); @@ -120,10 +130,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.accessListLineEdit = new QLineEdit(gridLayoutWidget_2); accessListLineEdit->setObjectName(QStringLiteral("accessListLineEdit")); accessListLineEdit->setText(accessList.c_str()); + QObject::connect(accessListLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(accessListLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { std::string hostOverride = tunnelConfig->gethostOverride(); @@ -135,10 +147,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.hostOverrideLineEdit = new QLineEdit(gridLayoutWidget_2); hostOverrideLineEdit->setObjectName(QStringLiteral("hostOverrideLineEdit")); hostOverrideLineEdit->setText(hostOverride.c_str()); + QObject::connect(hostOverrideLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(hostOverrideLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { std::string webIRCPass = tunnelConfig->getwebircpass(); @@ -150,10 +164,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.webIRCPassLineEdit = new QLineEdit(gridLayoutWidget_2); webIRCPassLineEdit->setObjectName(QStringLiteral("webIRCPassLineEdit")); webIRCPassLineEdit->setText(webIRCPass.c_str()); + QObject::connect(webIRCPassLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(webIRCPassLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { bool gzip = tunnelConfig->getgzip(); @@ -162,10 +178,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.gzipCheckBox = new QCheckBox(gridLayoutWidget_2); gzipCheckBox->setObjectName(QStringLiteral("gzipCheckBox")); gzipCheckBox->setChecked(gzip); + QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)), + this, SLOT(updated())); horizontalLayout_2->addWidget(gzipCheckBox); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); @@ -176,10 +194,12 @@ void ServerTunnelPane::appendServerTunnelForm( horizontalLayout_2->addWidget(sigTypeLabel); ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType); sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox")); + QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updated())); horizontalLayout_2->addWidget(sigTypeComboBox); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { uint32_t maxConns = tunnelConfig->getmaxConns(); @@ -192,10 +212,12 @@ void ServerTunnelPane::appendServerTunnelForm( maxConnsLineEdit->setObjectName(QStringLiteral("maxConnsLineEdit")); maxConnsLineEdit->setText(QString::number(maxConns)); maxConnsLineEdit->setMaximumWidth(80); + QObject::connect(maxConnsLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(maxConnsLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { std::string address = tunnelConfig->getaddress(); @@ -207,10 +229,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2); addressLineEdit->setObjectName(QStringLiteral("addressLineEdit")); addressLineEdit->setText(address.c_str()); + QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(addressLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { bool isUniqueLocal = tunnelConfig->getisUniqueLocal(); @@ -219,10 +243,12 @@ void ServerTunnelPane::appendServerTunnelForm( ui.isUniqueLocalCheckBox = new QCheckBox(gridLayoutWidget_2); isUniqueLocalCheckBox->setObjectName(QStringLiteral("isUniqueLocalCheckBox")); isUniqueLocalCheckBox->setChecked(isUniqueLocal); + QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)), + this, SLOT(updated())); horizontalLayout_2->addWidget(isUniqueLocalCheckBox); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); @@ -232,16 +258,16 @@ void ServerTunnelPane::appendServerTunnelForm( retranslateServerTunnelForm(ui); tunnelGridLayout->invalidate(); + + return h; } -void ServerTunnelPane::deleteServerTunnelForm(QGridLayout *tunnelsFormGridLayout) { - tunnelsFormGridLayout->removeWidget(tunnelGroupBox); +void ServerTunnelPane::deleteServerTunnelForm() { + delete serverTunnelNameGroupBox;//->deleteLater(); + serverTunnelNameGroupBox=nullptr; - tunnelGroupBox->deleteLater(); - tunnelGroupBox=nullptr; - - gridLayoutWidget_2->deleteLater(); - gridLayoutWidget_2=nullptr; + //gridLayoutWidget_2->deleteLater(); + //gridLayoutWidget_2=nullptr; } diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h index 2bab41d6..a6994841 100644 --- a/qt/i2pd_qt/ServerTunnelPane.h +++ b/qt/i2pd_qt/ServerTunnelPane.h @@ -2,7 +2,7 @@ #define SERVERTUNNELPANE_H #include "TunnelPane.h" -#include "mainwindow.h" +#include "TunnelsPageUpdateListener.h" #include #include @@ -18,6 +18,10 @@ #include #include #include +#include "QVBoxLayout" +#include "QCheckBox" + +#include "assert.h" class ServerTunnelConfig; @@ -27,15 +31,15 @@ class ServerTunnelPane : public TunnelPane { Q_OBJECT public: - ServerTunnelPane(); + ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf); virtual ~ServerTunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane(); virtual ClientTunnelPane* asClientTunnelPane(); - void appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, - QGridLayout *tunnelsFormGridLayout, int tunnelsRow); - void deleteServerTunnelForm(QGridLayout *tunnelsFormGridLayout); + int appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, + int tunnelsRow, int height); + void deleteServerTunnelForm(); private: QGroupBox *serverTunnelNameGroupBox; @@ -113,6 +117,45 @@ private: sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0)); } +protected: + virtual bool applyDataFromUIToTunnelConfig() { + bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); + if(!ok)return false; + ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig(); + assert(stc!=nullptr); + stc->sethost(hostLineEdit->text().toStdString()); + + auto portStr=portLineEdit->text(); + int portInt=portStr.toInt(&ok); + if(!ok)return false; + stc->setport(portInt); + + stc->setkeys(keysLineEdit->text().toStdString()); + + auto str=inPortLineEdit->text(); + int inPortInt=str.toInt(&ok); + if(!ok)return false; + stc->setinPort(inPortInt); + + stc->setaccessList(accessListLineEdit->text().toStdString()); + + stc->sethostOverride(hostOverrideLineEdit->text().toStdString()); + + stc->setwebircpass(webIRCPassLineEdit->text().toStdString()); + + stc->setaddress(addressLineEdit->text().toStdString()); + + auto mcStr=maxConnsLineEdit->text(); + uint32_t mcInt=(uint32_t)mcStr.toInt(&ok); + if(!ok)return false; + stc->setmaxConns(mcInt); + + stc->setgzip(gzipCheckBox->isChecked()); + + stc->setisUniqueLocal(isUniqueLocalCheckBox->isChecked()); + + stc->setsigType(readSigTypeComboboxUI(sigTypeComboBox)); + } }; #endif // SERVERTUNNELPANE_H diff --git a/qt/i2pd_qt/SignatureTypeComboboxFactory.h b/qt/i2pd_qt/SignatureTypeComboboxFactory.h index 9c9190ed..111b7296 100644 --- a/qt/i2pd_qt/SignatureTypeComboboxFactory.h +++ b/qt/i2pd_qt/SignatureTypeComboboxFactory.h @@ -8,7 +8,7 @@ class SignatureTypeComboBoxFactory { - static const QVariant& createUserData(const uint16_t sigType) { + static const QVariant createUserData(const uint16_t sigType) { return QVariant::fromValue((uint)sigType); } diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp index fbd8a2ab..0de17486 100644 --- a/qt/i2pd_qt/TunnelConfig.cpp +++ b/qt/i2pd_qt/TunnelConfig.cpp @@ -1,2 +1,41 @@ #include "TunnelConfig.h" +void TunnelConfig::saveHeaderToStringStream(std::stringstream& out) { + out << "[" << name << "]\n" + << "type=" << type.toStdString() << "\n"; +} + +void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) { + out << "inbound.length=" << i2cpParameters.getInbound_length().toStdString() << "\n" + << "outbound.length=" << i2cpParameters.getOutbound_length().toStdString() << "\n" + << "inbound.quantity=" << i2cpParameters.getInbound_quantity().toStdString() << "\n" + << "outbound.quantity=" << i2cpParameters.getOutbound_quantity().toStdString() << "\n" + << "crypto.tagsToSend=" << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n" + << "explicitPeers=" << i2cpParameters.getExplicitPeers().toStdString() << "\n\n"; +} + +void ClientTunnelConfig::saveToStringStream(std::stringstream& out) { + out << "address=" << address << "\n" + << "port=" << port << "\n" + << "destination=" << dest << "\n" + << "keys=" << keys << "\n" + << "destinationport=" << destinationPort << "\n" + << "signaturetype=" << sigType << "\n"; +} + + +void ServerTunnelConfig::saveToStringStream(std::stringstream& out) { + out << "host=" << host << "\n" + << "port=" << port << "\n" + << "keys=" << keys << "\n" + << "signaturetype=" << sigType << "\n" + << "inport=" << inPort << "\n" + << "accesslist=" << accessList << "\n" + << "gzip=" << (gzip?"true":"false") << "\n" + << "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n" + << "address=" << address << "\n" + << "hostoverride=" << hostOverride << "\n" + << "webircpassword=" << webircpass << "\n" + << "maxconns=" << maxConns << "\n"; +} + diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h index 806d082c..471afdef 100644 --- a/qt/i2pd_qt/TunnelConfig.h +++ b/qt/i2pd_qt/TunnelConfig.h @@ -5,6 +5,7 @@ #include #include "../../ClientContext.h" +#include "TunnelsPageUpdateListener.h" class I2CPParameters{ @@ -53,13 +54,17 @@ class TunnelConfig { QString type; std::string name; public: - TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_): type(type_), name(name_), i2cpParameters(i2cpParameters_) {} + TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_): + type(type_), name(name_), i2cpParameters(i2cpParameters_) {} virtual ~TunnelConfig(){} const QString& getType(){return type;} const std::string& getName(){return name;} void setType(const QString& type_){type=type_;} void setName(const std::string& name_){name=name_;} I2CPParameters& getI2cpParameters(){return i2cpParameters;} + void saveHeaderToStringStream(std::stringstream& out); + void saveI2CPParametersToStringStream(std::stringstream& out); + virtual void saveToStringStream(std::stringstream& out)=0; virtual ClientTunnelConfig* asClientTunnelConfig()=0; virtual ServerTunnelConfig* asServerTunnelConfig()=0; @@ -116,12 +121,13 @@ public: std::string & getaddress(){return address;} int getdestinationPort(){return destinationPort;} i2p::data::SigningKeyType getsigType(){return sigType;} - void setdest(std::string& dest_){dest=dest_;} + void setdest(const std::string& dest_){dest=dest_;} void setport(int port_){port=port_;} - void setkeys(std::string & keys_){keys=keys_;} - void setaddress(std::string & address_){address=address_;} + void setkeys(const std::string & keys_){keys=keys_;} + void setaddress(const std::string & address_){address=address_;} void setdestinationPort(int destinationPort_){destinationPort=destinationPort_;} void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} + virtual void saveToStringStream(std::stringstream& out); virtual ClientTunnelConfig* asClientTunnelConfig(){return this;} virtual ServerTunnelConfig* asServerTunnelConfig(){return nullptr;} }; @@ -203,18 +209,19 @@ public: uint32_t getmaxConns(){return maxConns;} std::string& getaddress(){return address;} bool getisUniqueLocal(){return isUniqueLocal;} - void sethost(std::string& host_){host=host_;} + void sethost(const std::string& host_){host=host_;} void setport(int port_){port=port_;} - void setkeys(std::string& keys_){keys=keys_;} + void setkeys(const std::string& keys_){keys=keys_;} void setinPort(int inPort_){inPort=inPort_;} - void setaccessList(std::string& accessList_){accessList=accessList_;} - void sethostOverride(std::string& hostOverride_){hostOverride=hostOverride_;} - void setwebircpass(std::string& webircpass_){webircpass=webircpass_;} + void setaccessList(const std::string& accessList_){accessList=accessList_;} + void sethostOverride(const std::string& hostOverride_){hostOverride=hostOverride_;} + void setwebircpass(const std::string& webircpass_){webircpass=webircpass_;} void setgzip(bool gzip_){gzip=gzip_;} void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} void setmaxConns(uint32_t maxConns_){maxConns=maxConns_;} - void setaddress(std::string& address_){address=address_;} + void setaddress(const std::string& address_){address=address_;} void setisUniqueLocal(bool isUniqueLocal_){isUniqueLocal=isUniqueLocal_;} + virtual void saveToStringStream(std::stringstream& out); virtual ClientTunnelConfig* asClientTunnelConfig(){return nullptr;} virtual ServerTunnelConfig* asServerTunnelConfig(){return this;} }; diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index d0d3a28e..0dda5185 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -1,26 +1,32 @@ #include "TunnelPane.h" +#include "QMessageBox" -TunnelPane::TunnelPane(): QObject(),gridLayoutWidget_2(nullptr) { -} +TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_): + QObject(), + tunnelConfig(tunnelConfig_), + tunnelsPageUpdateListener(tunnelsPageUpdateListener_), + gridLayoutWidget_2(nullptr) {} void TunnelPane::setupTunnelPane( TunnelConfig* tunnelConfig, QGroupBox *tunnelGroupBox, QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, - QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow) { - tunnelsFormGridLayoutWidget->resize(527, tunnelsFormGridLayoutWidget->height()+gridLayoutWidget_2->height()); - tunnelGroupBox->resize(gridLayoutWidget_2->width(), gridLayoutWidget_2->height()); - tunnelsFormGridLayout->addWidget(tunnelGroupBox, tunnelsRow, 0); + QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h) { + tunnelGroupBox->setGeometry(0, tunnelsFormGridLayoutWidget->height(), gridLayoutWidget_2->width(), h); + tunnelsFormGridLayoutWidget->resize(527, tunnelsFormGridLayoutWidget->height()+h); + + QObject::connect(tunnelTypeComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(updated())); this->tunnelGroupBox=tunnelGroupBox; gridLayoutWidget_2->setObjectName(QStringLiteral("gridLayoutWidget_2")); this->gridLayoutWidget_2=gridLayoutWidget_2; - tunnelGridLayout = new QGridLayout(gridLayoutWidget_2); + tunnelGridLayout = new QVBoxLayout(gridLayoutWidget_2); tunnelGridLayout->setObjectName(QStringLiteral("tunnelGridLayout")); tunnelGridLayout->setContentsMargins(5, 5, 5, 5); - tunnelGridLayout->setVerticalSpacing(5); + tunnelGridLayout->setSpacing(5); //header QHBoxLayout *headerHorizontalLayout = new QHBoxLayout(); @@ -37,14 +43,18 @@ void TunnelPane::setupTunnelPane( QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(setGroupBoxTitle(const QString &))); + QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); headerHorizontalLayout->addWidget(nameLineEdit); headerHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); headerHorizontalLayout->addItem(headerHorizontalSpacer); - deletePushButton = new QPushButton(gridLayoutWidget_2);//TODO handle it + deletePushButton = new QPushButton(gridLayoutWidget_2); deletePushButton->setObjectName(QStringLiteral("deletePushButton")); + QObject::connect(deletePushButton, SIGNAL(released()), + this, SLOT(deleteButtonReleased()));//MainWindow::DeleteTunnelNamed(std::string name) { headerHorizontalLayout->addWidget(deletePushButton); - tunnelGridLayout->addLayout(headerHorizontalLayout, 0, 0, 1, 1); + tunnelGridLayout->addLayout(headerHorizontalLayout); //type { @@ -58,7 +68,7 @@ void TunnelPane::setupTunnelPane( this->tunnelTypeComboBox=tunnelTypeComboBox; QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_, 1, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_); } retranslateTunnelForm(*this); @@ -77,10 +87,12 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, inbound_lengthLineEdit->setObjectName(QStringLiteral("inbound_lengthLineEdit")); inbound_lengthLineEdit->setText(inbound_length); inbound_lengthLineEdit->setMaximumWidth(80); + QObject::connect(inbound_lengthLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(inbound_lengthLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //number of hops of an outbound tunnel @@ -94,10 +106,12 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, outbound_lengthLineEdit->setObjectName(QStringLiteral("outbound_lengthLineEdit")); outbound_lengthLineEdit->setText(outbound_length); outbound_lengthLineEdit->setMaximumWidth(80); + QObject::connect(outbound_lengthLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(outbound_lengthLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //number of inbound tunnels @@ -111,10 +125,12 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, inbound_quantityLineEdit->setObjectName(QStringLiteral("inbound_quantityLineEdit")); inbound_quantityLineEdit->setText(inbound_quantity); inbound_quantityLineEdit->setMaximumWidth(80); + QObject::connect(inbound_quantityLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(inbound_quantityLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //number of outbound tunnels @@ -128,10 +144,12 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, outbound_quantityLineEdit->setObjectName(QStringLiteral("outbound_quantityLineEdit")); outbound_quantityLineEdit->setText(outbound_quantity); outbound_quantityLineEdit->setMaximumWidth(80); + QObject::connect(outbound_quantityLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(outbound_quantityLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } { //number of ElGamal/AES tags to send @@ -145,11 +163,55 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, crypto_tagsToSendLineEdit->setObjectName(QStringLiteral("crypto_tagsToSendLineEdit")); crypto_tagsToSendLineEdit->setText(crypto_tagsToSend); crypto_tagsToSendLineEdit->setMaximumWidth(80); + QObject::connect(crypto_tagsToSendLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(updated())); horizontalLayout_2->addWidget(crypto_tagsToSendLineEdit); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); - tunnelGridLayout->addLayout(horizontalLayout_2, ++gridIndex, 0, 1, 1); + tunnelGridLayout->addLayout(horizontalLayout_2); } retranslateI2CPParameters(); } + +void TunnelPane::updated() { + std::string oldName=tunnelConfig->getName(); + if(!applyDataFromUIToTunnelConfig())return;//TODO visualise bad input + tunnelsPageUpdateListener->updated(oldName, tunnelConfig); +} + +void TunnelPane::deleteButtonReleased() { + QMessageBox msgBox; + msgBox.setText(QApplication::tr("Are you sure to delete this tunnel?")); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Cancel); + int ret = msgBox.exec(); + switch (ret) { + case QMessageBox::Ok: + // OK was clicked + tunnelsPageUpdateListener->needsDeleting(tunnelConfig->getName()); + break; + case QMessageBox::Cancel: + // Cancel was clicked + return; + } +} + +/* +const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client"; +const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server"; +const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http"; +const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc"; +const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient"; +const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver"; +const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks"; +const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks"; +const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy"; +*/ +QString TunnelPane::readTunnelTypeComboboxData() { + return tunnelTypeComboBox->currentData().toString(); +} + +i2p::data::SigningKeyType TunnelPane::readSigTypeComboboxUI(QComboBox* sigTypeComboBox) { + return (i2p::data::SigningKeyType) sigTypeComboBox->currentData().toInt(); +} diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index af6c7351..d0a3d6a8 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -10,6 +10,7 @@ #include "QApplication" #include "QLineEdit" #include "QGroupBox" +#include "QVBoxLayout" #include "TunnelConfig.h" @@ -24,20 +25,30 @@ class TunnelPane : public QObject { Q_OBJECT public: - TunnelPane(); + TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf); virtual ~TunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane()=0; virtual ClientTunnelPane* asClientTunnelPane()=0; protected: - QGridLayout *tunnelGridLayout; + TunnelConfig* tunnelConfig; + TunnelsPageUpdateListener* tunnelsPageUpdateListener; + QVBoxLayout *tunnelGridLayout; QGroupBox *tunnelGroupBox; QWidget* gridLayoutWidget_2; //header QLabel *nameLabel; QLineEdit *nameLineEdit; +public: + QLineEdit * getNameLineEdit() { return nameLineEdit; } + +public slots: + void updated(); + void deleteButtonReleased(); + +protected: QSpacerItem *headerHorizontalSpacer; QPushButton *deletePushButton; @@ -62,11 +73,28 @@ protected: QLabel * crypto_tagsToSendLabel; QLineEdit * crypto_tagsToSendLineEdit; + QString readTunnelTypeComboboxData(); + + //should be created by factory + i2p::data::SigningKeyType readSigTypeComboboxUI(QComboBox* sigTypeComboBox); + + //returns false when invalid data at UI + virtual bool applyDataFromUIToTunnelConfig() { + tunnelConfig->setName(nameLineEdit->text().toStdString()); + tunnelConfig->setType(readTunnelTypeComboboxData()); + I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters(); + i2cpParams.setInbound_length(inbound_lengthLineEdit->text()); + i2cpParams.setInbound_quantity(inbound_quantityLineEdit->text()); + i2cpParams.setOutbound_length(outbound_lengthLineEdit->text()); + i2cpParams.setOutbound_quantity(outbound_quantityLineEdit->text()); + i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text()); + } + void setupTunnelPane( TunnelConfig* tunnelConfig, QGroupBox *tunnelGroupBox, QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, - QWidget *tunnelsFormGridLayoutWidget, QGridLayout *tunnelsFormGridLayout, int tunnelsRow); + QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h); void appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex); public: int height() { diff --git a/qt/i2pd_qt/TunnelsPageUpdateListener.h b/qt/i2pd_qt/TunnelsPageUpdateListener.h new file mode 100644 index 00000000..83b4e9fe --- /dev/null +++ b/qt/i2pd_qt/TunnelsPageUpdateListener.h @@ -0,0 +1,12 @@ +#ifndef TUNNELSPAGEUPDATELISTENER_H +#define TUNNELSPAGEUPDATELISTENER_H + +class TunnelConfig; + +class TunnelsPageUpdateListener { +public: + virtual void updated(std::string oldName, TunnelConfig* tunConf)=0; + virtual void needsDeleting(std::string oldName)=0; +}; + +#endif // TUNNELSPAGEUPDATELISTENER_H diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 37eea4c4..decd5470 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -29,6 +29,7 @@ MainWindow::MainWindow(QWidget *parent) : ,datadir() ,confpath() ,tunconfpath() + ,tunnelsPageUpdateListener(this) { ui->setupUi(this); @@ -185,16 +186,12 @@ MainWindow::MainWindow(QWidget *parent) : loadAllConfigs(); - tunnelsFormGridLayoutWidget = new QWidget(ui->tunnelsScrollAreaWidgetContents); - tunnelsFormGridLayoutWidget->setObjectName(QStringLiteral("tunnelsFormGridLayoutWidget")); - tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, 451)); + //tunnelsFormGridLayoutWidget = new QWidget(ui->tunnelsScrollAreaWidgetContents); + //tunnelsFormGridLayoutWidget->setObjectName(QStringLiteral("tunnelsFormGridLayoutWidget")); + //tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, 451)); ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, 451)); - tunnelsFormGridLayout = new QGridLayout(tunnelsFormGridLayoutWidget); - tunnelsFormGridLayout->setObjectName(QStringLiteral("tunnelsFormGridLayout")); - tunnelsFormGridLayout->setContentsMargins(5, 5, 5, 5); - tunnelsFormGridLayout->setVerticalSpacing(5); - appendTunnelForms(); + appendTunnelForms(""); ui->configFileLineEdit->setEnabled(false); ui->configFileBrowsePushButton->setEnabled(false); @@ -209,6 +206,8 @@ MainWindow::MainWindow(QWidget *parent) : QObject::connect(ui->tunnelsConfigFileLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(reloadTunnelsConfigAndUI())); + QObject::connect(ui->addServerTunnelPushButton, SIGNAL(released()), this, SLOT(addServerTunnelPushButtonReleased())); + QObject::connect(ui->addClientTunnelPushButton, SIGNAL(released()), this, SLOT(addClientTunnelPushButtonReleased())); #ifndef ANDROID @@ -476,10 +475,11 @@ bool MainWindow::saveAllConfigs(){ QFile::rename(confpath, backup);//TODO handle errors ofstream outfile; outfile.open(confpath.toStdString());//TODO handle errors - string dataToWrite = out.str(); - outfile << dataToWrite.c_str(); + outfile << out.str().c_str(); outfile.close(); + SaveTunnelsConfig(); + return true; } @@ -507,47 +507,53 @@ void CheckBoxItem::installListeners(MainWindow *mainWindow) { void MainWindowItem::installListeners(MainWindow *mainWindow) {} -void MainWindow::appendTunnelForms() { +void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) { int height=0; - tunnelsFormGridLayoutWidget->setGeometry(0,0,0,0); - for(std::list::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { - TunnelConfig* tunconf = *it; + ui->tunnelsScrollAreaWidgetContents->setGeometry(0,0,0,0); + for(std::map::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { + const std::string& name=it->first; + TunnelConfig* tunconf = it->second; ServerTunnelConfig* stc = tunconf->asServerTunnelConfig(); if(stc){ - ServerTunnelPane * tunnelPane=new ServerTunnelPane(); - tunnelPane->appendServerTunnelForm(stc, tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelPanes.size()); - height+=tunnelPane->height(); + ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc); + int h=tunnelPane->appendServerTunnelForm(stc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); + height+=h; qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); tunnelPanes.push_back(tunnelPane); + if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus(); continue; } ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig(); if(ctc){ - ClientTunnelPane * tunnelPane=new ClientTunnelPane(); - tunnelPane->appendClientTunnelForm(ctc, tunnelsFormGridLayoutWidget, tunnelsFormGridLayout, tunnelPanes.size()); - height+=tunnelPane->height(); + ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc); + int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); + height+=h; qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); tunnelPanes.push_back(tunnelPane); + if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus(); continue; } throw "unknown TunnelConfig subtype"; } qDebug() << "tun.setting height:" << height; - tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, height)); - tunnelsFormGridLayout->invalidate(); ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height)); + QList childWidgets = ui->tunnelsScrollAreaWidgetContents->findChildren(); + foreach(QWidget* widget, childWidgets) + widget->show(); } void MainWindow::deleteTunnelForms() { for(std::list::iterator it = tunnelPanes.begin(); it != tunnelPanes.end(); ++it) { TunnelPane* tp = *it; ServerTunnelPane* stp = tp->asServerTunnelPane(); if(stp){ - stp->deleteServerTunnelForm(tunnelsFormGridLayout); + stp->deleteServerTunnelForm(); + delete stp; continue; } ClientTunnelPane* ctp = tp->asClientTunnelPane(); if(ctp){ - ctp->deleteClientTunnelForm(tunnelsFormGridLayout); + ctp->deleteClientTunnelForm(); + delete ctp; continue; } throw "unknown TunnelPane subtype"; @@ -555,13 +561,58 @@ void MainWindow::deleteTunnelForms() { tunnelPanes.clear(); } -void MainWindow::reloadTunnelsConfigAndUI() { +void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) { deleteTunnelForms(); - for(std::list::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) { - TunnelConfig* tunconf = *it; + for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { + TunnelConfig* tunconf = it->second; delete tunconf; } tunnelConfigs.clear(); ReadTunnelsConfig(); - appendTunnelForms(); + appendTunnelForms(tunnelNameToFocus); +} + +void MainWindow::SaveTunnelsConfig() { + std::stringstream out; + + for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { + const std::string& name = it->first; + TunnelConfig* tunconf = it->second; + tunconf->saveHeaderToStringStream(out); + tunconf->saveToStringStream(out); + tunconf->saveI2CPParametersToStringStream(out); + } + + using namespace std; + + QString backup=tunconfpath+"~"; + if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors + QFile::rename(tunconfpath, backup);//TODO handle errors + ofstream outfile; + outfile.open(tunconfpath.toStdString());//TODO handle errors + outfile << out.str().c_str(); + outfile.close(); + +} + +void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string oldName, TunnelConfig* tunConf) { + if(oldName!=tunConf->getName()) { + //name has changed + std::map::const_iterator it=mainWindow->tunnelConfigs.find(oldName); + if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it); + mainWindow->tunnelConfigs[tunConf->getName()]=tunConf; + } + mainWindow->SaveTunnelsConfig(); +} + +void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){ + mainWindow->DeleteTunnelNamed(oldName); +} + +void MainWindow::addServerTunnelPushButtonReleased() { + CreateDefaultServerTunnel(); +} + +void MainWindow::addClientTunnelPushButtonReleased() { + CreateDefaultClientTunnel(); } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index f94a7b9d..4d465f1a 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -23,6 +23,7 @@ #include #include #include +#include "QVBoxLayout" #ifndef ANDROID # include @@ -48,6 +49,8 @@ #include #include +#include "TunnelsPageUpdateListener.h" + template bool isType(boost::any& a) { return @@ -380,20 +383,23 @@ protected: public slots: /** returns false iff not valid items present and save was aborted */ bool saveAllConfigs(); - void reloadTunnelsConfigAndUI(); + void SaveTunnelsConfig(); + void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus); + + //focus none + void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI(""); } + void addServerTunnelPushButtonReleased(); + void addClientTunnelPushButtonReleased(); private: QString datadir; QString confpath; QString tunconfpath; - std::list tunnelConfigs; + std::map tunnelConfigs; std::list tunnelPanes; - QWidget *tunnelsFormGridLayoutWidget; - QGridLayout *tunnelsFormGridLayout; - - void appendTunnelForms(); + void appendTunnelForms(std::string tunnelNameToFocus); void deleteTunnelForms(); @@ -427,6 +433,107 @@ private: options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);//TODO include into param } + void CreateDefaultI2CPOptions (I2CPParameters& param + /*TODO fill param*/) const + { + const int _INBOUND_TUNNEL_LENGTH = DEFAULT_INBOUND_TUNNEL_LENGTH; + param.setInbound_length(QString::number(_INBOUND_TUNNEL_LENGTH)); + const int _OUTBOUND_TUNNEL_LENGTH = DEFAULT_OUTBOUND_TUNNEL_LENGTH; + param.setOutbound_length(QString::number(_OUTBOUND_TUNNEL_LENGTH)); + const int _INBOUND_TUNNELS_QUANTITY = DEFAULT_INBOUND_TUNNELS_QUANTITY; + param.setInbound_quantity( QString::number(_INBOUND_TUNNELS_QUANTITY)); + const int _OUTBOUND_TUNNELS_QUANTITY = DEFAULT_OUTBOUND_TUNNELS_QUANTITY; + param.setOutbound_quantity(QString::number(_OUTBOUND_TUNNELS_QUANTITY)); + const int _TAGS_TO_SEND = DEFAULT_TAGS_TO_SEND; + param.setCrypto_tagsToSend(QString::number(_TAGS_TO_SEND)); + } + + + void DeleteTunnelNamed(std::string name) { + std::map::const_iterator it=tunnelConfigs.find(name); + if(it!=tunnelConfigs.end()){ + TunnelConfig* tc=it->second; + tunnelConfigs.erase(it); + delete tc; + SaveTunnelsConfig(); + reloadTunnelsConfigAndUI(""); + } + } + + std::string GenerateNewTunnelName() { + int i=1; + while(true){ + std::stringstream name; + name << "name" << i; + const std::string& str=name.str(); + if(tunnelConfigs.find(str)==tunnelConfigs.end())return str; + ++i; + } + } + + void CreateDefaultClientTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels () + std::string name=GenerateNewTunnelName(); + std::string type = I2P_TUNNELS_SECTION_TYPE_CLIENT; + std::string dest = "127.0.0.1"; + int port = 0; + std::string keys = ""; + std::string address = "127.0.0.1"; + int destinationPort = 0; + i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256; + // I2CP + I2CPParameters i2cpParameters; + CreateDefaultI2CPOptions (i2cpParameters); + + tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters, + dest, + port, + keys, + address, + destinationPort, + sigType); + + SaveTunnelsConfig(); + reloadTunnelsConfigAndUI(name); + } + + void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels () + std::string name=GenerateNewTunnelName(); + std::string type=I2P_TUNNELS_SECTION_TYPE_SERVER; + std::string host = "127.0.0.1"; + int port = 0; + std::string keys = ""; + int inPort = 0; + std::string accessList = ""; + std::string hostOverride = ""; + std::string webircpass = ""; + bool gzip = true; + i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256; + uint32_t maxConns = i2p::stream::DEFAULT_MAX_CONNS_PER_MIN; + std::string address = "127.0.0.1"; + bool isUniqueLocal = true; + + // I2CP + I2CPParameters i2cpParameters; + CreateDefaultI2CPOptions (i2cpParameters); + + tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters, + host, + port, + keys, + inPort, + accessList, + hostOverride, + webircpass, + gzip, + sigType, + maxConns, + address, + isUniqueLocal); + + + SaveTunnelsConfig(); + reloadTunnelsConfigAndUI(name); + } void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels () { @@ -479,13 +586,13 @@ private: I2CPParameters i2cpParameters; ReadI2CPOptions (section, options, i2cpParameters); - tunnelConfigs.push_back(new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters, + tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters, dest, port, keys, address, destinationPort, - sigType)); + sigType); } else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP @@ -528,7 +635,7 @@ private: while (comma != std::string::npos); } */ - tunnelConfigs.push_back(new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters, + tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters, host, port, keys, @@ -540,7 +647,7 @@ private: sigType, maxConns, address, - isUniqueLocal)); + isUniqueLocal); } else LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf);//TODO show err box and disable the tunn gui @@ -553,6 +660,16 @@ private: } } +private: + class TunnelsPageUpdateListenerMainWindowImpl : public TunnelsPageUpdateListener { + MainWindow* mainWindow; + public: + TunnelsPageUpdateListenerMainWindowImpl(MainWindow* mainWindow_):mainWindow(mainWindow_){} + virtual void updated(std::string oldName, TunnelConfig* tunConf); + virtual void needsDeleting(std::string oldName); + }; + + TunnelsPageUpdateListenerMainWindowImpl tunnelsPageUpdateListener; }; #endif // MAINWINDOW_H diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index b51f36cb..ca07c036 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -136,7 +136,7 @@ - 2 + 1 @@ -193,7 +193,7 @@ 0 0 701 - 450 + 400 @@ -231,8 +231,8 @@ 0 0 - 683 - 416 + 679 + 400 @@ -246,12 +246,13 @@ 10 11 - 661 - 3048 + 679 + 2962 + @@ -281,7 +282,7 @@ Enabled - + 0 @@ -290,9 +291,9 @@ 31 - + - + IP address to listen on: @@ -302,7 +303,7 @@ - + Qt::Horizontal @@ -316,18 +317,18 @@ - + 0 70 661 - 342 + 31 - + - + Port to listen on: @@ -344,7 +345,7 @@ - + Qt::Horizontal @@ -359,6 +360,9 @@ + + + @@ -1877,13 +1881,13 @@ 0 - 120 + 180 16777215 - 120 + 180 @@ -1918,31 +1922,33 @@ 0 40 391 - 21 + 42 - Make direct I2P connections only to routers in specified Family: + Make direct I2P connections only to +routers in specified Family: 0 - 60 + 82 661 - 16 + 42 - Make direct I2P connections only to routers specified here. Comma separated list of base64 identities: + Make direct I2P connections only to routers specified here. +Comma separated list of base64 identities: 0 - 80 + 124 661 23 @@ -1952,7 +1958,7 @@ 0 - 100 + 147 661 21 From 7379b4ddd2dd1c6dc59823a810eeddb8c2ebfc8e Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 2 Jun 2017 23:43:33 +0800 Subject: [PATCH 17/23] merged with upstream --- libi2pd_client/SAM.cpp | 2 +- libi2pd_client/SAM.h | 6 +- qt/i2pd_qt/ClientTunnelPane.cpp | 2 +- qt/i2pd_qt/ServerTunnelPane.cpp | 2 +- qt/i2pd_qt/SignatureTypeComboboxFactory.h | 20 ++- qt/i2pd_qt/TunnelConfig.h | 2 +- qt/i2pd_qt/i2pd_qt.pro | 171 ++++++++++++++++++---- qt/i2pd_qt/mainwindow.cpp | 8 +- qt/i2pd_qt/mainwindow.h | 4 +- 9 files changed, 167 insertions(+), 50 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 66b81ab2..778e0745 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -812,7 +812,7 @@ namespace client socks.push_back(sock); } } - for (auto & sock : socks ) sock->Terminate(); + for (auto & sock : socks ) sock->Terminate("SAMSession::CloseStreams()"); m_Sockets.clear(); } diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 5a6de143..499f0da7 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -87,10 +87,10 @@ namespace client void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; }; SAMSocketType GetSocketType () const { return m_SocketType; }; - void Terminate (); - private: + void Terminate (const char* reason); + + private: - void Terminate (const char* reason); void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleMessage (const boost::system::error_code& ecode, std::size_t bytes_transferred); diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp index 6ece1eaf..9fc00509 100644 --- a/qt/i2pd_qt/ClientTunnelPane.cpp +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -1,5 +1,5 @@ #include "ClientTunnelPane.h" -#include "../../ClientContext.h" +#include "ClientContext.h" #include "SignatureTypeComboboxFactory.h" #include "QVBoxLayout" diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp index 7261336e..d185be28 100644 --- a/qt/i2pd_qt/ServerTunnelPane.cpp +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -1,5 +1,5 @@ #include "ServerTunnelPane.h" -#include "../../ClientContext.h" +#include "ClientContext.h" #include "SignatureTypeComboboxFactory.h" ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf): diff --git a/qt/i2pd_qt/SignatureTypeComboboxFactory.h b/qt/i2pd_qt/SignatureTypeComboboxFactory.h index 111b7296..4d2289e1 100644 --- a/qt/i2pd_qt/SignatureTypeComboboxFactory.h +++ b/qt/i2pd_qt/SignatureTypeComboboxFactory.h @@ -4,7 +4,7 @@ #include #include #include -#include "../../Identity.h" +#include "Identity.h" class SignatureTypeComboBoxFactory { @@ -57,12 +57,22 @@ public: addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); //7 if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} ++index; - addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519PH", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519PH); //8 - if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519PH){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519PH", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph); //8 + if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} ++index; // the following signature type should never appear in netid=2 - addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_A_GOSTR3411", 0), SIGNING_KEY_TYPE_GOSTR3410_A_GOSTR3411); //65280 - if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_A_GOSTR3411){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256", 0), SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256); //9 + if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512); //10 + if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + // TODO: remove later + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST", 0), SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST); //65281 + if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} + ++index; + addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512_TEST", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST); //65282 + if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} ++index; if(!foundSelected){ addItem(signatureTypeCombobox, QString::number(selectedSigType), selectedSigType); //unknown sigtype diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h index 471afdef..b91a318c 100644 --- a/qt/i2pd_qt/TunnelConfig.h +++ b/qt/i2pd_qt/TunnelConfig.h @@ -4,7 +4,7 @@ #include "QString" #include -#include "../../ClientContext.h" +#include "../../libi2pd_client/ClientContext.h" #include "TunnelsPageUpdateListener.h" diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 247dc8a8..66839ff5 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -24,42 +24,149 @@ IFADDRS_PATH = $$MAIN_PATH/android-ifaddrs # 2) Check API 11 # Finally, click Install. -SOURCES += DaemonQT.cpp mainwindow.cpp -# ../../HTTPServer.cpp ../../I2PControl.cpp ../../Daemon.cpp ../../Config.cpp \ -# ../../AddressBook.cpp ../../api.cpp ../../Base.cpp ../../BOB.cpp ../../ClientContext.cpp \ -# ../../Crypto.cpp ../../Datagram.cpp ../../Destination.cpp ../../Family.cpp ../../FS.cpp \ -# ../../Garlic.cpp ../../HTTP.cpp ../../HTTPProxy.cpp ../../I2CP.cpp ../../I2NPProtocol.cpp \ -# ../../I2PEndian.cpp ../../I2PService.cpp ../../I2PTunnel.cpp ../../Identity.cpp \ -# ../../LeaseSet.cpp ../../Log.cpp ../../NetDb.cpp ../../NetDbRequests.cpp \ -# ../../NTCPSession.cpp ../../Profiling.cpp ../../Reseed.cpp ../../RouterContext.cpp \ -# ../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \ -# ../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \ -# ../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \ -# ../../TunnelPool.cpp ../../UPnP.cpp ../../Gzip.cpp ../../Timestamp.cpp ../../util.cpp \ -# ../../Event.cpp ../../BloomFiler.cpp ../../Gost.cpp ../../MatchedDestination.cpp \ -# ../../i2pd.cpp +SOURCES += DaemonQT.cpp mainwindow.cpp \ + ../../libi2pd/api.cpp \ + ../../libi2pd/Base.cpp \ + ../../libi2pd/BloomFilter.cpp \ + ../../libi2pd/Config.cpp \ + ../../libi2pd/Crypto.cpp \ + ../../libi2pd/Datagram.cpp \ + ../../libi2pd/Destination.cpp \ + ../../libi2pd/Event.cpp \ + ../../libi2pd/Family.cpp \ + ../../libi2pd/FS.cpp \ + ../../libi2pd/Garlic.cpp \ + ../../libi2pd/Gost.cpp \ + ../../libi2pd/Gzip.cpp \ + ../../libi2pd/HTTP.cpp \ + ../../libi2pd/I2NPProtocol.cpp \ + ../../libi2pd/I2PEndian.cpp \ + ../../libi2pd/Identity.cpp \ + ../../libi2pd/LeaseSet.cpp \ + ../../libi2pd/Log.cpp \ + ../../libi2pd/NetDb.cpp \ + ../../libi2pd/NetDbRequests.cpp \ + ../../libi2pd/NTCPSession.cpp \ + ../../libi2pd/Profiling.cpp \ + ../../libi2pd/Reseed.cpp \ + ../../libi2pd/RouterContext.cpp \ + ../../libi2pd/RouterInfo.cpp \ + ../../libi2pd/Signature.cpp \ + ../../libi2pd/SSU.cpp \ + ../../libi2pd/SSUData.cpp \ + ../../libi2pd/SSUSession.cpp \ + ../../libi2pd/Streaming.cpp \ + ../../libi2pd/Timestamp.cpp \ + ../../libi2pd/TransitTunnel.cpp \ + ../../libi2pd/Transports.cpp \ + ../../libi2pd/Tunnel.cpp \ + ../../libi2pd/TunnelEndpoint.cpp \ + ../../libi2pd/TunnelGateway.cpp \ + ../../libi2pd/TunnelPool.cpp \ + ../../libi2pd/util.cpp \ + ../../libi2pd_client/AddressBook.cpp \ + ../../libi2pd_client/BOB.cpp \ + ../../libi2pd_client/ClientContext.cpp \ + ../../libi2pd_client/HTTPProxy.cpp \ + ../../libi2pd_client/I2CP.cpp \ + ../../libi2pd_client/I2PService.cpp \ + ../../libi2pd_client/I2PTunnel.cpp \ + ../../libi2pd_client/MatchedDestination.cpp \ + ../../libi2pd_client/SAM.cpp \ + ../../libi2pd_client/SOCKS.cpp \ + ../../libi2pd_client/Websocket.cpp \ + ../../libi2pd_client/WebSocks.cpp \ + ClientTunnelPane.cpp \ + MainWindowItems.cpp \ + ServerTunnelPane.cpp \ + SignatureTypeComboboxFactory.cpp \ + TunnelConfig.cpp \ + TunnelPane.cpp \ + ../../daemon/Daemon.cpp \ + ../../daemon/HTTPServer.cpp \ + ../../daemon/i2pd.cpp \ + ../../daemon/I2PControl.cpp \ + ../../daemon/UnixDaemon.cpp \ + ../../daemon/UPnP.cpp -SOURCES += $$files(../../libi2pd/*.cpp) -SOURCES += $$files(../../libi2pd_client/*.cpp) -SOURCES += $$files(../../daemon/*.cpp) -SOURCES += $$files(./*.cpp) +#qt creator does not handle this well +#SOURCES += $$files(../../libi2pd/*.cpp) +#SOURCES += $$files(../../libi2pd_client/*.cpp) +#SOURCES += $$files(../../daemon/*.cpp) +#SOURCES += $$files(./*.cpp) SOURCES -= ../../daemon/UnixDaemon.cpp -HEADERS += DaemonQT.h mainwindow.h -# ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ -# ../../AddressBook.h ../../api.h ../../Base.h ../../BOB.h ../../ClientContext.h \ -# ../../Crypto.h ../../Datagram.h ../../Destination.h ../../Family.h ../../FS.h \ -# ../../Garlic.h ../../HTTP.h ../../HTTPProxy.h ../../I2CP.h ../../I2NPProtocol.h \ -# ../../I2PEndian.h ../../I2PService.h ../../I2PTunnel.h ../../Identity.h ../../LeaseSet.h \ -# ../../LittleBigEndian.h ../../Log.h ../../NetDb.h ../../NetDbRequests.h ../../NTCPSession.h \ -# ../../Profiling.h ../../Queue.h ../../Reseed.h ../../RouterContext.h ../../RouterInfo.h \ -# ../../SAM.h ../../Signature.h ../../SOCKS.h ../../SSU.h ../../SSUData.h ../../SSUSession.h \ -# ../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \ -# ../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \ -# ../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \ -# ../../util.h ../../version.h ../../Gzip.h ../../Tag.h \ -# ../../BloomFiler.h ../../Event.h ../../Gost.h ../../MatchedDestination.h +HEADERS += DaemonQT.h mainwindow.h \ + ../../libi2pd/api.h \ + ../../libi2pd/Base.h \ + ../../libi2pd/BloomFilter.h \ + ../../libi2pd/Config.h \ + ../../libi2pd/Crypto.h \ + ../../libi2pd/Datagram.h \ + ../../libi2pd/Destination.h \ + ../../libi2pd/Event.h \ + ../../libi2pd/Family.h \ + ../../libi2pd/FS.h \ + ../../libi2pd/Garlic.h \ + ../../libi2pd/Gost.h \ + ../../libi2pd/Gzip.h \ + ../../libi2pd/HTTP.h \ + ../../libi2pd/I2NPProtocol.h \ + ../../libi2pd/I2PEndian.h \ + ../../libi2pd/Identity.h \ + ../../libi2pd/LeaseSet.h \ + ../../libi2pd/LittleBigEndian.h \ + ../../libi2pd/Log.h \ + ../../libi2pd/NetDb.hpp \ + ../../libi2pd/NetDbRequests.h \ + ../../libi2pd/NTCPSession.h \ + ../../libi2pd/Profiling.h \ + ../../libi2pd/Queue.h \ + ../../libi2pd/Reseed.h \ + ../../libi2pd/RouterContext.h \ + ../../libi2pd/RouterInfo.h \ + ../../libi2pd/Signature.h \ + ../../libi2pd/SSU.h \ + ../../libi2pd/SSUData.h \ + ../../libi2pd/SSUSession.h \ + ../../libi2pd/Streaming.h \ + ../../libi2pd/Tag.h \ + ../../libi2pd/Timestamp.h \ + ../../libi2pd/TransitTunnel.h \ + ../../libi2pd/Transports.h \ + ../../libi2pd/TransportSession.h \ + ../../libi2pd/Tunnel.h \ + ../../libi2pd/TunnelBase.h \ + ../../libi2pd/TunnelConfig.h \ + ../../libi2pd/TunnelEndpoint.h \ + ../../libi2pd/TunnelGateway.h \ + ../../libi2pd/TunnelPool.h \ + ../../libi2pd/util.h \ + ../../libi2pd/version.h \ + ../../libi2pd_client/AddressBook.h \ + ../../libi2pd_client/BOB.h \ + ../../libi2pd_client/ClientContext.h \ + ../../libi2pd_client/HTTPProxy.h \ + ../../libi2pd_client/I2CP.h \ + ../../libi2pd_client/I2PService.h \ + ../../libi2pd_client/I2PTunnel.h \ + ../../libi2pd_client/MatchedDestination.h \ + ../../libi2pd_client/SAM.h \ + ../../libi2pd_client/SOCKS.h \ + ../../libi2pd_client/Websocket.h \ + ../../libi2pd_client/WebSocks.h \ + ClientTunnelPane.h \ + MainWindowItems.h \ + ServerTunnelPane.h \ + SignatureTypeComboboxFactory.h \ + TunnelConfig.h \ + TunnelPane.h \ + TunnelsPageUpdateListener.h \ + ../../daemon/Daemon.h \ + ../../daemon/HTTPServer.h \ + ../../daemon/I2PControl.h \ + ../../daemon/UPnP.h INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index decd5470..304a3758 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -4,10 +4,10 @@ #include #include #include -#include "../../RouterContext.h" -#include "../../Config.h" -#include "../../FS.h" -#include "../../Log.h" +#include "RouterContext.h" +#include "Config.h" +#include "FS.h" +#include "Log.h" #ifndef ANDROID # include diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 4d465f1a..03057f2e 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -41,8 +41,8 @@ #include "ClientTunnelPane.h" #include "TunnelConfig.h" -#include "../../Config.h" -#include "../../FS.h" +#include "Config.h" +#include "FS.h" #include From 7bab92042ab869326b0fbafea56ca09b62b33632 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 2 Jun 2017 23:50:42 +0800 Subject: [PATCH 18/23] removed some obsolete files --- qt/i2pd_qt/mainwindow.ui.backup_workingOK | 2873 ----------------- qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017 | 2873 ----------------- qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn2 | 2964 ----------------- qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn3 | 3161 ------------------ qt/i2pd_qt/mainwindow.ui_expandedForm_old4 | 3231 ------------------- 5 files changed, 15102 deletions(-) delete mode 100644 qt/i2pd_qt/mainwindow.ui.backup_workingOK delete mode 100644 qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017 delete mode 100644 qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn2 delete mode 100644 qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn3 delete mode 100644 qt/i2pd_qt/mainwindow.ui_expandedForm_old4 diff --git a/qt/i2pd_qt/mainwindow.ui.backup_workingOK b/qt/i2pd_qt/mainwindow.ui.backup_workingOK deleted file mode 100644 index 825fb0e6..00000000 --- a/qt/i2pd_qt/mainwindow.ui.backup_workingOK +++ /dev/null @@ -1,2873 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 816 - 3000 - - - - MainWindow - - - - - 0 - 0 - - - - - - 10 - 10 - 801 - 491 - - - - - QLayout::SetDefaultConstraint - - - - - QLayout::SetMinimumSize - - - - - true - - - Status - - - - - - - true - - - Settings - - - - - - - true - - - Tunnels - - - - - - - true - - - Restart - - - - - - - true - - - Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - 16777215 - 516 - - - - 1 - - - - - - 0 - 0 - 671 - 491 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Status - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 701 - 460 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Settings - - - - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - QAbstractScrollArea::AdjustIgnored - - - true - - - - - 0 - 0 - 683 - 426 - - - - - 0 - 0 - - - - - - 10 - 11 - 661 - 3000 - - - - - - - - 0 - 0 - - - - - 0 - 46 - - - - - 16777215 - 46 - - - - Configuration file: - - - - - 0 - 18 - 661 - 31 - - - - - QLayout::SetMinimumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 0 - - - - - 0 - 215 - - - - - 16777215 - 215 - - - - Router options - - - - - 0 - 20 - 661 - 188 - - - - - - - Enable communication through ipv6 - - - - - - - Router will not accept transit tunnels at startup - - - - - - - Router will be floodfill - - - - - - - - - Bandwidth limit (integer): - - - - - - - - - - KBps - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Family (name of a family router belongs to): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMaximumSize - - - - - NetID (network ID router belongs to. The main I2P ID is 2): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 309 - - - - - 16777215 - 309 - - - - Socks proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 250 - 661 - 31 - - - - - - - Outproxy address: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 280 - 661 - 31 - - - - - - - Outproxy port: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Router external address (for incoming connections) - - - Qt::AlignJustify|Qt::AlignTop - - - - - 0 - 20 - 661 - 81 - - - - - QLayout::SetMinAndMaxSize - - - - - QLayout::SetMinAndMaxSize - - - - - Host: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMinAndMaxSize - - - - - Port (leave empty to auto-assign): - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Tunnels configuration file: - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Data folder (for storage of i2pd data — RI, keys, peer profiles, …): - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 249 - - - - - 16777215 - 249 - - - - HTTP proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 179 - - - - - 16777215 - 179 - - - - HTTP webconsole - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 321 - 22 - - - - Enable basic HTTP auth - - - - - - 60 - 120 - 601 - 31 - - - - - - - Username: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 60 - 150 - 601 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - General options - - - - - - - - 0 - 107 - - - - - 16777215 - 107 - - - - Logging - - - Qt::AlignJustify|Qt::AlignTop - - - - - -1 - 19 - 661 - 91 - - - - - QLayout::SetMinimumSize - - - - - QLayout::SetMaximumSize - - - - - Log file: - - - - - - - - - - Browse… - - - - - - - - - QLayout::SetMinimumSize - - - - - - 0 - 0 - - - - Log level: - - - - - - - - Error - - - - - Warn - - - - - Info - - - - - Debug - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - SAM interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - BOB interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - I2CP interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 189 - - - - - 16777215 - 189 - - - - I2PControl interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Certificate file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Key file: - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 108 - - - - - 16777215 - 108 - - - - Limits - - - - - 0 - 20 - 661 - 31 - - - - - - - Maximum number of transit tunnels: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Maximum number of open files (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 80 - 661 - 31 - - - - - - - Maximum size of core file in Kb (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Ports - - - - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Insomnia (prevent system from sleeping) - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Pid file: - - - - - 0 - 20 - 661 - 31 - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 44 - - - - - 16777215 - 44 - - - - Cryptography - - - - - 0 - 20 - 661 - 22 - - - - Use ElGamal precomputed tables - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Windows-specific options - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Reseeding - - - - - 0 - 20 - 661 - 22 - - - - Request SU3 signature verification - - - - - - 0 - 40 - 661 - 31 - - - - - - - SU3 file to reseed from: - - - - - - - - - - Browse… - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Reseed URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 78 - - - - - 16777215 - 78 - - - - Addressbook settings - - - - - 0 - 20 - 661 - 31 - - - - - - - Addressbook default subscription URL for initial setup: - - - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Addressbook subscriptions URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Various options - - - - - - - - 0 - 68 - - - - - 16777215 - 68 - - - - UPnP - - - - - 0 - 20 - 97 - 22 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Name i2pd appears in UPnP forwardings list: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - - - - - 0 - 0 - 681 - 460 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Tunnels - - - - - - - Qt::ScrollBarAlwaysOn - - - true - - - - - 0 - 0 - 84 - 28 - - - - - - - - - - - - - 0 - 0 - 681 - 451 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Restart - - - - - - - Restart i2pd - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 671 - 480 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Quit - - - - - - - Quit Now - - - - - - - Graceful Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - handleQuitButton() - handleGracefulQuitButton() - - diff --git a/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017 b/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017 deleted file mode 100644 index 825fb0e6..00000000 --- a/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017 +++ /dev/null @@ -1,2873 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 816 - 3000 - - - - MainWindow - - - - - 0 - 0 - - - - - - 10 - 10 - 801 - 491 - - - - - QLayout::SetDefaultConstraint - - - - - QLayout::SetMinimumSize - - - - - true - - - Status - - - - - - - true - - - Settings - - - - - - - true - - - Tunnels - - - - - - - true - - - Restart - - - - - - - true - - - Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - 16777215 - 516 - - - - 1 - - - - - - 0 - 0 - 671 - 491 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Status - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 701 - 460 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Settings - - - - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - QAbstractScrollArea::AdjustIgnored - - - true - - - - - 0 - 0 - 683 - 426 - - - - - 0 - 0 - - - - - - 10 - 11 - 661 - 3000 - - - - - - - - 0 - 0 - - - - - 0 - 46 - - - - - 16777215 - 46 - - - - Configuration file: - - - - - 0 - 18 - 661 - 31 - - - - - QLayout::SetMinimumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 0 - - - - - 0 - 215 - - - - - 16777215 - 215 - - - - Router options - - - - - 0 - 20 - 661 - 188 - - - - - - - Enable communication through ipv6 - - - - - - - Router will not accept transit tunnels at startup - - - - - - - Router will be floodfill - - - - - - - - - Bandwidth limit (integer): - - - - - - - - - - KBps - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Family (name of a family router belongs to): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMaximumSize - - - - - NetID (network ID router belongs to. The main I2P ID is 2): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 309 - - - - - 16777215 - 309 - - - - Socks proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 250 - 661 - 31 - - - - - - - Outproxy address: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 280 - 661 - 31 - - - - - - - Outproxy port: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Router external address (for incoming connections) - - - Qt::AlignJustify|Qt::AlignTop - - - - - 0 - 20 - 661 - 81 - - - - - QLayout::SetMinAndMaxSize - - - - - QLayout::SetMinAndMaxSize - - - - - Host: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMinAndMaxSize - - - - - Port (leave empty to auto-assign): - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Tunnels configuration file: - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Data folder (for storage of i2pd data — RI, keys, peer profiles, …): - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 249 - - - - - 16777215 - 249 - - - - HTTP proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 179 - - - - - 16777215 - 179 - - - - HTTP webconsole - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 321 - 22 - - - - Enable basic HTTP auth - - - - - - 60 - 120 - 601 - 31 - - - - - - - Username: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 60 - 150 - 601 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - General options - - - - - - - - 0 - 107 - - - - - 16777215 - 107 - - - - Logging - - - Qt::AlignJustify|Qt::AlignTop - - - - - -1 - 19 - 661 - 91 - - - - - QLayout::SetMinimumSize - - - - - QLayout::SetMaximumSize - - - - - Log file: - - - - - - - - - - Browse… - - - - - - - - - QLayout::SetMinimumSize - - - - - - 0 - 0 - - - - Log level: - - - - - - - - Error - - - - - Warn - - - - - Info - - - - - Debug - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - SAM interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - BOB interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - I2CP interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 189 - - - - - 16777215 - 189 - - - - I2PControl interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Certificate file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Key file: - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 108 - - - - - 16777215 - 108 - - - - Limits - - - - - 0 - 20 - 661 - 31 - - - - - - - Maximum number of transit tunnels: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Maximum number of open files (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 80 - 661 - 31 - - - - - - - Maximum size of core file in Kb (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Ports - - - - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Insomnia (prevent system from sleeping) - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Pid file: - - - - - 0 - 20 - 661 - 31 - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 44 - - - - - 16777215 - 44 - - - - Cryptography - - - - - 0 - 20 - 661 - 22 - - - - Use ElGamal precomputed tables - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Windows-specific options - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Reseeding - - - - - 0 - 20 - 661 - 22 - - - - Request SU3 signature verification - - - - - - 0 - 40 - 661 - 31 - - - - - - - SU3 file to reseed from: - - - - - - - - - - Browse… - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Reseed URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 78 - - - - - 16777215 - 78 - - - - Addressbook settings - - - - - 0 - 20 - 661 - 31 - - - - - - - Addressbook default subscription URL for initial setup: - - - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Addressbook subscriptions URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Various options - - - - - - - - 0 - 68 - - - - - 16777215 - 68 - - - - UPnP - - - - - 0 - 20 - 97 - 22 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Name i2pd appears in UPnP forwardings list: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - - - - - 0 - 0 - 681 - 460 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Tunnels - - - - - - - Qt::ScrollBarAlwaysOn - - - true - - - - - 0 - 0 - 84 - 28 - - - - - - - - - - - - - 0 - 0 - 681 - 451 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Restart - - - - - - - Restart i2pd - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 671 - 480 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Quit - - - - - - - Quit Now - - - - - - - Graceful Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - handleQuitButton() - handleGracefulQuitButton() - - diff --git a/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn2 b/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn2 deleted file mode 100644 index b6bcc5ea..00000000 --- a/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn2 +++ /dev/null @@ -1,2964 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 816 - 5000 - - - - MainWindow - - - - - 0 - 0 - - - - - - 10 - 10 - 801 - 5000 - - - - - QLayout::SetDefaultConstraint - - - - - QLayout::SetMinimumSize - - - - - true - - - Status - - - - - - - true - - - Settings - - - - - - - true - - - Tunnels - - - - - - - true - - - Restart - - - - - - - true - - - Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - 16777215 - 516 - - - - 1 - - - - - - 0 - 0 - 671 - 5000 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Status - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 701 - 5000 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Settings - - - - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - QAbstractScrollArea::AdjustIgnored - - - true - - - - - 0 - 0 - 683 - 426 - - - - - 0 - 0 - - - - - - 10 - 11 - 661 - 3000 - - - - - - - - 0 - 44 - - - - - 16777215 - 44 - - - - Cryptography - - - - - 0 - 20 - 661 - 22 - - - - Use ElGamal precomputed tables - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Windows-specific options - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Reseeding - - - - - 0 - 20 - 661 - 22 - - - - Request SU3 signature verification - - - - - - 0 - 40 - 661 - 31 - - - - - - - SU3 file to reseed from: - - - - - - - - - - Browse… - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Reseed URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 78 - - - - - 16777215 - 78 - - - - Addressbook settings - - - - - 0 - 20 - 661 - 31 - - - - - - - Addressbook default subscription URL for initial setup: - - - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Addressbook subscriptions URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Various options - - - - - - - - 0 - 68 - - - - - 16777215 - 68 - - - - UPnP - - - - - 0 - 20 - 97 - 22 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Name i2pd appears in UPnP forwardings list: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 215 - - - - - 16777215 - 215 - - - - Router options - - - - - 0 - 20 - 661 - 188 - - - - - - - Enable communication through ipv6 - - - - - - - Router will not accept transit tunnels at startup - - - - - - - Router will be floodfill - - - - - - - - - Bandwidth limit (integer): - - - - - - - - - - KBps - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Family (name of a family router belongs to): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMaximumSize - - - - - NetID (network ID router belongs to. The main I2P ID is 2): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 179 - - - - - 16777215 - 179 - - - - HTTP webconsole - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 321 - 22 - - - - Enable basic HTTP auth - - - - - - 60 - 120 - 601 - 31 - - - - - - - Username: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 60 - 150 - 601 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - General options - - - - - - - - 0 - 107 - - - - - 16777215 - 107 - - - - Logging - - - Qt::AlignJustify|Qt::AlignTop - - - - - -1 - 19 - 661 - 91 - - - - - QLayout::SetMinimumSize - - - - - QLayout::SetMaximumSize - - - - - Log file: - - - - - - - - - - Browse… - - - - - - - - - QLayout::SetMinimumSize - - - - - - 0 - 0 - - - - Log level: - - - - - - - - Error - - - - - Warn - - - - - Info - - - - - Debug - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Tunnels configuration file: - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Data folder (for storage of i2pd data — RI, keys, peer profiles, …): - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 249 - - - - - 16777215 - 249 - - - - HTTP proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 189 - - - - - 16777215 - 189 - - - - I2PControl interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Certificate file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Key file: - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 108 - - - - - 16777215 - 108 - - - - Limits - - - - - 0 - 20 - 661 - 31 - - - - - - - Maximum number of transit tunnels: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Maximum number of open files (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 80 - 661 - 31 - - - - - - - Maximum size of core file in Kb (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Ports - - - - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Insomnia (prevent system from sleeping) - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Pid file: - - - - - 0 - 20 - 661 - 31 - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 309 - - - - - 16777215 - 309 - - - - Socks proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 250 - 661 - 31 - - - - - - - Outproxy address: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 280 - 661 - 31 - - - - - - - Outproxy port: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Router external address (for incoming connections) - - - Qt::AlignJustify|Qt::AlignTop - - - - - 0 - 20 - 661 - 81 - - - - - QLayout::SetMinAndMaxSize - - - - - QLayout::SetMinAndMaxSize - - - - - Host: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMinAndMaxSize - - - - - Port (leave empty to auto-assign): - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - SAM interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - BOB interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - I2CP interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 46 - - - - - 16777215 - 46 - - - - Configuration file: - - - - - 0 - 18 - 661 - 31 - - - - - QLayout::SetMinimumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 150 - - - - - 16777215 - 50 - - - - Trust options - - - - - 0 - 20 - 661 - 21 - - - - Enable explicit trust options - - - - - - 390 - 40 - 271 - 23 - - - - - - - 0 - 40 - 391 - 21 - - - - Make direct I2P connections only to routers in specified Family: - - - - - - 0 - 60 - 661 - 16 - - - - Make direct I2P connections only to routers specified here. Comma separated list of base64 identities: - - - - - - 0 - 80 - 661 - 23 - - - - - - - 0 - 100 - 661 - 21 - - - - Should we hide our router from other routers? - - - - - - - - - - - - - - - - - 0 - 0 - 681 - 460 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Tunnels - - - - - - - Qt::ScrollBarAlwaysOn - - - true - - - - - 0 - 0 - 663 - 426 - - - - - - - - - - - - - 0 - 0 - 681 - 451 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Restart - - - - - - - Restart i2pd - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 671 - 480 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Quit - - - - - - - Quit Now - - - - - - - Graceful Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - handleQuitButton() - handleGracefulQuitButton() - - diff --git a/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn3 b/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn3 deleted file mode 100644 index 9dbaca2b..00000000 --- a/qt/i2pd_qt/mainwindow.ui.bk_26_feb_2017_sn3 +++ /dev/null @@ -1,3161 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 816 - 5000 - - - - MainWindow - - - - - 0 - 0 - - - - - - 10 - 10 - 801 - 5000 - - - - - QLayout::SetDefaultConstraint - - - - - QLayout::SetMinimumSize - - - - - true - - - Status - - - - - - - true - - - Settings - - - - - - - true - - - Tunnels - - - - - - - true - - - Restart - - - - - - - true - - - Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - 16777215 - 516 - - - - 1 - - - - - - 0 - 0 - 671 - 5000 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Status - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 701 - 5000 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Settings - - - - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - QAbstractScrollArea::AdjustIgnored - - - true - - - - - 0 - 0 - 683 - 426 - - - - - 0 - 0 - - - - - - 10 - 11 - 661 - 3000 - - - - - - - - 0 - 68 - - - - - 16777215 - 68 - - - - UPnP - - - - - 0 - 20 - 97 - 22 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Name i2pd appears in UPnP forwardings list: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 78 - - - - - 16777215 - 78 - - - - Addressbook settings - - - - - 0 - 20 - 661 - 31 - - - - - - - Addressbook default subscription URL for initial setup: - - - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Addressbook subscriptions URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Tunnels configuration file: - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 44 - - - - - 16777215 - 44 - - - - Cryptography - - - - - 0 - 20 - 661 - 22 - - - - Use ElGamal precomputed tables - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Windows-specific options - - - - - - - - 0 - 110 - - - - - 16777215 - 110 - - - - Limits - - - - - 0 - 20 - 221 - 16 - - - - Maximum number of transit tunnels: - - - - - - 0 - 50 - 331 - 16 - - - - Maximum number of open files (0 — use system limit): - - - - - - 0 - 80 - 341 - 16 - - - - Maximum size of corefile in Kb (0 — use system limit): - - - - - - 360 - 20 - 113 - 23 - - - - - - - 360 - 50 - 113 - 23 - - - - - - - 360 - 80 - 113 - 23 - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Various options - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Reseeding - - - - - 0 - 20 - 661 - 22 - - - - Request SU3 signature verification - - - - - - 0 - 40 - 661 - 31 - - - - - - - SU3 file to reseed from: - - - - - - - - - - Browse… - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Reseed URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 179 - - - - - 16777215 - 179 - - - - HTTP webconsole - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 321 - 22 - - - - Enable basic HTTP auth - - - - - - 60 - 120 - 601 - 31 - - - - - - - Username: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 60 - 150 - 601 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Data folder (for storage of i2pd data — RI, keys, peer profiles, …): - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 107 - - - - - 16777215 - 107 - - - - Logging - - - Qt::AlignJustify|Qt::AlignTop - - - - - -1 - 19 - 661 - 91 - - - - - QLayout::SetMinimumSize - - - - - QLayout::SetMaximumSize - - - - - Log file: - - - - - - - - - - Browse… - - - - - - - - - QLayout::SetMinimumSize - - - - - - 0 - 0 - - - - Log level: - - - - - - - - Error - - - - - Warn - - - - - Info - - - - - Debug - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - General options - - - - - - - - 0 - 0 - - - - - 0 - 215 - - - - - 16777215 - 215 - - - - Router options - - - - - 0 - 20 - 661 - 188 - - - - - - - Enable communication through ipv6 - - - - - - - Router will not accept transit tunnels at startup - - - - - - - Router will be floodfill - - - - - - - - - Bandwidth limit (integer): - - - - - - - - - - KBps - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Family (name of a family router belongs to): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMaximumSize - - - - - NetID (network ID router belongs to. The main I2P ID is 2): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 249 - - - - - 16777215 - 249 - - - - HTTP proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 189 - - - - - 16777215 - 189 - - - - I2PControl interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Certificate file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Key file: - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 108 - - - - - 16777215 - 108 - - - - Limits - - - - - 0 - 20 - 661 - 31 - - - - - - - Maximum number of transit tunnels: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Maximum number of open files (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 80 - 661 - 31 - - - - - - - Maximum size of core file in Kb (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Ports - - - - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Insomnia (prevent system from sleeping) - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Pid file: - - - - - 0 - 20 - 661 - 31 - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 309 - - - - - 16777215 - 309 - - - - Socks proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 250 - 661 - 31 - - - - - - - Outproxy address: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 280 - 661 - 31 - - - - - - - Outproxy port: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Router external address (for incoming connections) - - - Qt::AlignJustify|Qt::AlignTop - - - - - 0 - 20 - 661 - 81 - - - - - QLayout::SetMinAndMaxSize - - - - - QLayout::SetMinAndMaxSize - - - - - Host: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMinAndMaxSize - - - - - Port (leave empty to auto-assign): - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - SAM interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - BOB interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - I2CP interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 46 - - - - - 16777215 - 46 - - - - Configuration file: - - - - - 0 - 18 - 661 - 31 - - - - - QLayout::SetMinimumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - Trust options - - - - - 0 - 20 - 661 - 21 - - - - Enable explicit trust options - - - - - - 390 - 40 - 271 - 23 - - - - - - - 0 - 40 - 391 - 21 - - - - Make direct I2P connections only to routers in specified Family: - - - - - - 0 - 60 - 661 - 16 - - - - Make direct I2P connections only to routers specified here. Comma separated list of base64 identities: - - - - - - 0 - 80 - 661 - 23 - - - - - - - 0 - 100 - 661 - 21 - - - - Should we hide our router from other routers? - - - - - - - - - 0 - 110 - - - - - 16777215 - 110 - - - - Websockets server - - - - - 0 - 20 - 85 - 21 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Address to bind websocket server on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to bind websocket server on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - - - - - 0 - 0 - 681 - 460 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Tunnels - - - - - - - Qt::ScrollBarAlwaysOn - - - true - - - - - 0 - 0 - 663 - 426 - - - - - - - - - - - - - 0 - 0 - 681 - 451 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Restart - - - - - - - Restart i2pd - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 671 - 480 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Quit - - - - - - - Quit Now - - - - - - - Graceful Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - handleQuitButton() - handleGracefulQuitButton() - - diff --git a/qt/i2pd_qt/mainwindow.ui_expandedForm_old4 b/qt/i2pd_qt/mainwindow.ui_expandedForm_old4 deleted file mode 100644 index 691e6a9e..00000000 --- a/qt/i2pd_qt/mainwindow.ui_expandedForm_old4 +++ /dev/null @@ -1,3231 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 816 - 5000 - - - - MainWindow - - - - - 0 - 0 - - - - - - 10 - 10 - 801 - 5000 - - - - - QLayout::SetDefaultConstraint - - - - - QLayout::SetMinimumSize - - - - - true - - - Status - - - - - - - true - - - Settings - - - - - - - true - - - Tunnels - - - - - - - true - - - Restart - - - - - - - true - - - Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - 16777215 - 5000 - - - - 1 - - - - - - 0 - 0 - 671 - 5000 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Status - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 701 - 5000 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Settings - - - - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - QAbstractScrollArea::AdjustIgnored - - - true - - - - - 0 - 0 - 683 - 4966 - - - - - 0 - 0 - - - - - - 10 - 11 - 661 - 4920 - - - - - - - - 0 - 68 - - - - - 16777215 - 68 - - - - UPnP - - - - - 0 - 20 - 97 - 22 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Name i2pd appears in UPnP forwardings list: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 78 - - - - - 16777215 - 78 - - - - Addressbook settings - - - - - 0 - 20 - 661 - 31 - - - - - - - Addressbook default subscription URL for initial setup: - - - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Addressbook subscriptions URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Tunnels configuration file: - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 44 - - - - - 16777215 - 44 - - - - Cryptography - - - - - 0 - 20 - 661 - 22 - - - - Use ElGamal precomputed tables - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Windows-specific options - - - - - - - - 0 - 110 - - - - - 16777215 - 110 - - - - Limits - - - - - 0 - 20 - 221 - 16 - - - - Maximum number of transit tunnels: - - - - - - 0 - 50 - 331 - 16 - - - - Maximum number of open files (0 — use system limit): - - - - - - 0 - 80 - 341 - 16 - - - - Maximum size of corefile in Kb (0 — use system limit): - - - - - - 360 - 20 - 113 - 23 - - - - - - - 360 - 50 - 113 - 23 - - - - - - - 360 - 80 - 113 - 23 - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Various options - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Reseeding - - - - - 0 - 20 - 661 - 22 - - - - Request SU3 signature verification - - - - - - 0 - 40 - 661 - 31 - - - - - - - SU3 file to reseed from: - - - - - - - - - - Browse… - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Reseed URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 179 - - - - - 16777215 - 179 - - - - HTTP webconsole - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 321 - 22 - - - - Enable basic HTTP auth - - - - - - 60 - 120 - 601 - 31 - - - - - - - Username: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 60 - 150 - 601 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Data folder (for storage of i2pd data — RI, keys, peer profiles, …): - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 107 - - - - - 16777215 - 107 - - - - Logging - - - Qt::AlignJustify|Qt::AlignTop - - - - - -1 - 19 - 661 - 91 - - - - - QLayout::SetMinimumSize - - - - - QLayout::SetMaximumSize - - - - - Log file: - - - - - - - - - - Browse… - - - - - - - - - QLayout::SetMinimumSize - - - - - - 0 - 0 - - - - Log level: - - - - - - - - Error - - - - - Warn - - - - - Info - - - - - Debug - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - General options - - - - - - - - 0 - 0 - - - - - 0 - 215 - - - - - 16777215 - 215 - - - - Router options - - - - - 0 - 20 - 661 - 188 - - - - - - - Enable communication through ipv6 - - - - - - - Router will not accept transit tunnels at startup - - - - - - - Router will be floodfill - - - - - - - - - Bandwidth limit (integer): - - - - - - - - - - KBps - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Family (name of a family router belongs to): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMaximumSize - - - - - NetID (network ID router belongs to. The main I2P ID is 2): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 280 - - - - - 16777215 - 280 - - - - HTTP proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 250 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Signature type: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 189 - - - - - 16777215 - 189 - - - - I2PControl interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Certificate file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Key file: - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 108 - - - - - 16777215 - 108 - - - - Limits - - - - - 0 - 20 - 661 - 31 - - - - - - - Maximum number of transit tunnels: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Maximum number of open files (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 80 - 661 - 31 - - - - - - - Maximum size of core file in Kb (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Ports - - - - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Insomnia (prevent system from sleeping) - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Pid file: - - - - - 0 - 20 - 661 - 31 - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 0 - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Router external address (for incoming connections) - - - Qt::AlignJustify|Qt::AlignTop - - - - - 0 - 20 - 661 - 81 - - - - - QLayout::SetMinAndMaxSize - - - - - QLayout::SetMinAndMaxSize - - - - - Host: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMinAndMaxSize - - - - - Port (leave empty to auto-assign): - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - SAM interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 342 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - BOB interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - I2CP interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 46 - - - - - 16777215 - 46 - - - - Configuration file: - - - - - 0 - 18 - 661 - 31 - - - - - QLayout::SetMinimumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 120 - - - - - 16777215 - 120 - - - - Trust options - - - - - 0 - 20 - 661 - 21 - - - - Enable explicit trust options - - - - - - 390 - 40 - 271 - 23 - - - - - - - 0 - 40 - 391 - 21 - - - - Make direct I2P connections only to routers in specified Family: - - - - - - 0 - 60 - 661 - 16 - - - - Make direct I2P connections only to routers specified here. Comma separated list of base64 identities: - - - - - - 0 - 80 - 661 - 23 - - - - - - - 0 - 100 - 661 - 21 - - - - Should we hide our router from other routers? - - - - - - - - - 0 - 110 - - - - - 16777215 - 110 - - - - Websockets server - - - - - 0 - 20 - 85 - 21 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Address to bind websocket server on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to bind websocket server on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 340 - - - - - 16777215 - 340 - - - - Socks proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 250 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 280 - 661 - 31 - - - - - - - Outproxy address: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 310 - 661 - 31 - - - - - - - Outproxy port: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - SIgnature type: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - - - - - 0 - 0 - 681 - 460 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Tunnels - - - - - - - Qt::ScrollBarAlwaysOn - - - true - - - - - 0 - 0 - 663 - 426 - - - - - - - - - - - - - 0 - 0 - 681 - 451 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Restart - - - - - - - Restart i2pd - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 671 - 480 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Quit - - - - - - - Quit Now - - - - - - - Graceful Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - - - handleQuitButton() - handleGracefulQuitButton() - - From 3a89f2c32f254331f90fcb2ed06f9398bfbd39f9 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sat, 17 Jun 2017 20:31:00 +0800 Subject: [PATCH 19/23] now starting the i2pd daemon - uncommented emit start line --- qt/i2pd_qt/DaemonQT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/i2pd_qt/DaemonQT.cpp b/qt/i2pd_qt/DaemonQT.cpp index c51e88e3..accd69b1 100644 --- a/qt/i2pd_qt/DaemonQT.cpp +++ b/qt/i2pd_qt/DaemonQT.cpp @@ -162,7 +162,7 @@ namespace qt { i2p::qt::Controller daemonQtController(daemon); qDebug("Starting the daemon..."); - //DEBUG //emit daemonQtController.startDaemon(); + emit daemonQtController.startDaemon(); //daemon.start (); qDebug("Starting GUI event loop..."); result = app.exec(); From 76fab1fea8471a942e0fe9832e985bda44fe057b Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 18 Jun 2017 16:41:09 -0400 Subject: [PATCH 20/23] reseeds update --- .../reseed/creativecowpat_at_mail.i2p.crt | 35 +++++++++++++++++++ .../certificates/reseed/parg_at_mail.i2p.crt | 34 ------------------ .../reseed/randomrng_at_mail.i2p.crt | 34 ------------------ libi2pd/Config.cpp | 5 ++- 4 files changed, 37 insertions(+), 71 deletions(-) create mode 100644 contrib/certificates/reseed/creativecowpat_at_mail.i2p.crt delete mode 100644 contrib/certificates/reseed/parg_at_mail.i2p.crt delete mode 100644 contrib/certificates/reseed/randomrng_at_mail.i2p.crt diff --git a/contrib/certificates/reseed/creativecowpat_at_mail.i2p.crt b/contrib/certificates/reseed/creativecowpat_at_mail.i2p.crt new file mode 100644 index 00000000..07fe75aa --- /dev/null +++ b/contrib/certificates/reseed/creativecowpat_at_mail.i2p.crt @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +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 +Hz8KWVkHZg== +-----END CERTIFICATE----- diff --git a/contrib/certificates/reseed/parg_at_mail.i2p.crt b/contrib/certificates/reseed/parg_at_mail.i2p.crt deleted file mode 100644 index e78b264c..00000000 --- a/contrib/certificates/reseed/parg_at_mail.i2p.crt +++ /dev/null @@ -1,34 +0,0 @@ ------BEGIN CERTIFICATE----- -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 -N1tGWBZt9Prq ------END CERTIFICATE----- diff --git a/contrib/certificates/reseed/randomrng_at_mail.i2p.crt b/contrib/certificates/reseed/randomrng_at_mail.i2p.crt deleted file mode 100644 index aa3330ad..00000000 --- a/contrib/certificates/reseed/randomrng_at_mail.i2p.crt +++ /dev/null @@ -1,34 +0,0 @@ ------BEGIN CERTIFICATE----- -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 -Cw== ------END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index a0ec3e69..7668da66 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -182,14 +182,13 @@ namespace config { // "https://us.reseed.i2p2.no:444/," // mamoth's shit // "https://uk.reseed.i2p2.no:444/," // mamoth's shit "https://i2p-0.manas.ca:8443/," - "https://reseed.i2p.vzaws.com:8443/," "https://download.xxlspeed.com/," "https://reseed-ru.lngserv.ru/," "https://reseed.atomike.ninja/," "https://reseed.memcpy.io/," "https://reseed.onion.im/," - "https://itoopie.atomike.ninja/" -// "https://randomrng.ddns.net/" // dead + "https://itoopie.atomike.ninja/," + "https://i2pseed.creativecowpat.net:8443/" ), "Reseed URLs, separated by comma") ; From 8121ab51632eef1ab99a474eef8584add2c5ad18 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 22 Jun 2017 15:37:02 +0300 Subject: [PATCH 21/23] added including of configs and certificates in mingw batch build --- build/build_mingw.cmd | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/build/build_mingw.cmd b/build/build_mingw.cmd index 022df45e..6c7407f1 100644 --- a/build/build_mingw.cmd +++ b/build/build_mingw.cmd @@ -33,6 +33,8 @@ FOR /F "usebackq" %%a IN (`%WD%bash -lc 'git describe --tags'`) DO ( set tag=%%a ) +"%WD%bash" -lc "echo To use configs and certificates, move all files and certificates folder from contrib directory here. > README.txt" >> nul + REM starting building set MSYSTEM=MINGW32 set bitness=32 @@ -44,6 +46,8 @@ set bitness=64 call :BUILDING echo. +del README.txt >> nul + echo Build complete... pause exit /b 0 @@ -51,12 +55,12 @@ exit /b 0 :BUILDING echo Building i2pd %tag% for win%bitness%: echo Build AVX+AESNI... -"%WD%bash" -lc "make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1 +"%WD%bash" -lc "make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1 echo Build AVX... -"%WD%bash" -lc "make USE_UPNP=yes USE_AVX=1 -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip i2pd.exe && make clean" > build/build_win%bitness%_avx.log 2>&1 +"%WD%bash" -lc "make USE_UPNP=yes USE_AVX=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_avx.log 2>&1 echo Build AESNI... -"%WD%bash" -lc "make USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip i2pd.exe && make clean" > build/build_win%bitness%_aesni.log 2>&1 +"%WD%bash" -lc "make USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%_aesni.log 2>&1 echo Build without extensions... -"%WD%bash" -lc "make USE_UPNP=yes -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw.zip i2pd.exe && make clean" > build/build_win%bitness%.log 2>&1 +"%WD%bash" -lc "make USE_UPNP=yes -j%threads% && zip -r9 build/i2pd_%tag%_win%bitness%_mingw.zip i2pd.exe README.txt contrib/i2pd.conf contrib/tunnels.conf contrib/certificates && make clean" > build/build_win%bitness%.log 2>&1 :EOF \ No newline at end of file From 8f8b4536b62b3c182c7330956136f7b00fd422ea Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 22 Jun 2017 15:45:23 +0300 Subject: [PATCH 22/23] add future R4SAS reseed cert replacement warn: will use after 2.16.0 release --- .../reseed/r4sas-reseed_at_mail.i2p.crt | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 contrib/certificates/reseed/r4sas-reseed_at_mail.i2p.crt diff --git a/contrib/certificates/reseed/r4sas-reseed_at_mail.i2p.crt b/contrib/certificates/reseed/r4sas-reseed_at_mail.i2p.crt new file mode 100644 index 00000000..850b1afd --- /dev/null +++ b/contrib/certificates/reseed/r4sas-reseed_at_mail.i2p.crt @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIEY2XeQjANBgkqhkiG9w0BAQ0FADB1MQswCQYDVQQGEwJY +WDELMAkGA1UECAwCWFgxHjAcBgNVBAcMFUkyUCBBbm9ueW1vdXMgTmV0d29yazEL +MAkGA1UECgwCWFgxDDAKBgNVBAsMA0kyUDEeMBwGA1UEAwwVcjRzYXMtcmVzZWVk +QG1haWwuaTJwMB4XDTE3MDYyMjEwNTQ1NFoXDTI3MDYyMDEwNTQ1NFowdTELMAkG +A1UEBhMCWFgxCzAJBgNVBAgMAlhYMR4wHAYDVQQHDBVJMlAgQW5vbnltb3VzIE5l +dHdvcmsxCzAJBgNVBAoMAlhYMQwwCgYDVQQLDANJMlAxHjAcBgNVBAMMFXI0c2Fz +LXJlc2VlZEBtYWlsLmkycDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ANgsj5LhF4uGG4RDueShqYQZsG5Rz6XUAtK9sVGFdmdJTDZirUMZcCGCGZP/Harz +QaZU9EYxOCztnpLCQksSCpdRsij56MURS0tW/1x7LHIDUOi911Of57jgIHH+3E5n +6tuRxEk6J/9Ji3PI+89kl0sPKMVFMyKkINprVTA5zr/keyYEG0p6HSEYYiJkQH78 +8uoOCAmlk9mxkJFb+zviCk6jsYwdH+ofD6Lw5ueOlYUbeZ9Nd7jfSdf20XM7ofIw +W2COtsbq3J7vNrQJMV7HkHxVx/7OqmjQF02OahZFZREVZqbHpL501iTn9Iqd5qKq +IsxYjk7ZnP4UUCBk8NOU5TuWsy0qNw+TJDI9s55Fi4KPtXWf47HIl6CdpM5y/D5L +eufCojSwPKlrD6x9gTyJdBggBZRIyplXdKffo/95hUhEkv86yfsVVR7Gu1uy0O8T +Gtb8Da/oi5eEZBHWonLVicLPei5jeo+1gbR09PQ6s41uMZlOhMe4RSgiIQj/7UVo +ffKdl1MPNKr1u2fgVj8kxqg8ZivWKQ2taEgimU2EkQcNcE96M9yQlNNpNvqSAQVk +wYXlHt0AN6A1A8u1pItxaTwXnbmx+OBJZoKl4ZQeaC8wtKjTgAgVXp+g5iot2gir +LjxCRx1WLG1c8vRg1W8CDZII8Swc8EWpMhI+0hPv7/4/AgMBAAGjITAfMB0GA1Ud +DgQWBBTN5sKbrNzwE8sgMGDekfOPgX8/JDANBgkqhkiG9w0BAQ0FAAOCAgEAjLaB +bHqvFTs0ikAtesk9r8+8XVIsP5FR57zZCek2vxkHcCQWw8Uqs3ndInRX4FirKSLT +WRb4aSwFCkrmwueecTpXN/RBC+fZj+POCfdILEsA+FGreAM2q5ZXv/Q0jyIXOXEM ++KL0JZXnNS0/dqR3IYbC7f39CL6Sf40gRGTwTWWGg3KnynoS0v1zQcZLTMhHBD2X +tgdIPbroq9t4gXa7Dhm0egYfQOI/7re2wiZT7UWVVwEpYqKf6JApFHa1nNOFMrLF +45JHQIHArkoxpQdfSe9HBoyJiB5vz398rHZeqbJaF3PIg9rxWWY/NvvOVuIk8U5z +0jExhg29a88B32U7ndvQJqIuGiQghzCiLxC/y1+wAdpeDSbD3OAOHqplvMj3BUn9 +yhDSLSjtfBJjnXKxtEcWLR0edHCGEk5mAcL7q1WNxDpxaICwGGpNZN53CtFx7amb +egYil448DmiqoQTCTE9pBz8YjwiVfCYLYv17O0NJyYM9Efy/wL3rFlsPJniWHMuH +imZybVU4ukjvfOZ+LY4COTwz6w4sfA7a+i+2mOynC7eKX8Yg6i1nXlcY1Z8ykNgi +7B3kz1T/DV56CIm6QUWtepfuKTYq4C6QrBBIXLk1d5g95aWA21u1LRqNZ9GLH+eA +gfvIm7v+cELj8a53EQY0LafzZqNC5kQAp916coU= +-----END CERTIFICATE----- From 4bc1143418f67370782edd2af631936d0d0ab84c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Fri, 23 Jun 2017 13:02:31 +0300 Subject: [PATCH 23/23] update makefile to use gcc 7 on archlinux --- Makefile.linux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.linux b/Makefile.linux index 782b0203..0fd8873d 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -19,7 +19,7 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # >= 4.7 NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 else ifeq ($(shell expr match ${CXXVER} "4\.6"),3) # = 4.6 NEEDED_CXXFLAGS += -std=c++0x -else ifeq ($(shell expr match ${CXXVER} "[5-6]\.[0-9]"),3) # gcc >= 5.0 +else ifeq ($(shell expr match ${CXXVER} "[5-7]\.[0-9]"),3) # gcc >= 5.0 NEEDED_CXXFLAGS += -std=c++11 else # not supported $(error Compiler too old)