Compare commits

..

No commits in common. "master" and "v0.6.7-RC1" have entirely different histories.

271 changed files with 70013 additions and 61025 deletions

2
.gitignore vendored
View file

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

View file

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

12
.gitmodules vendored
View file

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

View file

@ -7,9 +7,6 @@ RetroShare is a decentralized, private, secure, cross-platform, communication
toolkit.
RetroShare provides file sharing, chat, messages, forums, channels and more.
|===============================================================================
| Developer Documentation | image:https://deepwiki.com/badge.svg[link="https://deepwiki.com/RetroShare/RetroShare",title="Ask DeepWiki"]
|===============================================================================
.Build Status
|===============================================================================
|GNU/Linux (via Gitlab CI) | image:https://gitlab.com/RetroShare/RetroShare/badges/master/pipeline.svg[link="https://gitlab.com/RetroShare/RetroShare/-/commits/master",title="pipeline status"]

View file

@ -25,6 +25,9 @@ CONFIG += c++14
TEMPLATE = subdirs
SUBDIRS += openpgpsdk
openpgpsdk.file = openpgpsdk/src/openpgpsdk.pro
rs_jsonapi:isEmpty(JSONAPI_GENERATOR_EXE) {
SUBDIRS += jsonapi-generator
jsonapi-generator.file = jsonapi-generator/src/jsonapi-generator.pro
@ -33,7 +36,7 @@ rs_jsonapi:isEmpty(JSONAPI_GENERATOR_EXE) {
SUBDIRS += libbitdht
libbitdht.file = libbitdht/src/libbitdht.pro
libretroshare.depends += libbitdht
libretroshare.depends += openpgpsdk libbitdht
SUBDIRS += libretroshare
libretroshare.file = libretroshare/src/libretroshare.pro

View file

@ -40,23 +40,18 @@ RUN git clone --depth 1 https://github.com/aetilius/pHash.git && \
rm -rf pHash-build pHash
ARG FRESHCLONE=0
ARG REPO_URL=https://github.com/RetroShare/RetroShare.git
ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git
ARG REPO_BRANCH=master
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 submodule update --init \
libbitdht/ libretroshare/ openpgpsdk/ retroshare-webui/ \
supportlibs/restbed/ && \
cd supportlibs/restbed/ && \
git submodule update --init \
dependency/asio/ dependency/kashmir/ && \
cd ../../../
git submodule update --init --remote --force \
libbitdht/ libretroshare/ openpgpsdk/ && \
cd ..
RUN \
mkdir RetroShare-build && cd RetroShare-build && \
cmake -B. -S../RetroShare/retroshare-service \
-DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON -DRS_WEBUI=ON && \
-DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON && \
make -j$(nproc) && make install && \
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
ARG REPO_URL=https://github.com/RetroShare/RetroShare.git
ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git
ARG REPO_BRANCH=master
RUN \
cd RetroShare && git remote add testing $REPO_URL && \
git fetch --tags testing $REPO_BRANCH && \
git reset --hard testing/$REPO_BRANCH && \
git submodule update --init \
libbitdht/ libretroshare/ openpgpsdk/ retroshare-webui/ && \
git submodule update --init --remote --force \
libbitdht/ libretroshare/ openpgpsdk/ && \
git --no-pager log --max-count 1
RUN \
mkdir RetroShare-build && cd RetroShare-build && \
cmake -B. -S../RetroShare/retroshare-service \
-DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON -DRS_WEBUI=ON \
-DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON \
-DRS_WARN_DEPRECATED=OFF -DRS_WARN_LESS=ON && \
make -j$(nproc) && make install && \
cd .. && rm -rf RetroShare-build

@ -1 +1 @@
Subproject commit 0a3997cc1355b2c848161dca015b7e2df039707b
Subproject commit df16cb915465d058c75277678799ce4dadeae287

View file

@ -2,15 +2,13 @@
## Qt Installation
Qt 5.15 is not available as install package.
Install Qt via: [Qt Download](http://www.qt.io/download/)
Download Qt 5.15.x from here: [Qt 5.15.17](https://download.qt.io/archive/qt/5.15/5.15.17/single/qt-everywhere-opensource-src-5.15.17.tar.xz)
Use default options. And add Qt Script support.
Instruction howto Build Qt 5.15.x on macOS: [macOS Building](https://doc.qt.io/archives/qt-5.15/macos-building.html)
## Set the Environment Variables
Add to the PATH environment variable by editing your *~/.profile* file.
export PATH="/users/$USER/Qt/5.15.17/clang_64/bin:$PATH"
export PATH="/users/$USER/Qt/5.14.1/clang_64/bin:$PATH"
Depends on which version of Qt you use.
@ -32,20 +30,32 @@ In GitHub Desktop -> Clone Repository -> URL
Add Repository URL: https://github.com/RetroShare/RetroShare.git and Clone
## ***Get XCode & MacOSX SDK***
## ***Choose if you use MacPort or HomeBrew***
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.
### MacPort Installation
If you are running macOS Ventura 13.5 or later, you can install Xcode directly from App Store using the instructions below.
Install MacPort and XCode following this guide: [MacPort and XCode](http://guide.macports.org/#installing.xcode)
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
Start XCode to get it updated and to able C compiler to create executables.
To install from App Store:
#### Install libraries
Select [x] menu - > "App Store…".
Search for Xcode. Download and install.
$ sudo port -v selfupdate
$ sudo port install openssl
$ sudo port install miniupnpc
$ sudo port install libmicrohttpd
For VOIP Plugin:
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.
$ sudo port install speex-devel
$ sudo port install opencv
$ sudo port install ffmpeg
Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs)
### HOMEBREW Installation
Install HomeBrew following this guide: [HomeBrew](http://brew.sh/)
Install XCode command line developer tools:
@ -53,33 +63,13 @@ Install XCode command line developer tools:
Start XCode to get it updated and to able C compiler to create executables.
Older MacOSX SDK is available from here: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs)
### MacPort Installation
Install MacPort following this guide: [MacPort](http://guide.macports.org/#installing.xcode)
### HOMEBREW Installation
Install HomeBrew following this guide: [HomeBrew](http://brew.sh/)
#### Install libraries
$ brew install openssl
$ brew install miniupnpc
$ brew install libmicrohttpd
$ brew install rapidjson
$ brew install sqlcipher
For RNP lib:
$ brew install bzip2
$ brew install zlib
$ brew install json-c
$ brew install botan@2
#### Install CMake
$ brew install cmake
If you have error in linking, run this:
@ -95,7 +85,8 @@ For VOIP Plugin:
For FeedReader Plugin:
$ brew install libxslt
$ brew install libxml2
Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs)
## Last Settings
@ -113,8 +104,11 @@ In QtCreator Projects -> Build -> Build Settings -> Build Steps -> Add Additiona
## Set your Mac OS SDK version
Edit RetroShare.pro
Edit retroshare.pri and set your installed sdk version example for 11.1 -> rs_macos11.1 (line 135:)
CONFIG += c++14 rs_macos11.1
and then retroshare.pri
macx:CONFIG *= rs_macos11.1
rs_macos10.8:CONFIG -= rs_macos11.1
@ -128,7 +122,7 @@ Edit retroshare.pri and set your installed sdk version example for 11.1 -> rs_ma
## Link Include & Libraries
When required edit your retroshare.pri macx-* section, check if the Include and Lib path are correct (macx-* section)
Edit your retroshare.pri and add to macx-* section
INCLUDEPATH += "/usr/local/opt/openssl/include"
QMAKE_LIBDIR += "/usr/local/opt/openssl/lib"
@ -137,21 +131,13 @@ When required edit your retroshare.pri macx-* section, check if the Include and
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" \
CONFIG+=rs_autologin \
CONFIG+=rs_use_native_dialogs \
CONFIG+=release \
..
$ 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"
For FeedReader Plugin:
INCLUDEPATH += "/usr/local/opt/libxml2/include/libxml2"
With plugins:
For building RetroShare with plugins:
$ qmake \
INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" \
@ -173,30 +159,13 @@ With plugins:
You can now compile RetroShare into Qt Creator or with Terminal
$ cd /path/to/retroshare
$ qmake ..
$ make
cd retroshare
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 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
$ cp \
@ -204,13 +173,3 @@ For Qt Creator -> QtCreator Projects -> Build -> Build Settings -> Build Steps -
./plugins/VOIP/lib/libVOIP.dylib \
./plugins/RetroChess/lib/libRetroChess.dylib \
./retroshare-gui/src/RetroShare.app/Contents/Resources/
### Compile Retroshare-Service & Webui with CMake
before you can compile overwrite the file "asio/include/asio/detail/config.hpp" here is a fix for macos [
asio fix](https://github.com/chriskohlhoff/asio/commit/68df16d560c68944809bb2947360fe8035e9ae0a)
$ cd retroshare-service
$ mkdir build-dir
$ cd build-dir
$ cmake -DRS_WEBUI=ON -DCMAKE_BUILD_TYPE=Release ..
$ make

View file

@ -1,51 +0,0 @@
#!/bin/sh
APP="RetroShare"
RSVERSION="0.6.7a"
QTVERSION="Qt-5.15.11"
# 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
/usr/libexec/PlistBuddy -c "Delete :NSRequiresAquaSystemAppearance" 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

@ -1,11 +1,10 @@
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Name=RetroShare
Comment=Securely communicate with your friends
Comment=Securely share files with your friends
Exec=/usr/bin/retroshare %U
Icon=/usr/share/pixmaps/retroshare.xpm
Terminal=false
Type=Application
Categories=Network;Email;InstantMessaging;Chat;Feed;FileTransfer;P2P
Categories=Network;P2P;
MimeType=x-scheme-handler/retroshare;

View file

@ -18,8 +18,6 @@ if errorlevel 1 goto error_env
if not "%ParamNoupdate%"=="1" (
:: Install needed things
%EnvMSYS2Cmd% "pacman --noconfirm --needed -S make git mingw-w64-%RsMSYS2Architecture%-toolchain mingw-w64-%RsMSYS2Architecture%-qt5 mingw-w64-%RsMSYS2Architecture%-miniupnpc mingw-w64-%RsMSYS2Architecture%-sqlcipher mingw-w64-%RsMSYS2Architecture%-cmake mingw-w64-%RsMSYS2Architecture%-rapidjson"
:: rnp
%EnvMSYS2Cmd% "pacman --noconfirm --needed -S mingw-w64-%RsMSYS2Architecture%-json-c mingw-w64-%RsMSYS2Architecture%-libbotan"
:: Webui
if "%ParamWebui%"=="1" %EnvMSYS2Cmd% "pacman --noconfirm --needed -S mingw-w64-%RsMSYS2Architecture%-doxygen"

View file

@ -105,7 +105,6 @@ copy "%RsBuildPath%\retroshare-nogui\src\%RsBuildConfig%\retroshare*-nogui.exe"
copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite%
copy "%RsBuildPath%\supportlibs\cmark\build\src\libcmark.dll" "%RsDeployPath%" %Quite%
if exist "%RsBuildPath%\libretroshare\src\lib\retroshare.dll" copy "%RsBuildPath%\libretroshare\src\lib\retroshare.dll" "%RsDeployPath%" %Quite%
if exist "%RsBuildPath%\supportlibs\librnp\Build\src\lib\librnp.dll" copy "%RsBuildPath%\supportlibs\librnp\Build\src\lib\librnp.dll" "%RsDeployPath%" %Quite%
if exist "%RsBuildPath%\retroshare-friendserver\src\%RsBuildConfig%\retroshare-friendserver.exe" (
copy "%RsBuildPath%\retroshare-friendserver\src\%RsBuildConfig%\retroshare-friendserver.exe" "%RsDeployPath%" %Quite%
)

View file

@ -16,13 +16,7 @@ if "%~1"=="clean" (
goto exit
)
set MSYS2Version=20241208
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 exist "%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\pacman.exe" (
if "%~1"=="reinstall" (
choice /M "Found existing MSYS2 version. Do you want to proceed?"
if !ERRORLEVEL!==2 goto exit
@ -31,26 +25,30 @@ if exist "%MSYS2UnpackPath%\usr\bin\pacman.exe" (
)
)
if exist "%MSYS2UnpackPath%" (
%cecho% info "Remove previous MSYS2 version"
call "%ToolsPath%\remove-dir.bat" "%MSYS2UnpackPath%"
)
if "%MSYS2Architecture%"=="i686" set MSYS2Version=20210705
if "%MSYS2Architecture%"=="x86_64" set MSYS2Version=20210725
%cecho% info "Download MSYS2 installation files"
set MSYS2Install=msys2-base-%MSYS2Architecture%-%MSYS2Version%.tar.xz
set MSYS2Url=https://repo.msys2.org/distrib/%MSYS2Architecture%/%MSYS2Install%
%cecho% info "Remove previous MSYS2 version"
call "%ToolsPath%\remove-dir.bat" "%EnvMSYS2Path%"
%cecho% info "Download installation files"
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
%cecho% info "Unpack MSYS2"
"%EnvDownloadPath%\%MSYS2Install%" -y -o"%EnvMSYS2Path%"
"%EnvSevenZipExe%" x -so "%EnvDownloadPath%\%MSYS2Install%" | "%EnvSevenZipExe%" x -y -si -ttar -o"%EnvMSYS2Path%"
set MSYS2SH=%MSYS2UnpackPath%\usr\bin\sh
set MSYS2SH=%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\sh
%cecho% info "Initialize MSYS2"
"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring"
"%MSYS2SH%" -lc "pacman --noconfirm -Sy"
"%MSYS2SH%" -lc "pacman --noconfirm -Su"
call "%MSYS2UnpackPath%\autorebase.bat"
call "%EnvMSYS2Path%\msys%MSYS2Base%\autorebase.bat"
:exit
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
echo Unpack cecho
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CEchoInstall%" -y -bso0
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CEchoInstall%"
copy "%EnvTempPath%\cecho.exe" "%EnvToolsPath%"
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"

View file

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

View file

@ -1,7 +1,7 @@
ZLIB_VERSION=1.2.11
BZIP2_VERSION=1.0.8
MINIUPNPC_VERSION=2.2.3
OPENSSL_VERSION=1.1.1w
OPENSSL_VERSION=1.1.1p
SPEEX_VERSION=1.2.0
SPEEXDSP_VERSION=1.2.0
LIBXML2_VERSION=2.9.12
@ -13,18 +13,12 @@ LIBMICROHTTPD_VERSION=0.9.75
FFMPEG_VERSION=4.4
RAPIDJSON_VERSION=1.1.0
XAPIAN_VERSION=1.4.19
#RNP_VERSION=0.17.1
# libaries for rnp
JSON_C_VERSION=0.18
BOTAN_VERSION=2.19.5
DOWNLOAD_PATH?=download
BUILD_PATH=build
LIBS_PATH?=libs
all: dirs zlib bzip2 miniupnpc openssl speex speexdsp libxml2 libxslt curl sqlcipher libmicrohttpd ffmpeg rapidjson xapian jsonc botan copylibs
#rnp
all: dirs zlib bzip2 miniupnpc openssl speex speexdsp libxml2 libxslt curl sqlcipher libmicrohttpd ffmpeg rapidjson xapian copylibs
download: \
$(DOWNLOAD_PATH)/zlib-$(ZLIB_VERSION).tar.gz \
@ -369,57 +363,6 @@ $(BUILD_PATH)/xapian-core-$(XAPIAN_VERSION): $(DOWNLOAD_PATH)/xapian-core-$(XAPI
rm -r -f xapian-core-$(XAPIAN_VERSION)
mv $(BUILD_PATH)/xapian-core-$(XAPIAN_VERSION).tmp $(BUILD_PATH)/xapian-core-$(XAPIAN_VERSION)
jsonc: $(BUILD_PATH)/json-c-$(JSON_C_VERSION)
$(BUILD_PATH)/json-c-$(JSON_C_VERSION):
# prepare
rm -r -f $(BUILD_PATH)/json-c-*
[ -d "json-c-$(JSON_C_VERSION)" ] || git clone https://github.com/json-c/json-c.git --depth=1 --branch json-c-$(JSON_C_VERSION) "json-c-$(JSON_C_VERSION)"
# build
mkdir -p json-c-$(JSON_C_VERSION)/build
cd json-c-$(JSON_C_VERSION)/build && cmake .. -G"MSYS Makefiles" -Wno-dev -DCMAKE_BUILD_TYPE="release" -DBUILD_SHARED_LIBS=off -DBUILD_STATIC_LIBS=on -DBUILD_TESTING=off -DCMAKE_CXX_FLAGS="-D__MINGW_USE_VC2005_COMPAT" -DCMAKE_INSTALL_PREFIX="`pwd`/install" -DCMAKE_INSTALL_PREFIX="`pwd`/../../$(BUILD_PATH)/json-c-$(JSON_C_VERSION).tmp"
cd json-c-$(JSON_C_VERSION)/build && make install
# cleanup
rm -r -f json-c-$(JSON_C_VERSION)
mv $(BUILD_PATH)/json-c-$(JSON_C_VERSION).tmp $(BUILD_PATH)/json-c-$(JSON_C_VERSION)
botan: $(BUILD_PATH)/botan-$(BOTAN_VERSION)
$(BUILD_PATH)/botan-$(BOTAN_VERSION):
# prepare
pacman --needed --noconfirm -S python3
rm -r -f $(BUILD_PATH)/botan-*
[ -d "botan-$(BOTAN_VERSION)" ] || git clone https://github.com/randombit/botan.git --depth=1 --branch $(BOTAN_VERSION) "botan-$(BOTAN_VERSION)"
# build
if [ $(MSYSTEM) = "MINGW32" ] ; then cd botan-$(BOTAN_VERSION) && ./configure.py --os=mingw --cpu=x86_32 --disable-shared-library --enable-static-library --extra-cxxflags="-D__MINGW_USE_VC2005_COMPAT" --prefix="`pwd`/../$(BUILD_PATH)/botan-$(BOTAN_VERSION).tmp" ; fi
if [ $(MSYSTEM) = "MINGW64" ] ; then cd botan-$(BOTAN_VERSION) && ./configure.py --os=mingw --cpu=x86_64 --disable-shared-library --enable-static-library --prefix="`pwd`/../$(BUILD_PATH)/botan-$(BOTAN_VERSION).tmp" ; fi
cd botan-$(BOTAN_VERSION) && make install
# cleanup
rm -r -f botan-$(BOTAN_VERSION)
mv $(BUILD_PATH)/botan-$(BOTAN_VERSION).tmp $(BUILD_PATH)/botan-$(BOTAN_VERSION)
rnp: $(BUILD_PATH)/rnp-$(RNP_VERSION)
$(BUILD_PATH)/rnp-$(RNP_VERSION):
# prepare
rm -r -f $(BUILD_PATH)/rnp-*
[ -d "rnp-$(RNP_VERSION)" ] || git clone https://github.com/rnpgp/rnp.git --depth=1 --branch v$(RNP_VERSION) --recurse-submodules --shallow-submodules "rnp-$(RNP_VERSION)"
# build
mkdir -p rnp-$(RNP_VERSION)/build
cd rnp-$(RNP_VERSION)/build && cmake .. -G"MSYS Makefiles" -Wno-dev -DCMAKE_INSTALL_PREFIX="`pwd`/install" -DBUILD_SHARED_LIBS=yes -DBUILD_TESTING=off -DCMAKE_CXX_FLAGS="-D__MINGW_USE_VC2005_COMPAT -D__STDC_FORMAT_MACROS" -DBZIP2_INCLUDE_DIR="`pwd`/../../$(BUILD_PATH)/bzip2-$(BZIP2_VERSION)/include" -DBZIP2_LIBRARY_RELEASE="`pwd`/../../$(BUILD_PATH)/bzip2-$(BZIP2_VERSION)/lib/libbz2.a" -DBZIP2_LIBRARIES="`pwd`/../../$(BUILD_PATH)/bzip2-$(BZIP2_VERSION)/lib/libbz2.a" -DZLIB_INCLUDE_DIR="`pwd`/../../$(BUILD_PATH)/zlib-$(ZLIB_VERSION)/include" -DZLIB_LIBRARY="`pwd`/../../$(BUILD_PATH)/zlib-$(ZLIB_VERSION)/lib/libz.a" -DJSON-C_INCLUDE_DIR="`pwd`/../../$(BUILD_PATH)/json-c-$(JSON_C_VERSION)/include/json-c" -DJSON-C_LIBRARY="`pwd`/../../$(BUILD_PATH)/json-c-$(JSON_C_VERSION)/lib/libjson-c.a" -DBOTAN_INCLUDE_DIR="`pwd`/../../$(BUILD_PATH)/botan-$(BOTAN_VERSION)/include/botan-`echo $(BOTAN_VERSION) | cut -c1-1`" -DBOTAN_LIBRARY="`pwd`/../../$(BUILD_PATH)/botan-$(BOTAN_VERSION)/lib/libbotan-`echo $(BOTAN_VERSION) | cut -c1-1`.a"
cmake --build rnp-$(RNP_VERSION)/build
# copy files
mkdir -p $(BUILD_PATH)/rnp-$(RNP_VERSION).tmp/include/rnp
cp -r rnp-$(RNP_VERSION)/include/rnp/* $(BUILD_PATH)/rnp-$(RNP_VERSION).tmp/include/rnp/
cp -r rnp-$(RNP_VERSION)/build/src/lib/rnp/* $(BUILD_PATH)/rnp-$(RNP_VERSION).tmp/include/rnp/
mkdir -p $(BUILD_PATH)/rnp-$(RNP_VERSION).tmp/lib
cp -r rnp-$(RNP_VERSION)/build/src/lib/librnp.dll.a $(BUILD_PATH)/rnp-$(RNP_VERSION).tmp/lib/
mkdir -p $(BUILD_PATH)/rnp-$(RNP_VERSION).tmp/bin
cp -r rnp-$(RNP_VERSION)/build/src/lib/librnp.dll $(BUILD_PATH)/rnp-$(RNP_VERSION).tmp/bin/
# cleanup
rm -r -f rnp-$(RNP_VERSION)
mv $(BUILD_PATH)/rnp-$(RNP_VERSION).tmp $(BUILD_PATH)/rnp-$(RNP_VERSION)
copylibs:
rm -r -f $(LIBS_PATH) ; \
mkdir -p $(LIBS_PATH) ; \

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 "%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 "%ParamFriendServer%" NEQ "1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% no_retroshare_friendserver
if "%ParamFriendServer%" NEQ "1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% no_rs_friendserver
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"

View file

@ -96,7 +96,6 @@ copy nul "%RsDeployPath%\portable" %Quite%
echo copy binaries
copy "%RsBuildPath%\retroshare-gui\src\%RsBuildConfig%\retroshare*.exe" "%RsDeployPath%" %Quite%
if exist "%RsBuildPath%\libretroshare\src\lib\retroshare.dll" copy "%RsBuildPath%\libretroshare\src\lib\retroshare.dll" "%RsDeployPath%" %Quite%
if exist "%RsBuildPath%\supportlibs\librnp\Build\src\lib\librnp.dll" copy "%RsBuildPath%\supportlibs\librnp\Build\src\lib\librnp.dll" "%RsDeployPath%" %Quite%
if "%ParamService%"=="1" (
copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite%

View file

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

View file

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

View file

@ -19,9 +19,9 @@ set MinGitInstallPath=%EnvToolsPath%\MinGit
set DoxygenInstall=doxygen-1.9.6.windows.x64.bin.zip
set DoxygenUrl=https://github.com/doxygen/doxygen/releases/download/Release_1_9_6/%DoxygenInstall%
set DoxygenInstallPath=%EnvToolsPath%\doxygen
set CMakeVersion=cmake-3.31.3-windows-i386
set CMakeVersion=cmake-3.19.0-win32-x86
set CMakeInstall=%CMakeVersion%.zip
set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.31.3/%CMakeInstall%
set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.19.0/%CMakeInstall%
set CMakeInstallPath=%EnvToolsPath%\cmake
set TorProjectUrl=https://www.torproject.org
set TorDownloadIndexUrl=%TorProjectUrl%/download/tor
@ -53,7 +53,7 @@ if not exist "%EnvToolsPath%\cecho.exe" (
if not exist "%EnvDownloadPath%\%cCEhoInstall%" echo Cannot download cecho installation& goto error
echo Unpack cecho
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CEchoInstall%" -y -bso0
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CEchoInstall%"
copy "%EnvTempPath%\cecho.exe" "%EnvToolsPath%"
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
%cecho% info "Unpack Dependency Walker"
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%DependsInstall%" -y -bso0
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%DependsInstall%"
copy "%EnvTempPath%\*" "%EnvToolsPath%"
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
%cecho% info "Unpack Unix Tools"
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%UnixToolsInstall%" -y -bso0
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%UnixToolsInstall%"
copy "%EnvTempPath%\cut.exe" "%EnvToolsPath%"
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
%cecho% info "Unpack Unix Tools"
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%UnixToolsInstall%" -y -bso0
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%UnixToolsInstall%"
copy "%EnvTempPath%\sed.exe" "%EnvToolsPath%"
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
%cecho% info "Unpack NSIS"
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%NSISInstall%" -y -bso0
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%NSISInstall%"
if not exist "%NSISInstallPath%" mkdir "%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
%cecho% info "Unpack MinGit"
"%EnvSevenZipExe%" x -o"%MinGitInstallPath%" "%EnvDownloadPath%\%MinGitInstall%" -y -bso0
"%EnvSevenZipExe%" x -o"%MinGitInstallPath%" "%EnvDownloadPath%\%MinGitInstall%"
)
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
%cecho% info "Unpack Doxygen"
"%EnvSevenZipExe%" x -o"%DoxygenInstallPath%" "%EnvDownloadPath%\%DoxygenInstall%" -y -bso0
"%EnvSevenZipExe%" x -o"%DoxygenInstallPath%" "%EnvDownloadPath%\%DoxygenInstall%"
)
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
%cecho% info "Unpack CMake"
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CMakeInstall%" -y -bso0
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%CMakeInstall%"
move "%EnvTempPath%\%CMakeVersion%" "%CMakeInstallPath%"
@ -176,7 +176,7 @@ mkdir "%EnvTempPath%"
call "%ToolsPath%\download-file.bat" "%TorDownloadIndexUrl%" "%EnvTempPath%\index.html"
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%"
if "%TorInstall%"=="" %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
%cecho% info "Unpack Tor"
"%EnvSevenZipExe%" x -so "%EnvDownloadPath%\%TorInstall%" | "%EnvSevenZipExe%" x -si -ttar -o"%EnvTorPath%" -y -bso0
"%EnvSevenZipExe%" x -so "%EnvDownloadPath%\%TorInstall%" | "%EnvSevenZipExe%" x -si -ttar -o"%EnvTorPath%"
)
:exit

View file

@ -247,7 +247,6 @@ Section $(Section_Main) Section_Main
; External binaries
File "${EXTERNAL_LIB_DIR}\bin\miniupnpc.dll"
File "${RELEASEDIR}\supportlibs\librnp\Build\src\lib\librnp.dll"
!if ${ARCHITECTURE} == "x86"
File "${EXTERNAL_LIB_DIR}\bin\libcrypto-1_1.dll"
File "${EXTERNAL_LIB_DIR}\bin\libssl-1_1.dll"
@ -319,7 +318,7 @@ SectionEnd
!ifdef TOR_EXISTS
Section /o $(Section_Tor) Section_Tor
SetOutPath "$INSTDIR\tor"
File "${TORDIR}\*"
File /r "${TORDIR}\*"
SectionEnd
!endif

View file

@ -1,20 +0,0 @@
#!/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

View file

@ -7,5 +7,5 @@ Exec=/usr/bin/retroshare %U
Icon=/usr/share/pixmaps/retroshare.xpm
Terminal=false
Type=Application
Categories=Network;Email;InstantMessaging;Chat;Feed;FileTransfer;P2P
Categories=Application;Network;P2P;Feed;Chat;InstantMessaging
MimeType=x-scheme-handler/retroshare;

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

@ -1 +1 @@
Subproject commit ac83e00ea7a26cd6cf57cefef745d6dcfd07e5da
Subproject commit 8c02b54e4d16e38b28e77263a0b1570c50df4c99

@ -1 +1 @@
Subproject commit 178aa8ebcef47e3271d5a5ca5c07e45d3b71c81d
Subproject commit b41667912751a453e8e5d4733215a0609277a26f

View file

@ -129,8 +129,6 @@ FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, FeedReaderNotify *n
settingsChanged();
feedTreeItemActivated(NULL);
mFontSizeHandler.registerFontSize(ui->feedTreeWidget);
}
FeedReaderDialog::~FeedReaderDialog()

View file

@ -23,7 +23,6 @@
#include <retroshare-gui/mainpage.h>
#include "interface/rsFeedReader.h"
#include "util/FontSizeHandler.h"
namespace Ui {
class FeedReaderDialog;
@ -99,8 +98,6 @@ private:
RsFeedReader *mFeedReader;
FeedReaderNotify *mNotify;
FontSizeHandler mFontSizeHandler;
/** Qt Designer generated object */
Ui::FeedReaderDialog *ui;
};

View file

@ -57,10 +57,10 @@
<item row="0" column="0">
<widget class="QFrame" name="toolBarFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">

View file

@ -154,8 +154,6 @@ FeedReaderMessageWidget::FeedReaderMessageWidget(uint32_t feedId, RsFeedReader *
ui->msgTreeWidget->installEventFilter(this);
setFeedId(feedId);
mFontSizeHandler.registerFontSize(ui->msgTreeWidget);
}
FeedReaderMessageWidget::~FeedReaderMessageWidget()

View file

@ -24,7 +24,6 @@
#include <QWidget>
#include "interface/rsFeedReader.h"
#include "util/FontSizeHandler.h"
namespace Ui {
class FeedReaderMessageWidget;
@ -108,8 +107,6 @@ private:
RsFeedReader *mFeedReader;
FeedReaderNotify *mNotify;
FontSizeHandler mFontSizeHandler;
Ui::FeedReaderMessageWidget *ui;
};

View file

@ -848,22 +848,6 @@ RsFeedReaderErrorState p3FeedReaderThread::process(const RsFeedReaderFeed &feed,
RsFeedReaderErrorState result = RS_FEED_ERRORSTATE_OK;
time_t minimumPubDate = 0;
if (feed.lastUpdate == 0) {
// Get all items on first scan
} else {
// Get storage time
uint32_t storageTime = 0;
if (feed.flag & RS_FEED_FLAG_STANDARD_STORAGE_TIME) {
storageTime = mFeedReader->getStandardStorageTime();
} else {
storageTime = feed.storageTime;
}
if (storageTime > 0) {
minimumPubDate = time(NULL) - storageTime;
}
}
XMLWrapper xml;
if (xml.readXML(feed.content.c_str())) {
xmlNodePtr root = xml.getRootElement();
@ -1022,13 +1006,6 @@ RsFeedReaderErrorState p3FeedReaderThread::process(const RsFeedReaderFeed &feed,
}
}
if (minimumPubDate) {
if (item->pubDate < minimumPubDate) {
// pubDate is less than storage time, don't add as new item
continue;
}
}
entries.push_back(item);
}
} else {
@ -1120,7 +1097,7 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
std::string url;
if (feed.flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE) {
#ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") download page " << msg->link << std::endl;
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") download page " << msg->link << std::endl;
#endif
std::string content;
CURLWrapper CURL(proxy);
@ -1157,7 +1134,7 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
if (result != RS_FEED_ERRORSTATE_OK) {
#ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") cannot download page, CURLCode = " << code << ", error = " << errorString << std::endl;
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot download page, CURLCode = " << code << ", error = " << errorString << std::endl;
#endif
return result;
}
@ -1174,10 +1151,10 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
if (isRunning()) {
/* 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()) {
/* use attachment as image */
processPostedFirstImage = false;
processPostedFirstImage = FALSE;
}
//long todo; // encoding
@ -1303,7 +1280,7 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
if (!src.empty()) {
/* download image */
#ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") download image " << src << std::endl;
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") download image " << src << std::endl;
#endif
std::vector<unsigned char> data;
CURLWrapper CURL(proxy);
@ -1371,7 +1348,7 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
if (!html.saveHTML(msg->postedDescriptionWithoutFirstImage)) {
errorString = html.lastError();
#ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl;
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl;
std::cerr << " Error: " << errorString << std::endl;
#endif
result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR;
@ -1380,7 +1357,7 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
} else {
errorString = html.lastError();
#ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl;
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl;
std::cerr << " Error: " << errorString << std::endl;
#endif
result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR;
@ -1389,14 +1366,14 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
}
} else {
#ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") no root element" << std::endl;
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") no root element" << std::endl;
#endif
result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR;
}
} else {
errorString = html.lastError();
#ifdef FEEDREADER_DEBUG
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") cannot read html" << std::endl;
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot read html" << std::endl;
std::cerr << " Error: " << errorString << std::endl;
#endif
result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR;

View file

@ -8,11 +8,7 @@
#include "pgp/pgpkeyutil.h"
#include "pgp/rscertificate.h"
#ifdef USE_OPENPGPSDK
#include "pgp/openpgpsdkhandler.h"
#else
#include "pgp/rnppgphandler.h"
#endif
#include "friendserver.h"
#include "friend_server/fsitem.h"
@ -397,11 +393,7 @@ FriendServer::FriendServer(const std::string& base_dir,const std::string& listen
std::string pgp_private_keyring_path = RsDirUtil::makePath(base_dir,"pgp_private_keyring") ; // not used.
std::string pgp_trustdb_path = RsDirUtil::makePath(base_dir,"pgp_trustdb") ; // not used.
#ifdef USE_OPENPGPSDK
mPgpHandler = new OpenPGPSDKHandler(pgp_public_keyring_path,pgp_private_keyring_path,pgp_trustdb_path,pgp_lock_path);
#else
mPgpHandler = new RNPPGPHandler(pgp_public_keyring_path,pgp_private_keyring_path,pgp_trustdb_path,pgp_lock_path);
#endif
// Random bias. Should be cryptographically safe.

View file

@ -2,14 +2,17 @@
README for RetroShare
=======================================================================================
RetroShare web site . . . . https://retroshare.cc/
RetroShare web site . . . . http://retroshare.net/index.html
Developer's blog . . . . . https://retroshareteam.wordpress.com
Documentation . . . . . . . https://retrosharedocs.readthedocs.io/en/latest/
Documentation . . . . . . . https://retroshare.readthedocs.io/en/latest/
Support . . . . . . . . . . http://retroshare.net/support.html
Forums . . . . . . . . . . http://retroshare.sourceforge.net/forum/
Wiki . . . . . . . . . . . https://github.com/RetroShare/documentation/wiki
Old developers site . . . . http://retroshare.sourceforge.net/wiki/index.php/Developers_Corner
Project site . . . . . . . https://github.com/RetroShare/RetroShare
Related projects/plugins . .https://github.com/RetroShare
Relted projects/plugins . . https://github.com/RetroShare
Contact: . . . . . . . . . retroshare.project@gmail.com
Contact: . . . . . . . . . retroshare@lunamutt.com ,defnax@users.sourceforge.net
=========================================================================================
Compiling RetroShare
@ -19,9 +22,9 @@ Build Scripts are avaible on GIT:
https://github.com/RetroShare/RetroShare/tree/master/build_scripts
You can find here instructions howto compile RetroShare:
https://retrosharedocs.readthedocs.io/en/latest/developer/compilation/
https://retroshare.readthedocs.io/en/latest/developer/compilation/
You can go on over to our forum or chat room when you have trouble with compiling:
You can go on over to our forum or chat lobby when you have trouble with compiling:
retroshare://forum?name=Developers%20Discussions&id=8fd22bd8f99754461e7ba1ca8a727995
retroshare://chat_room?name=Retroshare%20Devel%20%28signed%29&id=L68DB0A1E09BDA3A5
http://retroshare.sourceforge.net/forum/

View file

@ -142,7 +142,7 @@ void AboutWidget::updateTitle()
{
if (tWidget == NULL)
{
setWindowTitle(QString("%1 %2").arg(tr("About RetroShare"), RsApplication::retroshareVersion(true)));
setWindowTitle(QString("%1 %2").arg(tr("About RetroShare"), Rshare::retroshareVersion(true)));
}
else
{
@ -228,7 +228,7 @@ void AWidget::initImages()
#ifdef RS_ONLYHIDDENNODE
p.drawText(QPointF(10, 50), QString("%1 : %2 (With embedded Tor)").arg(tr("Retroshare version"), Rshare::retroshareVersion(true)));
#else
p.drawText(QPointF(10, 50), QString("%1 : %2").arg(tr("Retroshare version"), RsApplication::retroshareVersion(true)));
p.drawText(QPointF(10, 50), QString("%1 : %2").arg(tr("Retroshare version"), Rshare::retroshareVersion(true)));
#endif
/* Draw Qt's version number */
@ -936,7 +936,7 @@ void AboutWidget::on_copy_button_clicked()
{
QString verInfo;
QString rsVerString = "RetroShare Version: ";
rsVerString+=RsApplication::retroshareVersion(true);
rsVerString+=Rshare::retroshareVersion(true);
verInfo+=rsVerString;
#ifdef RS_ONLYHIDDENNODE
verInfo+=" " + tr("Only Hidden Node");

View file

@ -143,28 +143,28 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
QHeaderView_setSectionResizeModeColumn(header, COLUMN_TOPIC, QHeaderView::Interactive);
privateSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
privateSubLobbyItem->setText(COLUMN_NAME, tr("Private Subscribed"));
privateSubLobbyItem->setText(COLUMN_NAME, tr("Private Subscribed chat rooms"));
privateSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "1");
// privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE));
privateSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE);
ui.lobbyTreeWidget->insertTopLevelItem(0, privateSubLobbyItem);
publicSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed"));
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed chat rooms"));
publicSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "2");
// publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC));
publicSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC);
ui.lobbyTreeWidget->insertTopLevelItem(1, publicSubLobbyItem);
privateLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
privateLobbyItem->setText(COLUMN_NAME, tr("Private"));
privateLobbyItem->setText(COLUMN_NAME, tr("Private chat rooms"));
privateLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "3");
// privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE));
privateLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE);
ui.lobbyTreeWidget->insertTopLevelItem(2, privateLobbyItem);
publicLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
publicLobbyItem->setText(COLUMN_NAME, tr("Public"));
publicLobbyItem->setText(COLUMN_NAME, tr("Public chat rooms"));
publicLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "4");
// publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC));
publicLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC);
@ -230,8 +230,6 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
int ltwH = misc::getFontSizeFactor("LobbyTreeWidget", 1.5).height();
ui.lobbyTreeWidget->setIconSize(QSize(ltwH,ltwH));
mFontSizeHandler.registerFontSize(ui.lobbyTreeWidget);
}
ChatLobbyWidget::~ChatLobbyWidget()
@ -422,7 +420,7 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
if(lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)
{
tooltipstr += QObject::tr("\nSecurity: no anonymous IDs") ;
QColor foreground = QColor(16, 157, 0); // green
QColor foreground = QColor(0, 128, 0); // green
for (int column = 0; column < COLUMN_COUNT; ++column)
item->setData(column, Qt::ForegroundRole, foreground);
}
@ -723,9 +721,9 @@ void ChatLobbyWidget::updateDisplay()
}
}
publicSubLobbyItem->setHidden(publicSubLobbyItem->childCount()==0);
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed")+ QString(" (") + QString::number(publicSubLobbyItem->childCount())+QString(")"));
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed chat rooms")+ QString(" (") + QString::number(publicSubLobbyItem->childCount())+QString(")"));
privateSubLobbyItem->setHidden(privateSubLobbyItem->childCount()==0);
publicLobbyItem->setText(COLUMN_NAME, tr("Public")+ " (" + QString::number(publicLobbyItem->childCount())+QString(")"));
publicLobbyItem->setText(COLUMN_NAME, tr("Public chat rooms")+ " (" + QString::number(publicLobbyItem->childCount())+QString(")"));
}
void ChatLobbyWidget::createChatLobby()

View file

@ -25,7 +25,6 @@
#include "chat/ChatLobbyUserNotify.h"
#include "gui/gxs/GxsIdChooser.h"
#include "util/FontSizeHandler.h"
#include <retroshare/rsmsgs.h>
@ -147,8 +146,6 @@ private:
QAbstractButton* myInviteYesButton;
GxsIdChooser* myInviteIdChooser;
FontSizeHandler mFontSizeHandler;
/* UI - from Designer */
Ui::ChatLobbyWidget ui;
};

View file

@ -73,7 +73,7 @@
<widget class="QLabel" name="titleBarLabel">
<property name="font">
<font>
<pointsize>12</pointsize>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
@ -191,6 +191,11 @@
</item>
<item>
<widget class="RSTreeWidget" name="lobbyTreeWidget">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="iconSize">
<size>
<width>16</width>
@ -459,7 +464,7 @@
<customwidget>
<class>LineEditClear</class>
<extends>QLineEdit</extends>
<header>gui/common/LineEditClear.h</header>
<header location="global">gui/common/LineEditClear.h</header>
</customwidget>
<customwidget>
<class>RSTreeWidget</class>

16
retroshare-gui/src/gui/FileTransfer/DLListDelegate.cpp Executable file → Normal file
View file

@ -102,7 +102,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
multi *= 1024.0;
}
}
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
painter->drawText(option.rect, Qt::AlignRight, temp);
break;
case COLUMN_REMAINING:
remaining = index.data().toLongLong();
@ -121,7 +121,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
multi *= 1024.0;
}
}
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
painter->drawText(option.rect, Qt::AlignRight, temp);
break;
case COLUMN_COMPLETED:
completed = index.data().toLongLong();
@ -140,7 +140,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
multi *= 1024.0;
}
}
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
painter->drawText(option.rect, Qt::AlignRight, temp);
break;
case COLUMN_DLSPEED:
dlspeed = index.data().toDouble();
@ -151,7 +151,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
temp.sprintf("%.2f", dlspeed/1024.);
temp += " KB/s";
}
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
painter->drawText(option.rect, Qt::AlignRight, temp);
break;
case COLUMN_PROGRESS:
{
@ -236,7 +236,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
pixmap = qvariant_cast<QIcon>(value).pixmap(option.decorationSize, option.state & QStyle::State_Enabled ? QIcon::Normal : QIcon::Disabled, option.state & QStyle::State_Open ? QIcon::On : QIcon::Off);
pixmapRect = (pixmap.isNull() ? QRect(0, 0, 0, 0): QRect(QPoint(0, 0), option.decorationSize));
if (pixmapRect.isValid()){
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft | Qt::AlignVCenter, pixmap.size(), option.rect).topLeft();
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft, pixmap.size(), option.rect).topLeft();
p.setX( p.x() + pixOffset);
painter->drawPixmap(p, pixmap);
temp = " " + temp;
@ -247,13 +247,13 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
pixmap = qvariant_cast<QIcon>(value).pixmap(option.decorationSize, option.state & QStyle::State_Enabled ? QIcon::Normal : QIcon::Disabled, option.state & QStyle::State_Open ? QIcon::On : QIcon::Off);
pixmapRect = (pixmap.isNull() ? QRect(0, 0, 0, 0): QRect(QPoint(0, 0), option.decorationSize));
if (pixmapRect.isValid()){
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft | Qt::AlignVCenter, pixmap.size(), option.rect).topLeft();
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft, pixmap.size(), option.rect).topLeft();
p.setX( p.x() + pixOffset);
painter->drawPixmap(p, pixmap);
temp = " " + temp;
pixOffset += pixmap.size().width();
}
painter->drawText(option.rect.translated(pixOffset, 0), Qt::AlignLeft | Qt::AlignVCenter, temp);
painter->drawText(option.rect.translated(pixOffset, 0), Qt::AlignLeft, temp);
}
break;
case COLUMN_LASTDL:
@ -279,7 +279,7 @@ QSize DLListDelegate::sizeHint(const QStyleOptionViewItem & option, const QModel
{
float w = QFontMetricsF(option.font).width(index.data(Qt::DisplayRole).toString());
int S = QFontMetricsF(option.font).height()*1.5 ;
int S = QFontMetricsF(option.font).height() ;
return QSize(w,S);
}

View file

@ -30,7 +30,7 @@
#include "gui/RetroShareLink.h"
#include "retroshare-gui/RsAutoUpdatePage.h"
#include "gui/msgs/MessageComposer.h"
#include "gui/common/RsCollectionDialog.h"
#include "gui/common/RsCollection.h"
#include "gui/common/FilesDefs.h"
#include "gui/common/RsUrlHandler.h"
#include "gui/settings/rsharesettings.h"
@ -38,7 +38,6 @@
#include "gui/common/RSTreeWidgetItem.h"
#include "util/QtVersion.h"
#include "util/qtthreadsutils.h"
#include "util/misc.h"
#include <retroshare/rsfiles.h>
#include <retroshare/rsturtle.h>
@ -87,18 +86,6 @@ const int SearchDialog::FILETYPE_IDX_DIRECTORY = 8;
QMap<int, QString> * SearchDialog::FileTypeExtensionMap = new QMap<int, QString>();
bool SearchDialog::initialised = false;
struct SearchDialog::FileDetail
{
public:
RsPeerId id;
std::string name;
RsFileHash hash;
std::string path;
uint64_t size;
uint32_t mtime;
uint32_t rank;
};
/** Constructor */
SearchDialog::SearchDialog(QWidget *parent)
: MainPage(parent),
@ -202,6 +189,10 @@ SearchDialog::SearchDialog(QWidget *parent)
ui.searchResultWidget->sortItems(SR_NAME_COL, Qt::AscendingOrder);
QFontMetricsF fontMetrics(ui.searchResultWidget->font());
int iconHeight = fontMetrics.height() * 1.4;
ui.searchResultWidget->setIconSize(QSize(iconHeight, iconHeight));
/* Set initial size the splitter */
QList<int> sizes;
sizes << 250 << width(); // Qt calculates the right sizes
@ -236,8 +227,6 @@ SearchDialog::SearchDialog(QWidget *parent)
RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this );
}, mEventHandlerId, RsEventType::FILE_TRANSFER );
mFontSizeHandler.registerFontSize(ui.searchSummaryWidget);
mFontSizeHandler.registerFontSize(ui.searchResultWidget, 1.4f);
}
SearchDialog::~SearchDialog()
@ -276,8 +265,6 @@ void SearchDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
f.hash = fe->mResults[i].fHash;
f.name = fe->mResults[i].fName;
f.size = fe->mResults[i].fSize;
f.mtime = 0; // zero what's not available, otherwise we'll get some random values displayed.
f.rank = 0;
updateFiles(fe->mRequestId,f);
}
@ -324,7 +311,7 @@ void SearchDialog::checkText(const QString& txt)
ui.searchButton->setDisabled(txt.length() < 3);
ui.searchLineFrame->setProperty("valid", (txt.length() >= 3));
ui.searchLineFrame->style()->unpolish(ui.searchLineFrame);
RsApplication::refreshStyleSheet(ui.searchLineFrame, false);
Rshare::refreshStyleSheet(ui.searchLineFrame, false);
}
void SearchDialog::initialiseFileTypeMappings()
@ -496,23 +483,25 @@ void SearchDialog::collCreate()
int selectedCount = selectedItems.size() ;
QTreeWidgetItem * item ;
RsFileTree tree;
for (int i = 0; i < selectedCount; ++i)
{
for (int i = 0; i < selectedCount; ++i) {
item = selectedItems.at(i) ;
if (!item->text(SR_HASH_COL).isEmpty())
{
if (!item->text(SR_HASH_COL).isEmpty()) {
std::string name = item->text(SR_NAME_COL).toUtf8().constData();
RsFileHash hash( item->text(SR_HASH_COL).toStdString() );
uint64_t count = item->text(SR_SIZE_COL).toULongLong();
tree.addFile(tree.root(),name,hash,count);
DirDetails details;
details.name = name;
details.hash = hash;
details.size = count;
details.type = DIR_TYPE_FILE;
dirVec.push_back(details);
}
}
RsCollectionDialog::openNewCollection(tree);
RsCollection(dirVec,RS_FILE_HINTS_LOCAL).openNewColl(this);
}
void SearchDialog::collModif()
@ -539,8 +528,12 @@ void SearchDialog::collModif()
/* open file with a suitable application */
QFileInfo qinfo;
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath());
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollection collection;
collection.openColl(qinfo.absoluteFilePath());
}//if (qinfo.absoluteFilePath().endsWith(RsCollectionFile::ExtensionString))
}//if (qinfo.exists())
}
void SearchDialog::collView()
@ -567,8 +560,12 @@ void SearchDialog::collView()
/* open file with a suitable application */
QFileInfo qinfo;
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath(), true);
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollection collection;
collection.openColl(qinfo.absoluteFilePath(), true);
}//if (qinfo.absoluteFilePath().endsWith(RsCollectionFile::ExtensionString))
}//if (qinfo.exists())
}
void SearchDialog::collOpen()
@ -586,35 +583,32 @@ void SearchDialog::collOpen()
if (rsFiles->FileDetails(hash, RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL
| RS_FILE_HINTS_BROWSABLE | RS_FILE_HINTS_NETWORK_WIDE
| RS_FILE_HINTS_SPEC_ONLY, info))
{
| RS_FILE_HINTS_SPEC_ONLY, info)) {
/* make path for downloaded files */
std::string path;
path = info.path;
/* open file with a suitable application */
QFileInfo qinfo;
RsCollection::RsCollectionErrorCode err;
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
RsCollectionDialog::downloadFiles(RsCollection(qinfo.absoluteFilePath(),err));
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollection collection;
if (collection.load(qinfo.absoluteFilePath())) {
collection.downloadFiles();
return;
}
}
}
}
}
}
QString fileName;
if (!misc::getOpenFileName(nullptr, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName))
return ;
std::cerr << "Got file name: " << fileName.toStdString() << std::endl;
RsCollection::RsCollectionErrorCode err;
RsCollection collection(fileName, err);
if(err == RsCollection::RsCollectionErrorCode::COLLECTION_NO_ERROR)
RsCollectionDialog::downloadFiles(collection);
else
QMessageBox::information(nullptr,tr("Error open RsCollection file"),RsCollection::errorString(err));
RsCollection collection;
if (collection.load(this)) {
collection.downloadFiles();
}//if (collection.load(this))
}
void SearchDialog::downloadDirectory(const QTreeWidgetItem *item, const QString &base)
@ -972,7 +966,7 @@ void SearchDialog::searchKeywords(const QString& keywords)
}
}
void SearchDialog::updateFiles(qulonglong search_id,const FileDetail& file)
void SearchDialog::updateFiles(qulonglong search_id,FileDetail file)
{
searchResultsQueue.push_back(std::pair<qulonglong,FileDetail>(search_id,file)) ;
@ -1040,7 +1034,7 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons
child->setText(SR_SOURCES_COL, QString::number(1));
child->setData(SR_SOURCES_COL, ROLE_SORT, 1);
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight | Qt::AlignVCenter );
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight );
child->setText(SR_SEARCH_ID_COL, sid_hexa);
setIconAndType(child, QString::fromUtf8(dir.name.c_str()));
@ -1065,7 +1059,7 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
child->setText(SR_SOURCES_COL, QString::number(1));
child->setData(SR_SOURCES_COL, ROLE_SORT, 1);
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight | Qt::AlignVCenter );
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight );
child->setText(SR_SEARCH_ID_COL, sid_hexa);
child->setText(SR_TYPE_COL, tr("Folder"));
@ -1134,7 +1128,7 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
child->setText(SR_SOURCES_COL, QString::number(1));
child->setData(SR_SOURCES_COL, ROLE_SORT, 1);
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight | Qt::AlignVCenter );
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight );
child->setText(SR_SEARCH_ID_COL, sid_hexa);
child->setText(SR_TYPE_COL, tr("Folder"));
@ -1326,11 +1320,9 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
item->setText(SR_SIZE_COL, QString::number(file.size));
item->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) file.size);
item->setText(SR_AGE_COL, QString::number(file.mtime));
item->setData(SR_AGE_COL, ROLE_SORT, file.mtime);
item->setText(SR_AGE_COL, QString::number(file.age));
item->setData(SR_AGE_COL, ROLE_SORT, file.age);
item->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
item->setTextAlignment( SR_AGE_COL, Qt::AlignCenter );
int friendSource = 0;
int anonymousSource = 0;
if(searchType == FRIEND_SEARCH)
@ -1349,7 +1341,7 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
item->setText(SR_SOURCES_COL,modifiedResult);
item->setToolTip(SR_SOURCES_COL, tr("Obtained via ")+QString::fromStdString(rsPeers->getPeerName(file.id)) );
item->setData(SR_SOURCES_COL, ROLE_SORT, fltRes);
item->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight | Qt::AlignVCenter );
item->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight );
item->setText(SR_SEARCH_ID_COL, sid_hexa);
QColor foreground;
@ -1404,21 +1396,21 @@ void SearchDialog::resultsToTree(const QString& txt,qulonglong searchId, const s
std::list<DirDetails>::const_iterator it;
for(it = results.begin(); it != results.end(); ++it)
if (it->type == DIR_TYPE_FILE)
{
if (it->type == DIR_TYPE_FILE) {
FileDetail fd;
fd.id = it->id;
fd.name = it->name;
fd.hash = it->hash;
fd.path = it->path;
fd.size = it->size;
fd.mtime= it->mtime;
fd.age = it->mtime;
fd.rank = 0;
insertFile(searchId,fd, FRIEND_SEARCH);
}
else if (it->type == DIR_TYPE_DIR)
} else if (it->type == DIR_TYPE_DIR) {
// insertDirectory(txt, searchId, *it, NULL);
insertDirectory(txt, searchId, *it);
}
ui.searchResultWidget->setSortingEnabled(true);
}

View file

@ -25,7 +25,6 @@
#include "retroshare/rsevents.h"
#include "ui_SearchDialog.h"
#include "retroshare-gui/mainpage.h"
#include "util/FontSizeHandler.h"
class AdvancedSearchDialog;
class RSTreeWidgetItemCompareRole;
@ -44,7 +43,6 @@ class SearchDialog : public MainPage
Q_PROPERTY(QColor textColorLowSources READ textColorLowSources WRITE setTextColorLowSources)
Q_PROPERTY(QColor textColorHighSources READ textColorHighSources WRITE setTextColorHighSources)
struct FileDetail; // useful structure to store search results.
public:
/** Default Constructor */
SearchDialog(QWidget *parent = 0);
@ -65,7 +63,8 @@ public:
void setTextColorLowSources(QColor color) { mTextColorLowSources = color; }
void setTextColorHighSources(QColor color) { mTextColorHighSources = color; }
void updateFiles(qulonglong request_id, const FileDetail& file) ;
public slots:
void updateFiles(qulonglong request_id,FileDetail file) ;
private slots:
@ -174,8 +173,6 @@ private:
QAction *collViewAct;
QAction *collOpenAct;
FontSizeHandler mFontSizeHandler;
/** Qt Designer generated object */
Ui::SearchDialog ui;

View file

@ -27,7 +27,7 @@
#include "gui/RetroShareLink.h"
#include "gui/ShareManager.h"
#include "gui/common/PeerDefs.h"
#include "gui/common/RsCollectionDialog.h"
#include "gui/common/RsCollection.h"
#include "gui/msgs/MessageComposer.h"
#include "gui/gxschannels/GxsChannelDialog.h"
#include "gui/gxsforums/GxsForumsDialog.h"
@ -652,7 +652,7 @@ void SharedFilesDialog::copyLinks(const QModelIndexList& lst, bool remote,QList<
QString dir_name = QDir(QString::fromUtf8(details.name.c_str())).dirName();
RetroShareLink link = RetroShareLink::createFileTree(dir_name,ft->totalFileSize(),ft->numFiles(),QString::fromStdString(ft->toRadix64())) ;
RetroShareLink link = RetroShareLink::createFileTree(dir_name,ft->mTotalSize,ft->mTotalFiles,QString::fromStdString(ft->toRadix64())) ;
if(link.valid())
urls.push_back(link) ;
@ -734,32 +734,7 @@ void SharedFilesDialog::sendLinkTo()
void SharedFilesDialog::collCreate()
{
QModelIndexList lst = getSelected();
std::vector <DirDetails> dirVec;
model->getDirDetailsFromSelect(lst, dirVec);
auto RemoteMode = isRemote();
FileSearchFlags f = RemoteMode?RS_FILE_HINTS_REMOTE:RS_FILE_HINTS_LOCAL ;
QString dir_name;
if(!RemoteMode)
{
if(!dirVec.empty())
{
const DirDetails& details = dirVec[0];
dir_name = QDir(QString::fromUtf8(details.name.c_str())).dirName();
}
}
RsFileTree tree;
for(uint32_t i=0;i<dirVec.size();++i)
tree.addFileTree(tree.root(),*RsFileTree::fromDirDetails(dirVec[i],RemoteMode,true));
RsCollectionDialog::openNewCollection(tree);
//auto ft = RsFileTree::fromDirDetails(details,remote);
model->createCollectionFile(this, lst);
}
void SharedFilesDialog::collModif()
@ -784,8 +759,12 @@ void SharedFilesDialog::collModif()
/* open file with a suitable application */
QFileInfo qinfo;
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
RsCollectionDialog::editExistingCollection(qinfo.absoluteFilePath());
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollection collection;
collection.openColl(qinfo.absoluteFilePath());
}
}
}
void SharedFilesDialog::collView()
@ -810,8 +789,12 @@ void SharedFilesDialog::collView()
/* open file with a suitable application */
QFileInfo qinfo;
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath(), true);
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollection collection;
collection.openColl(qinfo.absoluteFilePath(), true);
}
}
}
void SharedFilesDialog::collOpen()
@ -838,24 +821,20 @@ void SharedFilesDialog::collOpen()
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath(),true);
RsCollection collection;
if (collection.load(qinfo.absoluteFilePath())) {
collection.downloadFiles();
return;
}
}
}
}
}
QString fileName;
if (!misc::getOpenFileName(nullptr, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName))
return ;
std::cerr << "Got file name: " << fileName.toStdString() << std::endl;
RsCollection::RsCollectionErrorCode err;
RsCollection collection(fileName,err);
if(err == RsCollection::RsCollectionErrorCode::COLLECTION_NO_ERROR)
RsCollectionDialog::downloadFiles(collection);
RsCollection collection;
if (collection.load(this)) {
collection.downloadFiles();
}
}
void LocalSharedFilesDialog::playselectedfiles()
@ -1166,14 +1145,12 @@ void LocalSharedFilesDialog::spawnCustomPopupMenu( QPoint point )
collViewAct->setEnabled(bIsRsColl);
collOpenAct->setEnabled(true);
QMenu collectionMenu(tr("Retroshare Collection"), this);
QMenu collectionMenu(tr("Collection"), this);
collectionMenu.setIcon(QIcon(IMAGE_LIBRARY));
collectionMenu.addAction(collCreateAct);
if(bIsRsColl)
collectionMenu.addAction(collModifAct);
//collectionMenu.addAction(collViewAct);
//collectionMenu.addAction(collOpenAct);
collectionMenu.addAction(collModifAct);
collectionMenu.addAction(collViewAct);
collectionMenu.addAction(collOpenAct);
switch (type) {
case DIR_TYPE_DIR :
@ -1711,16 +1688,12 @@ bool SharedFilesDialog::tree_FilterItem(const QModelIndex &index, const QString
void SharedFilesDialog::updateFontSize()
{
#if defined(Q_OS_DARWIN)
int customFontSize = Settings->valueFromGroup("File", "MinimumFontSize", 13).toInt();
#else
int customFontSize = Settings->valueFromGroup("File", "MinimumFontSize", 11).toInt();
#endif
QFont newFont = ui.dirTreeView->font();
if (newFont.pointSize() != customFontSize) {
newFont.setPointSize(customFontSize);
QFontMetricsF fontMetrics(newFont);
int iconHeight = fontMetrics.height()*1.5;
int iconHeight = fontMetrics.height();
ui.dirTreeView->setFont(newFont);
ui.dirTreeView->setIconSize(QSize(iconHeight, iconHeight));
}

View file

@ -23,10 +23,10 @@
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
@ -399,8 +399,8 @@ border-image: url(:/images/closepressed.png)
</customwidget>
</customwidgets>
<resources>
<include location="../icons.qrc"/>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -24,7 +24,7 @@
#include "gui/SoundManager.h"
#include "gui/RetroShareLink.h"
#include "gui/common/FilesDefs.h"
#include "gui/common/RsCollectionDialog.h"
#include "gui/common/RsCollection.h"
#include "gui/common/RSTreeView.h"
#include "gui/common/RsUrlHandler.h"
#include "gui/FileTransfer/DetailsDialog.h"
@ -442,7 +442,7 @@ public:
{
QString strPath = QString::fromUtf8(fileInfo.path.c_str());
QString strPathAfterDL = strPath;
strPathAfterDL.replace(QString::fromUtf8(rsFiles->getDownloadDirectory().c_str()),"[Download Dir]");
strPathAfterDL.replace(QString::fromUtf8(rsFiles->getDownloadDirectory().c_str()),"");
return QVariant(strPathAfterDL);
}
@ -1975,7 +1975,7 @@ void TransfersDialog::pasteLink()
for(auto &it : links)
col.merge_in(it.name(),it.size(),RsFileHash(it.hash().toStdString())) ;
RsCollectionDialog::downloadFiles(col);
col.downloadFiles();
}
void TransfersDialog::getDLSelectedItems(std::set<RsFileHash> *ids, std::set<int> *rows)
@ -2074,23 +2074,22 @@ void TransfersDialog::dlOpenFolder()
break;
}
openFolder(info);
}
void TransfersDialog::openFolder(const FileInfo& info)
{
/* make path for downloaded or downloading files */
QDir directory;
if (info.downloadStatus == FT_STATE_COMPLETE)
directory = QFileInfo(QString::fromStdString(info.path)).absoluteDir().path();
else
directory = QDir(QString::fromStdString(rsFiles->getPartialsDirectory()));
QFileInfo qinfo;
std::string path;
if (info.downloadStatus == FT_STATE_COMPLETE) {
path = info.path;
} else {
path = rsFiles->getPartialsDirectory();
}
/* open folder with a suitable application */
if (directory.exists() && !RsUrlHandler::openUrl(QUrl::fromLocalFile(directory.path())))
std::cerr << "dlOpenFolder(): can't open folder " << directory.path().toStdString() << std::endl;
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists() && qinfo.isDir()) {
if (!RsUrlHandler::openUrl(QUrl::fromLocalFile(qinfo.absoluteFilePath()))) {
std::cerr << "dlOpenFolder(): can't open folder " << path << std::endl;
}
}
}
void TransfersDialog::ulOpenFolder()
@ -2105,7 +2104,19 @@ void TransfersDialog::ulOpenFolder()
break;
}
openFolder(info);
/* make path for uploading files */
QFileInfo qinfo;
std::string path;
path = info.path.substr(0,info.path.length()-info.fname.length());
/* open folder with a suitable application */
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists() && qinfo.isDir()) {
if (!RsUrlHandler::openUrl(QUrl::fromLocalFile(qinfo.absoluteFilePath()))) {
std::cerr << "ulOpenFolder(): can't open folder " << path << std::endl;
}
}
}
void TransfersDialog::dlPreviewFile()
@ -2128,7 +2139,7 @@ void TransfersDialog::dlPreviewFile()
/* make path for downloaded or downloading files */
QFileInfo fileInfo;
if (info.downloadStatus == FT_STATE_COMPLETE) {
fileInfo = QFileInfo(QString::fromUtf8(info.path.c_str()));
fileInfo = QFileInfo(QString::fromUtf8(info.path.c_str()), QString::fromUtf8(info.fname.c_str()));
} else {
fileInfo = QFileInfo(QString::fromUtf8(rsFiles->getPartialsDirectory().c_str()), QString::fromUtf8(info.hash.toStdString().c_str()));
@ -2193,7 +2204,7 @@ void TransfersDialog::dlOpenFile()
/* make path for downloaded or downloading files */
std::string path;
if (info.downloadStatus == FT_STATE_COMPLETE) {
path = info.path ;
path = info.path + "/" + info.fname;
/* open file with a suitable application */
QFileInfo qinfo;
@ -2233,10 +2244,6 @@ void TransfersDialog::chunkStreaming()
}
void TransfersDialog::chunkRandom()
{
#ifdef WINDOWS_SYS
if(QMessageBox::Yes != QMessageBox::warning(nullptr,tr("Warning"),tr("On Windows systems, writing in the middle of large empty files may hang the software for several seconds. Do you want to use this option anyway?"),QMessageBox::Yes,QMessageBox::No))
return;
#endif
setChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_RANDOM) ;
}
void TransfersDialog::chunkProgressive()
@ -2466,17 +2473,21 @@ void TransfersDialog::collCreate()
std::set<RsFileHash>::iterator it ;
getDLSelectedItems(&items, NULL);
RsFileTree tree;
for (it = items.begin(); it != items.end(); ++it)
{
FileInfo info;
if (!rsFiles->FileDetails(*it, RS_FILE_HINTS_DOWNLOAD, info)) continue;
tree.addFile(tree.root(),info.fname,info.hash,info.size);
DirDetails details;
details.name = info.fname;
details.hash = info.hash;
details.size = info.size;
details.type = DIR_TYPE_FILE;
dirVec.push_back(details);
}
RsCollectionDialog::openNewCollection(tree);
RsCollection(dirVec,RS_FILE_HINTS_LOCAL).openNewColl(this);
}
void TransfersDialog::collModif()
@ -2500,8 +2511,12 @@ void TransfersDialog::collModif()
/* open collection */
QFileInfo qinfo;
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath());
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollection collection;
collection.openColl(qinfo.absoluteFilePath());
}
}
}
}
@ -2526,8 +2541,12 @@ void TransfersDialog::collView()
/* open collection */
QFileInfo qinfo;
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath(), true);
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollection collection;
collection.openColl(qinfo.absoluteFilePath(), true);
}
}
}
}
@ -2552,29 +2571,23 @@ void TransfersDialog::collOpen()
/* open file with a suitable application */
QFileInfo qinfo;
qinfo.setFile(QString::fromUtf8(path.c_str()));
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
{
RsCollection::RsCollectionErrorCode code;
RsCollectionDialog::downloadFiles(RsCollection(qinfo.absoluteFilePath(),code));
return;
}
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollection collection;
if (collection.load(qinfo.absoluteFilePath())) {
collection.downloadFiles();
return;
}
}
}
}
}
}
QString fileName;
if (!misc::getOpenFileName(nullptr, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName))
return ;
std::cerr << "Got file name: " << fileName.toStdString() << std::endl;
RsCollection::RsCollectionErrorCode code;
RsCollection collection(fileName,code);
if(code == RsCollection::RsCollectionErrorCode::COLLECTION_NO_ERROR)
RsCollectionDialog::downloadFiles(collection);
else
QMessageBox::information(nullptr,tr("Error openning collection file"),RsCollection::errorString(code));
RsCollection collection;
if (collection.load(this)) {
collection.downloadFiles();
}
}
void TransfersDialog::collAutoOpen(const QString &fileHash)
@ -2586,18 +2599,21 @@ void TransfersDialog::collAutoOpen(const QString &fileHash)
if (rsFiles->FileDetails(hash, RS_FILE_HINTS_DOWNLOAD, info)) {
/* make path for downloaded files */
if (info.downloadStatus == FT_STATE_COMPLETE)
{
if (info.downloadStatus == FT_STATE_COMPLETE) {
std::string path;
path = info.path + "/" + info.fname;
/* open file with a suitable application */
QFileInfo qinfo;
qinfo.setFile(QString::fromUtf8(path.c_str()));
RsCollection::RsCollectionErrorCode err;
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
RsCollectionDialog::downloadFiles(RsCollection(qinfo.absoluteFilePath(),err));
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollection collection;
if (collection.load(qinfo.absoluteFilePath(), false)) {
collection.autoDownloadFiles();
}
}
}
}
}
}

View file

@ -173,7 +173,6 @@ signals:
void playFiles(QStringList files);
private:
void openFolder(const FileInfo& info);
RsDownloadListModel *DLListModel;
QSortFilterProxyModel *DLLFilterModel;

12
retroshare-gui/src/gui/FileTransfer/ULListDelegate.cpp Executable file → Normal file
View file

@ -101,7 +101,7 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
multi *= 1024.0;
}
}
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
painter->drawText(option.rect, Qt::AlignRight, temp);
break;
case COLUMN_UTRANSFERRED:
transferred = index.data().toLongLong();
@ -120,7 +120,7 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
multi *= 1024.0;
}
}
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
painter->drawText(option.rect, Qt::AlignRight, temp);
break;
case COLUMN_ULSPEED:
ulspeed = index.data().toDouble();
@ -131,7 +131,7 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
temp.sprintf("%.2f", ulspeed/1024.);
temp += " KB/s";
}
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
painter->drawText(option.rect, Qt::AlignRight, temp);
break;
case COLUMN_UPROGRESS:
{
@ -164,10 +164,10 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
pixmap = qvariant_cast<QIcon>(value).pixmap(option.decorationSize, option.state & QStyle::State_Enabled ? QIcon::Normal : QIcon::Disabled, option.state & QStyle::State_Open ? QIcon::On : QIcon::Off);
pixmapRect = (pixmap.isNull() ? QRect(0, 0, 0, 0): QRect(QPoint(0, 0), option.decorationSize));
if (pixmapRect.isValid()){
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft | Qt::AlignVCenter, pixmap.size(), option.rect).topLeft();
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft, pixmap.size(), option.rect).topLeft();
painter->drawPixmap(p, pixmap);
}
painter->drawText(option.rect.translated(pixmap.size().width(), 0), Qt::AlignLeft | Qt::AlignVCenter, index.data().toString());
painter->drawText(option.rect.translated(pixmap.size().width(), 0), Qt::AlignLeft, index.data().toString());
break;
default:
painter->drawText(option.rect, Qt::AlignCenter, index.data().toString());
@ -181,7 +181,7 @@ QSize ULListDelegate::sizeHint(const QStyleOptionViewItem & option, const QModel
{
float w = QFontMetricsF(option.font).width(index.data(Qt::DisplayRole).toString());
int S = QFontMetricsF(option.font).height()*1.5 ;
int S = QFontMetricsF(option.font).height() ;
return QSize(w,S);
}

View file

@ -251,7 +251,7 @@ void GenCertDialog::initKeyList()
void GenCertDialog::mouseMoveEvent(QMouseEvent *e)
{
//std::cerr << "Mouse : " << e->x() << ", " << e->y() << std::endl;
std::cerr << "Mouse : " << e->x() << ", " << e->y() << std::endl;
QDialog::mouseMoveEvent(e) ;
}
@ -609,9 +609,7 @@ void GenCertDialog::genPerson()
QCoreApplication::processEvents();
QAbstractEventDispatcher* ed = QAbstractEventDispatcher::instance();
#ifdef DEBUG_GENCERTDIALOG
std::cout << "Waiting ed->processEvents()" << std::endl;
#endif
std::cout << "Waiting ed->processEvents()" << std::endl;
time_t waitEnd = time(NULL) + 10;//Wait no more than 10 sec to processEvents
if (ed->hasPendingEvents())
while(ed->processEvents(QEventLoop::AllEvents) && (time(NULL) < waitEnd));
@ -649,7 +647,7 @@ void GenCertDialog::genPerson()
{
/* complete the process */
RsInit::LoadPassword(sslPasswd);
if (RsApplication::loadCertificate(sslId, false)) {
if (Rshare::loadCertificate(sslId, false)) {
// Normally we should clear the cached passphrase as soon as possible. However,some other GUI components may still need it at start.
// (csoler) This is really bad: we have to guess that 30 secs will be enough. I have no better way to do this.

View file

@ -421,7 +421,7 @@ void GetStartedDialog::emailSupport()
sysVersion = "Linux";
#endif
#endif
text += QString("My RetroShare Configuration is: (%1, %2, %3)").arg(RsApplication::retroshareVersion(true)
text += QString("My RetroShare Configuration is: (%1, %2, %3)").arg(Rshare::retroshareVersion(true)
, sysVersion
).arg(static_cast<typename std::underlying_type<RsConfigUserLvl>::type>(userLevel)) + "\n";
text += "\n";

View file

@ -80,7 +80,7 @@ HelpDialog::HelpDialog(QWidget *parent) :
ui->thanks->setHtml(in.readAll());
}
ui->version->setText(RsApplication::retroshareVersion(true));
ui->version->setText(Rshare::retroshareVersion(true));
/* Add version numbers of libretroshare */
std::list<RsLibraryInfo> libraries;

View file

@ -27,13 +27,11 @@
#include "util/misc.h"
#include "gui/notifyqt.h"
#include "gui/common/FilesDefs.h"
#include "gui/msgs/MessageComposer.h"
#include "gui/connect/ConnectFriendWizard.h"
#include "gui/connect/ConfCertDialog.h"
#include <gui/QuickStartWizard.h>
#include "gui/connect/FriendRecommendDialog.h"
#include "settings/rsharesettings.h"
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QUrlQuery>
@ -137,8 +135,6 @@ HomePage::HomePage(QWidget *parent) :
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) { handleEvent(event); }, mEventHandlerId, RsEventType::NETWORK );
updateOwnCert();
updateHomeLogo();
}
void HomePage::handleEvent(std::shared_ptr<const RsEvent> e)
@ -381,11 +377,3 @@ void HomePage::openWebHelp()
{
QDesktopServices::openUrl(QUrl(QString("https://retrosharedocs.readthedocs.io/en/latest/")));
}
void HomePage::updateHomeLogo()
{
if (Settings->getSheetName() == ":Standard_Dark")
ui->label->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":images/logo/logo_web_nobackground_black.png"));
else
ui->label->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":images/logo/logo_web_nobackground.png"));
}

View file

@ -63,8 +63,7 @@ private slots:
void addFriend();
void webMail();
void openWebHelp() ;
void recommendFriends();
void updateHomeLogo();
void recommendFriends();
private:
Ui::HomePage *ui;

View file

@ -43,6 +43,7 @@
<property name="font">
<font>
<family>Courier New</family>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
@ -87,6 +88,7 @@
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
@ -105,7 +107,7 @@
<string>...</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<iconset resource="images.qrc">
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
</property>
<property name="checkable">
@ -231,6 +233,11 @@
</item>
<item row="1" column="0" colspan="5">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Open Source cross-platform,
private and secure decentralized communication platform.
@ -310,6 +317,11 @@ private and secure decentralized communication platform.
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
@ -393,6 +405,11 @@ private and secure decentralized communication platform.
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>Do you need help with Retroshare?</string>
</property>
@ -407,8 +424,8 @@ private and secure decentralized communication platform.
</layout>
</widget>
<resources>
<include location="icons.qrc"/>
<include location="images.qrc"/>
<include location="icons.qrc"/>
</resources>
<connections/>
</ui>

File diff suppressed because it is too large Load diff

View file

@ -22,10 +22,8 @@
#define IDENTITYDIALOG_H
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
#include "util/FontSizeHandler.h"
#include "retroshare/rsidentity.h"
#include "IdentityListModel.h"
#include <retroshare/rsidentity.h>
#include <QTimer>
@ -36,11 +34,7 @@ class IdDialog;
}
class UIStateHelper;
class QStyledItemDelegate;
class QTreeWidgetItem;
class RsIdentityListModel;
class IdListSortFilterProxyModel;
class QItemSelection;
class IdDialog : public MainPage
{
@ -64,7 +58,6 @@ protected:
void loadIdentity(RsGxsIdGroup id_data);
void loadCircles(const std::list<RsGroupMetaData>& circle_metas);
void updateIdListRequest();
//void requestCircleGroupData(const RsGxsCircleId& circle_id);
bool getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id) ;
@ -73,13 +66,13 @@ protected:
private slots:
void updateIdList();
void updateCircles();
void createExternalCircle();
void updateIdList();
void updateCircles();
void createExternalCircle();
void showEditExistingCircle();
void updateCirclesDisplay();
void toggleAutoBanIdentities(bool b);
void sortColumn(int col,Qt::SortOrder so);
void acceptCircleSubscription() ;
void cancelCircleSubscription() ;
@ -93,20 +86,17 @@ private slots:
void removeIdentity();
void editIdentity();
void chatIdentity();
void chatIdentityItem(const QModelIndex &indx);
void chatIdentity(const RsGxsId& toGxsId);
void sendMsg();
void chatIdentityItem(QTreeWidgetItem* item);
void sendMsg();
void copyRetroshareLink();
void on_closeInfoFrameButton_Invite_clicked();
void updateSelection(const QItemSelection &new_sel, const QItemSelection &old_sel);
void updateSelection();
void modifyReputation();
/** Create the context popup menu and it's submenus */
void IdListCustomPopupMenu( QPoint point );
void headerContextMenuRequested(QPoint);
void toggleColumnVisible();
void CircleListCustomPopupMenu(QPoint point) ;
#ifdef SUSPENDED
@ -127,12 +117,7 @@ private:
void processSettings(bool load);
QString createUsageString(const RsIdentityUsage& u) const;
void saveExpandedPathsAndSelection_idTreeView(std::set<QStringList> &expanded, std::set<QStringList> &selected);
void restoreExpandedPathsAndSelection_idTreeView(const std::set<QStringList>& expanded, const std::set<QStringList>& selelected);
void recursSaveExpandedItems_idTreeView(const QModelIndex& index, const QStringList& parent_path, std::set<QStringList>& expanded, std::set<QStringList>& selected);
void recursRestoreExpandedItems_idTreeView(const QModelIndex& index,const QStringList& parent_path,const std::set<QStringList>& expanded,const std::set<QStringList>& selected);
void requestIdData(std::list<RsGxsGroupId> &ids);
void requestIdData(std::list<RsGxsGroupId> &ids);
bool fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, const RsPgpId &ownPgpId, int accept);
void insertIdList(uint32_t token);
void filterIds();
@ -149,32 +134,20 @@ private:
private:
UIStateHelper *mStateHelper;
QTreeWidgetItem *contactsItem;
QTreeWidgetItem *allItem;
QTreeWidgetItem *ownItem;
QTreeWidgetItem *mExternalBelongingCircleItem;
QTreeWidgetItem *mExternalOtherCircleItem;
QTreeWidgetItem *mMyCircleItem;
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
int mLastSortColumn;
Qt::SortOrder mLastSortOrder;
void saveExpandedCircleItems(std::vector<bool> &expanded_root_items, std::set<RsGxsCircleId>& expanded_circle_items) const;
void saveExpandedCircleItems(std::vector<bool> &expanded_root_items, std::set<RsGxsCircleId>& expanded_circle_items) const;
void restoreExpandedCircleItems(const std::vector<bool>& expanded_root_items,const std::set<RsGxsCircleId>& expanded_circle_items);
void applyWhileKeepingTree(std::function<void()> predicate);
RsGxsId getSelectedIdentity() const;
std::list<RsGxsId> getSelectedIdentities() const;
RsGxsGroupId mId;
RsGxsGroupId mId;
RsGxsGroupId mIdToNavigate;
int filter;
bool mColumnSizeAlreadySet; // remembers if we already did some size set. If not, automatically stretch to content.
QStyledItemDelegate *mElidedLabelDelegate;
QStyledItemDelegate *mReputationDelegate;
RsIdentityListModel *mIdListModel;
IdListSortFilterProxyModel *mProxyModel;
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
RsEventsHandlerId_t mEventHandlerId_identity;
@ -184,8 +157,6 @@ private:
bool needUpdateIdsOnNextShow;
bool needUpdateCirclesOnNextShow;
FontSizeHandler mFontSizeHandler;
/* UI - Designer */
Ui::IdDialog *ui;
};

File diff suppressed because it is too large Load diff

View file

@ -703,7 +703,7 @@ void IdEditDialog::updateInterface()
const QPixmap *pixmap = ui->avatarLabel->pixmap();
if (pixmap && !pixmap->isNull()) {
ui->removeButton->setEnabled(true);
} else if (mEditGroup.mImage.mSize > 0) {
} else if (mEditGroup.mImage.mSize != NULL) {
ui->removeButton->setEnabled(true);
} else {
ui->removeButton->setEnabled(false);

View file

@ -1,968 +0,0 @@
/*******************************************************************************
* retroshare-gui/src/gui/msgs/RsFriendListModel.cpp *
* *
* Copyright 2019 by Cyril Soler <csoler@users.sourceforge.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include <list>
#include <QApplication>
#include <QDateTime>
#include <QFontMetrics>
#include <QModelIndex>
#include <QTreeView>
#include <QPainter>
#include <QIcon>
#include "gui/common/AvatarDefs.h"
#include "util/qtthreadsutils.h"
#include "util/HandleRichText.h"
#include "util/DateTime.h"
#include "gui/gxs/GxsIdDetails.h"
#include "retroshare/rsexpr.h"
#include "IdentityListModel.h"
//#define DEBUG_MODEL
//#define DEBUG_MODEL_INDEX
std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// defined elsewhere
const QString RsIdentityListModel::FilterString("filtered");
const uint32_t MAX_INTERNAL_DATA_UPDATE_DELAY = 300 ; // re-update the internal data every 5 mins. Should properly cover sleep/wake-up changes.
const uint32_t MAX_NODE_UPDATE_DELAY = 10 ; // re-update the internal data every 5 mins. Should properly cover sleep/wake-up changes.
static const uint32_t ID_DETAILS_UPDATE_DELAY = 5; // update each node every 5 secs.
RsIdentityListModel::RsIdentityListModel(QObject *parent)
: QAbstractItemModel(parent)
, mLastInternalDataUpdate(0), mLastNodeUpdate(0)
{
mFontSize = QApplication::font().pointSize();
mFilterStrings.clear();
mIdentityUpdateTimer = new QTimer();
connect(mIdentityUpdateTimer,SIGNAL(timeout()),this,SLOT(timerUpdate()));
}
void RsIdentityListModel::timerUpdate()
{
emit dataChanged(index(0,0,QModelIndex()),index(2,0,QModelIndex()));
}
RsIdentityListModel::EntryIndex::EntryIndex()
: type(ENTRY_TYPE_INVALID),category_index(0),identity_index(0)
{
}
// The index encodes the whole hierarchy of parents. This allows to very efficiently compute indices of the parent of an index.
//
// On 32 bits and 64 bits architectures the format is the following:
//
// 0x [2 bits] 00000 [24 bits] [2 bits]
// | | |
// | | +-------------- type (0=top level, 1=category, 2=identity)
// | +----------------------- identity index
// +-------------------------------------- category index
//
bool RsIdentityListModel::convertIndexToInternalId(const EntryIndex& e,quintptr& id)
{
// the internal id is set to the place in the table of items. We simply shift to allow 0 to mean something special.
if(e.type == ENTRY_TYPE_INVALID)
{
RsErr() << "ERROR: asked for the internal id of an invalid EntryIndex" ;
id = 0;
return true;
}
if(bool(e.identity_index >> 24))
{
RsErr() << "Cannot encode more than 2^24 identities. Somthing's wrong. e.identity_index = " << std::hex << e.identity_index << std::dec ;
id = 0;
return false;
}
id = ((0x3 & (uint32_t)e.category_index) << 30) + ((uint32_t)e.identity_index << 2) + (0x3 & (uint32_t)e.type);
return true;
}
bool RsIdentityListModel::convertInternalIdToIndex(quintptr ref,EntryIndex& e)
{
// Compatible with ref=0 since it will cause type=TOP_LEVEL
e.type = static_cast<RsIdentityListModel::EntryType>((ref >> 0) & 0x3) ;// 2 bits
e.identity_index = (ref >> 2) & 0xffffff;// 24 bits
e.category_index = (ref >> 30) & 0x3 ;// 2 bits
return true;
}
static QIcon createAvatar(const QPixmap &avatar, const QPixmap &overlay)
{
int avatarWidth = avatar.width();
int avatarHeight = avatar.height();
QPixmap pixmap(avatar);
int overlaySize = (avatarWidth > avatarHeight) ? (avatarWidth/2.5) : (avatarHeight/2.5);
int overlayX = avatarWidth - overlaySize;
int overlayY = avatarHeight - overlaySize;
QPainter painter(&pixmap);
painter.drawPixmap(overlayX, overlayY, overlaySize, overlaySize, overlay);
QIcon icon;
icon.addPixmap(pixmap);
return icon;
}
void RsIdentityListModel::preMods()
{
emit layoutAboutToBeChanged();
}
void RsIdentityListModel::postMods()
{
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(rowCount()-1,columnCount()-1,(void*)NULL));
emit layoutChanged();
}
int RsIdentityListModel::rowCount(const QModelIndex& parent) const
{
if(parent.column() >= COLUMN_THREAD_NB_COLUMNS)
return 0;
EntryIndex index;
if(!parent.isValid() || !convertInternalIdToIndex(parent.internalId(),index))
return mCategories.size();
switch(index.type)
{
case ENTRY_TYPE_CATEGORY: return mCategories[index.category_index].child_identity_indices.size();
case ENTRY_TYPE_TOP_LEVEL: return mCategories.size();
default:
return 0;
}
}
int RsIdentityListModel::columnCount(const QModelIndex &/*parent*/) const
{
return COLUMN_THREAD_NB_COLUMNS ;
}
bool RsIdentityListModel::hasChildren(const QModelIndex &parent) const
{
if(!parent.isValid())
return true;
EntryIndex parent_index ;
convertInternalIdToIndex(parent.internalId(),parent_index);
if(parent_index.type == ENTRY_TYPE_TOP_LEVEL)
return true;
if(parent_index.type == ENTRY_TYPE_IDENTITY)
return false;
if(parent_index.type == ENTRY_TYPE_CATEGORY)
return !mCategories[parent_index.category_index].child_identity_indices.empty();
return false;
}
RsIdentityListModel::EntryIndex RsIdentityListModel::EntryIndex::parent() const
{
EntryIndex i(*this);
switch(type)
{
case ENTRY_TYPE_CATEGORY: i.type = ENTRY_TYPE_TOP_LEVEL;
i.category_index = 0;
i.identity_index = 0;
break;
case ENTRY_TYPE_IDENTITY: i.type = ENTRY_TYPE_CATEGORY;
i.identity_index = 0;
break;
case ENTRY_TYPE_TOP_LEVEL:
std::cerr << "ERROR: calling parent() on entryindex with no parent!" << std::endl;
default:
//Can be when request root index.
break;
}
return i;
}
RsIdentityListModel::EntryIndex RsIdentityListModel::EntryIndex::child(int row) const
{
EntryIndex i;
switch(type)
{
case ENTRY_TYPE_TOP_LEVEL:
i.type = ENTRY_TYPE_CATEGORY;
i.category_index = row;
i.identity_index = 0;
break;
case ENTRY_TYPE_CATEGORY: i.type = ENTRY_TYPE_IDENTITY;
i.category_index = category_index;
i.identity_index = row;
break;
case ENTRY_TYPE_IDENTITY: i = EntryIndex();
std::cerr << "ERROR: calling child() on entryindex with no children!" << std::endl;
default:
break;
}
return i;
}
uint32_t RsIdentityListModel::EntryIndex::parentRow() const
{
switch(type)
{
default:
case ENTRY_TYPE_TOP_LEVEL: return -1;
case ENTRY_TYPE_CATEGORY : return -1;
case ENTRY_TYPE_IDENTITY : return category_index;
}
}
QModelIndex RsIdentityListModel::index(int row, int column, const QModelIndex& parent) const
{
if(row < 0 || column < 0 || column >= columnCount(parent) || row >= rowCount(parent))
return QModelIndex();
EntryIndex parent_index ;
convertInternalIdToIndex(parent.internalId(),parent_index);
#ifdef DEBUG_MODEL_INDEX
RsDbg() << "Index row=" << row << " col=" << column << " parent=" << parent << std::endl;
#endif
quintptr ref;
EntryIndex new_index = parent_index.child(row);
convertIndexToInternalId(new_index,ref);
#ifdef DEBUG_MODEL_INDEX
RsDbg() << " returning " << createIndex(row,column,ref) << std::endl;
#endif
return createIndex(row,column,ref);
}
QModelIndex RsIdentityListModel::parent(const QModelIndex& index) const
{
if(!index.isValid())
return QModelIndex();
EntryIndex I ;
convertInternalIdToIndex(index.internalId(),I);
EntryIndex p = I.parent();
if(p.type == ENTRY_TYPE_TOP_LEVEL)
return QModelIndex();
quintptr i;
convertIndexToInternalId(p,i);
return createIndex(I.parentRow(),0,i);
}
Qt::ItemFlags RsIdentityListModel::flags(const QModelIndex& index) const
{
if (!index.isValid())
return Qt::ItemFlags();
return QAbstractItemModel::flags(index);
}
QVariant RsIdentityListModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const
{
if(role == Qt::DisplayRole)
switch(section)
{
case COLUMN_THREAD_NAME: return tr("Name");
case COLUMN_THREAD_ID: return tr("Id");
case COLUMN_THREAD_REPUTATION: return QVariant();
case COLUMN_THREAD_OWNER_ID: return tr("Owner Id");
case COLUMN_THREAD_OWNER_NAME: return tr("Owner");
default:
return QVariant();
}
if(role == Qt::DecorationRole && section == COLUMN_THREAD_REPUTATION)
return QIcon(":/icons/flag-green.png");
return QVariant();
}
QVariant RsIdentityListModel::data(const QModelIndex &index, int role) const
{
#ifdef DEBUG_MESSAGE_MODEL
std::cerr << "calling data(" << index << ") role=" << role << std::endl;
#endif
if(!index.isValid())
return QVariant();
quintptr ref = (index.isValid())?index.internalId():0 ;
#ifdef DEBUG_MESSAGE_MODEL
std::cerr << "data(" << index << ")" ;
#endif
if(!ref)
{
#ifdef DEBUG_MESSAGE_MODEL
std::cerr << " [empty]" << std::endl;
#endif
return QVariant() ;
}
EntryIndex entry;
if(!convertInternalIdToIndex(ref,entry))
{
#ifdef DEBUG_MESSAGE_MODEL
std::cerr << "Bad pointer: " << (void*)ref << std::endl;
#endif
return QVariant() ;
}
switch(role)
{
case Qt::SizeHintRole: return sizeHintRole(entry,index.column()) ;
case Qt::DisplayRole: return displayRole(entry,index.column()) ;
case Qt::FontRole: return fontRole(entry,index.column()) ;
case Qt::ForegroundRole: return foregroundRole(entry,index.column()) ;
case Qt::DecorationRole: return decorationRole(entry,index.column()) ;
case FilterRole: return filterRole(entry,index.column()) ;
case SortRole: return sortRole(entry,index.column()) ;
case TreePathRole: return treePathRole(entry,index.column()) ;
default:
return QVariant();
}
}
bool RsIdentityListModel::passesFilter(const EntryIndex& e,int /*column*/) const
{
QString s ;
if(mFilterStrings.empty() || e.type != ENTRY_TYPE_IDENTITY)
return true;
auto passes_strings = [&](const QString& s) -> bool {
bool res = true;
for(auto iter(mFilterStrings.begin()); iter != mFilterStrings.end(); ++iter)
res = res && s.contains(*iter,Qt::CaseInsensitive);
return res;
};
if((mFilterType & FilterType::FILTER_TYPE_ID) && passes_strings(displayRole(e,COLUMN_THREAD_ID ).toString())) return true;
if((mFilterType & FilterType::FILTER_TYPE_NAME) && passes_strings(displayRole(e,COLUMN_THREAD_NAME ).toString())) return true;
if((mFilterType & FilterType::FILTER_TYPE_OWNER_ID) && passes_strings(displayRole(e,COLUMN_THREAD_OWNER_ID ).toString())) return true;
if((mFilterType & FilterType::FILTER_TYPE_OWNER_NAME) && passes_strings(displayRole(e,COLUMN_THREAD_OWNER_NAME).toString())) return true;
return false;
}
QVariant RsIdentityListModel::filterRole(const EntryIndex& e,int column) const
{
if(passesFilter(e,column))
return QVariant(FilterString);
return QVariant(QString());
}
uint32_t RsIdentityListModel::updateFilterStatus(ForumModelIndex /*i*/,int /*column*/,const QStringList& /*strings*/)
{
return 0;
}
void RsIdentityListModel::setFilter(uint8_t filter_type, const QStringList& strings)
{
#ifdef DEBUG_MODEL
std::cerr << "Setting filter to filter_type=" << int(filter_type) << " and strings to " ;
foreach(const QString& str,strings)
std::cerr << "\"" << str.toStdString() << "\" " ;
std::cerr << std::endl;
#endif
preMods();
mFilterType = filter_type;
mFilterStrings = strings;
postMods();
}
QVariant RsIdentityListModel::toolTipRole(const EntryIndex& fmpe,int /*column*/) const
{
switch(fmpe.type)
{
case ENTRY_TYPE_IDENTITY:
{
auto id_info = getIdentityInfo(fmpe);
if(!id_info)
return QVariant();
if(id_info->flags & RS_IDENTITY_FLAGS_IS_DEPRECATED)
return QVariant( tr("\nThis identity has a insecure fingerprint (It's probably quite old).\nYou should get rid of it now and use a new one.\nThese identities are not supported anymore.") ) ;
if(rsIdentity->isOwnId(id_info->id))
return QVariant(tr("This identity is owned by you"));
if(id_info->owner.isNull())
return QVariant("Anonymous identity");
else
{
RsPeerDetails dd;
if(rsPeers->getGPGDetails(id_info->owner,dd))
return QVariant(tr("Identity owned by profile")+" \""+ QString::fromUtf8(dd.name.c_str()) +"\" ("+QString::fromStdString(id_info->owner.toStdString()));
else
return QVariant(tr("Identity possibly owned by unknown profile")+" \""+ QString::fromUtf8(dd.name.c_str()) +"\" ("+QString::fromStdString(id_info->owner.toStdString()));
}
}
break;
case ENTRY_TYPE_CATEGORY: ; // fallthrough
default:
return QVariant();
}
}
QVariant RsIdentityListModel::sizeHintRole(const EntryIndex& e,int col) const
{
float x_factor = QFontMetricsF(QApplication::font()).height()/14.0f ;
float y_factor = QFontMetricsF(QApplication::font()).height()/14.0f ;
if(e.type == ENTRY_TYPE_IDENTITY)
y_factor *= 1.0;
if(e.type == ENTRY_TYPE_CATEGORY)
y_factor *= 1.5;
std::cerr << "sizeHintRole()" << std::endl;
switch(col)
{
default:
case COLUMN_THREAD_REPUTATION: return QVariant( QSize(x_factor * 14 , y_factor*14*1.1f ));
case COLUMN_THREAD_NAME:
case COLUMN_THREAD_ID:
case COLUMN_THREAD_OWNER_NAME:
case COLUMN_THREAD_OWNER_ID: return QFontMetricsF(QApplication::font()).boundingRect(displayRole(e,col).toString()).size();
}
}
QString RsIdentityListModel::indexIdentifier(QModelIndex index)
{
quintptr ref = (index.isValid())?index.internalId():0 ;
#ifdef DEBUG_MESSAGE_MODEL
std::cerr << "data(" << index << ")" ;
#endif
if(!ref)
{
#ifdef DEBUG_MESSAGE_MODEL
std::cerr << " [empty]" << std::endl;
#endif
return QString();
}
EntryIndex entry;
if(!convertInternalIdToIndex(ref,entry))
return QString();
return treePathRole(entry,0).toString();
}
QVariant RsIdentityListModel::treePathRole(const EntryIndex& entry,int /*column*/) const
{
if(entry.type == ENTRY_TYPE_CATEGORY)
return QString::number((int)entry.category_index);
else
return QString::fromStdString(mIdentities[mCategories[entry.category_index].child_identity_indices[entry.identity_index]].id.toStdString());
}
QVariant RsIdentityListModel::sortRole(const EntryIndex& entry,int column) const
{
switch(column)
{
case COLUMN_THREAD_REPUTATION: return decorationRole(entry,column);
case COLUMN_THREAD_ID:
case COLUMN_THREAD_OWNER_ID:
case COLUMN_THREAD_OWNER_NAME:
case COLUMN_THREAD_NAME: [[__fallthrough__]];
default:
return displayRole(entry,column);
}
}
QModelIndex RsIdentityListModel::getIndexOfIdentity(const RsGxsId& id) const
{
for(uint i=0;i<mCategories.size();++i)
for(uint j=0;j<mCategories[i].child_identity_indices.size();++j)
if(mIdentities[mCategories[i].child_identity_indices[j]].id == id)
{
EntryIndex e;
e.category_index = i;
e.identity_index = j;
e.type = ENTRY_TYPE_IDENTITY;
quintptr idx;
convertIndexToInternalId(e,idx);
return createIndex(j,0,idx);
}
return QModelIndex();
}
QModelIndex RsIdentityListModel::getIndexOfCategory(Category id) const
{
EntryIndex e;
e.category_index = id;
e.type = ENTRY_TYPE_CATEGORY;
quintptr idx;
convertIndexToInternalId(e,idx);
return createIndex((int)id,0,idx);
}
QVariant RsIdentityListModel::foregroundRole(const EntryIndex& e, int /*col*/) const
{
auto it = getIdentityInfo(e);
if(!it)
return QVariant();
if(it->flags & RS_IDENTITY_FLAGS_IS_DEPRECATED)
return QVariant(QColor(Qt::red));
return QVariant();
}
QVariant RsIdentityListModel::fontRole(const EntryIndex& e, int /*col*/) const
{
QFont f;
f.setPointSize(mFontSize);
auto it = getIdentityInfo(e);
if(it)
{
RsGxsId id(it->id);
if(rsIdentity->isOwnId(id))
f.setBold(true);
}
return QVariant(f);
}
void RsIdentityListModel::setFontSize(int s)
{
if(s != mFontSize)
{
mFontSize = s;
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mCategories.size()-1,columnCount()-1,(void*)NULL));
}
}
#ifdef DEBUG_MODEL_INDEX
std::cerr << " font role " << e.type << ", (" << (int)e.group_index << ","<< (int)e.profile_index << ","<< (int)e.node_index << ") col="<< col<<": " << std::endl;
#endif
#ifdef TODO
int status = onlineRole(e,col).toInt();
switch (status)
{
case RS_STATUS_INACTIVE:
{
QFont font ;
QTreeView* myParent = dynamic_cast<QTreeView*>(QAbstractItemModel::parent());
if (myParent)
font = myParent->font();
font.setBold(true);
return QVariant(font);
}
default:
return QVariant();
}
#endif
QVariant RsIdentityListModel::displayRole(const EntryIndex& e, int col) const
{
#ifdef DEBUG_MODEL_INDEX
std::cerr << " Display role " << e.type << ", (" << (int)e.group_index << ","<< (int)e.profile_index << ","<< (int)e.node_index << ") col="<< col<<": ";
#endif
switch(e.type)
{
case ENTRY_TYPE_CATEGORY:
{
const HierarchicalCategoryInformation *cat = getCategoryInfo(e);
if(!cat)
return QVariant();
switch(col)
{
case COLUMN_THREAD_NAME:
#ifdef DEBUG_MODEL_INDEX
std::cerr << group->group_info.name.c_str() ;
#endif
if(!cat->child_identity_indices.empty())
return QVariant(cat->category_name+" (" + QString::number(cat->child_identity_indices.size()) + ")");
else
return QVariant(cat->category_name);
default:
return QVariant();
}
}
break;
case ENTRY_TYPE_IDENTITY:
{
const HierarchicalIdentityInformation *idinfo = getIdentityInfo(e);
const QString loading_string = "["+tr("Loading...")+"]";
#ifdef DEBUG_MODEL_INDEX
std::cerr << profile->profile_info.name.c_str() ;
#endif
if(col == COLUMN_THREAD_ID) return QVariant(QString::fromStdString(idinfo->id.toStdString()) );
if(col == COLUMN_THREAD_REPUTATION) return QVariant();
if(idinfo->nickname.empty())
return loading_string;
switch(col)
{
case COLUMN_THREAD_NAME: return QVariant(QString::fromUtf8(idinfo->nickname.c_str()));
case COLUMN_THREAD_OWNER_NAME: if(idinfo->owner.isNull())
return QVariant();
else
return QVariant(QString::fromStdString(rsPeers->getGPGName(idinfo->owner)) );
case COLUMN_THREAD_OWNER_ID: if(idinfo->owner.isNull())
return QVariant();
else
return QVariant(QString::fromStdString(idinfo->owner.toStdString()) );
default:
return QVariant();
}
}
break;
default: //ENTRY_TYPE
return QVariant();
}
}
// This function makes sure that the internal data gets updated. They are situations where the notification system cannot
// send the information about changes, such as when the computer is put on sleep.
void RsIdentityListModel::checkInternalData(bool force)
{
rstime_t now = time(NULL);
if( (mLastInternalDataUpdate + MAX_INTERNAL_DATA_UPDATE_DELAY < now) || force)
updateIdentityList();
}
const RsIdentityListModel::HierarchicalCategoryInformation *RsIdentityListModel::getCategoryInfo(const EntryIndex& e) const
{
if(e.category_index >= mCategories.size())
return NULL ;
else
return &mCategories[e.category_index];
}
const RsIdentityListModel::HierarchicalIdentityInformation *RsIdentityListModel::getIdentityInfo(const EntryIndex& e) const
{
// First look into the relevant group, then for the correct profile in this group.
if(e.type != ENTRY_TYPE_IDENTITY)
return nullptr ;
if(e.category_index >= mCategories.size())
return nullptr ;
if(e.identity_index < mCategories[e.category_index].child_identity_indices.size())
{
auto& it(mIdentities[mCategories[e.category_index].child_identity_indices[e.identity_index]]);
rstime_t now = time(nullptr);
if(now > it.last_update_TS + ID_DETAILS_UPDATE_DELAY)
{
RsIdentityDetails det;
if(rsIdentity->getIdDetails(it.id,det))
{
it.nickname = det.mNickname;
it.owner = det.mPgpId;
it.flags = det.mFlags;
it.last_update_TS = now;
}
}
return &it;
}
else
{
RsErr() << "Inconsistent identity index!" ;
return nullptr;
}
}
QVariant RsIdentityListModel::decorationRole(const EntryIndex& entry,int col) const
{
switch(entry.type)
{
case ENTRY_TYPE_CATEGORY:
return QVariant();
case ENTRY_TYPE_IDENTITY:
{
const HierarchicalIdentityInformation *hn = getIdentityInfo(entry);
if(!hn)
return QVariant();
if(col == COLUMN_THREAD_REPUTATION)
return QVariant( static_cast<uint8_t>(rsReputations->overallReputationLevel(hn->id)) );
else if(col == COLUMN_THREAD_NAME)
{
QPixmap sslAvatar;
RsIdentityDetails details ;
if(!rsIdentity->getIdDetails(hn->id, details))
{
mIdentityUpdateTimer->stop();
mIdentityUpdateTimer->setSingleShot(true);
mIdentityUpdateTimer->start(500);
return QVariant();
}
else if(details.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(details.mAvatar.mData, details.mAvatar.mSize, sslAvatar,GxsIdDetails::LARGE))
return QVariant(QIcon(GxsIdDetails::makeDefaultIcon(hn->id,GxsIdDetails::SMALL)));
else
return QVariant(QIcon(sslAvatar));
}
else
return QVariant();
}
break;
default:
return QVariant();
}
}
void RsIdentityListModel::clear()
{
preMods();
mIdentities.clear();
mCategories.clear();
mCategories.resize(3);
mCategories[0].category_name = tr("My own identities");
mCategories[1].category_name = tr("My contacts");
mCategories[2].category_name = tr("All");
postMods();
emit friendListChanged();
}
void RsIdentityListModel::debug_dump() const
{
std::cerr << "==== IdentityListModel Debug dump ====" << std::endl;
std::cerr << "Invalid index : " << QModelIndex() << std::endl;
EntryIndex top_level;
top_level.type = ENTRY_TYPE_TOP_LEVEL;
quintptr id;
convertIndexToInternalId(top_level,id);
std::cerr << "Top level index: " << createIndex(0,0,id) << std::endl;
EntryIndex tei;
convertInternalIdToIndex(0,tei);
std::cerr << "Top level entry index: " << tei << std::endl;
for(uint32_t j=0;j<mCategories.size();++j)
{
std::cerr << mCategories[j].category_name.toStdString() << " (" << mCategories[j].child_identity_indices.size() << ")" << std::endl;
const auto& hg(mCategories[j].child_identity_indices);
for(uint32_t i=0;i<hg.size();++i)
{
auto idx = getIndexOfIdentity(mIdentities[hg[i]].id);
auto parent = idx.parent();
EntryIndex index;
EntryIndex index_parent;
convertInternalIdToIndex(idx.internalId(),index);
convertInternalIdToIndex(parent.internalId(),index_parent);
std::cerr << " " << mIdentities[hg[i]].id << " index = " << idx << " parent = " << idx.parent() << " EntryIndex: " << index << " Parent index: " << index_parent << std::endl;
}
}
std::cerr << "====================================" << std::endl;
}
RsGxsId RsIdentityListModel::getIdentity(const QModelIndex& i) const
{
if(!i.isValid())
return RsGxsId();
EntryIndex e;
if(!convertInternalIdToIndex(i.internalId(),e) || e.type != ENTRY_TYPE_IDENTITY)
return RsGxsId();
const HierarchicalIdentityInformation *gnode = getIdentityInfo(e);
if(gnode)
return gnode->id;
else
return RsGxsId();
}
RsIdentityListModel::EntryType RsIdentityListModel::getType(const QModelIndex& i) const
{
if(!i.isValid())
return ENTRY_TYPE_TOP_LEVEL;
EntryIndex e;
if(!convertInternalIdToIndex(i.internalId(),e))
return ENTRY_TYPE_TOP_LEVEL;
return e.type;
}
int RsIdentityListModel::getCategory(const QModelIndex& i) const
{
if(!i.isValid())
return CATEGORY_ALL;
EntryIndex e;
if(!convertInternalIdToIndex(i.internalId(),e))
return CATEGORY_ALL;
return e.category_index;
}
void RsIdentityListModel::setIdentities(const std::list<RsGroupMetaData>& identities_meta)
{
preMods();
beginResetModel();
clear();
for(auto id:identities_meta)
{
HierarchicalIdentityInformation idinfo;
idinfo.id = RsGxsId(id.mGroupId);
idinfo.last_update_TS = 0;// forces update
if(rsIdentity->isOwnId(idinfo.id))
mCategories[CATEGORY_OWN].child_identity_indices.push_back(mIdentities.size());
else if(rsIdentity->isARegularContact(RsGxsId(id.mGroupId)))
mCategories[CATEGORY_CTS].child_identity_indices.push_back(mIdentities.size());
else
mCategories[CATEGORY_ALL].child_identity_indices.push_back(mIdentities.size());
mIdentities.push_back(idinfo);
}
if (mCategories.size()>0)
{
beginInsertRows(QModelIndex(),0,mCategories.size()-1);
endInsertRows();
}
endResetModel();
postMods();
mLastInternalDataUpdate = time(NULL);
}
void RsIdentityListModel::updateIdentityList()
{
std::cerr << "Updating identity list" << std::endl;
std::list<RsGroupMetaData> ids ;
if(!rsIdentity->getIdentitiesSummaries(ids))
{
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve identity metadata." << std::endl;
return;
}
setIdentities(ids) ;
debug_dump();
}
void RsIdentityListModel::collapseItem(const QModelIndex& index)
{
if(getType(index) != ENTRY_TYPE_CATEGORY)
return;
EntryIndex entry;
if(!convertInternalIdToIndex(index.internalId(),entry))
return;
mExpandedCategories[entry.category_index] = false;
// apparently we cannot be subtle here.
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mCategories.size()-1,columnCount()-1,(void*)NULL));
}
void RsIdentityListModel::expandItem(const QModelIndex& index)
{
if(getType(index) != ENTRY_TYPE_CATEGORY)
return;
EntryIndex entry;
if(!convertInternalIdToIndex(index.internalId(),entry))
return;
mExpandedCategories[entry.category_index] = true;
// apparently we cannot be subtle here.
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mCategories.size()-1,columnCount()-1,(void*)NULL));
}

View file

@ -1,252 +0,0 @@
/*******************************************************************************
* retroshare-gui/src/gui/msgs/RsFriendListModel.h *
* *
* Copyright 2019 by Cyril Soler <csoler@users.sourceforge.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <QModelIndex>
#include <QColor>
#include "retroshare/rsstatus.h"
#include "retroshare/rsmsgs.h"
#include "retroshare/rspeers.h"
#include "retroshare/rsidentity.h"
typedef uint32_t ForumModelIndex;
// This class is the item model used by Qt to display the information
class QTimer;
class RsIdentityListModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit RsIdentityListModel(QObject *parent = NULL);
~RsIdentityListModel(){}
enum Columns {
COLUMN_THREAD_NAME = 0x00,
COLUMN_THREAD_ID = 0x01,
COLUMN_THREAD_OWNER_NAME = 0x02,
COLUMN_THREAD_OWNER_ID = 0x03,
COLUMN_THREAD_REPUTATION = 0x04,
COLUMN_THREAD_NB_COLUMNS = 0x05
};
enum Roles{ SortRole = Qt::UserRole+1,
StatusRole = Qt::UserRole+2,
UnreadRole = Qt::UserRole+3,
FilterRole = Qt::UserRole+4,
TreePathRole = Qt::UserRole+5,
};
enum FilterType{ FILTER_TYPE_NONE = 0x00,
FILTER_TYPE_ID = 0x01,
FILTER_TYPE_NAME = 0x02,
FILTER_TYPE_OWNER_NAME = 0x04,
FILTER_TYPE_OWNER_ID = 0x08
};
enum EntryType{ ENTRY_TYPE_TOP_LEVEL = 0x00,
ENTRY_TYPE_CATEGORY = 0x01,
ENTRY_TYPE_IDENTITY = 0x02,
ENTRY_TYPE_INVALID = 0x03
};
enum Category{ CATEGORY_OWN = 0x00,
CATEGORY_CTS = 0x01,
CATEGORY_ALL = 0x02
};
struct HierarchicalCategoryInformation
{
QString category_name;
std::vector<uint32_t> child_identity_indices; // index in the array of hierarchical profiles
};
// This stores all the info that is useful avoiding a call to the more expensive getIdDetails()
//
struct HierarchicalIdentityInformation
{
rstime_t last_update_TS;
RsGxsId id;
RsPgpId owner;
uint32_t flags;
std::string nickname;
};
// This structure encodes the position of a node in the hierarchy. The type tells which of the index fields are valid.
struct EntryIndex
{
public:
EntryIndex();
EntryType type; // type of the entry (group,profile,location)
friend std::ostream& operator<<(std::ostream& o, const EntryIndex& e)
{
o << "[" ;
switch(e.type)
{
case RsIdentityListModel::ENTRY_TYPE_INVALID: o << "Invalid," ; break;
case RsIdentityListModel::ENTRY_TYPE_CATEGORY: o << "Category," ; break;
case RsIdentityListModel::ENTRY_TYPE_IDENTITY: o << "Identity," ; break;
case RsIdentityListModel::ENTRY_TYPE_TOP_LEVEL: o << "Toplevel," ; break;
}
o << " CI: " << e.category_index << ", ";
o << " II: " << e.identity_index << "]";
return o;
}
// Indices w.r.t. parent. The set of indices entirely determines the position of the entry in the hierarchy.
// An index of 0xff means "undefined"
uint16_t category_index; // index of the category in the mCategory array
uint16_t identity_index; // index of the identity in its own category
EntryIndex parent() const;
EntryIndex child(int row) const;
uint32_t parentRow() const;
};
QModelIndex root() const{ return createIndex(0,0,(void*)NULL) ;}
QModelIndex getIndexOfIdentity(const RsGxsId& id) const;
QModelIndex getIndexOfCategory(Category id) const;
void updateIdentityList();
int count() const { return mIdentities.size() ; } // total number of identities
static const QString FilterString ;
// This method will asynchroneously update the data
EntryType getType(const QModelIndex&) const;
RsGxsId getIdentity(const QModelIndex&) const;
int getCategory(const QModelIndex&) const;
void setFontSize(int s);
void setFilter(uint8_t filter_type, const QStringList& strings) ;
void expandItem(const QModelIndex&) ;
void collapseItem(const QModelIndex&) ;
// Overloaded methods from QAbstractItemModel
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex& child) const override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
void clear() ;
QString indexIdentifier(QModelIndex i);
/* Color definitions (for standard see default.qss) */
QColor mTextColorGroup;
QColor mTextColorStatus[RS_STATUS_COUNT];
void setIdentities(const std::list<RsGroupMetaData>& identities_meta);
private:
const HierarchicalCategoryInformation *getCategoryInfo (const EntryIndex&) const;
const HierarchicalIdentityInformation *getIdentityInfo(const EntryIndex&) const;
void checkIdentity(HierarchicalIdentityInformation& node);
QVariant sizeHintRole (const EntryIndex& e, int col) const;
QVariant displayRole (const EntryIndex& e, int col) const;
QVariant decorationRole(const EntryIndex& e, int col) const;
QVariant toolTipRole (const EntryIndex& e, int col) const;
QVariant statusRole (const EntryIndex& e, int col) const;
QVariant sortRole (const EntryIndex& e, int col) const;
QVariant fontRole (const EntryIndex& e, int col) const;
QVariant foregroundRole(const EntryIndex& e, int col) const;
QVariant textColorRole (const EntryIndex& e, int col) const;
QVariant filterRole (const EntryIndex& e, int col) const;
QVariant treePathRole (const EntryIndex& entry,int column) const;
/*!
* \brief debug_dump
* Dumps the hierarchy of posts in the terminal, to allow checking whether the internal representation is correct.
*/
public slots:
void checkInternalData(bool force);
void debug_dump() const;
void timerUpdate();
signals:
void dataLoaded(); // emitted after the messages have been set. Can be used to updated the UI.
void friendListChanged(); // emitted after the messages have been set. Can be used to updated the UI.
void dataAboutToLoad();
private:
bool passesFilter(const EntryIndex &e, int column) const;
void preMods() ;
void postMods() ;
void *getParentRef(void *ref,int& row) const;
void *getChildRef(void *ref,int row) const;
int getChildrenCount(void *ref) const;
static bool convertIndexToInternalId(const EntryIndex& e,quintptr& ref);
static bool convertInternalIdToIndex(quintptr ref, EntryIndex& e);
uint32_t updateFilterStatus(ForumModelIndex i,int column,const QStringList& strings);
QStringList mFilterStrings;
uint8_t mFilterType;
int mFontSize;
rstime_t mLastInternalDataUpdate;
rstime_t mLastNodeUpdate;;
// The 3 vectors below store thehierarchical information for groups, profiles and locations,
// meaning which is the child/parent of which. The actual group/profile/node data are also stored in the
// structure.
mutable std::vector<HierarchicalCategoryInformation> mCategories;
mutable std::vector<HierarchicalIdentityInformation> mIdentities;
// The top level list contains all nodes to display, which type depends on the option to display groups or not.
// Idices in the list may be profile indices or group indices. In the former case the profile child index refers to
// the inde in the mProfiles tab, whereas in the the later case, the child index refers to the index of the profile in the
// group it belows to.
std::vector<EntryIndex> mTopLevel;
// keeps track of expanded/collapsed items, so as to only show icon for collapsed profiles
std::vector<bool> mExpandedCategories;
// List of identities for which getIdDetails() failed, to be requested again.
mutable QTimer *mIdentityUpdateTimer;
};

View file

@ -28,15 +28,9 @@
#include <QString>
#include <QUrl>
#include <QtDebug>
#include <QMenuBar>
#include <retroshare/rsplugin.h>
#include <retroshare/rsconfig.h>
#include <util/argstream.h>
#if defined(Q_OS_DARWIN)
#include "gui/common/MacDockIconHandler.h"
#endif
#ifdef MESSENGER_WINDOW
#include "MessengerWindow.h"
@ -120,7 +114,7 @@
#include "gui/statistics/StatisticsWindow.h"
#include "gui/connect/ConnectFriendWizard.h"
#include "gui/common/RsCollectionDialog.h"
#include "gui/common/RsCollection.h"
#include "settings/rsettingswin.h"
#include "settings/rsharesettings.h"
#include "common/StatusDefs.h"
@ -212,7 +206,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags)
hiddenmode = true;
}
setWindowTitle(tr("RetroShare %1 a secure decentralized communication platform").arg(RsApplication::retroshareVersion(true)) + " - " + nameAndLocation);
setWindowTitle(tr("RetroShare %1 a secure decentralized communication platform").arg(Rshare::retroshareVersion(true)) + " - " + nameAndLocation);
connect(rApp, SIGNAL(newArgsReceived(QStringList)), this, SLOT(receiveNewArgs(QStringList)));
/* add url handler for RetroShare links */
@ -360,8 +354,6 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags)
connect(NotifyQt::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
settingsChanged();
mFontSizeHandler.registerFontSize(ui->listWidget, 1.5f);
}
/** Destructor. */
@ -385,11 +377,6 @@ MainWindow::~MainWindow()
delete sysTrayStatus;
delete trayIcon;
delete trayMenu;
#if defined(Q_OS_DARWIN)
delete menuBar;
delete dockMenu;
MacDockIconHandler::cleanup();
#endif
// delete notifyMenu; // already deleted by the deletion of trayMenu
StatisticsWindow::releaseInstance();
@ -566,11 +553,6 @@ void MainWindow::addPage(MainPage *page, QActionGroup *grp, QList<QPair<MainPage
QListWidgetItem *item = new QListWidgetItem(QIcon(page->iconPixmap()),page->pageName()) ;
ui->listWidget->addItem(item) ;
#if defined(Q_OS_DARWIN)
QFont f = ui->toolBarPage->font();
action->setFont(f);
#endif
if (notify)
{
QPair<QAction*, QListWidgetItem*> pair = QPair<QAction*, QListWidgetItem*>( action, item);
@ -669,75 +651,10 @@ void MainWindow::createTrayIcon()
trayIcon->setContextMenu(trayMenu);
trayIcon->setIcon(QIcon(IMAGE_NOONLINE));
#if defined(Q_OS_DARWIN)
// Note: On macOS, the Dock icon is used to provide the tray's functionality.
MacDockIconHandler* dockIconHandler = MacDockIconHandler::instance();
connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, [this] {
show();
activateWindow();
});
#endif
#if defined(Q_OS_DARWIN)
createMenuBar();
#endif
connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleVisibility(QSystemTrayIcon::ActivationReason)));
trayIcon->show();
}
#if defined(Q_OS_DARWIN)
/** Creates a new menubar for macOS */
void MainWindow::createMenuBar()
{
/* Mac users sure like their shortcuts. */
actionMinimize = new QAction(tr("Minimize"),this);
actionMinimize->setShortcutContext(Qt::ApplicationShortcut);
actionMinimize->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));
actionMinimize->setShortcutVisibleInContextMenu(true);
connect(actionMinimize,SIGNAL(triggered()),this,SLOT(minimizeWindow())) ;
actionCloseWindow = new QAction(tr("Close window"),this);
actionCloseWindow->setShortcutContext(Qt::ApplicationShortcut);
actionCloseWindow->setShortcut(QKeySequence::Close);
actionCloseWindow->setShortcutVisibleInContextMenu(true);
connect(actionCloseWindow,SIGNAL(triggered()),this,SLOT(closeWindow())) ;
menuBar = new QMenuBar(this);
QMenu *fileMenu = menuBar->addMenu("");
fileMenu->addAction(actionMinimize);
fileMenu->addAction(actionCloseWindow);
dockMenu = new QMenu(this);
dockMenu->setAsDockMenu();
dockMenu->addAction(tr("Open Messages"), this, SLOT(showMess()));
dockMenu->addAction(tr("Bandwidth Graph"), this, SLOT(showBandwidthGraph()));
dockMenu->addAction(tr("Statistics"), this, SLOT(showStatisticsWindow()));
dockMenu->addAction(tr("Options"), this, SLOT(showSettings()));
dockMenu->addAction(tr("Help"), this, SLOT(showHelpDialog()));
dockMenu->addSeparator();
QMenu *statusMenu = dockMenu->addMenu(tr("Status"));
initializeStatusObject(statusMenu, true);
}
#endif
#if defined(Q_OS_DARWIN)
void MainWindow::minimizeWindow()
{
setWindowState(windowState() | Qt::WindowMinimized);
}
#endif
#if defined(Q_OS_DARWIN)
void MainWindow::closeWindow()
{
// On macOS window close is basically equivalent to window hide.
close();
}
#endif
void MainWindow::showBandwidthGraph()
{
if(_bandwidthGraph == NULL)
@ -1029,7 +946,6 @@ void SetForegroundWindowInternal(HWND hWnd)
/* Show the dialog. */
raiseWindow();
/* Set the focus to the specified page. */
_instance->ui->stackPages->setCurrentPage(page);
}
@ -1262,91 +1178,10 @@ void MainWindow::doQuit()
rApp->quit();
}
// This method parses arguments passed by the operating system. All arguments
// except -r, -f, -o and lists of rscollection files and rslinks are discarded.
//
void MainWindow::receiveNewArgs(QStringList args)
{
RsInfo() << "Received new arguments from operating system call.";
std::string argstring = RsApplication::applicationFilePath().toStdString() ;
for(auto l:args)
argstring += " " + l.toStdString();
// This class does all the job at once: validate arguments, and parses them.
std::vector<std::string> links_and_files;
argstream as(argstring.c_str());
QString omValues = QString(";full;noturtle;gaming;minimal;");
std::string opModeStr;
std::string retroshare_link_url;
std::string rscollection_file;
as >> parameter('r',"rslink",retroshare_link_url,"Retroshare:// link","Retroshare link to open in Downloads " ,false)
>> parameter('f',"rsfile",rscollection_file,"file","File to open " ,false)
>> parameter('o',"opmode",opModeStr,"opmode","Set mode (Full, NoTurtle, Gaming, Minimal) " ,false)
>> values<std::string>(back_inserter(links_and_files),"links and files");
if(!as.isOk())
{
RsErr() << "Error while parsing arguments:" ;
RsErr() << as.errorLog() ;
return;
}
if(!opModeStr.empty() && omValues.contains(";"+QString::fromStdString(opModeStr).toLower()+";"))
{
QString opmode = QString::fromStdString(opModeStr).toLower();
//RsApplication::setOpMode(opModeStr.toLower()); // Do we need this??
RsInfo() << "Setting new operating mode to \"" << opmode.toStdString() << "\"";
if (opmode == "noturtle")
opModeStatus->setCurrentIndex(static_cast<typename std::underlying_type<RsOpMode>::type>(RsOpMode::NOTURTLE) - 1);
else if (opmode == "gaming")
opModeStatus->setCurrentIndex(static_cast<typename std::underlying_type<RsOpMode>::type>(RsOpMode::GAMING) - 1);
else if (opmode == "minimal")
opModeStatus->setCurrentIndex(static_cast<typename std::underlying_type<RsOpMode>::type>(RsOpMode::MINIMAL) - 1);
else if (opmode != "")
opModeStatus->setCurrentIndex(static_cast<typename std::underlying_type<RsOpMode>::type>(RsOpMode::FULL) - 1);
opModeStatus->setOpMode();
}
// Sort all collected arguments into rscollection files and retroshare links, accordingly
QStringList rscollection_files;
QList<RetroShareLink> rslinks;
auto sort = [&](const QString s) {
if(QFile(s).exists() && s.endsWith(".rscollection"))
rscollection_files.append(QString::fromUtf8(rscollection_file.c_str()));
else if(s.startsWith("retroshare://"))
{
RetroShareLink link(s);
if(link.valid())
rslinks.push_back(link);
}
};
sort(QString::fromUtf8(rscollection_file.c_str()));
sort(QString::fromUtf8(retroshare_link_url.c_str()));
for(auto s:links_and_files)
sort(QString::fromUtf8(s.c_str()));
// Now handle links and rscollection files.
for(auto file:rscollection_files)
if(file.endsWith(".rscollection"))
openRsCollection(file);
for(auto link:rslinks)
retroshareLinkActivated(link.toUrl());
Rshare::parseArguments(args, false);
processLastArgs();
}
void MainWindow::displayErrorMessage(int /*a*/,int /*b*/,const QString& error_msg)
@ -1385,11 +1220,7 @@ void MainWindow::updateMenu()
void MainWindow::toggleVisibility(QSystemTrayIcon::ActivationReason e)
{
#if defined(Q_OS_DARWIN)
if (e == QSystemTrayIcon::DoubleClick) {
#else
if (e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) {
#endif
if (isHidden() || isMinimized()) {
show();
if (isMinimized()) {
@ -1713,9 +1544,45 @@ void MainWindow::retroshareLinkActivated(const QUrl &url)
void MainWindow::openRsCollection(const QString &filename)
{
QFileInfo qinfo(filename);
if (qinfo.exists()) {
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
RsCollection collection;
collection.openColl(qinfo.absoluteFilePath());
}
}
}
void MainWindow::processLastArgs()
{
while (!Rshare::links()->isEmpty()) {
std::cerr << "MainWindow::processLastArgs() : " << Rshare::links()->count() << std::endl;
/* Now use links from the command line, because no RetroShare was running */
RetroShareLink link(Rshare::links()->takeFirst());
if (link.valid()) {
retroshareLinkActivated(link.toUrl());
}
}
while (!Rshare::files()->isEmpty()) {
/* Now use files from the command line, because no RetroShare was running */
openRsCollection(Rshare::files()->takeFirst());
}
/* Handle the -opmode options. */
if (opModeStatus) {
QString opmode = Rshare::opmode().toLower();
if (opmode == "noturtle") {
opModeStatus->setCurrentIndex(static_cast<typename std::underlying_type<RsOpMode>::type>(RsOpMode::NOTURTLE) - 1);
} else if (opmode == "gaming") {
opModeStatus->setCurrentIndex(static_cast<typename std::underlying_type<RsOpMode>::type>(RsOpMode::GAMING) - 1);
} else if (opmode == "minimal") {
opModeStatus->setCurrentIndex(static_cast<typename std::underlying_type<RsOpMode>::type>(RsOpMode::MINIMAL) - 1);
} else if (opmode != "") {
opModeStatus->setCurrentIndex(static_cast<typename std::underlying_type<RsOpMode>::type>(RsOpMode::FULL) - 1);
}
opModeStatus->setOpMode();
} else {
std::cerr << "ERR: MainWindow::processLastArgs opModeStatus is not initialized.";
}
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath());
}
void MainWindow::switchVisibilityStatus(StatusElement e,bool b)

View file

@ -27,7 +27,6 @@
#include "gui/common/rwindow.h"
#include "gui/common/RSComboBox.h"
#include "util/FontSizeHandler.h"
namespace Ui {
class MainWindow;
@ -215,6 +214,7 @@ public slots:
void externalLinkActivated(const QUrl &url);
void retroshareLinkActivated(const QUrl &url);
void openRsCollection(const QString &filename);
void processLastArgs();
//! Go to a specific part of the control panel.
void setNewPage(int page);
void setCompactStatusMode(bool compact);
@ -265,11 +265,6 @@ private slots:
void toggleVisibility(QSystemTrayIcon::ActivationReason e);
void toggleVisibilitycontextmenu();
#if defined(Q_OS_DARWIN)
void minimizeWindow();
void closeWindow();
#endif
/** Toolbar fns. */
void addFriend();
//void newRsCollection();
@ -313,10 +308,6 @@ private:
void initStackedPage();
void addPage(MainPage *page, QActionGroup *grp, QList<QPair<MainPage *, QPair<QAction *, QListWidgetItem *> > > *notify);
void createTrayIcon();
#if defined(Q_OS_DARWIN)
/** Creates a default menubar on Mac */
void createMenuBar();
#endif
void createNotifyIcons();
static MainWindow *_instance;
@ -333,14 +324,6 @@ private:
QString nameAndLocation;
#if defined(Q_OS_DARWIN)
/** The menubar (Mac OS X only). */
QMenuBar *menuBar;
QMenu *dockMenu;
QAction* actionMinimize;
QAction* actionCloseWindow;
#endif
QSystemTrayIcon *trayIcon;
QMenu *notifyMenu;
QMenu *trayMenu;
@ -372,8 +355,6 @@ private:
void setIdle(bool Idle);
bool isIdle;
FontSizeHandler mFontSizeHandler;
Ui::MainWindow *ui ;
};

View file

@ -33,6 +33,11 @@
<height>0</height>
</size>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@ -152,7 +157,7 @@
</action>
<action name="actionOptions">
<property name="icon">
<iconset>
<iconset resource="images.qrc">
<normaloff>:/images/kcmsystem24.png</normaloff>:/images/kcmsystem24.png</iconset>
</property>
<property name="text">

View file

@ -83,7 +83,7 @@ NetworkDialog::NetworkDialog(QWidget */*parent*/)
ui.connectTreeWidget->setUpdatesEnabled(true);
ui.connectTreeWidget->setSortingEnabled(true);
ui.connectTreeWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
ui.connectTreeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
ui.connectTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
connect(ui.connectTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( connectTreeWidgetCostumPopupMenu( QPoint ) ) );
connect(ui.connectTreeWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(peerdetails()));
@ -117,12 +117,24 @@ void NetworkDialog::connectTreeWidgetCostumPopupMenu( QPoint /*point*/ )
{
return;
}
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->addSeparator() ;
contextMnu->addAction(QIcon(), tr("Remove unused keys..."), this, SLOT(removeUnusedKeys()));
contextMnu->addAction(QIcon(), tr("Remove this key"), this, SLOT(removeSelectedKeys()));
contextMnu->exec(QCursor::pos());
}
@ -165,34 +177,11 @@ void NetworkDialog::removeSelectedKeys()
QModelIndexList l = ui.connectTreeWidget->selectionModel()->selection().indexes();
if(l.empty())
return;
std::set<RsPgpId> selected;
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);
updateDisplay();
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()));
removeKeys(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));
break;
case RsChannelEventCode::NEW_COMMENT:
addFeedItem(new ChannelsCommentsItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId,pe->mChannelThreadId, false, true));
addFeedItem(new ChannelsCommentsItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId, false, true));
break;
case RsChannelEventCode::RECEIVED_PUBLISH_KEY:
addFeedItem(new GxsChannelGroupItem(this, NEWSFEED_CHANNELPUBKEYLIST, pe->mChannelGroupId, false, true));

View file

@ -70,8 +70,8 @@
<widget class="QLabel" name="titleBarLabel">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>

View file

@ -41,7 +41,7 @@
PluginManager::PluginManager()
{
baseFolder = //qApp->applicationDirPath()+"///plugins" ;
RsApplication::dataDirectory() + "/plugins" ;
Rshare::dataDirectory() + "/plugins" ;
lastError = "No error.";
viewWidget = 0;

View file

@ -22,6 +22,7 @@
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>11</pointsize>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
@ -102,6 +103,7 @@
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>9</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
@ -112,7 +114,7 @@
</widget>
</item>
<item>
<widget class="AvatarWidget" name="avatarWidget">
<widget class="AvatarWidget" name="avatarWidget" native="true">
<property name="minimumSize">
<size>
<width>24</width>
@ -132,6 +134,7 @@
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>11</pointsize>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
@ -147,6 +150,7 @@
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
@ -159,6 +163,7 @@
<property name="font">
<font>
<family>MS Sans Serif</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
@ -204,17 +209,17 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>AvatarWidget</class>
<extends>QLabel</extends>
<header>gui/common/AvatarWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GxsIdLabel</class>
<extends>QLabel</extends>
<header>gui/gxs/GxsIdLabel.h</header>
</customwidget>
<customwidget>
<class>AvatarWidget</class>
<extends>QWidget</extends>
<header>gui/common/AvatarWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>AspectRatioPixmapLabel</class>
<extends>QLabel</extends>

View file

@ -74,7 +74,7 @@ BasePostedItem::BasePostedItem( FeedHolder *feedHolder, uint32_t feedId
BasePostedItem::~BasePostedItem()
{
auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(200);
auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(200);
while( (mIsLoadingGroup || mIsLoadingMessage || mIsLoadingComment)
&& std::chrono::steady_clock::now() < timeout)
{

View file

@ -262,6 +262,7 @@
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
@ -725,17 +726,17 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>GxsIdLabel</class>
<extends>QLabel</extends>
<header>gui/gxs/GxsIdLabel.h</header>
</customwidget>
<customwidget>
<class>ElidedLabel</class>
<extends>QLabel</extends>
<header>gui/common/ElidedLabel.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GxsIdLabel</class>
<extends>QLabel</extends>
<header>gui/gxs/GxsIdLabel.h</header>
</customwidget>
<customwidget>
<class>ZoomableLabel</class>
<extends>QLabel</extends>
@ -743,9 +744,9 @@
</customwidget>
</customwidgets>
<resources>
<include location="../icons.qrc"/>
<include location="Posted_images.qrc"/>
<include location="../images.qrc"/>
<include location="Posted_images.qrc"/>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -22,7 +22,6 @@
#include <QMenu>
#include <QSignalMapper>
#include <QPainter>
#include <QClipboard>
#include <QMessageBox>
#include "retroshare/rsgxscircles.h"
@ -73,7 +72,6 @@ static const int POSTED_TABS_POSTS = 1;
//
#define IMAGE_COPYLINK ":/images/copyrslink.png"
#define IMAGE_AUTHOR ":/images/user/personal64.png"
#define IMAGE_COPYHTTP ":/images/emblem-web.png"
Q_DECLARE_METATYPE(RsPostedPost);
@ -342,18 +340,7 @@ void PostedListWidgetWithModel::postContextMenu(const QPoint& point)
// 2 - generate the menu for that post.
RsPostedPost post = index.data(Qt::UserRole).value<RsPostedPost>() ;
menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink()))->setData(index);
QByteArray urlarray(post.mLink.c_str());
QUrl url = QUrl::fromEncoded(urlarray.trimmed());
std::cerr << "Using link: \"" << post.mLink << "\"" << std::endl;
if(url.scheme()=="http" || url.scheme()=="https")
menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYHTTP), tr("Copy http Link"), this, SLOT(copyHttpLink()))->setData(index);
menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR), tr("Show author in People tab"), this, SLOT(showAuthorInPeople()))->setData(index);
#ifdef TODO
@ -469,31 +456,6 @@ void PostedListWidgetWithModel::showAuthorInPeople()
MainWindow::showWindow(MainWindow::People);
idDialog->navigate(RsGxsId(post.mMeta.mAuthorId));
}
void PostedListWidgetWithModel::copyHttpLink()
{
try
{
if (groupId().isNull())
throw std::runtime_error("No channel currently selected!");
QModelIndex index = qobject_cast<QAction*>(QObject::sender())->data().toModelIndex();
if(!index.isValid())
throw std::runtime_error("No post under mouse!");
RsPostedPost post = index.data(Qt::UserRole).value<RsPostedPost>() ;
if(post.mMeta.mMsgId.isNull())
throw std::runtime_error("Post has empty MsgId!");
QApplication::clipboard()->setText(QString::fromStdString(post.mLink)) ;
QMessageBox::information(NULL,tr("information"),tr("The Retrohare link was copied to your clipboard.")) ;
}
catch(std::exception& e)
{
QMessageBox::critical(NULL,tr("Link creation error"),tr("Link could not be created: ")+e.what());
}
}
void PostedListWidgetWithModel::copyMessageLink()
{
try
@ -619,13 +581,12 @@ void PostedListWidgetWithModel::updateGroupData()
void PostedListWidgetWithModel::postPostLoad()
{
#ifdef DEBUG_POSTED
std::cerr << "Post channel load..." << std::endl;
#endif
whileBlocking(ui->filter_LE)->setText(QString()); //Clear it before navigate, as it will update it.
if (!mNavigatePendingMsgId.isNull())
navigate(mNavigatePendingMsgId);
#ifdef TO_REMOVE
else if( (mLastSelectedPosts.count(groupId()) > 0)
&& !mLastSelectedPosts[groupId()].isNull())
@ -640,10 +601,8 @@ void PostedListWidgetWithModel::postPostLoad()
ui->postsTree->setFocus();
}
#endif
#ifdef DEBUG_POSTED
else
std::cerr << "No pre-selected channel post." << std::endl;
#endif
updateShowLabel();
}
@ -864,7 +823,6 @@ void PostedListWidgetWithModel::insertBoardDetails(const RsPostedGroup& group)
ui->subscribeToolButton->setText(tr("Subscribe"));
ui->infoPosts->setText(QString::number(group.mMeta.mVisibleMsgCount));
ui->poplabel->setText(QString::number(group.mMeta.mPop));
if(group.mMeta.mLastPost==0)
ui->infoLastPost->setText(tr("Never"));

View file

@ -147,7 +147,6 @@ private slots:
void settingsChanged();
void postPostLoad();
void copyMessageLink();
void copyHttpLink();
void nextPosts();
void prevPosts();
void filterItems(QString s);

View file

@ -54,7 +54,7 @@
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'.AppleSystemUIFont'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
@ -84,11 +84,8 @@ p, li { white-space: pre-wrap; }
<bold>true</bold>
</font>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Maximum number of data items (including posts, comments, votes) across friend nodes.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Items (at friends):</string>
<string>Contributions:</string>
</property>
</widget>
</item>
@ -182,9 +179,6 @@ p, li { white-space: pre-wrap; }
<bold>true</bold>
</font>
</property>
<property name="toolTip">
<string>Number of subscribed friend nodes</string>
</property>
<property name="text">
<string>Popularity:</string>
</property>
@ -355,10 +349,10 @@ p, li { white-space: pre-wrap; }
<item>
<widget class="QFrame" name="toolBarFrame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<enum>QFrame::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
@ -576,10 +570,37 @@ p, li { white-space: pre-wrap; }
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ElidedLabel</class>
<extends>QLabel</extends>
<header>gui/common/ElidedLabel.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GxsIdChooser</class>
<extends>QComboBox</extends>
<header>gui/gxs/GxsIdChooser.h</header>
</customwidget>
<customwidget>
<class>GxsIdLabel</class>
<extends>QLabel</extends>
<header>gui/gxs/GxsIdLabel.h</header>
</customwidget>
<customwidget>
<class>LineEditClear</class>
<extends>QLineEdit</extends>
<header location="global">gui/common/LineEditClear.h</header>
<header>gui/common/LineEditClear.h</header>
</customwidget>
<customwidget>
<class>RSComboBox</class>
<extends>QComboBox</extends>
<header>gui/common/RSComboBox.h</header>
</customwidget>
<customwidget>
<class>RSTabWidget</class>
<extends>QTabWidget</extends>
<header>gui/common/RSTabWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>RSTreeView</class>
@ -587,38 +608,11 @@ p, li { white-space: pre-wrap; }
<header>gui/common/RSTreeView.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GxsIdLabel</class>
<extends>QLabel</extends>
<header>gui/gxs/GxsIdLabel.h</header>
</customwidget>
<customwidget>
<class>ElidedLabel</class>
<extends>QLabel</extends>
<header>gui/common/ElidedLabel.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>SubscribeToolButton</class>
<extends>QToolButton</extends>
<header>gui/common/SubscribeToolButton.h</header>
</customwidget>
<customwidget>
<class>RSComboBox</class>
<extends>QComboBox</extends>
<header>gui/common/RSComboBox.h</header>
</customwidget>
<customwidget>
<class>GxsIdChooser</class>
<extends>QComboBox</extends>
<header>gui/gxs/GxsIdChooser.h</header>
</customwidget>
<customwidget>
<class>RSTabWidget</class>
<extends>QTabWidget</extends>
<header>gui/common/RSTabWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../icons.qrc"/>

View file

@ -88,16 +88,10 @@ class RSHumanReadableAgeDelegate: public RSHumanReadableDelegate
public:
virtual void paint(QPainter *painter,const QStyleOptionViewItem & option, const QModelIndex & index) const
{
painter->save();
QStyleOptionViewItem opt(option) ;
setPainterOptions(painter,opt,index) ;
if(index.data().toLongLong() > 0) { // no date is present.
painter->setFont(opt.font);
painter->drawText(opt.rect, opt.displayAlignment, misc::timeRelativeToNow(index.data().toLongLong())) ;
}
painter->restore();
painter->drawText(opt.rect, Qt::AlignCenter, misc::timeRelativeToNow(index.data().toLongLong())) ;
}
};
@ -106,14 +100,10 @@ class RSHumanReadableSizeDelegate: public RSHumanReadableDelegate
public:
virtual void paint(QPainter *painter,const QStyleOptionViewItem & option, const QModelIndex & index) const
{
painter->save();
QStyleOptionViewItem opt(option) ;
setPainterOptions(painter,opt,index) ;
painter->setFont(opt.font);
painter->drawText(opt.rect, opt.displayAlignment, misc::friendlyUnit(index.data().toULongLong()));
painter->restore();
painter->drawText(opt.rect, Qt::AlignRight, misc::friendlyUnit(index.data().toULongLong()));
}
};

View file

@ -24,7 +24,7 @@
#include "gui/common/FilesDefs.h"
#include "gui/common/GroupDefs.h"
#include "gui/common/RsCollectionDialog.h"
#include "gui/common/RsCollection.h"
#include "gui/common/RsUrlHandler.h"
#include "gui/gxs/GxsIdDetails.h"
#include "retroshare/rsfiles.h"
@ -1233,6 +1233,31 @@ bool RetroshareDirModel::requestDirDetails(void *ref, bool remote,DirDetails& d)
return false ;
}
void RetroshareDirModel::createCollectionFile(QWidget *parent, const QModelIndexList &list)
{
/* if(RemoteMode)
{
std::cerr << "Cannot create a collection file from remote" << std::endl;
return ;
}*/
std::vector <DirDetails> dirVec;
getDirDetailsFromSelect(list, dirVec);
FileSearchFlags f = RemoteMode?RS_FILE_HINTS_REMOTE:RS_FILE_HINTS_LOCAL ;
QString dir_name;
if(!RemoteMode)
{
if(!dirVec.empty())
{
const DirDetails& details = dirVec[0];
dir_name = QDir(QString::fromUtf8(details.name.c_str())).dirName();
}
}
RsCollection(dirVec,f).openNewColl(parent,dir_name);
}
void RetroshareDirModel::downloadSelected(const QModelIndexList &list,bool interactive)
{
if (!RemoteMode)
@ -1253,7 +1278,7 @@ void RetroshareDirModel::downloadSelected(const QModelIndexList &list,bool inter
FileSearchFlags f = RemoteMode?RS_FILE_HINTS_REMOTE:RS_FILE_HINTS_LOCAL ;
if(interactive)
RsCollectionDialog::downloadFiles(RsCollection(dirVec,f)) ;
RsCollection(dirVec,f).downloadFiles() ;
else /* Fire off requests */
for (int i = 0, n = dirVec.size(); i < n; ++i)
{

View file

@ -68,6 +68,8 @@ class RetroshareDirModel : public QAbstractItemModel
/* Callback from GUI */
void downloadSelected(const QModelIndexList &list, bool interactive);
void createCollectionFile(QWidget *parent, const QModelIndexList &list);
void getDirDetailsFromSelect (const QModelIndexList &list, std::vector <DirDetails>& dirVec);
int getType ( const QModelIndex & index ) const ;

View file

@ -25,7 +25,7 @@
#include "HomePage.h"
#include "chat/ChatDialog.h"
#include "common/PeerDefs.h"
#include "common/RsCollectionDialog.h"
#include "common/RsCollection.h"
#include "common/RsUrlHandler.h"
#include "connect/ConfCertDialog.h"
#include "connect/ConnectFriendWizard.h"
@ -1143,13 +1143,11 @@ QString RetroShareLink::toHtmlSize() const
if (type() == TYPE_FILE && RsCollection::isCollectionFile(name())) {
FileInfo finfo;
if (rsFiles->FileDetails(RsFileHash(hash().toStdString()), RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL, finfo))
{
RsCollection::RsCollectionErrorCode code;
RsCollection collection(QString::fromUtf8(finfo.path.c_str()), code) ;
if(code == RsCollection::RsCollectionErrorCode::COLLECTION_NO_ERROR)
if (rsFiles->FileDetails(RsFileHash(hash().toStdString()), RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL, finfo)) {
RsCollection collection;
if (collection.load(QString::fromUtf8(finfo.path.c_str()), false)) {
size += QString(" [%1]").arg(misc::friendlyUnit(collection.size()));
}
}
}
QString link = QString("<a href=\"%1\">%2</a> <font color=\"blue\">%3</font>").arg(toString()).arg(name()).arg(size);
@ -1724,9 +1722,10 @@ static void processList(const QStringList &list, const QString &textSingular, co
case TYPE_FILE_TREE:
{
auto ft = RsFileTree::fromRadix64(link.radix().toStdString() );
RsCollectionDialog::downloadFiles(RsCollection(*ft));
break;
auto ft = RsFileTree::fromRadix64(
link.radix().toStdString() );
RsCollection(*ft).downloadFiles();
break;
}
case TYPE_CHAT_ROOM:
@ -1777,7 +1776,7 @@ static void processList(const QStringList &list, const QString &textSingular, co
// were single file links found?
if (fileLinkFound)
RsCollectionDialog::downloadFiles(col);
col.downloadFiles();
int countProcessed = 0;
int countError = 0;
@ -1920,9 +1919,7 @@ static void processList(const QStringList &list, const QString &textSingular, co
void RSLinkClipboard::copyLinks(const QList<RetroShareLink>& links)
{
QString res ;
if(links.size() == 1)
res += links[0].toString();
else for(int i = 0; i < links.size(); ++i)
for (int i = 0; i < links.size(); ++i)
res += links[i].toString() + "\n" ;
QApplication::clipboard()->setText(res) ;
@ -2038,3 +2035,4 @@ void RSLinkClipboard::parseText(QString text, QList<RetroShareLink> &links,Retro
pos += rx.matchedLength();
}
}

View file

@ -123,7 +123,7 @@ void StartDialog::loadPerson()
rsNotify->cachePgpPassphrase(ui.password_input->text().toUtf8().constData()) ;
rsNotify->setDisableAskPassword(true);
bool res = RsApplication::loadCertificate(accountId, ui.autologin_checkbox->isChecked()) ;
bool res = Rshare::loadCertificate(accountId, ui.autologin_checkbox->isChecked()) ;
rsNotify->setDisableAskPassword(false);
rsNotify->clearPgpPassphrase();
@ -161,7 +161,7 @@ void StartDialog::notSecureWarning()
QMessageBox::warning ( this, tr("Warning"), tr("The password to your SSL certificate (your node) will be stored encrypted in your Keychain. \n\n Your PGP passwd will not be stored.\n\nThis choice can be reverted in settings."), QMessageBox::Ok);
#else
// this handles all linux systems at once.
QMessageBox::warning ( this, tr("Warning"), tr("The password to your SSL certificate (your node) will be stored encrypted in your desktop's keyring. \n\n Your PGP passwd will not be stored.\n\nThis choice can be reverted in settings."), QMessageBox::Ok);
QMessageBox::warning ( this, tr("Warning"), tr("The password to your SSL certificate (your node) will be stored encrypted in your Gnome Keyring. \n\n Your PGP passwd will not be stored.\n\nThis choice can be reverted in settings."), QMessageBox::Ok);
#endif
#endif
}

View file

@ -345,8 +345,8 @@ The current identities/locations will not be affected.</string>
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;Create new Profile...&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:14pt; text-decoration: underline; color:#366fe0;&quot;&gt;New Profile/Node&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;Create new Profile...&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;New Profile/Node&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
@ -370,8 +370,8 @@ p, li { white-space: pre-wrap; }
</customwidget>
</customwidgets>
<resources>
<include location="icons.qrc"/>
<include location="images.qrc"/>
<include location="icons.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -1,41 +0,0 @@
/*******************************************************************************
* gui/TheWire/CustomFrame.cpp *
* *
* Copyright (c) 2012-2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "CustomFrame.h"
#include <QPainter>
// Constructor
CustomFrame::CustomFrame(QWidget *parent) : QFrame(parent)
{
// Any initializations for this frame.
}
// Overriding the inbuilt paint function
void CustomFrame::paintEvent(QPaintEvent *event)
{
QFrame::paintEvent(event);
QPainter painter(this);
painter.drawPixmap(rect(), backgroundImage);
}
// Function to set the member variable 'backgroundImage'
void CustomFrame::setPixmap(QPixmap pixmap){
backgroundImage = pixmap;
}

View file

@ -1,44 +0,0 @@
/*******************************************************************************
* gui/TheWire/CustomFrame.h *
* *
* Copyright (c) 2012-2020 Robert Fernie <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Affero General Public License for more details. *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef CUSTOMFRAMEH_H
#define CUSTOMFRAMEH_H
#include <QFrame>
#include <QPixmap>
// This class is made to implement the background image in a Qframe or any widget
class CustomFrame : public QFrame
{
Q_OBJECT
public:
explicit CustomFrame(QWidget *parent = nullptr);
void setPixmap(QPixmap pixmap);
protected:
void paintEvent(QPaintEvent *event) override;
private:
QPixmap backgroundImage;
};
#endif //CUSTOMFRAMEH_H

View file

@ -25,7 +25,6 @@
#include "gui/gxs/GxsIdDetails.h"
#include "gui/common/FilesDefs.h"
#include "util/misc.h"
#include "util/qtthreadsutils.h"
#include "PulseAddDialog.h"
@ -99,31 +98,11 @@ void PulseAddDialog::setGroup(RsWireGroup &group)
// set ReplyWith Group.
void PulseAddDialog::setGroup(const RsGxsGroupId &grpId)
{
if(grpId.isNull()){
return;
}
/* fetch in the background */
RsWireGroupSPtr pGroup;
rsWire->getWireGroup(grpId, pGroup);
RsThread::async([this,grpId](){
RsWireGroupSPtr pGroup;
if(!rsWire->getWireGroup(grpId,pGroup))
{
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve wire group info for wire id: " << grpId << std::endl;
return;
}
RsQThreadUtils::postToObject( [pGroup,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, note that
* Qt::QueuedConnection is important!
*/
setGroup(*pGroup);
}, this );
});
setGroup(*pGroup);
}
void PulseAddDialog::cleanup()
@ -215,7 +194,7 @@ void PulseAddDialog::setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse
mReplyToPulse = pulse;
mReplyType = replyType;
ui.frame_reply->setVisible(true);
ui.pushButton_picture->hide();
ui.pushButton_picture->show();
ui.topheadshot->hide();
{
@ -244,12 +223,10 @@ void PulseAddDialog::setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse
if (mReplyType & WIRE_PULSE_TYPE_REPUBLISH) {
ui.postButton->setText(tr("Republish Pulse"));
ui.pushButton_picture->hide();
ui.pushButton_Browse->hide();
}
else if (mReplyType & WIRE_PULSE_TYPE_LIKE) {
ui.postButton->setText(tr("Like Pulse"));
ui.pushButton_picture->hide();
ui.pushButton_Browse->hide();
}
}
@ -257,46 +234,30 @@ void PulseAddDialog::setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse
void PulseAddDialog::setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, uint32_t replyType)
{
if(grpId.isNull()){
return;
}
/* fetch in the background */
RsWireGroupSPtr pGroup;
if (!rsWire->getWireGroup(grpId, pGroup))
{
std::cerr << "PulseAddDialog::setRplyTo() failed to fetch group";
std::cerr << std::endl;
return;
}
RsThread::async([this,grpId,msgId,replyType](){
RsWirePulseSPtr pPulse;
if (!rsWire->getWirePulse(grpId, msgId, pPulse))
{
std::cerr << "PulseAddDialog::setRplyTo() failed to fetch pulse";
std::cerr << std::endl;
return;
}
RsWireGroupSPtr pGroup;
RsWirePulseSPtr pPulse;
if(!rsWire->getWireGroup(grpId,pGroup))
{
std::cerr << __PRETTY_FUNCTION__ << "PulseAddDialog::setRplyTo() failed to fetch group id: " << grpId << std::endl;
return;
}
if (!rsWire->getWirePulse(grpId, msgId, pPulse))
{
std::cerr << "PulseAddDialog::setRplyTo() failed to fetch pulse of group id: " << grpId << std::endl;
return;
}
// update GroupPtr
// TODO - this should be handled in libretroshare if possible.
if (pPulse->mGroupPtr == NULL) {
pPulse->mGroupPtr = pGroup;
}
RsQThreadUtils::postToObject( [pGroup,this,pPulse,replyType]()
{
/* 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, note that
* Qt::QueuedConnection is important!
*/
setReplyTo(*pPulse, pPulse, pGroup->mMeta.mGroupName, replyType);
}, this );
});
// update GroupPtr
// TODO - this should be handled in libretroshare if possible.
if (pPulse->mGroupPtr == NULL) {
pPulse->mGroupPtr = pGroup;
}
setReplyTo(*pPulse, pPulse, pGroup->mMeta.mGroupName, replyType);
}
void PulseAddDialog::addURL()
@ -346,39 +307,26 @@ void PulseAddDialog::postOriginalPulse()
std::cerr << "PulseAddDialog::postOriginalPulse()";
std::cerr << std::endl;
RsWirePulseSPtr pPulse(new RsWirePulse());
RsWirePulseSPtr pPulse(new RsWirePulse());
pPulse->mSentiment = WIRE_PULSE_SENTIMENT_NO_SENTIMENT;
pPulse->mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
// set images here too.
pPulse->mImage1 = mImage1;
pPulse->mImage2 = mImage2;
pPulse->mImage3 = mImage3;
pPulse->mImage4 = mImage4;
pPulse->mSentiment = WIRE_PULSE_SENTIMENT_NO_SENTIMENT;
pPulse->mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
// set images here too.
pPulse->mImage1 = mImage1;
pPulse->mImage2 = mImage2;
pPulse->mImage3 = mImage3;
pPulse->mImage4 = mImage4;
RsThread::async([this,pPulse](){
if (!rsWire->createOriginalPulse(mGroup.mMeta.mGroupId, pPulse))
{
std::cerr << "PulseAddDialog::postOriginalPulse() FAILED";
std::cerr << std::endl;
return;
}
RsQThreadUtils::postToObject( [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, note that
* Qt::QueuedConnection is important!
*/
clearDialog();
hide();
}, this );
});
// this should be in async thread, so doesn't block UI thread.
if (!rsWire->createOriginalPulse(mGroup.mMeta.mGroupId, pPulse))
{
std::cerr << "PulseAddDialog::postOriginalPulse() FAILED";
std::cerr << std::endl;
return;
}
clearDialog();
hide();
}
uint32_t PulseAddDialog::toPulseSentiment(int index)
@ -408,15 +356,15 @@ void PulseAddDialog::postReplyPulse()
std::cerr << "PulseAddDialog::postReplyPulse()";
std::cerr << std::endl;
RsWirePulseSPtr pPulse(new RsWirePulse());
RsWirePulseSPtr pPulse(new RsWirePulse());
pPulse->mSentiment = toPulseSentiment(ui.comboBox_sentiment->currentIndex());
pPulse->mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
// set images here too.
pPulse->mImage1 = mImage1;
pPulse->mImage2 = mImage2;
pPulse->mImage3 = mImage3;
pPulse->mImage4 = mImage4;
pPulse->mSentiment = toPulseSentiment(ui.comboBox_sentiment->currentIndex());
pPulse->mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
// set images here too.
pPulse->mImage1 = mImage1;
pPulse->mImage2 = mImage2;
pPulse->mImage3 = mImage3;
pPulse->mImage4 = mImage4;
if (mReplyType & WIRE_PULSE_TYPE_REPUBLISH) {
// Copy details from parent, and override
@ -430,33 +378,20 @@ void PulseAddDialog::postReplyPulse()
pPulse->mImage4 = mReplyToPulse.mImage4;
}
RsThread::async([this, pPulse](){
if (!rsWire->createReplyPulse(mReplyToPulse.mMeta.mGroupId,
mReplyToPulse.mMeta.mOrigMsgId,
mGroup.mMeta.mGroupId,
mReplyType,
pPulse))
{
std::cerr << "PulseAddDialog::postReplyPulse() FAILED";
std::cerr << std::endl;
return;
}
RsQThreadUtils::postToObject( [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, note that
* Qt::QueuedConnection is important!
*/
clearDialog();
hide();
}, this );
});
// this should be in async thread, so doesn't block UI thread.
if (!rsWire->createReplyPulse(mReplyToPulse.mMeta.mGroupId,
mReplyToPulse.mMeta.mOrigMsgId,
mGroup.mMeta.mGroupId,
mReplyType,
pPulse))
{
std::cerr << "PulseAddDialog::postReplyPulse() FAILED";
std::cerr << std::endl;
return;
}
clearDialog();
hide();
}
void PulseAddDialog::clearDialog()

View file

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

View file

@ -40,7 +40,10 @@
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
<string notr="true">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}</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>

View file

@ -767,6 +767,7 @@
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>

View file

@ -24,149 +24,86 @@
#include <QBuffer>
#include "PulseViewGroup.h"
#include "CustomFrame.h"
#include "WireGroupDialog.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/common/FilesDefs.h"
#include "util/DateTime.h"
Q_DECLARE_METATYPE(RsWireGroup)
/** Constructor */
PulseViewGroup::PulseViewGroup(PulseViewHolder *holder, RsWireGroupSPtr group)
:PulseViewItem(holder), mGroup(group)
{
setupUi(this);
setAttribute ( Qt::WA_DeleteOnClose, true );
setup();
connect(editButton, SIGNAL(clicked()), this, SLOT(editProfile()));
setupUi(this);
setAttribute ( Qt::WA_DeleteOnClose, true );
setup();
}
void PulseViewGroup::setup()
{
if (mGroup) {
connect(followButton, SIGNAL(clicked()), this, SLOT(actionFollow()));
if (mGroup) {
connect(followButton, SIGNAL(clicked()), this, SLOT(actionFollow()));
label_groupName->setText("@" + QString::fromStdString(mGroup->mMeta.mGroupName));
label_authorName->setText(BoldString(QString::fromStdString(mGroup->mMeta.mAuthorId.toStdString())));
label_date->setText(DateTime::formatDateTime(mGroup->mMeta.mPublishTs));
label_tagline->setText(QString::fromStdString(mGroup->mTagline));
label_location->setText(QString::fromStdString(mGroup->mLocation));
label_groupName->setText("@" + QString::fromStdString(mGroup->mMeta.mGroupName));
label_authorName->setText(BoldString(QString::fromStdString(mGroup->mMeta.mAuthorId.toStdString())));
label_date->setText(DateTime::formatDateTime(mGroup->mMeta.mPublishTs));
label_tagline->setText(QString::fromStdString(mGroup->mTagline));
label_location->setText(QString::fromStdString(mGroup->mLocation));
// need to draw mGroup->mMasthead, as background to headshot.
// TODO frame_headerBackground->setBackground()
if (mGroup->mMasthead.mData)
{
QPixmap pixmap;
if (GxsIdDetails::loadPixmapFromData(
mGroup->mMasthead.mData,
mGroup->mMasthead.mSize,
pixmap, GxsIdDetails::ORIGINAL))
{
QSize frameSize = frame_masthead->size();
// Scale the pixmap based on the frame size
pixmap = pixmap.scaledToWidth(frameSize.width(), Qt::SmoothTransformation);
frame_masthead->setPixmap(pixmap);
}
}
// Uncomment the below code for default background
// else
// {
// // Default pixmap
// QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/png/posted.png");
// QSize frameSize = frame_masthead->size();
// // Scale the pixmap based on the frame size
// pixmap = pixmap.scaled(frameSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
// frame_masthead->setPixmap(pixmap);
// }
if (mGroup->mHeadshot.mData)
{
QPixmap pixmap;
if (GxsIdDetails::loadPixmapFromData(
mGroup->mHeadshot.mData,
mGroup->mHeadshot.mSize,
pixmap,GxsIdDetails::ORIGINAL))
{
pixmap = pixmap.scaled(100,100, Qt::KeepAspectRatio, Qt::SmoothTransformation);
label_headshot->setPixmap(pixmap);
}
}
else
{
if (mGroup->mHeadshot.mData)
{
QPixmap pixmap;
if (GxsIdDetails::loadPixmapFromData(
mGroup->mHeadshot.mData,
mGroup->mHeadshot.mSize,
pixmap,GxsIdDetails::ORIGINAL))
{
pixmap = pixmap.scaled(50,50);
label_headshot->setPixmap(pixmap);
}
}
else
{
// default.
QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png").scaled(100,100, Qt::KeepAspectRatio, Qt::SmoothTransformation);
label_headshot->setPixmap(pixmap);
}
QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/png/posted.png").scaled(50,50);
label_headshot->setPixmap(pixmap);
}
if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
uint32_t pulses = mGroup->mGroupPulses + mGroup->mGroupReplies;
uint32_t replies = mGroup->mRefReplies;
uint32_t republishes = mGroup->mRefRepublishes;
uint32_t likes = mGroup->mRefLikes;
if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
uint32_t pulses = mGroup->mGroupPulses + mGroup->mGroupReplies;
uint32_t replies = mGroup->mRefReplies;
uint32_t republishes = mGroup->mRefRepublishes;
uint32_t likes = mGroup->mRefLikes;
label_extra_pulses->setText(BoldString(ToNumberUnits(pulses)));
label_extra_replies->setText(BoldString(ToNumberUnits(replies)));
label_extra_republishes->setText(BoldString(ToNumberUnits(republishes)));
label_extra_likes->setText(BoldString(ToNumberUnits(likes)));
label_extra_pulses->setText(BoldString(ToNumberUnits(pulses)));
label_extra_replies->setText(BoldString(ToNumberUnits(replies)));
label_extra_republishes->setText(BoldString(ToNumberUnits(republishes)));
label_extra_likes->setText(BoldString(ToNumberUnits(likes)));
// hide follow.
widget_actions->setVisible(false);
}
else
{
// hide stats.
widget_replies->setVisible(false);
}
}
setGroupSet();
}
void PulseViewGroup::setGroupSet()
{
if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) {
editButton->show();
}
else if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
editButton->hide();
}
else
{
editButton->hide();
// hide follow.
widget_actions->setVisible(false);
}
else
{
// hide stats.
widget_replies->setVisible(false);
}
}
}
void PulseViewGroup::actionFollow()
{
RsGxsGroupId groupId = mGroup->mMeta.mGroupId;
std::cerr << "PulseViewGroup::actionFollow() following ";
std::cerr << groupId;
std::cerr << std::endl;
if (mHolder) {
mHolder->PVHfollow(groupId);
}
}
void PulseViewGroup::editProfile()
{
RsGxsGroupId groupId = mGroup->mMeta.mGroupId;
if (groupId.isNull())
{
std::cerr << "PulseViewGroup::editProfile() No Group selected";
std::cerr << std::endl;
return;
}
std::cerr << "PulseViewGroup::actionFollow() following ";
std::cerr << groupId;
std::cerr << std::endl;
WireGroupDialog wireEdit(GxsGroupDialog::MODE_EDIT, groupId, this);
wireEdit.exec ();
if (mHolder) {
mHolder->PVHfollow(groupId);
}
}

View file

@ -35,13 +35,10 @@ public:
private slots:
void actionFollow();
void editProfile();
protected:
void setup();
private:
void setGroupSet();
protected:
RsWireGroupSPtr mGroup;

View file

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>746</width>
<width>745</width>
<height>483</height>
</rect>
</property>
@ -48,37 +48,19 @@
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="plainFrame_VL">
<item>
<widget class="CustomFrame" name="frame_masthead">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>700</width>
<height>135</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<widget class="QFrame" name="frame_headerBackground">
<layout class="QHBoxLayout" name="frame_headerBackground_HL">
<item>
<spacer name="widget_actions_RHSpacer_2">
<spacer name="frame_headerBackground_LHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>277</width>
<height>17</height>
<width>283</width>
<height>20</height>
</size>
</property>
</spacer>
@ -97,22 +79,19 @@
<height>100</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>headshot</string>
</property>
</widget>
</item>
<item>
<spacer name="widget_actions_LHSpacer_2">
<spacer name="frame_headerBackground_RHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>281</width>
<width>23</width>
<height>20</height>
</size>
</property>
@ -136,6 +115,38 @@
</size>
</property>
<layout class="QGridLayout" name="widget_header_GL">
<item row="0" column="1" rowspan="3">
<spacer name="widget_header_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>518</width>
<height>58</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_groupName">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#555753;&quot;&gt;@sidler_here&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_authorName">
<property name="sizePolicy">
@ -171,45 +182,6 @@
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_groupName">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#555753;&quot;&gt;@sidler_here&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="3">
<spacer name="widget_header_HSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>518</width>
<height>58</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2" rowspan="3">
<widget class="QPushButton" name="editButton">
<property name="text">
<string>Edit profile</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -234,44 +206,6 @@
</size>
</property>
<layout class="QGridLayout" name="widget_publish_GL">
<item row="1" column="0">
<widget class="QLabel" name="label_location">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Location</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="label_tagline">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Tag Line</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_date">
<property name="sizePolicy">
@ -291,19 +225,6 @@
</property>
</widget>
</item>
<item row="1" column="3">
<spacer name="widget_publish_RHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>2000</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<spacer name="widget_publish_LHSpacer">
<property name="orientation">
@ -320,6 +241,57 @@
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_location">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Location</string>
</property>
</widget>
</item>
<item row="1" column="3">
<spacer name="widget_publish_RHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>2000</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="label_tagline">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>Tag Line</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -566,25 +538,10 @@
</widget>
</item>
</layout>
<zorder>widget_header</zorder>
<zorder>widget_publish</zorder>
<zorder>line_1</zorder>
<zorder>widget_replies</zorder>
<zorder>line_2</zorder>
<zorder>widget_actions</zorder>
<zorder>frame_masthead</zorder>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CustomFrame</class>
<extends>QFrame</extends>
<header>gui/TheWire/CustomFrame.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -140,7 +140,6 @@ WireDialog::~WireDialog()
processSettings(false);
clearTwitterView();
std::cerr << "WireDialog::~WireDialog()" << std::endl;
delete(mWireQueue);
rsEvents->unregisterEventsHandler(mEventHandlerId);
@ -155,16 +154,9 @@ void WireDialog::processSettings(bool load)
// state of splitter
ui.splitter->restoreState(Settings->value("SplitterWire").toByteArray());
// state of filter combobox
int index = Settings->value("ShowGroup", 0).toInt();
ui.comboBox_groupSet->setCurrentIndex(index);
} else {
// save settings
// state of filter combobox
Settings->setValue("ShowGroup", ui.comboBox_groupSet->currentIndex());
// state of splitter
Settings->setValue("SplitterWire", ui.splitter->saveState());
}
@ -475,13 +467,13 @@ bool WireDialog::loadGroupData(const uint32_t &token)
std::cerr << "WireDialog::loadGroupData()";
std::cerr << std::endl;
std::vector<RsWireGroup> groups;
rsWire->getGroupData(token, groups);
std::vector<RsWireGroup> groups;
rsWire->getGroupData(token, groups);
// save list of groups.
updateGroups(groups);
showGroups();
return true;
// save list of groups.
updateGroups(groups);
showGroups();
return true;
}
rstime_t WireDialog::getFilterTimestamp()
@ -689,7 +681,6 @@ void WireDialog::PVHrate(const RsGxsId &authorId)
void WireDialog::postTestTwitterView()
{
clearTwitterView();
std::cerr << "WireDialog::postTestTwitterView()" << std::endl;
addTwitterView(new PulseTopLevel(NULL,RsWirePulseSPtr()));
addTwitterView(new PulseReply(NULL,RsWirePulseSPtr()));
@ -846,7 +837,6 @@ void WireDialog::requestPulseFocus(const RsGxsGroupId groupId, const RsGxsMessag
void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId msgId)
{
clearTwitterView();
std::cerr << "WireDialog::showPulseFocus()" << std::endl;
// background thread for loading.
RsThread::async([this, groupId, msgId]()
@ -876,8 +866,6 @@ void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId
void WireDialog::postPulseFocus(RsWirePulseSPtr pPulse)
{
clearTwitterView();
std::cerr << "WireDialog::postPulseFocus()" << std::endl;
if (!pPulse)
{
std::cerr << "WireDialog::postPulseFocus() Invalid pulse";
@ -950,7 +938,7 @@ void WireDialog::requestGroupFocus(const RsGxsGroupId groupId)
void WireDialog::showGroupFocus(const RsGxsGroupId groupId)
{
clearTwitterView();
std::cerr << "WireDialog::showGroupFocus()" << std::endl;
// background thread for loading.
RsThread::async([this, groupId]()
{
@ -1027,7 +1015,6 @@ void WireDialog::requestGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
void WireDialog::showGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
{
clearTwitterView();
std::cerr << "WireDialog::showGroupPulses()" << std::endl;
// background thread for loading.
RsThread::async([this, groupIds]()
@ -1077,3 +1064,4 @@ void WireDialog::postGroupsPulses(std::list<RsWirePulseSPtr> pulses)
}
}

View file

@ -150,7 +150,7 @@ private:
// Loading Data.
void requestGroupData();
bool loadGroupData(const uint32_t &token);
bool loadGroupData(const uint32_t &token);
void acknowledgeGroup(const uint32_t &token, const uint32_t &userType);
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) override;

View file

@ -434,8 +434,8 @@
</customwidget>
</customwidgets>
<resources>
<include location="../icons.qrc"/>
<include location="TheWire_images.qrc"/>
<include location="../icons.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -152,7 +152,7 @@ bool WireGroupDialog::service_updateGroup(const RsGroupMetaData &editedMeta)
std::cerr << "WireGroupDialog::service_updateGroup() submitting changes";
std::cerr << std::endl;
bool success = rsWire->editWire(grp);
bool success = rsWire->updateGroup(grp);
// TODO updateGroup should refresh groupId or Data
return success;
}

View file

@ -34,19 +34,13 @@ WireGroupExtra::~WireGroupExtra()
void WireGroupExtra::setUp()
{
connect(ui.pushButton_masthead, SIGNAL(clicked() ), this , SLOT(addMasthead()));
int desired_height = ui.pushButton_masthead->height() + ui.removeButton->height() + ui.lineEdit_Tagline->height();
int desired_width = 3/1.0 * desired_height + ui.lineEdit_Tagline->width();
ui.label_masthead->setFixedSize(desired_width, desired_height);
setMasthead(QPixmap());
connect(ui.pushButton_masthead, SIGNAL(clicked() ), this , SLOT(addMasthead()));
}
void WireGroupExtra::addMasthead()
{
QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Masthead"), 800, 600);
QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Masthead"), 400, 100);
if (img.isNull())
return;
@ -54,6 +48,7 @@ void WireGroupExtra::addMasthead()
setMasthead(img);
}
void WireGroupExtra::setTagline(const std::string &str)
{
ui.lineEdit_Tagline->setText(QString::fromStdString(str));
@ -66,21 +61,8 @@ void WireGroupExtra::setLocation(const std::string &str)
void WireGroupExtra::setMasthead(const QPixmap &pixmap)
{
mMasthead = pixmap;
if (!mMasthead.isNull()) {
ui.label_masthead->setPicture(mMasthead);
ui.label_masthead->setToolTip(tr("Use the mouse to zoom and adjust the image for your background."));
} else {
ui.label_masthead->setPicture(QPixmap());
ui.label_masthead->setText(tr("MastHead background Image"));
}
}
void WireGroupExtra::on_removeButton_clicked()
{
ui.label_masthead->setPicture(QPixmap());
ui.label_masthead->setText(tr("MastHead background Image"));
mMasthead = pixmap;
ui.label_masthead->setPixmap(mMasthead);
}
std::string WireGroupExtra::getTagline()
@ -95,5 +77,7 @@ std::string WireGroupExtra::getLocation()
QPixmap WireGroupExtra::getMasthead()
{
return ui.label_masthead->extractCroppedScaledPicture();
return mMasthead;
}

View file

@ -34,6 +34,7 @@ public:
void setMasthead(const QPixmap &pixmap);
QPixmap getMasthead();
void setTagline(const std::string &str);
void setLocation(const std::string &str);
@ -42,7 +43,7 @@ public:
private slots:
void addMasthead();
void on_removeButton_clicked();
private:
void setUp();
private:

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>516</width>
<height>133</height>
<height>199</height>
</rect>
</property>
<property name="sizePolicy">
@ -19,127 +19,50 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_Location"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="captionLabel">
<property name="text">
<string>Tagline:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_Tagline"/>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="removeButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Location:</string>
</property>
</widget>
</item>
<item row="0" 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>10</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButton_masthead">
<property name="text">
<string>Select Image</string>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1" rowspan="3">
<widget class="ZoomableLabel" name="label_masthead">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="text">
<string>MastHead background Image</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Masthead</string>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QLabel" name="label_masthead">
<property name="text">
<string>MastHead background Image</string>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<widget class="QPushButton" name="pushButton_masthead">
<property name="text">
<string>Select Image</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="captionLabel">
<property name="text">
<string>Tagline:</string>
</property>
</spacer>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_Tagline"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Location:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_Location"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ZoomableLabel</class>
<extends>QLabel</extends>
<header>gui/gxschannels/GxsChannelPostThumbnail.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -65,7 +65,8 @@ WireGroupItem::WireGroupItem(WireGroupHolder *holder, const RsWireGroup &grp)
setAttribute ( Qt::WA_DeleteOnClose, true );
setup();
editButton->setEnabled(true);
// disabled, still not yet functional Edit/Update
editButton->setEnabled(false);
}
RsGxsGroupId &WireGroupItem::groupId()
@ -92,14 +93,14 @@ void WireGroupItem::setup()
QImage circleImage = getCirclePhoto(orginalImage,orginalImage.size().width());
pixmap.convertFromImage(circleImage);
pixmap = pixmap.scaled(40,40, Qt::KeepAspectRatio, Qt::SmoothTransformation);
pixmap = pixmap.scaled(40,40);
label_headshot->setPixmap(pixmap);
}
}
else
{
// default.
QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png").scaled(32,32, Qt::KeepAspectRatio, Qt::SmoothTransformation);
QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png").scaled(32,32);
label_headshot->setPixmap(pixmap);
}
@ -123,21 +124,21 @@ void WireGroupItem::setup()
void WireGroupItem::setGroupSet()
{
if (mGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) {
toolButton_type->setText(tr("Own"));
toolButton_subscribe->setText(tr("N/A"));
toolButton_type->setText("Own");
toolButton_subscribe->setText("N/A");
toolButton_subscribe->setEnabled(false);
editButton->show();
}
else if (mGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
toolButton_type->setText(tr("Following"));
toolButton_subscribe->setText(tr("Unfollow"));
toolButton_type->setText("Following");
toolButton_subscribe->setText("Unfollow");
editButton->hide();
}
else
{
toolButton_type->setText(tr("Other"));
toolButton_subscribe->setText(tr("Follow"));
toolButton_type->setText("Other");
toolButton_subscribe->setText("Follow");
editButton->hide();
}
}

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>292</width>
<height>115</height>
<width>276</width>
<height>114</height>
</rect>
</property>
<property name="windowTitle">

View file

@ -208,8 +208,6 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
connect(unsubscribeButton, SIGNAL(clicked()), this , SLOT(leaveLobby()));
getChatWidget()->addTitleBarWidget(unsubscribeButton) ;
mFontSizeHandler.registerFontSize(ui.participantsList);
}
void ChatLobbyDialog::leaveLobby()

View file

@ -26,7 +26,6 @@
#include "gui/common/RSTreeWidgetItem.h"
#include "ChatDialog.h"
#include "PopupChatWindow.h"
#include "util/FontSizeHandler.h"
// Q_DECLARE_METATYPE(RsGxsId)
// Q_DECLARE_METATYPE(QList<RsGxsId>)
@ -116,8 +115,6 @@ private:
bool mWindowedSetted;
PopupChatWindow* mPCWindow;
FontSizeHandler mFontSizeHandler;
/** Qt Designer generated object */
Ui::ChatLobbyDialog ui;

View file

@ -146,48 +146,8 @@ QString ChatLobbyUserNotify::getNotifyMessage(bool plural)
void ChatLobbyUserNotify::iconClicked()
{
#if defined(Q_OS_DARWIN)
std::list<ChatLobbyId> lobbies;
rsMsgs->getChatLobbyList(lobbies);
bool doUpdate=false;
for (lobby_map::iterator itCL=_listMsg.begin(); itCL!=_listMsg.end();)
{
bool bFound=false;
QString strLobbyName=tr("Unknown Lobby");
QIcon icoLobby=QIcon();
std::list<ChatLobbyId>::const_iterator lobbyIt;
for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) {
ChatLobbyId clId = *lobbyIt;
if (clId==itCL->first) {
ChatLobbyInfo clInfo;
if (rsMsgs->getChatLobbyInfo(clId,clInfo))
strLobbyName=QString::fromUtf8(clInfo.lobby_name.c_str()) ;
bFound=true;
break;
}
}
if (bFound)
{
MainWindow::showWindow(MainWindow::ChatLobby);
ChatLobbyWidget *chatLobbyWidget = dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby));
if (chatLobbyWidget) chatLobbyWidget->showLobbyAnchor(itCL->first,strLobbyName);
++itCL ;
}
else
{
lobby_map::iterator ittmp(itCL);
++ittmp ;
_listMsg.erase(itCL);
itCL=ittmp ;
doUpdate=true;
}
}
#else
/// Tray icon Menu ///
QMenu* trayMenu = createMenu();
QMenu* trayMenu = new QMenu(MainWindow::getInstance());
std::list<ChatLobbyId> lobbies;
rsMsgs->getChatLobbyList(lobbies);
bool doUpdate=false;
@ -226,25 +186,27 @@ void ChatLobbyUserNotify::iconClicked()
}
}
if (notifyCombined()) {
QSystemTrayIcon* trayIcon=getTrayIcon();
if (trayIcon!=NULL) trayIcon->setContextMenu(trayMenu);
} else {
QAction* action=getNotifyIcon();
if (action!=NULL) {
action->setMenu(trayMenu);
}
}
QString strName=tr("Remove All");
QAction *pAction = new QAction( QIcon(), strName, trayMenu);
ActionTag actionTag={0x0, "", true};
pAction->setData(qVariantFromValue(actionTag));
connect(trayMenu, SIGNAL(triggered(QAction*)), this, SLOT(subMenuClicked(QAction*)));
connect(trayMenu, SIGNAL(hovered(QAction*)), this, SLOT(subMenuHovered(QAction*)));
trayMenu->addAction(pAction);
trayMenu->exec(QCursor::pos());
delete(trayMenu);
if (doUpdate) updateIcon();
#endif
}
QMenu* ChatLobbyUserNotify::createMenu()
{
QMenu* menu = new QMenu(MainWindow::getInstance());
connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(subMenuClicked(QAction*)));
connect(menu, SIGNAL(hovered(QAction*)), this, SLOT(subMenuHovered(QAction*)));
return menu;
}
void ChatLobbyUserNotify::makeSubMenu(QMenu* parentMenu, QIcon icoLobby, QString strLobbyName, ChatLobbyId id)
@ -255,7 +217,11 @@ void ChatLobbyUserNotify::makeSubMenu(QMenu* parentMenu, QIcon icoLobby, QString
unsigned int msgCount=msgMap.size();
if(!parentMenu) parentMenu = new QMenu(MainWindow::getInstance());
QMenu *lobbyMenu = parentMenu->addMenu(icoLobby, strLobbyName);
connect(lobbyMenu, SIGNAL(triggered(QAction*)), this, SLOT(subMenuClicked(QAction*)));
connect(lobbyMenu, SIGNAL(hovered(QAction*)), this, SLOT(subMenuHovered(QAction*)));
lobbyMenu->setToolTip(getNotifyMessage(msgCount>1).arg(msgCount));
for (msg_map::iterator itMsg=msgMap.begin(); itMsg!=msgMap.end(); ++itMsg) {
@ -277,6 +243,7 @@ void ChatLobbyUserNotify::makeSubMenu(QMenu* parentMenu, QIcon icoLobby, QString
ActionTag actionTag={itCL->first, "", true};
pAction->setData(qVariantFromValue(actionTag));
lobbyMenu->addAction(pAction);
}
void ChatLobbyUserNotify::iconHovered()
@ -284,6 +251,7 @@ void ChatLobbyUserNotify::iconHovered()
iconClicked();
}
void ChatLobbyUserNotify::chatLobbyNewMessage(ChatLobbyId lobby_id, QDateTime time, QString senderName, QString msg)
{

Some files were not shown because too many files have changed in this diff Show more