Merge branch 'RetroShare:master' into new_token_service

This commit is contained in:
Tushar Garg 2023-12-15 00:03:01 +05:30 committed by GitHub
commit 74e0692f69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
75 changed files with 1456 additions and 888 deletions

2
.gitignore vendored
View file

@ -21,7 +21,7 @@ Thumbs.db
!supportlibs/libsam3/Makefile !supportlibs/libsam3/Makefile
# QtCreator cruft # QtCreator cruft
*CMakeLists.txt.user *CMakeLists.txt.user*
# Build artifacts # Build artifacts
/jsonapi-generator/src/jsonapi-generator /jsonapi-generator/src/jsonapi-generator

View file

@ -1,7 +1,7 @@
image: docker:stable image: docker:latest
services: services:
- docker:stable-dind - docker:dind
stages: stages:
- build - build
@ -18,6 +18,7 @@ variables:
build-ubuntu-test-image: build-ubuntu-test-image:
stage: build stage: build
script: script:
- docker --version
- > - >
docker login "$CI_REGISTRY" docker login "$CI_REGISTRY"
--username "$CI_REGISTRY_USER" --username "$CI_REGISTRY_USER"
@ -35,6 +36,7 @@ build-ubuntu-test-image:
test-ubuntu: test-ubuntu:
stage: test stage: test
script: script:
- docker --version
- > - >
docker login "$CI_REGISTRY" docker login "$CI_REGISTRY"
--username "$CI_REGISTRY_USER" --username "$CI_REGISTRY_USER"

7
.gitmodules vendored
View file

@ -10,7 +10,8 @@
[submodule "supportlibs/udp-discovery-cpp"] [submodule "supportlibs/udp-discovery-cpp"]
path = supportlibs/udp-discovery-cpp path = supportlibs/udp-discovery-cpp
url = https://github.com/truvorskameikin/udp-discovery-cpp.git url = https://github.com/truvorskameikin/udp-discovery-cpp.git
branch = develop branch = master
# develop branch was removed we were using it at commit f3a3103a6c52e5707629e8d0a7e279a7758fe845
[submodule "supportlibs/rapidjson"] [submodule "supportlibs/rapidjson"]
path = supportlibs/rapidjson path = supportlibs/rapidjson
url = https://github.com/Tencent/rapidjson.git url = https://github.com/Tencent/rapidjson.git
@ -30,8 +31,8 @@
branch = master branch = master
[submodule "libretroshare"] [submodule "libretroshare"]
path = libretroshare path = libretroshare
url = ../libretroshare url = https://github.com/RetroShare/libretroshare.git
branch = master branch = master
[submodule "retroshare-webui"] [submodule "retroshare-webui"]
path = retroshare-webui path = retroshare-webui
url = ../RSNewWebUI url = https://github.com/RetroShare/RSNewWebUI.git

View file

@ -40,18 +40,23 @@ RUN git clone --depth 1 https://github.com/aetilius/pHash.git && \
rm -rf pHash-build pHash rm -rf pHash-build pHash
ARG FRESHCLONE=0 ARG FRESHCLONE=0
ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git ARG REPO_URL=https://github.com/RetroShare/RetroShare.git
ARG REPO_BRANCH=master ARG REPO_BRANCH=master
ARG REPO_DEPTH="--depth 2000" ARG REPO_DEPTH="--depth 2000"
RUN git clone $REPO_DEPTH $REPO_URL -b $REPO_BRANCH && cd RetroShare && \ RUN git clone $REPO_DEPTH $REPO_URL -b $REPO_BRANCH && \
cd RetroShare && \
git fetch --tags && \ git fetch --tags && \
git submodule update --init --remote --force \ git submodule update --init \
libbitdht/ libretroshare/ openpgpsdk/ && \ libbitdht/ libretroshare/ openpgpsdk/ retroshare-webui/ \
cd .. supportlibs/restbed/ && \
cd supportlibs/restbed/ && \
git submodule update --init \
dependency/asio/ dependency/kashmir/ && \
cd ../../../
RUN \ RUN \
mkdir RetroShare-build && cd RetroShare-build && \ mkdir RetroShare-build && cd RetroShare-build && \
cmake -B. -S../RetroShare/retroshare-service \ cmake -B. -S../RetroShare/retroshare-service \
-DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON && \ -DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON -DRS_WEBUI=ON && \
make -j$(nproc) && make install && \ make -j$(nproc) && make install && \
cd .. && rm -rf RetroShare-build cd .. && rm -rf RetroShare-build

View file

@ -2,19 +2,19 @@ FROM registry.gitlab.com/retroshare/retroshare:base
RUN apt-get update -y && apt-get upgrade -y RUN apt-get update -y && apt-get upgrade -y
ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git ARG REPO_URL=https://github.com/RetroShare/RetroShare.git
ARG REPO_BRANCH=master ARG REPO_BRANCH=master
RUN \ RUN \
cd RetroShare && git remote add testing $REPO_URL && \ cd RetroShare && git remote add testing $REPO_URL && \
git fetch --tags testing $REPO_BRANCH && \ git fetch --tags testing $REPO_BRANCH && \
git reset --hard testing/$REPO_BRANCH && \ git reset --hard testing/$REPO_BRANCH && \
git submodule update --init --remote --force \ git submodule update --init \
libbitdht/ libretroshare/ openpgpsdk/ && \ libbitdht/ libretroshare/ openpgpsdk/ retroshare-webui/ && \
git --no-pager log --max-count 1 git --no-pager log --max-count 1
RUN \ RUN \
mkdir RetroShare-build && cd RetroShare-build && \ mkdir RetroShare-build && cd RetroShare-build && \
cmake -B. -S../RetroShare/retroshare-service \ cmake -B. -S../RetroShare/retroshare-service \
-DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON \ -DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON -DRS_WEBUI=ON \
-DRS_WARN_DEPRECATED=OFF -DRS_WARN_LESS=ON && \ -DRS_WARN_DEPRECATED=OFF -DRS_WARN_LESS=ON && \
make -j$(nproc) && make install && \ make -j$(nproc) && make install && \
cd .. && rm -rf RetroShare-build cd .. && rm -rf RetroShare-build

@ -1 +1 @@
Subproject commit df16cb915465d058c75277678799ce4dadeae287 Subproject commit 97a75f2f098babf2f6498f01ff9119aa35ce9a28

View file

@ -30,13 +30,36 @@ In GitHub Desktop -> Clone Repository -> URL
Add Repository URL: https://github.com/RetroShare/RetroShare.git and Clone Add Repository URL: https://github.com/RetroShare/RetroShare.git and Clone
## ***Get XCode & MacOSX SDK***
Install XCode following this guide: [XCode](http://guide.macports.org/#installing.xcode)
To identify the correct version of Xcode to install, you need to know which OS you are running. Go to the [x] menu -> "About This Mac" and read the macOS version number.
If you are running the macOS Catalina >= 10.15, you can install Xcode directly from App Store using the instructions below.
You can find older versions of Xcode at [Apple Developer Downloads](https://developer.apple.com/downloads/). Find the appropriate .xip file for your macOS version
To install from App Store:
Select [x] menu - > "App Store…".
Search for Xcode. Download and install.
Once Xcode has installed, you must drag the XCode icon into your Applications folder. After you have done this, open Xcode from the Applications folder by double-clicking on the icon and then follow the remaining instructions below.
Install XCode command line developer tools:
$xcode-select --install
Start XCode to get it updated and to able C compiler to create executables.
Get Your MacOSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs)
## ***Choose if you use MacPort or HomeBrew*** ## ***Choose if you use MacPort or HomeBrew***
### MacPort Installation ### MacPort Installation
Install MacPort and XCode following this guide: [MacPort and XCode](http://guide.macports.org/#installing.xcode) Install MacPort following this guide: [MacPort](http://guide.macports.org/#installing.xcode)
Start XCode to get it updated and to able C compiler to create executables.
#### Install libraries #### Install libraries
@ -51,18 +74,11 @@ For VOIP Plugin:
$ sudo port install opencv $ sudo port install opencv
$ sudo port install ffmpeg $ sudo port install ffmpeg
Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs)
### HOMEBREW Installation ### HOMEBREW Installation
Install HomeBrew following this guide: [HomeBrew](http://brew.sh/) Install HomeBrew following this guide: [HomeBrew](http://brew.sh/)
Install XCode command line developer tools:
$xcode-select --install
Start XCode to get it updated and to able C compiler to create executables.
#### Install libraries #### Install libraries
$ brew install openssl $ brew install openssl
@ -86,7 +102,6 @@ For FeedReader Plugin:
$ brew install libxslt $ brew install libxslt
Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs)
## Last Settings ## Last Settings
@ -104,11 +119,8 @@ In QtCreator Projects -> Build -> Build Settings -> Build Steps -> Add Additiona
## Set your Mac OS SDK version ## Set your Mac OS SDK version
Edit RetroShare.pro
CONFIG += c++14 rs_macos11.1 Edit retroshare.pri and set your installed sdk version example for 11.1 -> rs_macos11.1 (line 135:)
and then retroshare.pri
macx:CONFIG *= rs_macos11.1 macx:CONFIG *= rs_macos11.1
rs_macos10.8:CONFIG -= rs_macos11.1 rs_macos10.8:CONFIG -= rs_macos11.1
@ -122,7 +134,7 @@ and then retroshare.pri
## Link Include & Libraries ## Link Include & Libraries
Edit your retroshare.pri and add to macx-* section When required edit your retroshare.pri macx-* section, check if the Include and Lib path are correct (macx-* section)
INCLUDEPATH += "/usr/local/opt/openssl/include" INCLUDEPATH += "/usr/local/opt/openssl/include"
QMAKE_LIBDIR += "/usr/local/opt/openssl/lib" QMAKE_LIBDIR += "/usr/local/opt/openssl/lib"
@ -131,13 +143,18 @@ Edit your retroshare.pri and add to macx-* section
alternative via Terminal alternative via Terminal
$ qmake INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib" $ qmake
INCLUDEPATH+="/usr/local/opt/openssl/include" \
QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" \
QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" \
QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib" \
CONFIG+=rs_autologin \
CONFIG+=rs_use_native_dialogs \
CONFIG+=release \
..
For FeedReader Plugin:
INCLUDEPATH += "/usr/local/opt/libxml2/include/libxml2" With plugins:
For building RetroShare with plugins:
$ qmake \ $ qmake \
INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" \ INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" \
@ -159,13 +176,30 @@ For building RetroShare with plugins:
You can now compile RetroShare into Qt Creator or with Terminal You can now compile RetroShare into Qt Creator or with Terminal
cd retroshare $ cd /path/to/retroshare
qmake; make $ qmake ..
$ make
You can change Target and SDK in *./retroshare.pri:82* changing value of QMAKE_MACOSX_DEPLOYMENT_TARGET and QMAKE_MAC_SDK You can change Target and SDK in *./retroshare.pri:82* changing value of QMAKE_MACOSX_DEPLOYMENT_TARGET and QMAKE_MAC_SDK
You can find the compiled application at *./retroshare/retroshare-gui/src/retroshare.app* You can find the compiled application at *./retroshare/retroshare-gui/src/retroshare.app*
## Issues
If you have issues with openssl (Undefined symbols for architecture x86_64) try to add to *~/.profile* file this or via Terminal
export PATH="/usr/local/opt/openssl/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/openssl/lib"
export CPPFLAGS="-I/usr/local/opt/openssl/include"
export PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig"
For Qt Creator -> QtCreator Projects -> Build -> Build Settings -> Build Steps -> Add Additional arguments:
LDFLAGS="-L/usr/local/opt/openssl/lib"
CPPFLAGS="-I/usr/local/opt/openssl/include"
## Copy Plugins ## Copy Plugins
$ cp \ $ cp \

View file

@ -0,0 +1,50 @@
#!/bin/sh
APP="RetroShare"
RSVERSION="0.6.7a"
QTVERSION="Qt-5.14.1"
# Install the 7z to create dmg archives.
#brew list p7zip || brew install p7zip
# Package your app
echo "Packaging retroshare..."
#cd ${project_dir}/build/macOS/clang/x86_64/release/
cd retroshare-gui/src/
# Remove build directories that you don't want to deploy
rm -rf moc
rm -rf obj
rm -rf qrc
# This sets the CFBundleVersion & CFBundleShortVersionString string
#/usr/libexec/PlistBuddy -c "Delete :CFBundleGetInfoString" retroshare.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :CFBundleVersion string $RSVERSION" retroshare.app/Contents/Info.plist
/usr/libexec/PlistBuddy -c "Add :CFBundleShortVersionString string $RSVERSION" retroshare.app/Contents/Info.plist
# This automatically creates retroshare.dmg
echo "Creating dmg archive..."
macdeployqt retroshare.app -dmg
DATE=`date +"%m-%d-%Y"`
MACVERSION=`sw_vers -productVersion`
#RSVERSION=`git describe --abbrev=0 --tags`
GITHEAD=`git rev-parse --short HEAD`
mv $APP.dmg "$APP-$RSVERSION-$GITHEAD-$DATE-MacOS-$MACVERSION-$QTVERSION.dmg"
# You can use the appdmg command line app to create your dmg file if
# you want to use a custom background and icon arrangement. I'm still
# working on this for my apps, myself. If you want to do this, you'll
# remove the -dmg option above.
# appdmg json-path YourApp_${TRAVIS_TAG}.dmg
# Copy other project files
cp "../../libbitdht/src/bitdht/bdboot.txt" "retroshare.app/Contents/Resources/"
cp "../../plugins/FeedReader/lib/libFeedReader.dylib" "retroshare.app/Contents/Resources/"
cp -R "sounds" "retroshare.app/Contents/Resources/sounds"
# cp "${project_dir}/README.md" "README.md"
# cp "${project_dir}/LICENSE" "LICENSE"
# cp "${project_dir}/Qt License" "Qt License"

View file

@ -16,7 +16,13 @@ if "%~1"=="clean" (
goto exit goto exit
) )
if exist "%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\pacman.exe" ( set MSYS2Version=20231026
set MSYS2Install=msys2-base-x86_64-%MSYS2Version%.sfx.exe
set MSYS2Url=https://github.com/msys2/msys2-installer/releases/download/%MSYS2Version:~0,4%-%MSYS2Version:~4,2%-%MSYS2Version:~6,2%/%MSYS2Install%
set MSYS2UnpackPath=%EnvMSYS2Path%\msys64
if exist "%MSYS2UnpackPath%\usr\bin\pacman.exe" (
if "%~1"=="reinstall" ( if "%~1"=="reinstall" (
choice /M "Found existing MSYS2 version. Do you want to proceed?" choice /M "Found existing MSYS2 version. Do you want to proceed?"
if !ERRORLEVEL!==2 goto exit if !ERRORLEVEL!==2 goto exit
@ -25,30 +31,26 @@ if exist "%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\pacman.exe" (
) )
) )
if "%MSYS2Architecture%"=="i686" set MSYS2Version=20210705 if exist "%MSYS2UnpackPath%" (
if "%MSYS2Architecture%"=="x86_64" set MSYS2Version=20210725
set MSYS2Install=msys2-base-%MSYS2Architecture%-%MSYS2Version%.tar.xz
set MSYS2Url=https://repo.msys2.org/distrib/%MSYS2Architecture%/%MSYS2Install%
%cecho% info "Remove previous MSYS2 version" %cecho% info "Remove previous MSYS2 version"
call "%ToolsPath%\remove-dir.bat" "%EnvMSYS2Path%" call "%ToolsPath%\remove-dir.bat" "%MSYS2UnpackPath%"
)
%cecho% info "Download installation files" %cecho% info "Download MSYS2 installation files"
if not exist "%EnvDownloadPath%\%MSYS2Install%" call "%ToolsPath%\download-file.bat" "%MSYS2Url%" "%EnvDownloadPath%\%MSYS2Install%" if not exist "%EnvDownloadPath%\%MSYS2Install%" call "%ToolsPath%\download-file.bat" "%MSYS2Url%" "%EnvDownloadPath%\%MSYS2Install%"
if not exist "%EnvDownloadPath%\%MSYS2Install%" %cecho% error "Cannot download MSYS" & goto error if not exist "%EnvDownloadPath%\%MSYS2Install%" %cecho% error "Cannot download MSYS" & goto error
%cecho% info "Unpack MSYS2" %cecho% info "Unpack MSYS2"
"%EnvSevenZipExe%" x -so "%EnvDownloadPath%\%MSYS2Install%" | "%EnvSevenZipExe%" x -y -si -ttar -o"%EnvMSYS2Path%" "%EnvDownloadPath%\%MSYS2Install%" -y -o"%EnvMSYS2Path%"
set MSYS2SH=%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\sh set MSYS2SH=%MSYS2UnpackPath%\usr\bin\sh
%cecho% info "Initialize MSYS2" %cecho% info "Initialize MSYS2"
"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" "%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring"
"%MSYS2SH%" -lc "pacman --noconfirm -Sy" "%MSYS2SH%" -lc "pacman --noconfirm -Sy"
"%MSYS2SH%" -lc "pacman --noconfirm -Su" "%MSYS2SH%" -lc "pacman --noconfirm -Su"
call "%EnvMSYS2Path%\msys%MSYS2Base%\autorebase.bat" call "%MSYS2UnpackPath%\autorebase.bat"
:exit :exit
endlocal endlocal

View file

@ -34,7 +34,7 @@ if not exist "%EnvToolsPath%\cecho.exe" (
if not exist "%EnvDownloadPath%\%cCEhoInstall%" echo Cannot download cecho installation& goto error if not exist "%EnvDownloadPath%\%cCEhoInstall%" echo Cannot download cecho installation& goto error
echo Unpack cecho echo Unpack cecho
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CEchoInstall%" "%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CEchoInstall%" -y -bso0
copy "%EnvTempPath%\cecho.exe" "%EnvToolsPath%" copy "%EnvTempPath%\cecho.exe" "%EnvToolsPath%"
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%" call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"

View file

@ -2,18 +2,13 @@
setlocal setlocal
if exist "%~dp0msys2\msys32" call :update 32 if not exist "%~dp0msys2\msys64" goto :EOF
if exist "%~dp0msys2\msys64" call :update 64
goto :EOF set MSYS2SH=%~dp0msys2\msys64\usr\bin\sh
:update echo Update MSYS2
set MSYS2SH=%~dp0msys2\msys%~1\usr\bin\sh
echo Update MSYS2 %~1
"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" "%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring"
"%MSYS2SH%" -lc "pacman --noconfirm -Su" "%MSYS2SH%" -lc "pacman --noconfirm -Su"
:exit
endlocal endlocal
goto :EOF goto :EOF

View file

@ -1,7 +1,7 @@
ZLIB_VERSION=1.2.11 ZLIB_VERSION=1.2.11
BZIP2_VERSION=1.0.8 BZIP2_VERSION=1.0.8
MINIUPNPC_VERSION=2.2.3 MINIUPNPC_VERSION=2.2.3
OPENSSL_VERSION=1.1.1p OPENSSL_VERSION=1.1.1w
SPEEX_VERSION=1.2.0 SPEEX_VERSION=1.2.0
SPEEXDSP_VERSION=1.2.0 SPEEXDSP_VERSION=1.2.0
LIBXML2_VERSION=2.9.12 LIBXML2_VERSION=2.9.12

View file

@ -56,7 +56,7 @@ if "%ParamWebui%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% rs_webui
if "%ParamPlugins%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% retroshare_plugins if "%ParamPlugins%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% retroshare_plugins
if "%ParamUseNativeDialogs%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% rs_use_native_dialogs if "%ParamUseNativeDialogs%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% rs_use_native_dialogs
if "%ParamService%" NEQ "1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% no_retroshare_service if "%ParamService%" NEQ "1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% no_retroshare_service
if "%ParamFriendServer%" NEQ "1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% no_rs_friendserver if "%ParamFriendServer%" NEQ "1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% no_retroshare_friendserver
if "%ParamEmbeddedFriendServer%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% rs_efs if "%ParamEmbeddedFriendServer%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% rs_efs
qmake "%SourcePath%\RetroShare.pro" -r -spec win32-g++ "CONFIG+=%RS_QMAKE_CONFIG%" "EXTERNAL_LIB_DIR=%BuildLibsPath%\libs" qmake "%SourcePath%\RetroShare.pro" -r -spec win32-g++ "CONFIG+=%RS_QMAKE_CONFIG%" "EXTERNAL_LIB_DIR=%BuildLibsPath%\libs"

View file

@ -22,11 +22,12 @@ if "%GCCArchitecture%"=="x64" (
) )
set EnvMSYS2Path=%EnvRootPath%\msys2 set EnvMSYS2Path=%EnvRootPath%\msys2
set EnvMSYS2BasePath=%EnvMSYS2Path%\msys64
call "%~dp0tools\prepare-msys2.bat" %1 call "%~dp0tools\prepare-msys2.bat" %1
if errorlevel 1 exit /B %ERRORLEVEL% if errorlevel 1 exit /B %ERRORLEVEL%
set EnvMSYS2SH=%EnvMSYS2Path%\msys64\usr\bin\sh.exe set EnvMSYS2SH=%EnvMSYS2BasePath%\usr\bin\sh.exe
if not exist "%EnvMSYS2SH%" if errorlevel 1 goto error_env if not exist "%EnvMSYS2SH%" if errorlevel 1 goto error_env
set EnvMSYS2Cmd="%EnvMSYS2SH%" -lc set EnvMSYS2Cmd="%EnvMSYS2SH%" -lc

View file

@ -16,15 +16,15 @@ if "%~1"=="clean" (
goto exit goto exit
) )
set MSYS2Version=20230318 set MSYS2Version=20231026
set MSYS2Install=msys2-base-x86_64-%MSYS2Version%.sfx.exe set MSYS2Install=msys2-base-x86_64-%MSYS2Version%.sfx.exe
set MSYS2Url=https://github.com/msys2/msys2-installer/releases/download/%MSYS2Version:~0,4%-%MSYS2Version:~4,2%-%MSYS2Version:~6,2%/%MSYS2Install% set MSYS2Url=https://github.com/msys2/msys2-installer/releases/download/%MSYS2Version:~0,4%-%MSYS2Version:~4,2%-%MSYS2Version:~6,2%/%MSYS2Install%
set MSYS2UnpackPath=%EnvMSYS2Path%\msys64
set CMakeInstall=cmake-3.19.0-win32-x86.zip set CMakeInstall=cmake-3.19.0-win32-x86.zip
set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.19.0/%CMakeInstall% set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.19.0/%CMakeInstall%
set CMakeUnpackPath=%EnvMSYS2Path%\msys64
if exist "%CMakeUnpackPath%\usr\bin\pacman.exe" ( if exist "%MSYS2UnpackPath%\usr\bin\pacman.exe" (
if "%~1"=="reinstall" ( if "%~1"=="reinstall" (
choice /M "Found existing MSYS2 version. Do you want to proceed?" choice /M "Found existing MSYS2 version. Do you want to proceed?"
if !ERRORLEVEL!==2 goto exit if !ERRORLEVEL!==2 goto exit
@ -33,13 +33,12 @@ if exist "%CMakeUnpackPath%\usr\bin\pacman.exe" (
) )
) )
if exist "%MSYS2UnpackPath%" (
if exist "%CMakeUnpackPath%" (
%cecho% info "Remove previous MSYS2 version" %cecho% info "Remove previous MSYS2 version"
call "%ToolsPath%\remove-dir.bat" "%CMakeUnpackPath%" call "%ToolsPath%\remove-dir.bat" "%MSYS2UnpackPath%"
) )
%cecho% info "Download installation files" %cecho% info "Download MSYS2 installation files"
if not exist "%EnvDownloadPath%\%MSYS2Install%" call "%ToolsPath%\download-file.bat" "%MSYS2Url%" "%EnvDownloadPath%\%MSYS2Install%" if not exist "%EnvDownloadPath%\%MSYS2Install%" call "%ToolsPath%\download-file.bat" "%MSYS2Url%" "%EnvDownloadPath%\%MSYS2Install%"
if not exist "%EnvDownloadPath%\%MSYS2Install%" %cecho% error "Cannot download MSYS" & goto error if not exist "%EnvDownloadPath%\%MSYS2Install%" %cecho% error "Cannot download MSYS" & goto error
@ -50,29 +49,29 @@ if not exist "%EnvDownloadPath%\%CMakeInstall%" %cecho% error "Cannot download C
"%EnvDownloadPath%\%MSYS2Install%" -y -o"%EnvMSYS2Path%" "%EnvDownloadPath%\%MSYS2Install%" -y -o"%EnvMSYS2Path%"
%cecho% info "Unpack CMake" %cecho% info "Unpack CMake"
"%EnvSevenZipExe%" x -o"%CMakeUnpackPath%" "%EnvDownloadPath%\%CMakeInstall%" "%EnvSevenZipExe%" x -o"%MSYS2UnpackPath%" "%EnvDownloadPath%\%CMakeInstall%" -y -bso0
%cecho% info "Install CMake" %cecho% info "Install CMake"
set CMakeVersion= set CMakeVersion=
for /D %%F in (%CMakeUnpackPath%\cmake*) do set CMakeVersion=%%~nxF for /D %%F in (%MSYS2UnpackPath%\cmake*) do set CMakeVersion=%%~nxF
if "%CMakeVersion%"=="" %cecho% error "CMake version not found." & goto :exit if "%CMakeVersion%"=="" %cecho% error "CMake version not found." & goto :exit
%cecho% info "Found CMake version %CMakeVersion%" %cecho% info "Found CMake version %CMakeVersion%"
set FoundProfile= set FoundProfile=
for /f "tokens=3" %%F in ('find /c /i "%CMakeVersion%" "%CMakeUnpackPath%\etc\profile"') do set FoundProfile=%%F for /f "tokens=3" %%F in ('find /c /i "%CMakeVersion%" "%MSYS2UnpackPath%\etc\profile"') do set FoundProfile=%%F
if "%FoundProfile%"=="0" ( if "%FoundProfile%"=="0" (
echo export PATH="${PATH}:/%CMakeVersion%/bin">>"%CMakeUnpackPath%\etc\profile" echo export PATH="${PATH}:/%CMakeVersion%/bin">>"%MSYS2UnpackPath%\etc\profile"
) )
set MSYS2SH=%CMakeUnpackPath%\usr\bin\sh set MSYS2SH=%MSYS2UnpackPath%\usr\bin\sh
%cecho% info "Initialize MSYS2" %cecho% info "Initialize MSYS2"
"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" "%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring"
"%MSYS2SH%" -lc "pacman --noconfirm -Sy" "%MSYS2SH%" -lc "pacman --noconfirm -Sy"
"%MSYS2SH%" -lc "pacman --noconfirm -Su" "%MSYS2SH%" -lc "pacman --noconfirm -Su"
call "%CMakeUnpackPath%\autorebase.bat" call "%MSYS2UnpackPath%\autorebase.bat"
:exit :exit
endlocal endlocal

View file

@ -53,7 +53,7 @@ if not exist "%EnvToolsPath%\cecho.exe" (
if not exist "%EnvDownloadPath%\%cCEhoInstall%" echo Cannot download cecho installation& goto error if not exist "%EnvDownloadPath%\%cCEhoInstall%" echo Cannot download cecho installation& goto error
echo Unpack cecho echo Unpack cecho
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CEchoInstall%" "%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CEchoInstall%" -y -bso0
copy "%EnvTempPath%\cecho.exe" "%EnvToolsPath%" copy "%EnvTempPath%\cecho.exe" "%EnvToolsPath%"
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%" call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
@ -69,7 +69,7 @@ if not exist "%EnvToolsPath%\depends.exe" (
if not exist "%EnvDownloadPath%\%DependsInstall%" %cecho% error "Cannot download Dependendy Walker installation" & goto error if not exist "%EnvDownloadPath%\%DependsInstall%" %cecho% error "Cannot download Dependendy Walker installation" & goto error
%cecho% info "Unpack Dependency Walker" %cecho% info "Unpack Dependency Walker"
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%DependsInstall%" "%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%DependsInstall%" -y -bso0
copy "%EnvTempPath%\*" "%EnvToolsPath%" copy "%EnvTempPath%\*" "%EnvToolsPath%"
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%" call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
@ -85,7 +85,7 @@ if not exist "%EnvToolsPath%\cut.exe" (
if not exist "%EnvDownloadPath%\%UnixToolsInstall%" %cecho% error "Cannot download Unix Tools installation" & goto error if not exist "%EnvDownloadPath%\%UnixToolsInstall%" %cecho% error "Cannot download Unix Tools installation" & goto error
%cecho% info "Unpack Unix Tools" %cecho% info "Unpack Unix Tools"
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%UnixToolsInstall%" "%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%UnixToolsInstall%" -y -bso0
copy "%EnvTempPath%\cut.exe" "%EnvToolsPath%" copy "%EnvTempPath%\cut.exe" "%EnvToolsPath%"
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%" call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
@ -101,7 +101,7 @@ if not exist "%EnvToolsPath%\sed.exe" (
if not exist "%EnvDownloadPath%\%UnixToolsInstall%" %cecho% error "Cannot download Unix Tools installation" & goto error if not exist "%EnvDownloadPath%\%UnixToolsInstall%" %cecho% error "Cannot download Unix Tools installation" & goto error
%cecho% info "Unpack Unix Tools" %cecho% info "Unpack Unix Tools"
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%UnixToolsInstall%" "%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%UnixToolsInstall%" -y -bso0
copy "%EnvTempPath%\sed.exe" "%EnvToolsPath%" copy "%EnvTempPath%\sed.exe" "%EnvToolsPath%"
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%" call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
@ -121,7 +121,7 @@ if not exist "%NSISInstallPath%\nsis.exe" (
if not exist "%EnvDownloadPath%\%NSISInstall%" %cecho% error "Cannot download NSIS installation" & goto error if not exist "%EnvDownloadPath%\%NSISInstall%" %cecho% error "Cannot download NSIS installation" & goto error
%cecho% info "Unpack NSIS" %cecho% info "Unpack NSIS"
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%NSISInstall%" "%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%NSISInstall%" -y -bso0
if not exist "%NSISInstallPath%" mkdir "%NSISInstallPath%" if not exist "%NSISInstallPath%" mkdir "%NSISInstallPath%"
xcopy /s "%EnvTempPath%" "%NSISInstallPath%" xcopy /s "%EnvTempPath%" "%NSISInstallPath%"
@ -135,7 +135,7 @@ if not exist "%MinGitInstallPath%\cmd\git.exe" (
if not exist "%EnvDownloadPath%\%MinGitInstall%" %cecho% error "Cannot download MinGit installation" & goto error if not exist "%EnvDownloadPath%\%MinGitInstall%" %cecho% error "Cannot download MinGit installation" & goto error
%cecho% info "Unpack MinGit" %cecho% info "Unpack MinGit"
"%EnvSevenZipExe%" x -o"%MinGitInstallPath%" "%EnvDownloadPath%\%MinGitInstall%" "%EnvSevenZipExe%" x -o"%MinGitInstallPath%" "%EnvDownloadPath%\%MinGitInstall%" -y -bso0
) )
if not exist "%EnvDownloadPath%\%DoxygenInstall%" call "%ToolsPath%\remove-dir.bat" "%DoxygenInstallPath%" if not exist "%EnvDownloadPath%\%DoxygenInstall%" call "%ToolsPath%\remove-dir.bat" "%DoxygenInstallPath%"
@ -148,7 +148,7 @@ if not exist "%DoxygenInstallPath%\doxygen.exe" (
if not exist "%EnvDownloadPath%\%DoxygenInstall%" %cecho% error "Cannot download doxygen installation" & goto error if not exist "%EnvDownloadPath%\%DoxygenInstall%" %cecho% error "Cannot download doxygen installation" & goto error
%cecho% info "Unpack Doxygen" %cecho% info "Unpack Doxygen"
"%EnvSevenZipExe%" x -o"%DoxygenInstallPath%" "%EnvDownloadPath%\%DoxygenInstall%" "%EnvSevenZipExe%" x -o"%DoxygenInstallPath%" "%EnvDownloadPath%\%DoxygenInstall%" -y -bso0
) )
if not exist "%EnvDownloadPath%\%CMakeInstall%" call "%ToolsPath%\remove-dir.bat" "%CMakeInstallPath%" if not exist "%EnvDownloadPath%\%CMakeInstall%" call "%ToolsPath%\remove-dir.bat" "%CMakeInstallPath%"
@ -163,7 +163,7 @@ if not exist "%CMakeInstallPath%\bin\cmake.exe" (
if not exist "%EnvDownloadPath%\%CMakeInstall%" %cecho% error "Cannot download CMake installation" & goto error if not exist "%EnvDownloadPath%\%CMakeInstall%" %cecho% error "Cannot download CMake installation" & goto error
%cecho% info "Unpack CMake" %cecho% info "Unpack CMake"
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CMakeInstall%" "%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CMakeInstall%" -y -bso0
move "%EnvTempPath%\%CMakeVersion%" "%CMakeInstallPath%" move "%EnvTempPath%\%CMakeVersion%" "%CMakeInstallPath%"
@ -176,7 +176,7 @@ mkdir "%EnvTempPath%"
call "%ToolsPath%\download-file.bat" "%TorDownloadIndexUrl%" "%EnvTempPath%\index.html" call "%ToolsPath%\download-file.bat" "%TorDownloadIndexUrl%" "%EnvTempPath%\index.html"
if not exist "%EnvTempPath%\index.html" %cecho% error "Cannot download Tor installation" & goto error if not exist "%EnvTempPath%\index.html" %cecho% error "Cannot download Tor installation" & goto error
for /F "tokens=1,2 delims= " %%A in ('%EnvSedExe% -r -n -e"s/.*href=\"^(.*^)^(tor-.*windows-i686\.tar\.gz^)\".*/\2 \1\2/p" "%EnvTempPath%\index.html"') do set TorInstall=%%A& set TorDownloadUrl=%%B for /F "tokens=1,2 delims= " %%A in ('%EnvSedExe% -r -n -e"s/.*href=\"^(.*^)^(tor-.*windows-i686.*\.tar\.gz^)\".*/\2 \1\2/p" "%EnvTempPath%\index.html"') do set TorInstall=%%A& set TorDownloadUrl=%%B
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%" call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
if "%TorInstall%"=="" %cecho% error "Cannot download Tor installation" & goto error if "%TorInstall%"=="" %cecho% error "Cannot download Tor installation" & goto error
if "%TorDownloadUrl%"=="" %cecho% error "Cannot download Tor installation" & goto error if "%TorDownloadUrl%"=="" %cecho% error "Cannot download Tor installation" & goto error
@ -189,7 +189,7 @@ if not exist "%EnvTorPath%\Tor\tor.exe" (
if not exist "%EnvDownloadPath%\%TorInstall%" %cecho% error "Cannot download Tor installation" & goto error if not exist "%EnvDownloadPath%\%TorInstall%" %cecho% error "Cannot download Tor installation" & goto error
%cecho% info "Unpack Tor" %cecho% info "Unpack Tor"
"%EnvSevenZipExe%" x -so "%EnvDownloadPath%\%TorInstall%" | "%EnvSevenZipExe%" x -si -ttar -o"%EnvTorPath%" "%EnvSevenZipExe%" x -so "%EnvDownloadPath%\%TorInstall%" | "%EnvSevenZipExe%" x -si -ttar -o"%EnvTorPath%" -y -bso0
) )
:exit :exit

View file

@ -318,7 +318,7 @@ SectionEnd
!ifdef TOR_EXISTS !ifdef TOR_EXISTS
Section /o $(Section_Tor) Section_Tor Section /o $(Section_Tor) Section_Tor
SetOutPath "$INSTDIR\tor" SetOutPath "$INSTDIR\tor"
File /r "${TORDIR}\*" File "${TORDIR}\*"
SectionEnd SectionEnd
!endif !endif

View file

@ -0,0 +1,20 @@
#!/bin/bash
function git_del_tag()
{
mTag=$1
for mRemote in $(git remote); do
echo "Attempting tag $mTag removal from remote $mRemote"
GIT_TERMINAL_PROMPT=0 git push $mRemote :$mTag || true
done
git tag --delete $mTag
}
for mModule in . build_scripts/OBS/ libbitdht/ libretroshare/ openpgpsdk/ retroshare-webui/ ; do
pushd $mModule
git_del_tag v0.6.7a
git tag --list | grep untagged | while read mTag; do git_del_tag $mTag ; done
popd
done

@ -1 +1 @@
Subproject commit 659423769541169457c41f71c8a038e2d64ba079 Subproject commit 2ddc86fb575a61170f4c06a00152e3e7dc74c8f4

@ -1 +1 @@
Subproject commit 8c02b54e4d16e38b28e77263a0b1570c50df4c99 Subproject commit 78739f1eb504503b12f107109356624da49e75ef

View file

@ -1151,10 +1151,10 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
if (isRunning()) { if (isRunning()) {
/* process description */ /* process description */
bool processPostedFirstImage = (feed.flag & RS_FEED_FLAG_POSTED_FIRST_IMAGE) ? TRUE : FALSE; bool processPostedFirstImage = (feed.flag & RS_FEED_FLAG_POSTED_FIRST_IMAGE) ? true : false;
if (!msg->attachmentBinary.empty()) { if (!msg->attachmentBinary.empty()) {
/* use attachment as image */ /* use attachment as image */
processPostedFirstImage = FALSE; processPostedFirstImage = false;
} }
//long todo; // encoding //long todo; // encoding

View file

@ -609,7 +609,9 @@ void GenCertDialog::genPerson()
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QAbstractEventDispatcher* ed = QAbstractEventDispatcher::instance(); QAbstractEventDispatcher* ed = QAbstractEventDispatcher::instance();
#ifdef DEBUG_GENCERTDIALOG
std::cout << "Waiting ed->processEvents()" << std::endl; std::cout << "Waiting ed->processEvents()" << std::endl;
#endif
time_t waitEnd = time(NULL) + 10;//Wait no more than 10 sec to processEvents time_t waitEnd = time(NULL) + 10;//Wait no more than 10 sec to processEvents
if (ed->hasPendingEvents()) if (ed->hasPendingEvents())
while(ed->processEvents(QEventLoop::AllEvents) && (time(NULL) < waitEnd)); while(ed->processEvents(QEventLoop::AllEvents) && (time(NULL) < waitEnd));

View file

@ -301,8 +301,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>456</width> <width>466</width>
<height>731</height> <height>738</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout"> <layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
@ -573,17 +573,68 @@ border-image: url(:/images/closepressed.png)
<string>Identity info</string> <string>Identity info</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="3" column="0"> <item row="13" column="0">
<widget class="QLabel" name="label_GpgId"> <widget class="QLabel" name="neighborNodesOpinion_LB">
<property name="text"> <property name="text">
<string>Owner node ID :</string> <string>Friend votes:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="1"> <item row="9" column="0" colspan="2">
<widget class="QLineEdit" name="overallOpinion_TF"> <widget class="Line" name="line_IdInfo">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgName">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_KeyId">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_LastUsed">
<property name="text">
<string>Last used:</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QCheckBox" name="autoBanIdentities_CB">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Overall reputation score, accounting for yours and your friends'.&lt;/p&gt;&lt;p&gt;Negative is bad, positive is good. Zero is neutral. If the score is too low,&lt;/p&gt;&lt;p&gt;the identity is flagged as bad, and will be filtered out in forums, chat lobbies,&lt;/p&gt;&lt;p&gt;channels, etc.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>Auto-Ban all identities signed by the same node</string>
</property>
<property name="text">
<string>Auto-Ban profile</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_PublishTS">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_Nickname">
<property name="enabled">
<bool>true</bool>
</property> </property>
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
@ -600,12 +651,170 @@ border-image: url(:/images/closepressed.png)
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2" rowspan="14"> <item row="14" column="1">
<widget class="QLineEdit" name="overallOpinion_TF">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Overall reputation score, accounting for yours and your friends'.&lt;/p&gt;&lt;p&gt;Negative is bad, positive is good. Zero is neutral. If the score is too low,&lt;/p&gt;&lt;p&gt;the identity is flagged as bad, and will be filtered out in forums, chat lobbies,&lt;/p&gt;&lt;p&gt;channels, etc.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="10" column="0" rowspan="2">
<widget class="QLabel" name="label_YourOpinion">
<property name="text">
<string>Your opinion:</string>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="overallOpinion_LB">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Overall:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_PublishTS">
<property name="text">
<string>Created on :</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_Nickname">
<property name="text">
<string>Identity name :</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_KeyId">
<property name="text">
<string>Identity ID :</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QLineEdit" name="neighborNodesOpinion_TF">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Average opinion of neighbor nodes about this identity. Negative is bad,&lt;/p&gt;&lt;p&gt;positive is good. Zero is neutral.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_Type">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_Type">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_LastUsed">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="15" column="0" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_GpgId">
<property name="text">
<string>Owner node ID :</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_GpgName">
<property name="text">
<string>Owner node name :</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="banoption_label">
<property name="text">
<string>Ban-option:</string>
</property>
</widget>
</item>
<item row="10" column="1" rowspan="2">
<widget class="RSComboBox" name="ownOpinion_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-family:'Sans'; font-size:9pt;&quot;&gt;Your own opinion about an identity rules the visibility of that identity for yourself and your friend nodes. Your own opinion is shared among friends and used to compute a reputation score: If your opinion about an identity is neutral, the reputation score is the difference between friend's positive and negative opinions. If not, your own opinion gives the score.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'Sans'; font-size:9pt;&quot;&gt;The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity. When the overall score is lower than -1, the identity is banned, which prevents all messages and forums/channels authored by this identity to be forwarded, both ways. Some forums also have special anti-spam flags that require a non negative reputation level, making them more sensitive to bad opinions. Banned identities gradually lose their activity and eventually disappear (after 5 days).&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'Sans'; font-size:9pt;&quot;&gt;You can change the thresholds and the time of inactivity to delete identities in preferences -&amp;gt; people. &lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="iconSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<item>
<property name="text">
<string>Negative</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/thumbs-down.png</normaloff>:/icons/png/thumbs-down.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Neutral</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/thumbs-neutral.png</normaloff>:/icons/png/thumbs-neutral.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Positive</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/thumbs-up.png</normaloff>:/icons/png/thumbs-up.png</iconset>
</property>
</item>
</widget>
</item>
<item row="0" column="2" rowspan="15">
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<widget class="QLabel" name="avatarLabel"> <widget class="QLabel" name="avatarLabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@ -642,19 +851,53 @@ border-image: url(:/images/closepressed.png)
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="2" column="1">
<widget class="QPushButton" name="editButton">
<property name="text">
<string>Edit Identity</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="inviteButton"> <widget class="QPushButton" name="inviteButton">
<property name="text"> <property name="text">
<string>Send Invite</string> <string>Send Invite</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="2" rowspan="3">
<widget class="QPushButton" name="editButton"> <spacer name="horizontalSpacer">
<property name="text"> <property name="orientation">
<string>Edit Identity</string> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> <property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>6</width>
<height>128</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" rowspan="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>6</width>
<height>128</height>
</size>
</property>
</spacer>
</item>
</layout>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="avatarOpinionHLayout"> <layout class="QHBoxLayout" name="avatarOpinionHLayout">
@ -756,200 +999,6 @@ border-image: url(:/images/closepressed.png)
</item> </item>
</layout> </layout>
</item> </item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_Type">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_Type">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="overallOpinion_LB">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Overall:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_LastUsed">
<property name="text">
<string>Last used:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_KeyId">
<property name="text">
<string>Identity ID :</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_PublishTS">
<property name="text">
<string>Created on :</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_GpgName">
<property name="text">
<string>Owner node name :</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="banoption_label">
<property name="text">
<string>Ban-option:</string>
</property>
</widget>
</item>
<item row="9" column="0" rowspan="2">
<widget class="QLabel" name="label_YourOpinion">
<property name="text">
<string>Your opinion:</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QLineEdit" name="neighborNodesOpinion_TF">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Average opinion of neighbor nodes about this identity. Negative is bad,&lt;/p&gt;&lt;p&gt;positive is good. Zero is neutral.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_LastUsed">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="1" rowspan="2">
<widget class="RSComboBox" name="ownOpinion_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-family:'Sans'; font-size:9pt;&quot;&gt;Your own opinion about an identity rules the visibility of that identity for yourself and your friend nodes. Your own opinion is shared among friends and used to compute a reputation score: If your opinion about an identity is neutral, the reputation score is the difference between friend's positive and negative opinions. If not, your own opinion gives the score.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'Sans'; font-size:9pt;&quot;&gt;The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity. When the overall score is lower than -1, the identity is banned, which prevents all messages and forums/channels authored by this identity to be forwarded, both ways. Some forums also have special anti-spam flags that require a non negative reputation level, making them more sensitive to bad opinions. Banned identities gradually lose their activity and eventually disappear (after 5 days).&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'Sans'; font-size:9pt;&quot;&gt;You can change the thresholds and the time of inactivity to delete identities in preferences -&amp;gt; people. &lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="iconSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<item>
<property name="text">
<string>Negative</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/thumbs-down.png</normaloff>:/icons/png/thumbs-down.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Neutral</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/thumbs-neutral.png</normaloff>:/icons/png/thumbs-neutral.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Positive</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/thumbs-up.png</normaloff>:/icons/png/thumbs-up.png</iconset>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_Nickname">
<property name="text">
<string>Identity name :</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QCheckBox" name="autoBanIdentities_CB">
<property name="toolTip">
<string>Auto-Ban all identities signed by the same node</string>
</property>
<property name="text">
<string>Auto-Ban profile</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgName">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_PublishTS">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="neighborNodesOpinion_LB">
<property name="text">
<string>Friend votes:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_Nickname">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="Line" name="line_IdInfo">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_KeyId">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View file

@ -83,7 +83,7 @@ NetworkDialog::NetworkDialog(QWidget */*parent*/)
ui.connectTreeWidget->setUpdatesEnabled(true); ui.connectTreeWidget->setUpdatesEnabled(true);
ui.connectTreeWidget->setSortingEnabled(true); ui.connectTreeWidget->setSortingEnabled(true);
ui.connectTreeWidget->setSelectionBehavior(QAbstractItemView::SelectRows); ui.connectTreeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
ui.connectTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); ui.connectTreeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
connect(ui.connectTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( connectTreeWidgetCostumPopupMenu( QPoint ) ) ); connect(ui.connectTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( connectTreeWidgetCostumPopupMenu( QPoint ) ) );
connect(ui.connectTreeWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(peerdetails())); connect(ui.connectTreeWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(peerdetails()));
@ -117,24 +117,12 @@ void NetworkDialog::connectTreeWidgetCostumPopupMenu( QPoint /*point*/ )
{ {
return; return;
} }
QMenu *contextMnu = new QMenu; QMenu *contextMnu = new QMenu;
RsPgpId peer_id(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERID)).toString().toStdString()) ;
// That's what context menus are made for
RsPeerDetails detail;
if(!rsPeers->getGPGDetails(peer_id, detail)) // that is not suppose to fail.
return ;
if(peer_id == rsPeers->getGPGOwnId())
contextMnu->addAction(QIcon(), tr("Export/create a new node"), this, SLOT(on_actionExportKey_activated()));
contextMnu->addAction(QIcon(IMAGE_PEERDETAILS), tr("Profile details..."), this, SLOT(peerdetails())); contextMnu->addAction(QIcon(IMAGE_PEERDETAILS), tr("Profile details..."), this, SLOT(peerdetails()));
contextMnu->addSeparator() ; contextMnu->addSeparator() ;
contextMnu->addAction(QIcon(), tr("Remove unused keys..."), this, SLOT(removeUnusedKeys())); contextMnu->addAction(QIcon(), tr("Remove unused keys..."), this, SLOT(removeUnusedKeys()));
contextMnu->addAction(QIcon(), tr("Remove this key"), this, SLOT(removeSelectedKeys())); contextMnu->addAction(QIcon(), tr("Remove this key"), this, SLOT(removeSelectedKeys()));
contextMnu->exec(QCursor::pos()); contextMnu->exec(QCursor::pos());
} }
@ -177,11 +165,34 @@ void NetworkDialog::removeSelectedKeys()
QModelIndexList l = ui.connectTreeWidget->selectionModel()->selection().indexes(); QModelIndexList l = ui.connectTreeWidget->selectionModel()->selection().indexes();
if(l.empty()) if(l.empty())
return; return;
std::set<RsPgpId> selected; std::set<RsPgpId> selected;
selected.insert(RsPgpId(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERID)).toString().toStdString()));
std::set<RsPgpId> friends;
for (int i = 0; i < l.size(); i++)
{
RsPgpId peer_id = RsPgpId(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l[i].row(), pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERID)).toString().toStdString());
RsPeerDetails details ;
if(rsPeers->getGPGDetails(peer_id,details))
{
if(details.accept_connection)
friends.insert(peer_id);
else
selected.insert(peer_id);
}
}
if(!friends.empty())
{
if ((QMessageBox::question(this, "RetroShare", tr("You have selected %1 accepted peers among others,\n Are you sure you want to un-friend them?").arg(friends.size()), QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes)) == QMessageBox::Yes)
{
for(std::set<RsPgpId>::const_iterator it(friends.begin());it!=friends.end();++it)
rsPeers->removeFriend(*it);
selected.insert(friends.begin(),friends.end());
}
}
if(!selected.empty())
removeKeys(selected); removeKeys(selected);
updateDisplay();
} }
void NetworkDialog::removeKeys(std::set<RsPgpId> selected) void NetworkDialog::removeKeys(std::set<RsPgpId> selected)

View file

@ -299,7 +299,7 @@ void NewsFeed::handleChannelEvent(std::shared_ptr<const RsEvent> event)
addFeedItem(new GxsChannelPostItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId, false, true)); addFeedItem(new GxsChannelPostItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId, false, true));
break; break;
case RsChannelEventCode::NEW_COMMENT: case RsChannelEventCode::NEW_COMMENT:
addFeedItem(new ChannelsCommentsItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId, false, true)); addFeedItem(new ChannelsCommentsItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId,pe->mChannelThreadId, false, true));
break; break;
case RsChannelEventCode::RECEIVED_PUBLISH_KEY: case RsChannelEventCode::RECEIVED_PUBLISH_KEY:
addFeedItem(new GxsChannelGroupItem(this, NEWSFEED_CHANNELPUBKEYLIST, pe->mChannelGroupId, false, true)); addFeedItem(new GxsChannelGroupItem(this, NEWSFEED_CHANNELPUBKEYLIST, pe->mChannelGroupId, false, true));

View file

@ -216,7 +216,7 @@ void PulseAddDialog::setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse
mReplyToPulse = pulse; mReplyToPulse = pulse;
mReplyType = replyType; mReplyType = replyType;
ui.frame_reply->setVisible(true); ui.frame_reply->setVisible(true);
ui.pushButton_picture->show(); ui.pushButton_picture->hide();
ui.topheadshot->hide(); ui.topheadshot->hide();
{ {
@ -245,10 +245,12 @@ void PulseAddDialog::setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse
if (mReplyType & WIRE_PULSE_TYPE_REPUBLISH) { if (mReplyType & WIRE_PULSE_TYPE_REPUBLISH) {
ui.postButton->setText(tr("Republish Pulse")); ui.postButton->setText(tr("Republish Pulse"));
ui.pushButton_picture->hide(); ui.pushButton_picture->hide();
ui.pushButton_Browse->hide();
} }
else if (mReplyType & WIRE_PULSE_TYPE_LIKE) { else if (mReplyType & WIRE_PULSE_TYPE_LIKE) {
ui.postButton->setText(tr("Like Pulse")); ui.postButton->setText(tr("Like Pulse"));
ui.pushButton_picture->hide(); ui.pushButton_picture->hide();
ui.pushButton_Browse->hide();
} }
} }

View file

@ -140,7 +140,7 @@
<widget class="QWidget" name="widget_sentiment" native="true"> <widget class="QWidget" name="widget_sentiment" native="true">
<layout class="QHBoxLayout" name="widget_sentiment_HL"> <layout class="QHBoxLayout" name="widget_sentiment_HL">
<property name="leftMargin"> <property name="leftMargin">
<number>20</number> <number>9</number>
</property> </property>
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>0</number>

View file

@ -40,10 +40,7 @@
</size> </size>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">QFrame#frame{border: 2px solid #CCCCCC; <string notr="true"/>
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #EEEEEE, stop: 1 #CCCCCC);
border-radius: 10px}</string>
</property> </property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>

View file

@ -154,9 +154,16 @@ void WireDialog::processSettings(bool load)
// state of splitter // state of splitter
ui.splitter->restoreState(Settings->value("SplitterWire").toByteArray()); ui.splitter->restoreState(Settings->value("SplitterWire").toByteArray());
// state of filter combobox
int index = Settings->value("ShowGroup", 0).toInt();
ui.comboBox_groupSet->setCurrentIndex(index);
} else { } else {
// save settings // save settings
// state of filter combobox
Settings->setValue("ShowGroup", ui.comboBox_groupSet->currentIndex());
// state of splitter // state of splitter
Settings->setValue("SplitterWire", ui.splitter->saveState()); Settings->setValue("SplitterWire", ui.splitter->saveState());
} }
@ -1064,4 +1071,3 @@ void WireDialog::postGroupsPulses(std::list<RsWirePulseSPtr> pulses)
} }
} }

View file

@ -1145,8 +1145,6 @@ void RsFriendListModel::updateInternalData()
mLocations.clear(); mLocations.clear();
mTopLevel.clear(); mTopLevel.clear();
endResetModel();
auto TL = mTopLevel ; // This allows to fill TL without touching mTopLevel outside of [begin/end]InsertRows(). auto TL = mTopLevel ; // This allows to fill TL without touching mTopLevel outside of [begin/end]InsertRows().
// create a map of profiles and groups // create a map of profiles and groups
@ -1282,6 +1280,7 @@ void RsFriendListModel::updateInternalData()
endInsertRows(); endInsertRows();
} }
endResetModel();
postMods(); postMods();
mLastInternalDataUpdate = time(NULL); mLastInternalDataUpdate = time(NULL);

View file

@ -1619,7 +1619,9 @@ bool NewFriendList::isColumnVisible(int col) const
} }
void NewFriendList::setColumnVisible(int col,bool visible) void NewFriendList::setColumnVisible(int col,bool visible)
{ {
#ifdef DEBUG_NEW_FRIEND_LIST
std::cerr << "Setting column " << col << " to be visible: " << visible << std::endl; std::cerr << "Setting column " << col << " to be visible: " << visible << std::endl;
#endif
ui->peerTreeWidget->setColumnHidden(col, !visible); ui->peerTreeWidget->setColumnHidden(col, !visible);
} }
void NewFriendList::toggleColumnVisible() void NewFriendList::toggleColumnVisible()

View file

@ -34,6 +34,7 @@
#endif #endif
#include "gui/common/FilesDefs.h" #include "gui/common/FilesDefs.h"
#include "gui/RetroShareLink.h"
#include "gui/settings/rsharesettings.h" #include "gui/settings/rsharesettings.h"
#include "util/misc.h" #include "util/misc.h"
#include "ConnectFriendWizard.h" #include "ConnectFriendWizard.h"
@ -449,8 +450,9 @@ void ConnectFriendWizard::initializePage(int id)
} }
sockaddr_storage addr ; sockaddr_storage addr ;
#ifdef DEBUG_FRIENDWIZARD
std::cerr << "Cert IP = " << peerDetails.extAddr << std::endl; std::cerr << "Cert IP = " << peerDetails.extAddr << std::endl;
#endif
if(sockaddr_storage_ipv4_aton(addr,peerDetails.extAddr.c_str()) && sockaddr_storage_isValidNet(addr)) if(sockaddr_storage_ipv4_aton(addr,peerDetails.extAddr.c_str()) && sockaddr_storage_isValidNet(addr))
{ {
@ -870,7 +872,18 @@ void ConnectFriendWizard::cleanFriendCert()
bool certValid = false; bool certValid = false;
QString errorMsg ; QString errorMsg ;
QString certDetail; QString certDetail;
std::string cert = ui->friendCertEdit->toPlainText().toUtf8().constData();
std::string cert ;
RetroShareLink rslink(ui->friendCertEdit->toPlainText());
if(rslink.valid() && rslink.type() == RetroShareLink::TYPE_CERTIFICATE)
cert = rslink.radix().toStdString();
else
cert = ui->friendCertEdit->toPlainText().toUtf8().constData();
#ifdef DEBUG_FRIENDWIZARD
std::cerr << "Friend cert:\"" << cert << "\"" << std::endl;
#endif
if (cert.empty()) { if (cert.empty()) {
ui->friendCertCleanLabel->setToolTip(""); ui->friendCertCleanLabel->setToolTip("");

View file

@ -49,46 +49,41 @@
* #define DEBUG_ITEM 1 * #define DEBUG_ITEM 1
****/ ****/
ChannelsCommentsItem::ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData& group_meta, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) : // ChannelsCommentsItem::ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData& group_meta, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
GxsFeedItem(feedHolder, feedId, group_meta.mGroupId, messageId, isHome, rsGxsChannels, autoUpdate), // GxsFeedItem(feedHolder, feedId, group_meta.mGroupId, messageId, isHome, rsGxsChannels, autoUpdate),
mGroupMeta(group_meta) // mGroupMeta(group_meta)
// {
// mLoadingGroup = false;
// mLoadingMessage = false;
// mLoadingComment = false;
//
// mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
// mPost.mMeta.mGroupId = mGroupMeta.mGroupId;
//
// QVector<RsGxsMessageId> v;
// //bool self = false;
//
// for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
// v.push_back(*it) ;
//
// if(older_versions.find(messageId) == older_versions.end())
// v.push_back(messageId);
//
// setMessageVersions(v) ;
// setup();
//
// // no call to loadGroup() here because we have it already.
// }
ChannelsCommentsItem::ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &commentId, const RsGxsMessageId &threadId, bool isHome, bool autoUpdate) :
GxsFeedItem(feedHolder, feedId, groupId, commentId, isHome, rsGxsChannels, autoUpdate), // this one should be in GxsFeedItem
mThreadId(threadId)
{ {
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded mLoading= false;
mPost.mMeta.mGroupId = mGroupMeta.mGroupId;
QVector<RsGxsMessageId> v; QVector<RsGxsMessageId> v;
//bool self = false;
for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
v.push_back(*it) ;
if(older_versions.find(messageId) == older_versions.end())
v.push_back(messageId);
setMessageVersions(v) ;
setup(); setup();
// no call to loadGroup() here because we have it already.
}
ChannelsCommentsItem::ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, autoUpdate) // this one should be in GxsFeedItem
{
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
QVector<RsGxsMessageId> v;
//bool self = false;
for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
v.push_back(*it) ;
if(older_versions.find(messageId) == older_versions.end())
v.push_back(messageId);
setMessageVersions(v) ;
setup();
loadGroup();
} }
void ChannelsCommentsItem::paintEvent(QPaintEvent *e) void ChannelsCommentsItem::paintEvent(QPaintEvent *e)
@ -99,14 +94,7 @@ void ChannelsCommentsItem::paintEvent(QPaintEvent *e)
if(!mLoaded) if(!mLoaded)
{ {
mLoaded = true ; mLoaded = true ;
load();
std::set<RsGxsMessageId> older_versions; // not so nice. We need to use std::set everywhere
for(auto& m:messageVersions())
older_versions.insert(m);
fill();
requestMessage();
requestComment();
} }
GxsFeedItem::paintEvent(e) ; GxsFeedItem::paintEvent(e) ;
@ -114,6 +102,14 @@ void ChannelsCommentsItem::paintEvent(QPaintEvent *e)
ChannelsCommentsItem::~ChannelsCommentsItem() ChannelsCommentsItem::~ChannelsCommentsItem()
{ {
auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(300);
while( mLoading && std::chrono::steady_clock::now() < timeout )
{
RsDbg() << __PRETTY_FUNCTION__ << " is Waiting for data to load " << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
delete(ui); delete(ui);
} }
@ -184,20 +180,18 @@ void ChannelsCommentsItem::setup()
bool ChannelsCommentsItem::setPost(const RsGxsChannelPost& post, bool doFill) bool ChannelsCommentsItem::setPost(const RsGxsChannelPost& post, bool doFill)
{ {
if (groupId() != post.mMeta.mGroupId || messageId() != post.mMeta.mMsgId) {
std::cerr << "ChannelsCommentsItem::setPost() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mPost = post; mPost = post;
if (doFill) { if (doFill)
fill(); fill();
}
return true; return true;
} }
bool ChannelsCommentsItem::setMissingPost()
{
fill(true);
return true;
}
QString ChannelsCommentsItem::getTitleLabel() QString ChannelsCommentsItem::getTitleLabel()
{ {
@ -230,14 +224,68 @@ void ChannelsCommentsItem::loadComments()
void ChannelsCommentsItem::loadGroup() void ChannelsCommentsItem::loadGroup()
{ {
//#ifdef DEBUG_ITEM
// std::cerr << "GxsChannelGroupItem::loadGroup()";
// std::cerr << std::endl;
//#endif
// if(mLoading)
// return;
//
// mLoading= true;
//
// std::cerr << "Loading group" << std::endl;
// RsThread::async([this]()
// {
// // 1 - get group data
//
// std::vector<RsGxsChannelGroup> groups;
// const std::list<RsGxsGroupId> groupIds = { groupId() };
//
// if(!rsGxsChannels->getChannelsInfo(groupIds,groups)) // would be better to call channel Summaries for a single group
// {
// RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
// return;
// }
//
// if (groups.size() != 1)
// {
// std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items";
// std::cerr << std::endl;
// return;
// }
// RsGxsChannelGroup group(groups[0]);
//
// RsQThreadUtils::postToObject( [group,this]()
// {
// /* Here it goes any code you want to be executed on the Qt Gui
// * thread, for example to update the data model with new information
// * after a blocking call to RetroShare API complete */
//
// mGroupMeta = group.mMeta;
// mLoading= false;
//
// std::cerr << "End loading group" << std::endl;
// }, this );
// });
}
void ChannelsCommentsItem::load()
{
// This function loads everything that's needed:
// - the comment text
// - the comment parent message
#ifdef DEBUG_ITEM #ifdef DEBUG_ITEM
std::cerr << "GxsChannelGroupItem::loadGroup()"; std::cerr << "ChannelsCommentsItem::loadMessage()";
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
if(mLoading)
return;
mLoading= true;
RsThread::async([this]() RsThread::async([this]()
{ {
// 1 - get group data // 1 - get group meta data
std::vector<RsGxsChannelGroup> groups; std::vector<RsGxsChannelGroup> groups;
const std::list<RsGxsGroupId> groupIds = { groupId() }; const std::list<RsGxsGroupId> groupIds = { groupId() };
@ -250,13 +298,26 @@ void ChannelsCommentsItem::loadGroup()
if (groups.size() != 1) if (groups.size() != 1)
{ {
std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items"; std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items" << std::endl;
std::cerr << std::endl;
return; return;
} }
RsGxsChannelGroup group(groups[0]); RsGxsChannelGroup group(groups[0]);
RsQThreadUtils::postToObject( [group,this]() // 2 - get message and comment data
std::vector<RsGxsChannelPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
if(! rsGxsChannels->getChannelContent( groupId(), std::set<RsGxsMessageId>( { messageId(),mThreadId } ),posts,comments,votes))
{
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
return;
}
// now that everything is in place, update the UI
RsQThreadUtils::postToObject( [group,posts,comments,this]()
{ {
/* Here it goes any code you want to be executed on the Qt Gui /* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information * thread, for example to update the data model with new information
@ -264,52 +325,14 @@ void ChannelsCommentsItem::loadGroup()
mGroupMeta = group.mMeta; mGroupMeta = group.mMeta;
}, this ); if(comments.size()==1)
});
}
void ChannelsCommentsItem::loadMessage()
{
#ifdef DEBUG_ITEM
std::cerr << "ChannelsCommentsItem::loadMessage()";
std::cerr << std::endl;
#endif
RsThread::async([this]()
{
// 1 - get group data
std::vector<RsGxsChannelPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
if(! rsGxsChannels->getChannelContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments,votes))
{
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
return;
}
if (posts.size() == 1)
{
#ifdef DEBUG_ITEM
std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl;
#endif
RsGxsChannelPost post(posts[0]); // no reference to temporary here, because we pass this to a thread
RsQThreadUtils::postToObject( [post,this]() { setPost(post); }, this );
}
else if(comments.size() == 1)
{ {
RsGxsComment cmt(comments[0]); RsGxsComment cmt(comments[0]);
#ifdef DEBUG_ITEM
std::cerr << (void*)this << ": Obtained comment, setting messageId to threadID = " << cmt.mMeta.mThreadId << std::endl;
#endif
RsQThreadUtils::postToObject( [cmt,this]()
{
uint32_t autorized_lines = (int)floor( (ui->avatarLabel->height() - ui->button_HL->sizeHint().height()) uint32_t autorized_lines = (int)floor( (ui->avatarLabel->height() - ui->button_HL->sizeHint().height())
/ QFontMetricsF(ui->subjectLabel->font()).height()); / QFontMetricsF(ui->subjectLabel->font()).height());
ui->commLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(cmt.mComment.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_LINKS)); ui->commLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(cmt.mComment.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_LINKS));
ui->nameLabel->setId(cmt.mMeta.mAuthorId); ui->nameLabel->setId(cmt.mMeta.mAuthorId);
ui->datetimeLabel->setText(DateTime::formatLongDateTime(cmt.mMeta.mPublishTs)); ui->datetimeLabel->setText(DateTime::formatLongDateTime(cmt.mMeta.mPublishTs));
@ -321,77 +344,28 @@ void ChannelsCommentsItem::loadMessage()
pixmap = GxsIdDetails::makeDefaultIcon(cmt.mMeta.mAuthorId,GxsIdDetails::LARGE); pixmap = GxsIdDetails::makeDefaultIcon(cmt.mMeta.mAuthorId,GxsIdDetails::LARGE);
ui->avatarLabel->setPixmap(pixmap); ui->avatarLabel->setPixmap(pixmap);
//Change this item to be uploaded with thread element. //Change this item to be uploaded with thread element. This is really bad practice.
setMessageId(cmt.mMeta.mThreadId);
requestMessage();
}, this );
} }
else else
{ {
#ifdef DEBUG_ITEM mLoading=false;
std::cerr << "ChannelsCommentsItem::loadMessage() Wrong number of Items. Remove It."; removeItem();
std::cerr << std::endl;
#endif
RsQThreadUtils::postToObject( [this]() { removeItem(); }, this );
} }
});
if (posts.size() == 1)
setPost(posts[0]);
else
setMissingPost();
emit sizeChanged(this); emit sizeChanged(this);
} mLoading=false;
void ChannelsCommentsItem::loadComment()
{
#ifdef DEBUG_ITEM
std::cerr << "ChannelsCommentsItem::loadComment()";
std::cerr << std::endl;
#endif
RsThread::async([this]()
{
// 1 - get group data
std::set<RsGxsMessageId> msgIds;
for(auto MsgId: messageVersions())
msgIds.insert(MsgId);
std::vector<RsGxsChannelPost> posts;
std::vector<RsGxsComment> comments;
if(! rsGxsChannels->getChannelComments( groupId(),msgIds,comments))
{
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
return;
}
int comNb = comments.size();
RsQThreadUtils::postToObject( [comNb]()
{
QString sComButText = tr("Comment");
if (comNb == 1)
sComButText = sComButText.append("(1)");
else if(comNb > 1)
sComButText = tr("Comments ").append("(%1)").arg(comNb);
//ui->commentButton->setText(sComButText);
}, this ); }, this );
}); });
} }
void ChannelsCommentsItem::fill() void ChannelsCommentsItem::fill(bool missing_post)
{ {
/* fill in */
// if (isLoading()) {
// /* Wait for all requests */
//return;
// }
#ifdef DEBUG_ITEM #ifdef DEBUG_ITEM
std::cerr << "ChannelsCommentsItem::fill()"; std::cerr << "ChannelsCommentsItem::fill()";
std::cerr << std::endl; std::cerr << std::endl;
@ -399,9 +373,6 @@ void ChannelsCommentsItem::fill()
mInFill = true; mInFill = true;
//QString title;
//float f = QFontMetricsF(font()).height()/14.0 ;
if (!mIsHome) if (!mIsHome)
{ {
if (mCloseOnRead && !IS_MSG_NEW(mPost.mMeta.mMsgStatus)) { if (mCloseOnRead && !IS_MSG_NEW(mPost.mMeta.mMsgStatus)) {
@ -413,18 +384,13 @@ void ChannelsCommentsItem::fill()
//ui->titleLabel->setText(title); //ui->titleLabel->setText(title);
RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_CHANNEL, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, messageName()); RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_CHANNEL, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, messageName());
if(missing_post)
ui->subjectLabel->setText("[" + QObject::tr("Missing channel post")+"]");
else
ui->subjectLabel->setText(msgLink.toHtml()); ui->subjectLabel->setText(msgLink.toHtml());
if (IS_GROUP_SUBSCRIBED(mGroupMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroupMeta.mSubscribeFlags))
{
//ui->unsubscribeButton->setEnabled(true);
}
else
{
//ui->unsubscribeButton->setEnabled(false);
}
ui->readButton->hide(); ui->readButton->hide();
//ui->titleLabel->hide();
if (IS_MSG_NEW(mPost.mMeta.mMsgStatus)) { if (IS_MSG_NEW(mPost.mMeta.mMsgStatus)) {
mCloseOnRead = true; mCloseOnRead = true;
@ -432,20 +398,11 @@ void ChannelsCommentsItem::fill()
} }
else else
{ {
/* subject */ if(missing_post)
//ui->titleLabel->setText(QString::fromUtf8(mPost.mMeta.mMsgName.c_str())); ui->subjectLabel->setText("[" + QObject::tr("Missing channel post")+"]");
else
//uint32_t autorized_lines = (int)floor( (ui->avatarLabel->height() - ui->button_HL->sizeHint().height())
// / QFontMetricsF(ui->subjectLabel->font()).height());
// fill first 4 lines of message. (csoler) Disabled the replacement of smileys and links, because the cost is too crazy
//ui->subjectLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
ui->subjectLabel->setText(RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), 2)) ; ui->subjectLabel->setText(RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), 2)) ;
//QString score = QString::number(post.mTopScore);
// scoreLabel->setText(score);
/* disable buttons: deletion facility not enabled with cache services yet */ /* disable buttons: deletion facility not enabled with cache services yet */
ui->clearButton->setEnabled(false); ui->clearButton->setEnabled(false);
ui->clearButton->hide(); ui->clearButton->hide();
@ -467,50 +424,9 @@ void ChannelsCommentsItem::fill()
mCloseOnRead = false; mCloseOnRead = false;
} }
// differences between Feed or Top of Comment.
if (mFeedHolder)
{
//ui->commentButton->show();
// Not yet functional
/*if (mPost.mCommentCount)
{
QString commentText = QString::number(mPost.mCommentCount);
commentText += " ";
commentText += tr("Comments");
ui->commentButton->setText(commentText);
}
else
{
ui->commentButton->setText(tr("Comment"));
}*/
}
else
{
//ui->commentButton->hide();
}
// disable voting buttons - if they have already voted.
/*if (post.mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK)
{
voteUpButton->setEnabled(false);
voteDownButton->setEnabled(false);
}*/
if (wasExpanded() || ui->expandFrame->isVisible()) {
fillExpandFrame();
}
mInFill = false; mInFill = false;
} }
void ChannelsCommentsItem::fillExpandFrame()
{
//ui->msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
}
QString ChannelsCommentsItem::messageName() QString ChannelsCommentsItem::messageName()
{ {
return QString::fromUtf8(mPost.mMeta.mMsgName.c_str()); return QString::fromUtf8(mPost.mMeta.mMsgName.c_str());
@ -574,10 +490,6 @@ void ChannelsCommentsItem::doExpand(bool open)
void ChannelsCommentsItem::expandFill(bool first) void ChannelsCommentsItem::expandFill(bool first)
{ {
GxsFeedItem::expandFill(first); GxsFeedItem::expandFill(first);
if (first) {
fillExpandFrame();
}
} }
void ChannelsCommentsItem::toggle() void ChannelsCommentsItem::toggle()

View file

@ -42,12 +42,17 @@ public:
// It can be used for all apparences of channel posts. But in rder to merge comments from the previous versions of the post, the list of // It can be used for all apparences of channel posts. But in rder to merge comments from the previous versions of the post, the list of
// previous posts should be supplied. It's optional. If not supplied only the comments of the new version will be displayed. // previous posts should be supplied. It's optional. If not supplied only the comments of the new version will be displayed.
ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>()); ChannelsCommentsItem(FeedHolder *feedHolder,
uint32_t feedId,
const RsGxsGroupId& groupId,
const RsGxsMessageId& commentId,
const RsGxsMessageId& threadId,
bool isHome,
bool autoUpdate);
// This one is used in channel thread widget. We don't want the group data to reload at every post, so we load it in the hosting // This one is used in channel thread widget. We don't want the group data to reload at every post, so we load it in the hosting
// GxsChannelsPostsWidget and pass it to created items. // GxsChannelsPostsWidget and pass it to created items.
// ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData& group, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData& group, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
virtual ~ChannelsCommentsItem(); virtual ~ChannelsCommentsItem();
@ -55,6 +60,7 @@ public:
bool setGroup(const RsGxsChannelGroup& group, bool doFill = true); bool setGroup(const RsGxsChannelGroup& group, bool doFill = true);
bool setPost(const RsGxsChannelPost& post, bool doFill = true); bool setPost(const RsGxsChannelPost& post, bool doFill = true);
bool setMissingPost();
QString getTitleLabel(); QString getTitleLabel();
QString getMsgLabel(); QString getMsgLabel();
@ -85,8 +91,8 @@ protected:
/* GxsFeedItem */ /* GxsFeedItem */
virtual QString messageName(); virtual QString messageName();
virtual void loadMessage(); virtual void loadMessage() override {}
virtual void loadComment(); virtual void loadComment() override {}
private slots: private slots:
/* default stuff */ /* default stuff */
@ -104,17 +110,20 @@ signals:
void vote(const RsGxsGrpMsgIdPair& msgId, bool up); void vote(const RsGxsGrpMsgIdPair& msgId, bool up);
private: private:
void load();
void setup(); void setup();
void fill(); void fill(bool missing_post=false);
void fillExpandFrame();
private: private:
bool mInFill; bool mInFill;
bool mCloseOnRead; bool mCloseOnRead;
bool mLoaded; bool mLoaded;
bool mLoading;
RsGroupMetaData mGroupMeta; RsGroupMetaData mGroupMeta;
RsGxsChannelPost mPost; RsGxsChannelPost mPost;
RsGxsMessageId mThreadId;
/** Qt Designer generated object */ /** Qt Designer generated object */
Ui::ChannelsCommentsItem *ui; Ui::ChannelsCommentsItem *ui;

View file

@ -37,20 +37,47 @@ GxsChannelGroupItem::GxsChannelGroupItem(FeedHolder *feedHolder, uint32_t feedId
GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, rsGxsChannels, autoUpdate) GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, rsGxsChannels, autoUpdate)
{ {
setup(); setup();
requestGroup(); requestGroup();
addEventHandler();
} }
GxsChannelGroupItem::GxsChannelGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelGroup &group, bool isHome, bool autoUpdate) : GxsChannelGroupItem::GxsChannelGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelGroup &group, bool isHome, bool autoUpdate) :
GxsGroupFeedItem(feedHolder, feedId, group.mMeta.mGroupId, isHome, rsGxsChannels, autoUpdate) GxsGroupFeedItem(feedHolder, feedId, group.mMeta.mGroupId, isHome, rsGxsChannels, autoUpdate)
{ {
setup(); setup();
setGroup(group); setGroup(group);
addEventHandler();
}
void GxsChannelGroupItem::addEventHandler()
{
mEventHandlerId = 0;
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event)
{
RsQThreadUtils::postToObject([=]()
{
const auto *e = dynamic_cast<const RsGxsChannelEvent*>(event.get());
if(!e || e->mChannelGroupId != this->groupId())
return;
switch(e->mChannelEventCode)
{
case RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED:
case RsChannelEventCode::UPDATED_CHANNEL:
case RsChannelEventCode::RECEIVED_PUBLISH_KEY:
loadGroup();
break;
default:
break;
}
}, this );
}, mEventHandlerId, RsEventType::GXS_CHANNELS );
} }
GxsChannelGroupItem::~GxsChannelGroupItem() GxsChannelGroupItem::~GxsChannelGroupItem()
{ {
rsEvents->unregisterEventsHandler(mEventHandlerId);
delete(ui); delete(ui);
} }

View file

@ -60,12 +60,14 @@ private slots:
private: private:
void fill(); void fill();
void setup(); void setup();
void addEventHandler();
private: private:
RsGxsChannelGroup mGroup; RsGxsChannelGroup mGroup;
/** Qt Designer generated object */ /** Qt Designer generated object */
Ui::GxsChannelGroupItem *ui; Ui::GxsChannelGroupItem *ui;
RsEventsHandlerId_t mEventHandlerId;
}; };
#endif #endif

View file

@ -251,7 +251,7 @@
<enum>Qt::NoFocus</enum> <enum>Qt::NoFocus</enum>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Subscribe to Channel</string> <string>Subscribe this Channel</string>
</property> </property>
<property name="text"> <property name="text">
<string>Subscribe</string> <string>Subscribe</string>

View file

@ -49,6 +49,10 @@ GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId,
GxsFeedItem(feedHolder, feedId, group_meta.mGroupId, messageId, isHome, rsGxsChannels, autoUpdate), GxsFeedItem(feedHolder, feedId, group_meta.mGroupId, messageId, isHome, rsGxsChannels, autoUpdate),
mGroupMeta(group_meta) mGroupMeta(group_meta)
{ {
mLoadingGroup = false;
mLoadingMessage = false;
mLoadingComment = false;
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
mPost.mMeta.mGroupId = mGroupMeta.mGroupId; mPost.mMeta.mGroupId = mGroupMeta.mGroupId;
@ -136,6 +140,19 @@ void GxsChannelPostItem::paintEvent(QPaintEvent *e)
GxsChannelPostItem::~GxsChannelPostItem() GxsChannelPostItem::~GxsChannelPostItem()
{ {
auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(300);
while( (mLoadingGroup || mLoadingMessage || mLoadingComment)
&& std::chrono::steady_clock::now() < timeout)
{
RsDbg() << __PRETTY_FUNCTION__ << " is Waiting for "
<< (mLoadingGroup ? "Group " : "")
<< (mLoadingMessage ? "Message " : "")
<< (mLoadingComment ? "Comment " : "")
<< "loading." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
delete(ui); delete(ui);
} }
@ -277,6 +294,7 @@ void GxsChannelPostItem::loadGroup()
std::cerr << "GxsChannelGroupItem::loadGroup()"; std::cerr << "GxsChannelGroupItem::loadGroup()";
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
mLoadingGroup = true;
RsThread::async([this]() RsThread::async([this]()
{ {
@ -306,6 +324,7 @@ void GxsChannelPostItem::loadGroup()
* after a blocking call to RetroShare API complete */ * after a blocking call to RetroShare API complete */
mGroupMeta = group.mMeta; mGroupMeta = group.mMeta;
mLoadingGroup = false;
}, this ); }, this );
}); });
@ -316,6 +335,8 @@ void GxsChannelPostItem::loadMessage()
std::cerr << "GxsChannelPostItem::loadMessage()"; std::cerr << "GxsChannelPostItem::loadMessage()";
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
mLoadingMessage = true;
RsThread::async([this]() RsThread::async([this]()
{ {
// 1 - get group data // 1 - get group data
@ -337,7 +358,11 @@ void GxsChannelPostItem::loadMessage()
#endif #endif
const RsGxsChannelPost& post(posts[0]); const RsGxsChannelPost& post(posts[0]);
RsQThreadUtils::postToObject( [post,this]() { setPost(post); }, this ); RsQThreadUtils::postToObject( [post,this]()
{
setPost(post);
mLoadingMessage = false;
}, this );
} }
else if(comments.size() == 1) else if(comments.size() == 1)
{ {
@ -356,6 +381,7 @@ void GxsChannelPostItem::loadMessage()
setMessageId(cmt.mMeta.mThreadId); setMessageId(cmt.mMeta.mThreadId);
requestMessage(); requestMessage();
mLoadingMessage = false;
}, this ); }, this );
} }
@ -366,7 +392,11 @@ void GxsChannelPostItem::loadMessage()
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
RsQThreadUtils::postToObject( [this]() { removeItem(); }, this ); RsQThreadUtils::postToObject( [this]()
{
removeItem();
mLoadingMessage = false;
}, this );
} }
}); });
} }
@ -377,6 +407,7 @@ void GxsChannelPostItem::loadComment()
std::cerr << "GxsChannelPostItem::loadComment()"; std::cerr << "GxsChannelPostItem::loadComment()";
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
mLoadingComment = true;
RsThread::async([this]() RsThread::async([this]()
{ {
@ -407,6 +438,7 @@ void GxsChannelPostItem::loadComment()
sComButText = tr("Comments ").append("(%1)").arg(comNb); sComButText = tr("Comments ").append("(%1)").arg(comNb);
ui->commentButton->setText(sComButText); ui->commentButton->setText(sComButText);
mLoadingComment = false;
}, this ); }, this );
}); });

View file

@ -121,6 +121,11 @@ private:
bool mCloseOnRead; bool mCloseOnRead;
bool mLoaded; bool mLoaded;
bool mLoadingMessage;
bool mLoadingGroup;
bool mLoadingComment;
RsGroupMetaData mGroupMeta; RsGroupMetaData mGroupMeta;
RsGxsChannelPost mPost; RsGxsChannelPost mPost;

View file

@ -35,8 +35,8 @@ GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, co
GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, rsGxsForums, autoUpdate) GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, rsGxsForums, autoUpdate)
{ {
setup(); setup();
requestGroup(); requestGroup();
addEventHandler();
} }
GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const std::list<RsGxsId>& added_moderators,const std::list<RsGxsId>& removed_moderators,bool isHome, bool autoUpdate): GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const std::list<RsGxsId>& added_moderators,const std::list<RsGxsId>& removed_moderators,bool isHome, bool autoUpdate):
@ -45,20 +45,47 @@ GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, co
mRemovedModerators(removed_moderators) mRemovedModerators(removed_moderators)
{ {
setup(); setup();
requestGroup(); requestGroup();
addEventHandler();
}
void GxsForumGroupItem::addEventHandler()
{
mEventHandlerId = 0;
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event)
{
RsQThreadUtils::postToObject([=]()
{
const auto *e = dynamic_cast<const RsGxsForumEvent*>(event.get());
if(!e || e->mForumGroupId != this->groupId())
return;
switch(e->mForumEventCode)
{
case RsForumEventCode::SUBSCRIBE_STATUS_CHANGED:
case RsForumEventCode::UPDATED_FORUM:
case RsForumEventCode::MODERATOR_LIST_CHANGED:
loadGroup();
break;
default:
break;
}
}, this );
}, mEventHandlerId, RsEventType::GXS_FORUMS );
} }
GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsForumGroup &group, bool isHome, bool autoUpdate) : GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsForumGroup &group, bool isHome, bool autoUpdate) :
GxsGroupFeedItem(feedHolder, feedId, group.mMeta.mGroupId, isHome, rsGxsForums, autoUpdate) GxsGroupFeedItem(feedHolder, feedId, group.mMeta.mGroupId, isHome, rsGxsForums, autoUpdate)
{ {
setup(); setup();
setGroup(group); setGroup(group);
addEventHandler();
} }
GxsForumGroupItem::~GxsForumGroupItem() GxsForumGroupItem::~GxsForumGroupItem()
{ {
rsEvents->unregisterEventsHandler(mEventHandlerId);
delete(ui); delete(ui);
} }

View file

@ -22,6 +22,7 @@
#define _GXSFORUMGROUPITEM_H #define _GXSFORUMGROUPITEM_H
#include <retroshare/rsgxsforums.h> #include <retroshare/rsgxsforums.h>
#include <retroshare/rsevents.h>
#include "gui/gxs/GxsGroupFeedItem.h" #include "gui/gxs/GxsGroupFeedItem.h"
namespace Ui { namespace Ui {
@ -39,27 +40,28 @@ public:
GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate); GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate);
GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const std::list<RsGxsId>& added_moderators,const std::list<RsGxsId>& removed_moderators,bool isHome, bool autoUpdate); GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const std::list<RsGxsId>& added_moderators,const std::list<RsGxsId>& removed_moderators,bool isHome, bool autoUpdate);
GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsForumGroup &group, bool isHome, bool autoUpdate); GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsForumGroup &group, bool isHome, bool autoUpdate);
~GxsForumGroupItem(); virtual ~GxsForumGroupItem() override;
bool setGroup(const RsGxsForumGroup &group); bool setGroup(const RsGxsForumGroup &group);
uint64_t uniqueIdentifier() const override { return hash_64bits("GxsForumGroupItem " + groupId().toStdString()) ; } uint64_t uniqueIdentifier() const override { return hash_64bits("GxsForumGroupItem " + groupId().toStdString()) ; }
protected: protected:
/* FeedItem */ /* FeedItem */
virtual void doExpand(bool open); virtual void doExpand(bool open) override;
void toggle() override;
/* GxsGroupFeedItem */ /* GxsGroupFeedItem */
virtual QString groupName(); virtual QString groupName() override;
virtual void loadGroup() override; virtual void loadGroup() override;
virtual RetroShareLink::enumType getLinkType() { return RetroShareLink::TYPE_FORUM; } virtual RetroShareLink::enumType getLinkType() override { return RetroShareLink::TYPE_FORUM; }
private slots: private slots:
void subscribeForum(); void subscribeForum();
void toggle() override;
private: private:
void fill(); void fill();
void setup(); void setup();
void addEventHandler();
private: private:
RsGxsForumGroup mGroup; RsGxsForumGroup mGroup;
@ -69,6 +71,8 @@ private:
std::list<RsGxsId> mAddedModerators; std::list<RsGxsId> mAddedModerators;
std::list<RsGxsId> mRemovedModerators; std::list<RsGxsId> mRemovedModerators;
RsEventsHandlerId_t mEventHandlerId;
}; };
#endif #endif

View file

@ -47,6 +47,12 @@ GxsForumMsgItem::GxsForumMsgItem(FeedHolder *feedHolder, uint32_t feedId, const
{ {
mMessage.mMeta.mMsgId = messageId; // useful for uniqueIdentifier() before the post is actually loaded mMessage.mMeta.mMsgId = messageId; // useful for uniqueIdentifier() before the post is actually loaded
mMessage.mMeta.mGroupId = groupId; mMessage.mMeta.mGroupId = groupId;
mLoadingGroup = false;
mLoadingMessage = false;
mLoadingSetAsRead = false;
mLoadingParentMessage = false;
setup(); setup();
requestGroup(); requestGroup();

View file

@ -29,6 +29,8 @@
#include <QMessageBox> #include <QMessageBox>
#include <QDateTime> #include <QDateTime>
//#define DEBUG_COMMENT_DIALOG 1
/** Constructor */ /** Constructor */
GxsCommentDialog::GxsCommentDialog(QWidget *parent, const RsGxsId &default_author, RsGxsCommentService *comment_service) GxsCommentDialog::GxsCommentDialog(QWidget *parent, const RsGxsId &default_author, RsGxsCommentService *comment_service)
: QWidget(parent), ui(new Ui::GxsCommentDialog) : QWidget(parent), ui(new Ui::GxsCommentDialog)
@ -95,8 +97,11 @@ void GxsCommentDialog::commentClear()
} }
void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId>& msg_versions,const RsGxsMessageId& most_recent_msgId,bool use_cache) void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId>& msg_versions,const RsGxsMessageId& most_recent_msgId,bool use_cache)
{ {
std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", most recent msg version: " << most_recent_msgId << ")"; #ifdef DEBUG_COMMENT_DIALOG
std::cerr << std::endl; std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", most recent msg version: " << most_recent_msgId << ")" << std::endl;
for(const auto& mid:msg_versions)
std::cerr << " msg version: " << mid << std::endl;
#endif
mGrpId = grpId; mGrpId = grpId;
mMostRecentMsgId = most_recent_msgId; mMostRecentMsgId = most_recent_msgId;

View file

@ -42,6 +42,8 @@
#include <iostream> #include <iostream>
//#define DEBUG_COMMENT_TREE_WIDGET
#define PCITEM_COLUMN_COMMENT 0 #define PCITEM_COLUMN_COMMENT 0
#define PCITEM_COLUMN_AUTHOR 1 #define PCITEM_COLUMN_AUTHOR 1
#define PCITEM_COLUMN_DATE 2 #define PCITEM_COLUMN_DATE 2
@ -73,6 +75,7 @@ std::map<RsGxsMessageId, std::vector<RsGxsComment> > GxsCommentTreeWidget::mComm
QMutex GxsCommentTreeWidget::mCacheMutex; QMutex GxsCommentTreeWidget::mCacheMutex;
//#define USE_NEW_DELEGATE 1 //#define USE_NEW_DELEGATE 1
//#define DEBUG_GXSCOMMENT_TREEWIDGET 1
// This class allows to draw the item using an appropriate size // This class allows to draw the item using an appropriate size
@ -508,6 +511,8 @@ void GxsCommentTreeWidget::service_requestComments(const RsGxsGroupId& group_id,
/* request comments */ /* request comments */
#ifdef DEBUG_GXSCOMMENT_TREEWIDGET #ifdef DEBUG_GXSCOMMENT_TREEWIDGET
std::cerr << "GxsCommentTreeWidget::service_requestComments for group " << group_id << std::endl; std::cerr << "GxsCommentTreeWidget::service_requestComments for group " << group_id << std::endl;
for(const auto& mid:msgIds)
std::cerr << " including message " << mid << std::endl;
#endif #endif
RsThread::async([this,group_id,msgIds]() RsThread::async([this,group_id,msgIds]()
@ -765,8 +770,10 @@ void GxsCommentTreeWidget::insertComments(const std::vector<RsGxsComment>& comme
new_comments.push_back(comment.mMeta.mMsgId); new_comments.push_back(comment.mMeta.mMsgId);
/* convert to a QTreeWidgetItem */ /* convert to a QTreeWidgetItem */
#ifdef DEBUG_COMMENT_TREE_WIDGET
std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment.mMeta.mMsgId; std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment.mMeta.mMsgId;
std::cerr << std::endl; std::cerr << std::endl;
#endif
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(NULL,GxsIdDetails::ICON_TYPE_AVATAR) ; GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(NULL,GxsIdDetails::ICON_TYPE_AVATAR) ;
QString text; QString text;

View file

@ -35,6 +35,7 @@
#include "util/rsdir.h" #include "util/rsdir.h"
#include "util/qtthreadsutils.h" #include "util/qtthreadsutils.h"
#include "util/RichTextEdit.h" #include "util/RichTextEdit.h"
#include "util/imageutil.h"
#include <retroshare/rsfiles.h> #include <retroshare/rsfiles.h>
@ -607,11 +608,13 @@ bool CreateGxsChannelMsg::setThumbNail(const std::string& path, int frame){
if(imageBuffer == NULL) if(imageBuffer == NULL)
return false; return false;
QImage tNail(imageBuffer, width, height, QImage::Format_RGB32); QImage tNail(imageBuffer, width, height, QImage::Format_RGBA32);
QByteArray ba; QByteArray ba;
QBuffer buffer(&ba); QBuffer buffer(&ba);
bool has_transparency = ImageUtil::hasAlphaContent(tNail.toImage());
buffer.open(QIODevice::WriteOnly); buffer.open(QIODevice::WriteOnly);
tNail.save(&buffer, "JPG"); tNail.save(&buffer, has_transparency?"PNG":"JPG");
QPixmap img; QPixmap img;
img.loadFromData(ba, "PNG"); img.loadFromData(ba, "PNG");
img = img.scaled(thumbnail_label->width(), thumbnail_label->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); img = img.scaled(thumbnail_label->width(), thumbnail_label->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
@ -798,13 +801,17 @@ void CreateGxsChannelMsg::sendMessage(const std::string &subject, const std::str
QBuffer buffer(&ba); QBuffer buffer(&ba);
RsGxsImage image; RsGxsImage image;
QPixmap pixmap;
pixmap = preview_W->getCroppedScaledPicture();
QImage qimg = pixmap.toImage();
bool has_transparency = ImageUtil::hasAlphaContent(qimg);
if(!picture.isNull()) if(!picture.isNull())
{ {
// send chan image // send chan image
buffer.open(QIODevice::WriteOnly); buffer.open(QIODevice::WriteOnly);
preview_W->getCroppedScaledPicture().save(&buffer, "JPG"); // writes image into ba in PNG format preview_W->getCroppedScaledPicture().save(&buffer, has_transparency?"PNG":"JPG"); // writes image into ba in PNG format
image.copy((uint8_t *) ba.data(), ba.size()); image.copy((uint8_t *) ba.data(), ba.size());
} }

View file

@ -176,6 +176,25 @@ int RsGxsChannelPostsModel::rowCount(const QModelIndex& parent) const
return 0; return 0;
} }
int RsGxsChannelPostsModel::columnCount(int row) const
{
if(mTreeMode == TREE_MODE_GRID)
{
if(row+1 == rowCount())
{
int r = ((int)mFilteredPosts.size() % (int)mColumns);
if(r > 0)
return r;
else
return columnCount();
}
else
return columnCount();
}
else
return 2;
}
int RsGxsChannelPostsModel::columnCount(const QModelIndex &/*parent*/) const int RsGxsChannelPostsModel::columnCount(const QModelIndex &/*parent*/) const
{ {
if(mTreeMode == TREE_MODE_GRID) if(mTreeMode == TREE_MODE_GRID)
@ -245,7 +264,7 @@ bool RsGxsChannelPostsModel::convertRefPointerToTabEntry(quintptr ref, uint32_t&
QModelIndex RsGxsChannelPostsModel::index(int row, int column, const QModelIndex & parent) const QModelIndex RsGxsChannelPostsModel::index(int row, int column, const QModelIndex & parent) const
{ {
if(row < 0 || column < 0 || column >= (int)mColumns) if(row < 0 || column < 0 || row >= rowCount() || column >= columnCount(row))
return QModelIndex(); return QModelIndex();
quintptr ref = getChildRef(parent.internalId(),(mTreeMode == TREE_MODE_GRID)?(column + row*mColumns):row); quintptr ref = getChildRef(parent.internalId(),(mTreeMode == TREE_MODE_GRID)?(column + row*mColumns):row);

View file

@ -105,6 +105,7 @@ public:
QModelIndex root() const{ return createIndex(0,0,(void*)NULL) ;} QModelIndex root() const{ return createIndex(0,0,(void*)NULL) ;}
QModelIndex getIndexOfMessage(const RsGxsMessageId& mid) const; QModelIndex getIndexOfMessage(const RsGxsMessageId& mid) const;
int columnCount(int row) const; // columns in the row of this particular index.
std::vector<std::pair<time_t,RsGxsMessageId> > getPostVersions(const RsGxsMessageId& mid) const; std::vector<std::pair<time_t,RsGxsMessageId> > getPostVersions(const RsGxsMessageId& mid) const;

View file

@ -504,6 +504,30 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI
}, mEventHandlerId, RsEventType::GXS_CHANNELS ); }, mEventHandlerId, RsEventType::GXS_CHANNELS );
} }
void GxsChannelPostsWidgetWithModel::keyPressEvent(QKeyEvent *e)
{
QModelIndex index = ui->postsTree->selectionModel()->currentIndex();
if(index.isValid() && mChannelPostsModel->getMode() == RsGxsChannelPostsModel::TREE_MODE_GRID)
{
int n = mChannelPostsModel->columnCount(index.row())-1;
if(e->key() == Qt::Key_Left && index.column()==0)
{
ui->postsTree->setCurrentIndex(index.sibling(index.row(),n));
e->accept();
return;
}
if(e->key() == Qt::Key_Right && index.column()==n)
{
ui->postsTree->setCurrentIndex(index.sibling(index.row(),0));
e->accept();
return;
}
}
GxsMessageFrameWidget::keyPressEvent(e);
}
void GxsChannelPostsWidgetWithModel::resizeEvent(QResizeEvent *e) void GxsChannelPostsWidgetWithModel::resizeEvent(QResizeEvent *e)
{ {
GxsMessageFrameWidget::resizeEvent(e); GxsMessageFrameWidget::resizeEvent(e);

View file

@ -139,6 +139,7 @@ protected:
/* GxsMessageFrameWidget */ /* GxsMessageFrameWidget */
virtual void setAllMessagesReadDo(bool read) override; virtual void setAllMessagesReadDo(bool read) override;
virtual void resizeEvent(QResizeEvent *e) override; virtual void resizeEvent(QResizeEvent *e) override;
virtual void keyPressEvent(QKeyEvent *e) override;
private slots: private slots:
void showPostDetails(); void showPostDetails();

View file

@ -255,7 +255,7 @@ private:
QList<QLabel*> tagLabels; QList<QLabel*> tagLabels;
// needed to send system flags with reply // needed to send system flags with reply
unsigned msgFlags; unsigned int msgFlags;
RSTreeWidgetItemCompareRole *m_compareRole; RSTreeWidgetItemCompareRole *m_compareRole;
QCompleter *m_completer; QCompleter *m_completer;

View file

@ -690,6 +690,10 @@ void RsMessageModel::setCurrentBox(Rs::Msgs::BoxName bn)
} }
} }
Rs::Msgs::BoxName RsMessageModel::currentBox() const
{
return mCurrentBox;
}
void RsMessageModel::setQuickViewFilter(QuickViewFilter fn) void RsMessageModel::setQuickViewFilter(QuickViewFilter fn)
{ {
if(fn != mQuickViewFilter) if(fn != mQuickViewFilter)

View file

@ -100,6 +100,7 @@ public:
// This method will asynchroneously update the data // This method will asynchroneously update the data
void setCurrentBox(Rs::Msgs::BoxName bn) ; void setCurrentBox(Rs::Msgs::BoxName bn) ;
Rs::Msgs::BoxName currentBox() const ;
void setQuickViewFilter(QuickViewFilter fn) ; void setQuickViewFilter(QuickViewFilter fn) ;
void setFilter(FilterType filter_type, const QStringList& strings) ; void setFilter(FilterType filter_type, const QStringList& strings) ;

View file

@ -738,6 +738,7 @@ void MessageWidget::remove()
return; return;
} }
#ifdef TO_REMOVE
bool deleteReal = false; bool deleteReal = false;
if (msgInfo.msgflags & RS_MSG_TRASH) { if (msgInfo.msgflags & RS_MSG_TRASH) {
deleteReal = true; deleteReal = true;
@ -763,8 +764,8 @@ void MessageWidget::remove()
deleteLater(); deleteLater();
} }
} }
#endif
emit messageRemoved(); emit messageRemovalRequested(currMsgId);
} }
void MessageWidget::print() void MessageWidget::print()

View file

@ -61,6 +61,7 @@ public:
signals: signals:
void messageRemoved(); void messageRemoved();
void messageRemovalRequested(std::string);
private slots: private slots:
void reply(); void reply();

View file

@ -95,6 +95,7 @@
#define ROW_SENTBOX 3 #define ROW_SENTBOX 3
#define ROW_TRASHBOX 4 #define ROW_TRASHBOX 4
// #define DEBUG_MESSAGES_DIALOG 1
class MessageSortFilterProxyModel: public QSortFilterProxyModel class MessageSortFilterProxyModel: public QSortFilterProxyModel
{ {
@ -144,7 +145,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
msgWidget = new MessageWidget(true, this); msgWidget = new MessageWidget(true, this);
ui.msgLayout->addWidget(msgWidget); ui.msgLayout->addWidget(msgWidget);
connect(msgWidget, SIGNAL(messageRemoved()), this, SLOT(messageRemoved())); connect(msgWidget, SIGNAL(messageRemovalRequested(std::string)), this, SLOT(removemessage()));
connectActions(); connectActions();
@ -365,15 +366,18 @@ void MessagesDialog::preModelUpdate()
if (m.isValid()) { if (m.isValid()) {
mTmpSavedCurrentId = m.sibling(m.row(), RsMessageModel::COLUMN_THREAD_MSGID).data(RsMessageModel::MsgIdRole).toString(); mTmpSavedCurrentId = m.sibling(m.row(), RsMessageModel::COLUMN_THREAD_MSGID).data(RsMessageModel::MsgIdRole).toString();
} }
#ifdef DEBUG_MESSAGES_DIALOG
std::cerr << "Pre-change: saving selection for " << mTmpSavedSelectedIds.size() << " indexes" << std::endl; std::cerr << "Pre-change: saving selection for " << mTmpSavedSelectedIds.size() << " indexes" << std::endl;
#endif
} }
void MessagesDialog::postModelUpdate() void MessagesDialog::postModelUpdate()
{ {
// restore selection // restore selection
#ifdef DEBUG_MESSAGES_DIALOG
std::cerr << "Post-change: restoring selection for " << mTmpSavedSelectedIds.size() << " indexes" << std::endl; std::cerr << "Post-change: restoring selection for " << mTmpSavedSelectedIds.size() << " indexes" << std::endl;
#endif
QItemSelection sel; QItemSelection sel;
foreach(const QString& s,mTmpSavedSelectedIds) foreach(const QString& s,mTmpSavedSelectedIds)
@ -838,7 +842,7 @@ void MessagesDialog::openAsWindow()
} }
msgWidget->activateWindow(); msgWidget->activateWindow();
connect(msgWidget, SIGNAL(messageRemoved()), this, SLOT(messageRemoved())); connect(msgWidget, SIGNAL(messageRemovalRequested(std::string)), this, SLOT(removemessage()));
/* window will destroy itself! */ /* window will destroy itself! */
} }
@ -858,7 +862,7 @@ void MessagesDialog::openAsTab()
ui.tabWidget->addTab(msgWidget,FilesDefs::getIconFromQtResourcePath(IMAGE_MAIL), msgWidget->subject(true)); ui.tabWidget->addTab(msgWidget,FilesDefs::getIconFromQtResourcePath(IMAGE_MAIL), msgWidget->subject(true));
ui.tabWidget->setCurrentWidget(msgWidget); ui.tabWidget->setCurrentWidget(msgWidget);
connect(msgWidget, SIGNAL(messageRemoved()), this, SLOT(messageRemoved())); connect(msgWidget, SIGNAL(messageRemovalRequested(std::string)), this, SLOT(removemessage()));
/* window will destroy itself! */ /* window will destroy itself! */
} }
@ -921,9 +925,9 @@ void MessagesDialog::changeBox(int box_row)
ui.messageTreeWidget->setPlaceholderText(placeholderText); ui.messageTreeWidget->setPlaceholderText(placeholderText);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_READ,box_row!=ROW_INBOX); ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_READ,box_row!=ROW_INBOX);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_STAR,box_row==ROW_OUTBOX); ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_STAR,box_row!=ROW_INBOX);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_SPAM,box_row==ROW_OUTBOX); ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_SPAM,box_row!=ROW_INBOX);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_TAGS,box_row==ROW_OUTBOX); ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_TAGS,box_row!=ROW_INBOX);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_MSGID,true); ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_MSGID,true);
ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_CONTENT,true); ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_CONTENT,true);
} }
@ -1292,7 +1296,7 @@ void MessagesDialog::updateMessageSummaryList()
/* calculating the new messages */ /* calculating the new messages */
std::list<MsgInfoSummary> msgList; std::list<MsgInfoSummary> msgList;
rsMail->getMessageSummaries(Rs::Msgs::BoxName::BOX_ALL,msgList); rsMail->getMessageSummaries(mMessageModel->currentBox(),msgList);
QMap<int, int> tagCount; QMap<int, int> tagCount;

View file

@ -2436,7 +2436,7 @@ WireGroupItem QFrame#wire_frame QLabel{
background: transparent; background: transparent;
} }
WireGroupItem QFrame#wire_frame:hover { WireGroupItem QFrame#wire_frame:hover {
background-color: #2e8bab; background-color: #346792;
} }
PulseTopLevel QFrame#frame, PulseTopLevel QFrame#frame,
@ -2446,13 +2446,6 @@ PulseReply QFrame#frame {
border-radius: 6px; border-radius: 6px;
} }
PulseAddDialog QTextEdit#textEdit_Pulse {
border: 2px solid #c4cfd6;
border-radius: 6px;
background: white;
color: black;
}
PulseReply #line_replyLine, PulseReply #line_replyLine,
PulseMessage #line{ PulseMessage #line{
color: #c4cfd6; color: #c4cfd6;
@ -2462,6 +2455,16 @@ PulseReply QLabel#label_groupName{
color: #5b7083; color: #5b7083;
} }
PulseReplySeperator QFrame#frame {
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #455364, stop: 0.5 #54687A,stop: 0.6 #44586A, stop:1 #455364);
border-radius: 10px;
}
QLabel#label_masthead{
border: 2px solid #CCCCCC;
border-radius: 4px;
}
/**** Color definitions ****/ /**** Color definitions ****/
ForumsDialog, GxsForumThreadWidget ForumsDialog, GxsForumThreadWidget
@ -2552,10 +2555,3 @@ OpModeStatus[opMode="Minimal"] {
[WrongValue="true"] { [WrongValue="true"] {
background-color: #702020; background-color: #702020;
} }
/**** The Wire ****/
QLabel#label_masthead{
border: 2px solid #CCCCCC;
border-radius: 4px;
}

View file

@ -2687,6 +2687,12 @@ PulseReply QLabel#label_groupName{
color: #5b7083; color: #5b7083;
} }
PulseReplySeperator QFrame#frame {
border: 2px solid #CCCCCC;
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC);
border-radius: 10px}
}
QLabel#label_masthead{ QLabel#label_masthead{
border: 2px solid #CCCCCC; border: 2px solid #CCCCCC;
border-radius: 4px; border-radius: 4px;

View file

@ -74,7 +74,12 @@ AppearancePage::AppearancePage(QWidget * parent, Qt::WindowFlags flags)
foreach (QString code, LanguageSupport::languageCodes()) { foreach (QString code, LanguageSupport::languageCodes()) {
ui.cmboLanguage->addItem(FilesDefs::getIconFromQtResourcePath(":/images/flags/" + code + ".png"), LanguageSupport::languageName(code), code); ui.cmboLanguage->addItem(FilesDefs::getIconFromQtResourcePath(":/images/flags/" + code + ".png"), LanguageSupport::languageName(code), code);
} }
// Note: apparently, on some linux systems (e.g. Debian 11), the gtk2 style makes Qt libs crash when the environment variable is not set.
// So we first check that it's here before start.
foreach (QString style, QStyleFactory::keys()) { foreach (QString style, QStyleFactory::keys()) {
if(style.toLower() != "gtk2" || (getenv("QT_QPA_PLATFORMTHEME")!=nullptr && !strcmp(getenv("QT_QPA_PLATFORMTHEME"),"gtk2")))
ui.cmboStyle->addItem(style, style.toLower()); ui.cmboStyle->addItem(style, style.toLower());
} }
@ -266,9 +271,9 @@ void AppearancePage::load()
index = ui.mainPageButtonType_CB->findData(Settings->getPageButtonLoc()); index = ui.mainPageButtonType_CB->findData(Settings->getPageButtonLoc());
if (index != 0) { if (index != 0) {
ui.cmboTollButtonsStyle->hide();
}else {
ui.cmboTollButtonsStyle->show(); ui.cmboTollButtonsStyle->show();
}else {
ui.cmboTollButtonsStyle->hide();
} }
whileBlocking(ui.mainPageButtonType_CB)->setCurrentIndex(!Settings->getPageButtonLoc()); whileBlocking(ui.mainPageButtonType_CB)->setCurrentIndex(!Settings->getPageButtonLoc());

View file

@ -23,11 +23,14 @@
#include "rsharesettings.h" #include "rsharesettings.h"
#include "jsonapi/jsonapi.h" #include "jsonapi/jsonapi.h"
#include "util/misc.h" #include "util/misc.h"
#include "util/qtthreadsutils.h"
#include <QTimer> #include <QTimer>
#include <QStringListModel> #include <QStringListModel>
#include <QProgressDialog> #include <QProgressDialog>
#define IMAGE_LEDOFF ":/images/ledoff1.png"
#define IMAGE_LEDON ":/images/ledon1.png"
JsonApiPage::JsonApiPage(QWidget */*parent*/, Qt::WindowFlags /*flags*/) JsonApiPage::JsonApiPage(QWidget */*parent*/, Qt::WindowFlags /*flags*/)
{ {
@ -57,9 +60,41 @@ JsonApiPage::JsonApiPage(QWidget */*parent*/, Qt::WindowFlags /*flags*/)
QRegExpValidator *ipValidator = new QRegExpValidator(ipRegex, this); QRegExpValidator *ipValidator = new QRegExpValidator(ipRegex, this);
ui.listenAddressLineEdit->setValidator(ipValidator); ui.listenAddressLineEdit->setValidator(ipValidator);
ui.providersListView->setSelectionMode(QAbstractItemView::NoSelection); // prevents edition.
mEventHandlerId = 0;
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> e)
{
if(e->mType != RsEventType::JSON_API)
return;
auto je = dynamic_cast<const RsJsonApiEvent*>(e.get());
if(!je)
return;
#ifdef DEBUG
std::cerr << "Caught JSONAPI event! code=" << static_cast<int>(je->mJsonApiEventCode) << std::endl;
#endif
RsQThreadUtils::postToObject([=]() { load(); }, this );
},
mEventHandlerId, RsEventType::JSON_API );
} }
JsonApiPage::~JsonApiPage()
{
rsEvents->unregisterEventsHandler(mEventHandlerId);
}
QString JsonApiPage::helpText() const
{
return tr("<h1><img width=\"24\" src=\":/icons/help_64.png\">&nbsp;&nbsp;Webinterface</h1> \
<p>Retroshare provides a JSON API allowing other softwares to communicate with its core using token-controlled HTTP requests to http://localhost:[port]. \
Please refer to the Retroshare documentation for how to use this feature. </p>\
<p>Unless you know what you're doing, you shouldn't need to change anything in this page. \
The web interface for instance will automatically register its own token to the JSON API which will be visible \
in the list of authenticated tokens after you enable it.</p>");
}
void JsonApiPage::enableJsonApi(bool checked) void JsonApiPage::enableJsonApi(bool checked)
{ {
ui.addTokenPushButton->setEnabled(checked); ui.addTokenPushButton->setEnabled(checked);
@ -93,9 +128,9 @@ bool JsonApiPage::updateParams()
void JsonApiPage::load() void JsonApiPage::load()
{ {
whileBlocking(ui.portSpinBox)->setValue(Settings->getJsonApiPort()); whileBlocking(ui.portSpinBox)->setValue(rsJsonApi->listeningPort());
whileBlocking(ui.listenAddressLineEdit)->setText(Settings->getJsonApiListenAddress()); whileBlocking(ui.listenAddressLineEdit)->setText(QString::fromStdString(rsJsonApi->getBindingAddress()));
whileBlocking(ui.enableCheckBox)->setChecked(Settings->getJsonApiEnabled()); whileBlocking(ui.enableCheckBox)->setChecked(rsJsonApi->isRunning());
QStringList newTk; QStringList newTk;
@ -105,9 +140,19 @@ void JsonApiPage::load()
QString::fromStdString(it.second) ); QString::fromStdString(it.second) );
whileBlocking(ui.tokensListView)->setModel(new QStringListModel(newTk)); whileBlocking(ui.tokensListView)->setModel(new QStringListModel(newTk));
}
QString JsonApiPage::helpText() const { return ""; } QStringList newTk2;
for(const auto& it : rsJsonApi->getResourceProviders())
newTk2.push_back( QString::fromStdString(it.get().getName())) ;
whileBlocking(ui.providersListView)->setModel(new QStringListModel(newTk2));
if(rsJsonApi->isRunning())
ui.statusLabelLED->setPixmap(FilesDefs::getPixmapFromQtResourcePath(IMAGE_LEDON)) ;
else
ui.statusLabelLED->setPixmap(FilesDefs::getPixmapFromQtResourcePath(IMAGE_LEDOFF)) ;
}
bool JsonApiPage::checkStartJsonApi() bool JsonApiPage::checkStartJsonApi()
{ {

View file

@ -20,6 +20,8 @@
#pragma once #pragma once
#include "retroshare/rsevents.h"
#include "retroshare-gui/configpage.h" #include "retroshare-gui/configpage.h"
#include "gui/common/FilesDefs.h" #include "gui/common/FilesDefs.h"
#include "ui_JsonApiPage.h" #include "ui_JsonApiPage.h"
@ -31,7 +33,7 @@ class JsonApiPage : public ConfigPage
public: public:
JsonApiPage(QWidget * parent = nullptr, Qt::WindowFlags flags = 0); JsonApiPage(QWidget * parent = nullptr, Qt::WindowFlags flags = 0);
~JsonApiPage() override = default; ~JsonApiPage() override ;
virtual QPixmap iconPixmap() const override virtual QPixmap iconPixmap() const override
{ {
@ -63,4 +65,6 @@ public slots:
private: private:
Ui::JsonApiPage ui; /// Qt Designer generated object Ui::JsonApiPage ui; /// Qt Designer generated object
RsEventsHandlerId_t mEventHandlerId;
}; };

View file

@ -13,7 +13,7 @@
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="WebuiPageVLayout"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<widget class="QGroupBox" name="jsonApiGroupBox"> <widget class="QGroupBox" name="jsonApiGroupBox">
<property name="minimumSize"> <property name="minimumSize">
@ -25,7 +25,9 @@
<property name="title"> <property name="title">
<string>JSON API Server</string> <string>JSON API Server</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item> <item>
<widget class="QCheckBox" name="enableCheckBox"> <widget class="QCheckBox" name="enableCheckBox">
<property name="text"> <property name="text">
@ -33,6 +35,56 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Status:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="statusLabelLED">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/ledoff1.png</pixmap>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Listen Address:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="listenAddressLineEdit">
<property name="text">
<string>127.0.0.1</string>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
@ -57,24 +109,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Listen Address:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="listenAddressLineEdit">
<property name="text">
<string>127.0.0.1</string>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
@ -110,13 +144,23 @@
<item> <item>
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>Authenticated Tokens</string> <string>Authenticated Tokens:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QListView" name="tokensListView"/> <widget class="QListView" name="tokensListView"/>
</item> </item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Registered services:</string>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="providersListView"/>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -142,6 +186,8 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<resources/> <resources>
<include location="../images.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

View file

@ -107,6 +107,8 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags)
ui.hiddenpage_proxyPort_tor->setEnabled(false) ; ui.hiddenpage_proxyPort_tor->setEnabled(false) ;
ui.hiddenpage_localAddress->setEnabled(false) ; ui.hiddenpage_localAddress->setEnabled(false) ;
ui.hiddenpage_localPort->setEnabled(false) ; ui.hiddenpage_localPort->setEnabled(false) ;
ui.hiddenpage_serviceAddress->setEnabled(false) ;
ui.hiddenpage_servicePort->setEnabled(false) ;
ui.testIncoming_PB->hide() ; ui.testIncoming_PB->hide() ;
ui.l_incomingTestResult->hide() ; ui.l_incomingTestResult->hide() ;
ui.iconlabel_service_incoming->hide() ; ui.iconlabel_service_incoming->hide() ;

View file

@ -256,11 +256,14 @@
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="iconlabel_ext"> <widget class="QLabel" name="iconlabel_ext">
<property name="maximumSize"> <property name="sizePolicy">
<size> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<width>16</width> <horstretch>0</horstretch>
<height>16</height> <verstretch>0</verstretch>
</size> </sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
@ -272,6 +275,12 @@
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QLabel" name="textlabel_ext"> <widget class="QLabel" name="textlabel_ext">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The bullet turns green as soon as Retroshare manages to get your own IP from the websites listed below, if you enabled that action. Retroshare will also use other means to find out your own IP.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The bullet turns green as soon as Retroshare manages to get your own IP from the websites listed below, if you enabled that action. Retroshare will also use other means to find out your own IP.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
@ -290,13 +299,29 @@
<property name="rightMargin"> <property name="rightMargin">
<number>6</number> <number>6</number>
</property> </property>
<item row="0" column="1">
<widget class="QLabel" name="textlabel_netLimited">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Local network</string>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="iconlabel_netLimited"> <widget class="QLabel" name="iconlabel_netLimited">
<property name="maximumSize"> <property name="sizePolicy">
<size> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<width>16</width> <horstretch>0</horstretch>
<height>16</height> <verstretch>0</verstretch>
</size> </sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
@ -306,13 +331,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1">
<widget class="QLabel" name="textlabel_netLimited">
<property name="text">
<string>Local network</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item row="6" column="0"> <item row="6" column="0">
@ -351,13 +369,29 @@
<property name="rightMargin"> <property name="rightMargin">
<number>6</number> <number>6</number>
</property> </property>
<item row="0" column="1">
<widget class="QLabel" name="textlabel_upnp">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>UPnP</string>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="iconlabel_upnp"> <widget class="QLabel" name="iconlabel_upnp">
<property name="maximumSize"> <property name="sizePolicy">
<size> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<width>16</width> <horstretch>0</horstretch>
<height>16</height> <verstretch>0</verstretch>
</size> </sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
@ -367,13 +401,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1">
<widget class="QLabel" name="textlabel_upnp">
<property name="text">
<string>UPnP</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item row="0" column="3"> <item row="0" column="3">
@ -386,11 +413,14 @@
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="iconlabel_hiddenMode"> <widget class="QLabel" name="iconlabel_hiddenMode">
<property name="maximumSize"> <property name="sizePolicy">
<size> <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<width>16</width> <horstretch>0</horstretch>
<height>16</height> <verstretch>0</verstretch>
</size> </sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property> </property>
<property name="text"> <property name="text">
<string/> <string/>
@ -402,6 +432,12 @@
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QLabel" name="textlabel_hiddenMode"> <widget class="QLabel" name="textlabel_hiddenMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -802,12 +838,6 @@ behind a firewall or a VPN.</string>
<layout class="QHBoxLayout" name="hiddenpage_proxyOKHLayout_tor"> <layout class="QHBoxLayout" name="hiddenpage_proxyOKHLayout_tor">
<item> <item>
<widget class="QLabel" name="iconlabel_tor_outgoing"> <widget class="QLabel" name="iconlabel_tor_outgoing">
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>

View file

@ -27,6 +27,7 @@
#include <QSpinBox> #include <QSpinBox>
#include "util/misc.h" #include "util/misc.h"
#include "util/qtthreadsutils.h"
#include "retroshare/rswebui.h" #include "retroshare/rswebui.h"
#include "retroshare/rsjsonapi.h" #include "retroshare/rsjsonapi.h"
@ -40,6 +41,8 @@ resource_api::ApiServerLocal* WebuiPage::apiServerLocal = 0;
#endif #endif
resource_api::RsControlModule* WebuiPage::controlModule = 0; resource_api::RsControlModule* WebuiPage::controlModule = 0;
#define IMAGE_LEDOFF ":/images/ledoff1.png"
#define IMAGE_LEDON ":/images/ledon1.png"
WebuiPage::WebuiPage(QWidget */*parent*/, Qt::WindowFlags /*flags*/) WebuiPage::WebuiPage(QWidget */*parent*/, Qt::WindowFlags /*flags*/)
{ {
@ -50,11 +53,22 @@ WebuiPage::WebuiPage(QWidget */*parent*/, Qt::WindowFlags /*flags*/)
connect(ui.password_LE, SIGNAL(textChanged(QString)), this, SLOT(onPasswordValueChanged(QString))); connect(ui.password_LE, SIGNAL(textChanged(QString)), this, SLOT(onPasswordValueChanged(QString)));
connect(ui.startWebBrowser_PB, SIGNAL(clicked()), this, SLOT(onStartWebBrowserClicked())); connect(ui.startWebBrowser_PB, SIGNAL(clicked()), this, SLOT(onStartWebBrowserClicked()));
connect(ui.webInterfaceFilesDirectory_PB, SIGNAL(clicked()), this, SLOT(selectWebInterfaceDirectory())); connect(ui.webInterfaceFilesDirectory_PB, SIGNAL(clicked()), this, SLOT(selectWebInterfaceDirectory()));
mEventsHandlerId = 0;
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> /* event */)
{
#ifdef DEBUG
std::cerr << "Caught JSONAPI event in webui!" << std::endl;
#endif
RsQThreadUtils::postToObject([=]() { load(); }, this );
},
mEventsHandlerId, RsEventType::JSON_API );
} }
WebuiPage::~WebuiPage() WebuiPage::~WebuiPage()
{ {
rsEvents->unregisterEventsHandler(mEventsHandlerId);
} }
void WebuiPage::selectWebInterfaceDirectory() void WebuiPage::selectWebInterfaceDirectory()
@ -73,22 +87,12 @@ void WebuiPage::selectWebInterfaceDirectory()
bool WebuiPage::updateParams(QString &errmsg) bool WebuiPage::updateParams(QString &errmsg)
{ {
std::cerr << "WebuiPage::save()" << std::endl; std::cerr << "WebuiPage::save()" << std::endl;
bool ok = true;
bool changed = false;
if(ui.enableWebUI_CB->isChecked() != Settings->getWebinterfaceEnabled())
changed = true;
if(ui.webInterfaceFiles_LE->text() != Settings->getWebinterfaceFilesDirectory())
changed = true;
if(changed)
{
// store config // store config
Settings->setWebinterfaceEnabled(ui.enableWebUI_CB->isChecked()); Settings->setWebinterfaceEnabled(ui.enableWebUI_CB->isChecked());
Settings->setWebinterfaceFilesDirectory(ui.webInterfaceFiles_LE->text()); Settings->setWebinterfaceFilesDirectory(ui.webInterfaceFiles_LE->text());
rsWebUi->setHtmlFilesDirectory(ui.webInterfaceFiles_LE->text().toStdString()); return true;
}
return ok;
} }
void WebuiPage::onPasswordValueChanged(QString password) void WebuiPage::onPasswordValueChanged(QString password)
@ -112,12 +116,27 @@ void WebuiPage::onPasswordValueChanged(QString password)
bool WebuiPage::restart() bool WebuiPage::restart()
{ {
return checkStartWebui(); if(ui.password_LE->text().isNull())
{
QMessageBox::critical(nullptr,tr("Missing passphrase"),tr("Please set a passphrase to proect the access to the WEB interface."));
return false;
} }
void WebuiPage::load() rsWebUi->setUserPassword(ui.password_LE->text().toStdString());
rsWebUi->setHtmlFilesDirectory(ui.webInterfaceFiles_LE->text().toStdString());
setCursor(Qt::WaitCursor) ;
rsWebUi->restart();
setCursor(Qt::ArrowCursor) ;
return true;
}
void WebuiPage::loadParams()
{ {
#ifdef DEBUG
std::cerr << "WebuiPage::load()" << std::endl; std::cerr << "WebuiPage::load()" << std::endl;
#endif
whileBlocking(ui.enableWebUI_CB)->setChecked(Settings->getWebinterfaceEnabled()); whileBlocking(ui.enableWebUI_CB)->setChecked(Settings->getWebinterfaceEnabled());
whileBlocking(ui.webInterfaceFiles_LE)->setText(Settings->getWebinterfaceFilesDirectory()); whileBlocking(ui.webInterfaceFiles_LE)->setText(Settings->getWebinterfaceFilesDirectory());
@ -127,6 +146,15 @@ void WebuiPage::load()
if(it != smap.end()) if(it != smap.end())
whileBlocking(ui.password_LE)->setText(QString::fromStdString(it->second)); whileBlocking(ui.password_LE)->setText(QString::fromStdString(it->second));
else
whileBlocking(ui.enableWebUI_CB)->setChecked(false);
if(rsWebUi->isRunning())
ui.statusLabelLED->setPixmap(FilesDefs::getPixmapFromQtResourcePath(IMAGE_LEDON)) ;
else
ui.statusLabelLED->setPixmap(FilesDefs::getPixmapFromQtResourcePath(IMAGE_LEDOFF)) ;
#else
ui.statusLabelLED->setPixmap(FilesDefs::getPixmapFromQtResourcePath(IMAGE_LEDOFF)) ;
#endif #endif
} }
@ -138,11 +166,9 @@ QString WebuiPage::helpText() const
<p>Warning: don't expose the webinterface to the internet, because there is no access control and no encryption. If you want to use the webinterface over the internet, use a SSH tunnel or a proxy to secure the connection.</p>"); <p>Warning: don't expose the webinterface to the internet, because there is no access control and no encryption. If you want to use the webinterface over the internet, use a SSH tunnel or a proxy to secure the connection.</p>");
} }
/*static*/ bool WebuiPage::checkStartWebui() /*static*/ bool WebuiPage::checkStartWebui() // This is supposed to be called from main(). But normally the parameters below (including the paswd
// for the webUI should be saved in p3webui instead.
{ {
if(!Settings->getWebinterfaceEnabled())
return false;
rsWebUi->setHtmlFilesDirectory(Settings->getWebinterfaceFilesDirectory().toStdString()); rsWebUi->setHtmlFilesDirectory(Settings->getWebinterfaceFilesDirectory().toStdString());
rsWebUi->restart(); rsWebUi->restart();
@ -173,15 +199,21 @@ QString WebuiPage::helpText() const
void WebuiPage::onEnableCBClicked(bool checked) void WebuiPage::onEnableCBClicked(bool checked)
{ {
ui.params_GB->setEnabled(checked); QString errmsg;
ui.apply_PB->setEnabled(checked); updateParams(errmsg);
ui.startWebBrowser_PB->setEnabled(checked);
QString S;
Settings->setWebinterfaceEnabled(checked); ui.params_GB->setEnabled(checked);
ui.startWebBrowser_PB->setEnabled(checked);
ui.apply_PB->setEnabled(checked);
if(checked) if(checked)
checkStartWebui(); {
if(!restart())
{
QMessageBox::warning(0, tr("failed to start Webinterface"), "Failed to start the webinterface.");
return;
}
}
else else
checkShutdownWebui(); checkShutdownWebui();
} }
@ -199,18 +231,12 @@ void WebuiPage::onAllIPCBClicked(bool /*checked*/)
} }
void WebuiPage::onApplyClicked() void WebuiPage::onApplyClicked()
{ {
rsWebUi->setUserPassword(ui.password_LE->text().toStdString());
QString errmsg; QString errmsg;
updateParams(errmsg); updateParams(errmsg);
if(!restart()) restart();
{
QMessageBox::warning(0, tr("failed to start Webinterface"), "Failed to start the webinterface.");
return;
}
emit passwordChanged(); load();
} }
void WebuiPage::onStartWebBrowserClicked() { showWebui(); } void WebuiPage::onStartWebBrowserClicked() { showWebui(); }

View file

@ -20,6 +20,8 @@
#pragma once #pragma once
#include "retroshare/rsevents.h"
#include "retroshare-gui/configpage.h" #include "retroshare-gui/configpage.h"
#include "gui/common/FilesDefs.h" #include "gui/common/FilesDefs.h"
#include "ui_WebuiPage.h" #include "ui_WebuiPage.h"
@ -42,11 +44,11 @@ public:
~WebuiPage(); ~WebuiPage();
/** Loads the settings for this page */ /** Loads the settings for this page */
virtual void load(); virtual void load() override { loadParams() ; }
virtual QPixmap iconPixmap() const { return FilesDefs::getPixmapFromQtResourcePath(":/icons/settings/webinterface.svg") ; } virtual QPixmap iconPixmap() const override { return FilesDefs::getPixmapFromQtResourcePath(":/icons/settings/webinterface.svg") ; }
virtual QString pageName() const { return tr("Webinterface") ; } virtual QString pageName() const override { return tr("Webinterface") ; }
virtual QString helpText() const; virtual QString helpText() const override ;
// call this after start of libretroshare/Retroshare // call this after start of libretroshare/Retroshare
// checks the settings and starts the webinterface if required // checks the settings and starts the webinterface if required
@ -67,10 +69,9 @@ public slots:
void onApplyClicked(); void onApplyClicked();
void onStartWebBrowserClicked(); void onStartWebBrowserClicked();
signals:
void passwordChanged();
private: private:
virtual void loadParams();
/** Qt Designer generated object */ /** Qt Designer generated object */
Ui::WebuiPage ui; Ui::WebuiPage ui;
@ -83,4 +84,6 @@ private:
static resource_api::ApiServerLocal* apiServerLocal; static resource_api::ApiServerLocal* apiServerLocal;
#endif #endif
static resource_api::RsControlModule* controlModule; static resource_api::RsControlModule* controlModule;
RsEventsHandlerId_t mEventsHandlerId;
}; };

View file

@ -6,14 +6,16 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>960</width> <width>570</width>
<height>717</height> <height>646</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="QCheckBox" name="enableWebUI_CB"> <widget class="QCheckBox" name="enableWebUI_CB">
<property name="text"> <property name="text">
@ -21,6 +23,38 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Status:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="statusLabelLED">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/ledoff1.png</pixmap>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<widget class="QGroupBox" name="params_GB"> <widget class="QGroupBox" name="params_GB">
<property name="enabled"> <property name="enabled">

View file

@ -178,10 +178,7 @@ SettingsPage::initStackedWidget()
JsonApiPage *jsonapi_p = new JsonApiPage() ; JsonApiPage *jsonapi_p = new JsonApiPage() ;
addPage(jsonapi_p); addPage(jsonapi_p);
#ifdef RS_WEBUI #ifdef RS_WEBUI
WebuiPage *webui_p = new WebuiPage() ;
addPage(new WebuiPage()); addPage(new WebuiPage());
QObject::connect(webui_p,SIGNAL(passwordChanged()),jsonapi_p,SLOT(load()));
#endif #endif
#endif #endif

View file

@ -22,6 +22,7 @@
#include "util/stacktrace.h" #include "util/stacktrace.h"
#include "util/argstream.h" #include "util/argstream.h"
#include "retroshare/rswebui.h"
CrashStackTrace gCrashStackTrace; CrashStackTrace gCrashStackTrace;
@ -380,7 +381,7 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
return 1; return 1;
} }
/* recreate global settings object, now with correct path */ /* recreate global settings object, now with correct path, specific to the selected node */
RshareSettings::Create(true); RshareSettings::Create(true);
Rshare::resetLanguageAndStyle(); Rshare::resetLanguageAndStyle();
@ -537,8 +538,9 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
// //
qRegisterMetaType<RsPeerId>("RsPeerId") ; qRegisterMetaType<RsPeerId>("RsPeerId") ;
#ifdef DEBUG
std::cerr << "connecting signals and slots" << std::endl ; std::cerr << "connecting signals and slots" << std::endl ;
#endif
QObject::connect(notify,SIGNAL(deferredSignatureHandlingRequested()),notify,SLOT(handleSignatureEvent()),Qt::QueuedConnection) ; QObject::connect(notify,SIGNAL(deferredSignatureHandlingRequested()),notify,SLOT(handleSignatureEvent()),Qt::QueuedConnection) ;
QObject::connect(notify,SIGNAL(chatLobbyTimeShift(int)),notify,SLOT(handleChatLobbyTimeShift(int)),Qt::QueuedConnection) ; QObject::connect(notify,SIGNAL(chatLobbyTimeShift(int)),notify,SLOT(handleChatLobbyTimeShift(int)),Qt::QueuedConnection) ;
QObject::connect(notify,SIGNAL(diskFull(int,int)) ,w ,SLOT(displayDiskSpaceWarning(int,int))) ; QObject::connect(notify,SIGNAL(diskFull(int,int)) ,w ,SLOT(displayDiskSpaceWarning(int,int))) ;
@ -571,13 +573,18 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
notify->enable() ; // enable notification system after GUI creation, to avoid data races in Qt. notify->enable() ; // enable notification system after GUI creation, to avoid data races in Qt.
#ifdef RS_JSONAPI // Read webui params in settings. We cannot save them to some webui.cfg because cfg needs the node id and
JsonApiPage::checkStartJsonApi(); // jsonapi is started before node ID selection in retroshare-service.
#ifdef RS_JSONAPI
#ifdef RS_WEBUI #ifdef RS_WEBUI
WebuiPage::checkStartWebui(); // normally we should rather save the UI flags internally to p3webui conf.enableWebUI = Settings->getWebinterfaceEnabled();
if(!Settings->getWebinterfaceFilesDirectory().isNull())
rsWebUi->setHtmlFilesDirectory(Settings->getWebinterfaceFilesDirectory().toStdString());
#endif
RsInit::startupWebServices(conf,false);
#endif #endif
#endif // RS_JSONAPI
/* dive into the endless loop */ /* dive into the endless loop */
int ti = rshare.exec(); int ti = rshare.exec();

View file

@ -184,3 +184,9 @@ QLabel#label_masthead{
border: 2px solid #CCCCCC; border: 2px solid #CCCCCC;
border-radius: 4px; border-radius: 4px;
} }
PulseReplySeperator QFrame#frame {
border: 2px solid #CCCCCC;
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC);
border-radius: 10px}
}

View file

@ -139,17 +139,22 @@ static bool notifyRunningInstance()
// that a new process had been started // that a new process had been started
QLocalSocket localSocket; QLocalSocket localSocket;
localSocket.connectToServer(QString(TARGET)); localSocket.connectToServer(QString(TARGET));
#ifdef DEBUG
std::cerr << "Rshare::Rshare waitForConnected to other instance." << std::endl; std::cerr << "Rshare::Rshare waitForConnected to other instance." << std::endl;
#endif
if( localSocket.waitForConnected(100) ) if( localSocket.waitForConnected(100) )
{ {
#ifdef DEBUG
std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl; std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl;
#endif
localSocket.waitForDisconnected(1000); localSocket.waitForDisconnected(1000);
return true; return true;
} }
else else
{ {
#ifdef DEBUG
std::cerr << "Rshare::Rshare failed to connect to other instance." << std::endl; std::cerr << "Rshare::Rshare failed to connect to other instance." << std::endl;
#endif
return false; return false;
} }
} }

View file

@ -95,7 +95,7 @@ if(EXISTS "${LIBRETROSHARE_DEVEL_DIR}/CMakeLists.txt" )
else() else()
FetchContent_Declare( FetchContent_Declare(
libretroshare libretroshare
GIT_REPOSITORY "https://gitlab.com/RetroShare/libretroshare.git" GIT_REPOSITORY "https://github.com/RetroShare/libretroshare.git"
GIT_TAG "origin/master" GIT_TAG "origin/master"
GIT_SHALLOW TRUE GIT_SHALLOW TRUE
GIT_PROGRESS TRUE GIT_PROGRESS TRUE
@ -116,15 +116,17 @@ if(RS_SERVICE_DESKTOP)
install( install(
FILES data/retroshare-service_48x48.png FILES data/retroshare-service_48x48.png
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps/retroshare-service.png ) DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps/
RENAME retroshare-service.png)
install( install(
FILES data/retroshare-service_128x128.png FILES data/retroshare-service_128x128.png
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/128x128/apps/retroshare-service.png ) DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/128x128/apps/
RENAME retroshare-service.png )
install( install(
FILES data/retroshare-service.desktop FILES data/retroshare-service.desktop
DESTINATION ${CMAKE_INSTALL_PREFIX}/data/retroshare-service.desktop ) DESTINATION ${CMAKE_INSTALL_PREFIX}/data/ )
endif(UNIX AND NOT APPLE) endif(UNIX AND NOT APPLE)
endif(RS_SERVICE_DESKTOP) endif(RS_SERVICE_DESKTOP)
@ -149,7 +151,7 @@ if(RS_WEBUI)
else() else()
FetchContent_Declare( FetchContent_Declare(
webui webui
GIT_REPOSITORY "https://gitlab.com/RetroShare/RetroShareWebUI.git" GIT_REPOSITORY "https://github.com/RetroShare/RSNewWebUI.git"
GIT_TAG "origin/master" GIT_TAG "origin/master"
GIT_SHALLOW TRUE GIT_SHALLOW TRUE
GIT_PROGRESS TRUE GIT_PROGRESS TRUE

View file

@ -33,6 +33,7 @@
#include "retroshare/rsiface.h" #include "retroshare/rsiface.h"
#include "util/stacktrace.h" #include "util/stacktrace.h"
#include "util/rsprint.h"
#include "util/argstream.h" #include "util/argstream.h"
#include "util/rskbdinput.h" #include "util/rskbdinput.h"
#include "util/rsdir.h" #include "util/rsdir.h"
@ -48,6 +49,28 @@
static CrashStackTrace gCrashStackTrace; static CrashStackTrace gCrashStackTrace;
// We should move these functions to rsprint in libretroshare
#define COLOR_GREEN 0
#define COLOR_YELLOW 1
#define COLOR_BLUE 2
#define COLOR_PURPLE 3
#define COLOR_RED 4
std::string colored(int color,const std::string& s)
{
switch(color)
{
case COLOR_GREEN : return "\033[0;32m"+s+"\033[0m";
case COLOR_YELLOW: return "\033[0;33m"+s+"\033[0m";
case COLOR_BLUE : return "\033[0;36m"+s+"\033[0m";
case COLOR_PURPLE: return "\033[0;35m"+s+"\033[0m";
case COLOR_RED : return "\033[0;31m"+s+"\033[0m";
default:
return s;
}
}
#ifdef RS_SERVICE_TERMINAL_LOGIN #ifdef RS_SERVICE_TERMINAL_LOGIN
class RsServiceNotify: public NotifyClient class RsServiceNotify: public NotifyClient
{ {
@ -59,9 +82,7 @@ public:
const std::string& title, const std::string& question, const std::string& title, const std::string& question,
bool /*prev_is_bad*/, std::string& password, bool& cancel ) bool /*prev_is_bad*/, std::string& password, bool& cancel )
{ {
std::string question1 = title + std::string question1 = title + colored(COLOR_GREEN,"Please enter your PGP password for key:\n ") + question + " :";
"\nPlease enter your PGP password for key:\n " +
question + " :";
password = RsUtil::rs_getpass(question1.c_str()) ; password = RsUtil::rs_getpass(question1.c_str()) ;
cancel = false ; cancel = false ;
@ -90,6 +111,33 @@ int main(int argc, char* argv[])
signal(SIGBREAK, signalHandler); signal(SIGBREAK, signalHandler);
#endif // ifdef SIGBREAK #endif // ifdef SIGBREAK
#ifdef WINDOWS_SYS
// Enable ANSI color support in Windows console
{
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4
#endif
HANDLE hStdin = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdin) {
DWORD consoleMode;
if (GetConsoleMode(hStdin, &consoleMode)) {
if ((consoleMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0) {
if (SetConsoleMode(hStdin, consoleMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
std::cout << "Enabled ANSI color support in console" << std::endl;
} else {
RsErr() << "Error getting console mode" << std::endl;
}
}
} else {
RsErr() << "Error getting console mode" << std::endl;
}
} else {
RsErr() << "Error getting stdin handle" << std::endl;
}
}
#endif
RsInfo() << "\n" << RsInfo() << "\n" <<
"+================================================================+\n" "+================================================================+\n"
"| o---o o |\n" "| o---o o |\n"
@ -181,31 +229,45 @@ int main(int argc, char* argv[])
while(keepRunning) while(keepRunning)
{ {
webui_pass1 = RsUtil::rs_getpass( webui_pass1 = RsUtil::rs_getpass( colored(COLOR_GREEN,"Please register a password for the web interface: "));
"Please register a password for the web interface: " ); webui_pass2 = RsUtil::rs_getpass( colored(COLOR_GREEN,"Please enter the same password again : "));
webui_pass2 = RsUtil::rs_getpass(
"Please enter the same password again : " );
if(webui_pass1 != webui_pass2) if(webui_pass1 != webui_pass2)
{ {
std::cout << "Passwords do not match!" << std::endl; std::cout << colored(COLOR_RED,"Passwords do not match!") << std::endl;
continue; continue;
} }
if(webui_pass1.empty()) if(webui_pass1.empty())
{ {
std::cout << "Password cannot be empty!" << std::endl; std::cout << colored(COLOR_RED,"Password cannot be empty!") << std::endl;
continue; continue;
} }
break; break;
} }
} }
#ifdef RS_SERVICE_TERMINAL_WEBUI_PASSWORD
if(askWebUiPassword && !webui_pass1.empty())
{
rsWebUi->setHtmlFilesDirectory(webui_base_directory);
conf.webUIPasswd = webui_pass1; // cannot be set using rsWebUI methods because it calls the still non-existent rsJsonApi
conf.enableWebUI = true;
// JsonApi is started below in InitRetroShare(). Not calling restart here avoids multiple restart.
}
#endif
#endif /* defined(RS_JSONAPI) && defined(RS_WEBUI) #endif /* defined(RS_JSONAPI) && defined(RS_WEBUI)
&& defined(RS_SERVICE_TERMINAL_WEBUI_PASSWORD) */ && defined(RS_SERVICE_TERMINAL_WEBUI_PASSWORD) */
conf.main_executable_path = argv[0]; conf.main_executable_path = argv[0];
int initResult = RsInit::InitRetroShare(conf); int initResult = RsInit::InitRetroShare(conf);
#ifdef RS_JSONAPI
RsInit::startupWebServices(conf,true);
rstime::rs_usleep(1000000); // waits for jas->restart to print stuff
#endif
if(initResult != RS_INIT_OK) if(initResult != RS_INIT_OK)
{ {
RsFatal() << "Retroshare core initalization failed with: " << initResult RsFatal() << "Retroshare core initalization failed with: " << initResult
@ -223,28 +285,27 @@ int main(int argc, char* argv[])
if(locations.size() == 0) if(locations.size() == 0)
{ {
RsErr() << "No available accounts. You cannot use option -U list" << std::endl; RsErr() << colored(COLOR_RED,"No available accounts. You cannot use option -U list") << std::endl;
return -RsInit::ERR_NO_AVAILABLE_ACCOUNT; return -RsInit::ERR_NO_AVAILABLE_ACCOUNT;
} }
std::cout << std::endl << std::endl std::cout << std::endl << std::endl
<< "Available accounts:" << std::endl; << colored(COLOR_GREEN,"Available accounts:") << std::endl<<std::endl;
int accountCountDigits = static_cast<int>( ceil(log(locations.size())/log(10.0)) ); int accountCountDigits = static_cast<int>( ceil(log(locations.size())/log(10.0)) );
for( uint32_t i=0; i<locations.size(); ++i ) for( uint32_t i=0; i<locations.size(); ++i )
std::cout << "[" << std::setw(accountCountDigits) std::cout << colored(COLOR_GREEN," [" + RsUtil::NumberToString(i+1,false,'0',accountCountDigits)+"]") << " "
<< std::setfill('0') << i+1 << "] " << colored(COLOR_YELLOW,locations[i].mLocationId.toStdString())<< " "
<< locations[i].mLocationId << " (" << colored(COLOR_BLUE,"(" + locations[i].mPgpId.toStdString()+ "): ")
<< locations[i].mPgpId << "): " << colored(COLOR_PURPLE,locations[i].mPgpName + " (" + locations[i].mLocationName + ")" )
<< locations[i].mPgpName
<< " \t (" << locations[i].mLocationName << ")"
<< std::endl; << std::endl;
std::cout << std::endl;
uint32_t nacc = 0; uint32_t nacc = 0;
while(keepRunning && (nacc < 1 || nacc >= locations.size())) while(keepRunning && (nacc < 1 || nacc >= locations.size()))
{ {
std::cout << "Please enter account number: "; std::cout << colored(COLOR_GREEN,"Please enter account number: ");
std::cout.flush(); std::cout.flush();
std::string inputStr; std::string inputStr;
@ -264,7 +325,7 @@ int main(int argc, char* argv[])
RsPeerId ssl_id(prefUserString); RsPeerId ssl_id(prefUserString);
if(ssl_id.isNull()) if(ssl_id.isNull())
{ {
RsErr() << "Invalid User location id: a hexadecimal ID is expected." RsErr() << colored(COLOR_RED,"Invalid User location id: a hexadecimal ID is expected.")
<< std::endl; << std::endl;
return -EINVAL; return -EINVAL;
} }
@ -299,7 +360,7 @@ int main(int argc, char* argv[])
if(RsAccounts::isTorAuto()) if(RsAccounts::isTorAuto())
{ {
std::cerr << "(II) Hidden service is ready:" << std::endl; std::cerr << colored(COLOR_GREEN,"(II) Hidden service is ready:") << std::endl;
std::string service_id ; std::string service_id ;
std::string onion_address ; std::string onion_address ;
@ -312,13 +373,13 @@ int main(int argc, char* argv[])
RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port);
RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ; RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ;
std::cerr << " onion address : " << onion_address << std::endl; std::cerr << colored(COLOR_GREEN," onion address : ") << onion_address << std::endl;
std::cerr << " service_id : " << service_id << std::endl; std::cerr << colored(COLOR_GREEN," service_id : ") << service_id << std::endl;
std::cerr << " service port : " << service_port << std::endl; std::cerr << colored(COLOR_GREEN," service port : ") << service_port << std::endl;
std::cerr << " target port : " << service_target_port << std::endl; std::cerr << colored(COLOR_GREEN," target port : ") << service_target_port << std::endl;
std::cerr << " target address : " << service_target_address << std::endl; std::cerr << colored(COLOR_GREEN," target address : ") << service_target_address << std::endl;
std::cerr << "Setting proxy server to " << service_target_address << ":" << service_target_port << std::endl; std::cerr << colored(COLOR_GREEN,"Setting proxy server to ") << service_target_address << ":" << service_target_port << std::endl;
rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port); rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port);
rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port); rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port);
@ -327,15 +388,6 @@ int main(int argc, char* argv[])
} }
#endif // def RS_SERVICE_TERMINAL_LOGIN #endif // def RS_SERVICE_TERMINAL_LOGIN
#if (defined(RS_JSONAPI) && defined(RS_WEBUI)) && defined(RS_SERVICE_TERMINAL_WEBUI_PASSWORD)
if(rsJsonApi && !webui_pass1.empty())
{
rsWebUi->setHtmlFilesDirectory(webui_base_directory);
rsWebUi->setUserPassword(webui_pass1);
rsWebUi->restart();
}
#endif
rsControl->setShutdownCallback([&](int){keepRunning = false;}); rsControl->setShutdownCallback([&](int){keepRunning = false;});
while(keepRunning) while(keepRunning)

@ -1 +1 @@
Subproject commit b0ddb09184e8fff86bd3325e00c6d4b329ae1790 Subproject commit dae0c13ef78aee59a4f1f9e1cdb0127b5e27d256

View file

@ -52,9 +52,9 @@ CONFIG *= retroshare_service
no_retroshare_service:CONFIG -= retroshare_service no_retroshare_service:CONFIG -= retroshare_service
# To disable RetroShare FriendServer append the following assignation to # To disable RetroShare FriendServer append the following assignation to
# qmake command line "CONFIG+=no_rs_friendserver" # qmake command line "CONFIG+=no_retroshare_friendserver"
CONFIG *= retroshare_friendserver CONFIG *= retroshare_friendserver
no_rs_friendserver:CONFIG -= retroshare_friendserver no_retroshare_friendserver:CONFIG -= retroshare_friendserver
# To disable SQLCipher support append the following assignation to qmake # To disable SQLCipher support append the following assignation to qmake
# command line "CONFIG+=no_sqlcipher" # command line "CONFIG+=no_sqlcipher"
@ -456,13 +456,26 @@ defined in command line")
RS_MINOR_VERSION = $$member(RS_GIT_DESCRIBE_SPLIT, 1) RS_MINOR_VERSION = $$member(RS_GIT_DESCRIBE_SPLIT, 1)
RS_GIT_DESCRIBE_SPLIT = $$member(RS_GIT_DESCRIBE_SPLIT, 2) RS_GIT_DESCRIBE_SPLIT = $$member(RS_GIT_DESCRIBE_SPLIT, 2)
RS_GIT_DESCRIBE_SPLIT = $$split(RS_GIT_DESCRIBE_SPLIT, -) RS_GIT_DESCRIBE_SPLIT = $$split(RS_GIT_DESCRIBE_SPLIT, )
RS_MINI_VERSION = $$member(RS_GIT_DESCRIBE_SPLIT, 0) # Split string into mini version (leading numbers) and extra version (string after the numbers)
RS_MINI_VERSION =
RS_GIT_DESCRIBE_SPLIT = $$member(RS_GIT_DESCRIBE_SPLIT, 1, -1) RS_EXTRA_VERSION =
for(CHAR, RS_GIT_DESCRIBE_SPLIT) {
RS_EXTRA_VERSION = $$join(RS_GIT_DESCRIBE_SPLIT,-,-) isEqual(CHAR, 0) | greaterThan(CHAR, 0):lessThan(CHAR, 9) | isEqual(CHAR, 9) {
# Number
isEmpty(RS_EXTRA_VERSION) {
# Add leading numbers to mini version
RS_MINI_VERSION = $${RS_MINI_VERSION}$${CHAR}
} else {
# Add to extra version
RS_EXTRA_VERSION = $${RS_EXTRA_VERSION}$${CHAR}
}
} else {
# Add to extra version
RS_EXTRA_VERSION = $${RS_EXTRA_VERSION}$${CHAR}
}
}
message("RetroShare version\ message("RetroShare version\
$${RS_MAJOR_VERSION}.$${RS_MINOR_VERSION}.$${RS_MINI_VERSION}$${RS_EXTRA_VERSION}\ $${RS_MAJOR_VERSION}.$${RS_MINOR_VERSION}.$${RS_MINI_VERSION}$${RS_EXTRA_VERSION}\

@ -1 +1 @@
Subproject commit 8623304b62294dafbe477573f321a464fef721dd Subproject commit 2226ef0a20a001ec0942be6abe5e909c15447d8e