mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-04-11 18:29:16 -04:00
Compare commits
235 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f2bf2f04cc | ||
![]() |
42bbf785ea | ||
![]() |
f26fc5ab14 | ||
![]() |
06c0be19e9 | ||
![]() |
e87566ef92 | ||
![]() |
18b14a033a | ||
![]() |
973246624f | ||
![]() |
93154fddc4 | ||
![]() |
cab91819d6 | ||
![]() |
95ea588c9f | ||
![]() |
2644a0ccb7 | ||
![]() |
c61c939b2a | ||
![]() |
cd338613c1 | ||
![]() |
49242e185b | ||
![]() |
5005c0303d | ||
![]() |
a5752ec4d3 | ||
![]() |
6d394c9f55 | ||
![]() |
3ffa362079 | ||
![]() |
b168110a58 | ||
![]() |
7399c42dfb | ||
![]() |
533caea81e | ||
![]() |
18f4ef5574 | ||
![]() |
e14fc66ca3 | ||
![]() |
b99988385f | ||
![]() |
85b6d18094 | ||
![]() |
86d96fe60c | ||
![]() |
8fcc52b304 | ||
![]() |
5f3f1c9c43 | ||
![]() |
e835385000 | ||
![]() |
e44a216873 | ||
![]() |
4b5dd51681 | ||
![]() |
e18bb74a5e | ||
![]() |
c9599ea817 | ||
![]() |
b2d05d7d8e | ||
![]() |
2c53c02319 | ||
![]() |
99053597a9 | ||
![]() |
e5f2ef2335 | ||
![]() |
0759359e06 | ||
![]() |
2ca36f5957 | ||
![]() |
89ceba2f92 | ||
![]() |
41bb83054c | ||
![]() |
f9ca8934db | ||
![]() |
01617da863 | ||
![]() |
8d96bb920d | ||
![]() |
b502dd71e2 | ||
![]() |
359305c24f | ||
![]() |
ca2f8c5bed | ||
![]() |
ccd1cfbde6 | ||
![]() |
32a43b1892 | ||
![]() |
6cde715e66 | ||
![]() |
6825c7e925 | ||
![]() |
433ab6514d | ||
![]() |
142049a61e | ||
![]() |
8cc2cf8cd2 | ||
![]() |
cbd9dfc86a | ||
![]() |
675b430833 | ||
![]() |
b17cb811d6 | ||
![]() |
d6d2f09673 | ||
![]() |
d79ce90c68 | ||
![]() |
38e82adaea | ||
![]() |
5d7b235941 | ||
![]() |
8e94a99a53 | ||
![]() |
6a77d6b7bc | ||
![]() |
e6f1878f1f | ||
![]() |
9a7c94314c | ||
![]() |
5c9bf3bf7c | ||
![]() |
d8d2243b9e | ||
![]() |
00241d6252 | ||
![]() |
3248a06134 | ||
![]() |
ae1bd27ad1 | ||
![]() |
9fefbb3b13 | ||
![]() |
ed0105f44c | ||
![]() |
126ce6607e | ||
![]() |
e20a4c4e60 | ||
![]() |
e888e89437 | ||
![]() |
bb4b8f0bc5 | ||
![]() |
a9c87225e2 | ||
![]() |
37261761dd | ||
![]() |
3361727a37 | ||
![]() |
d222cfe8e0 | ||
![]() |
64f4d84e74 | ||
![]() |
b90e75e912 | ||
![]() |
d72e46cfda | ||
![]() |
874748e7da | ||
![]() |
b5b2e77a7e | ||
![]() |
afc4096740 | ||
![]() |
2c3b0a1c44 | ||
![]() |
c8975bb2e9 | ||
![]() |
19d613edcc | ||
![]() |
56b6b0cb5a | ||
![]() |
3461da7c3a | ||
![]() |
332939c3f5 | ||
![]() |
2fb9b3eb46 | ||
![]() |
794ec3576c | ||
![]() |
1b4886715d | ||
![]() |
7dfd6de15f | ||
![]() |
a60f3f44f7 | ||
![]() |
83b433a2e2 | ||
![]() |
55c414b400 | ||
![]() |
5a24fad354 | ||
![]() |
16d6d4d597 | ||
![]() |
d92404d047 | ||
![]() |
0b75abaa04 | ||
![]() |
3f9d49921d | ||
![]() |
0551f4f819 | ||
![]() |
8366cbca59 | ||
![]() |
20f4b51bb7 | ||
![]() |
a02d2e63e2 | ||
![]() |
2ebd7617fc | ||
![]() |
5aa80f2f68 | ||
![]() |
c7fe3059a5 | ||
![]() |
5f748b3131 | ||
![]() |
21c2312952 | ||
![]() |
a36f7221e7 | ||
![]() |
27f0962654 | ||
![]() |
094c80e046 | ||
![]() |
0697116289 | ||
![]() |
7ef81a37ff | ||
![]() |
5e3434396c | ||
![]() |
c1a6b8fe12 | ||
![]() |
9ba4ac6362 | ||
![]() |
67ff37a0d4 | ||
![]() |
f375912bc5 | ||
![]() |
80a5705aea | ||
![]() |
c0d222dedf | ||
![]() |
2a5698c9d3 | ||
![]() |
be96f417b3 | ||
![]() |
398db7dfe8 | ||
![]() |
e106959fbd | ||
![]() |
31c390aa27 | ||
![]() |
2ed72a146b | ||
![]() |
790c169c02 | ||
![]() |
885eb640dc | ||
![]() |
eae4fe86aa | ||
![]() |
a163f716b0 | ||
![]() |
f425f2fa23 | ||
![]() |
b0b3d51571 | ||
![]() |
eb0ef1e39b | ||
![]() |
97309f2f9f | ||
![]() |
5bc071b03c | ||
![]() |
5071656209 | ||
![]() |
206da93d99 | ||
![]() |
258fe58547 | ||
![]() |
eccfc7ba71 | ||
![]() |
142a8e2503 | ||
![]() |
91ed9ed894 | ||
![]() |
f4f51e53eb | ||
![]() |
9210e52aae | ||
![]() |
c5aface2cb | ||
![]() |
4f56c7dd2f | ||
![]() |
8db6076ce1 | ||
![]() |
ae24db1da0 | ||
![]() |
b7414c078a | ||
![]() |
8564a22bef | ||
![]() |
9437bce60a | ||
![]() |
ed13a2f47f | ||
![]() |
388120956d | ||
![]() |
e4da288b25 | ||
![]() |
a523d654ef | ||
![]() |
dc5131567f | ||
![]() |
3063e74e59 | ||
![]() |
d9f7e96c68 | ||
![]() |
0c03e93a47 | ||
![]() |
020e9e5927 | ||
![]() |
d3513ffed0 | ||
![]() |
15f2ea4e29 | ||
![]() |
91dd22d8d3 | ||
![]() |
f00e8ba18e | ||
![]() |
73f1da20f0 | ||
![]() |
24f13a4b88 | ||
![]() |
249ff6e8c5 | ||
![]() |
aac9425626 | ||
![]() |
4982e4b664 | ||
![]() |
267ffc99af | ||
![]() |
75ef4dceb5 | ||
![]() |
79977a0c37 | ||
![]() |
3615ebf05e | ||
![]() |
0caf8e79db | ||
![]() |
b5d40f7964 | ||
![]() |
17407f7ea3 | ||
![]() |
5c9c7e8cf6 | ||
![]() |
d1393acfa6 | ||
![]() |
c0f9f14455 | ||
![]() |
4af12b14e1 | ||
![]() |
d395be256b | ||
![]() |
eb4a5a4e4d | ||
![]() |
1374d4520f | ||
![]() |
081782c97c | ||
![]() |
0ec569216b | ||
![]() |
48510e3818 | ||
![]() |
50c6b4a8aa | ||
![]() |
419d3895be | ||
![]() |
883d9f9b52 | ||
![]() |
6f982a20ba | ||
![]() |
6fb53d823e | ||
![]() |
351855a5bd | ||
![]() |
b9e7bb5457 | ||
![]() |
74e0692f69 | ||
![]() |
852ddb96d8 | ||
![]() |
7decd2b7b0 | ||
![]() |
d27616f28b | ||
![]() |
e00e94e87f | ||
![]() |
493f89643c | ||
![]() |
ec35e74400 | ||
![]() |
6fffb322ae | ||
![]() |
31552b1119 | ||
![]() |
5ee6f6a2e8 | ||
![]() |
463a25a048 | ||
![]() |
67762c1eb0 | ||
![]() |
3f40837b1c | ||
![]() |
678357ab2a | ||
![]() |
ea943369a0 | ||
![]() |
a1fdce2e58 | ||
![]() |
331cc2e374 | ||
![]() |
9ae8c7a196 | ||
![]() |
c0e564517e | ||
![]() |
e0873687a2 | ||
![]() |
441ba17b53 | ||
![]() |
951be8f9a1 | ||
![]() |
737eecad9e | ||
![]() |
95ad01c4db | ||
![]() |
8d243b964f | ||
![]() |
6c22125980 | ||
![]() |
45c701c8e8 | ||
![]() |
929c04edd5 | ||
![]() |
69a84c94a2 | ||
![]() |
6555cc5792 | ||
![]() |
902f278a19 | ||
![]() |
533e711d47 | ||
![]() |
98c27fcf6d | ||
![]() |
d84b981e9a | ||
![]() |
5433e85323 | ||
![]() |
1b8bee4262 | ||
![]() |
3a07a268ca | ||
![]() |
4a20e1b4d2 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -21,7 +21,7 @@ Thumbs.db
|
|||||||
!supportlibs/libsam3/Makefile
|
!supportlibs/libsam3/Makefile
|
||||||
|
|
||||||
# QtCreator cruft
|
# QtCreator cruft
|
||||||
*CMakeLists.txt.user
|
*CMakeLists.txt.user*
|
||||||
|
|
||||||
# Build artifacts
|
# Build artifacts
|
||||||
/jsonapi-generator/src/jsonapi-generator
|
/jsonapi-generator/src/jsonapi-generator
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
image: docker:stable
|
image: docker:latest
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- docker:stable-dind
|
- docker:dind
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
@ -18,6 +18,7 @@ variables:
|
|||||||
build-ubuntu-test-image:
|
build-ubuntu-test-image:
|
||||||
stage: build
|
stage: build
|
||||||
script:
|
script:
|
||||||
|
- docker --version
|
||||||
- >
|
- >
|
||||||
docker login "$CI_REGISTRY"
|
docker login "$CI_REGISTRY"
|
||||||
--username "$CI_REGISTRY_USER"
|
--username "$CI_REGISTRY_USER"
|
||||||
@ -35,6 +36,7 @@ build-ubuntu-test-image:
|
|||||||
test-ubuntu:
|
test-ubuntu:
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
|
- docker --version
|
||||||
- >
|
- >
|
||||||
docker login "$CI_REGISTRY"
|
docker login "$CI_REGISTRY"
|
||||||
--username "$CI_REGISTRY_USER"
|
--username "$CI_REGISTRY_USER"
|
||||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -36,3 +36,6 @@
|
|||||||
[submodule "retroshare-webui"]
|
[submodule "retroshare-webui"]
|
||||||
path = retroshare-webui
|
path = retroshare-webui
|
||||||
url = https://github.com/RetroShare/RSNewWebUI.git
|
url = https://github.com/RetroShare/RSNewWebUI.git
|
||||||
|
[submodule "supportlibs/librnp"]
|
||||||
|
path = supportlibs/librnp
|
||||||
|
url = https://github.com/rnpgp/rnp.git
|
||||||
|
@ -25,9 +25,6 @@ CONFIG += c++14
|
|||||||
|
|
||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
SUBDIRS += openpgpsdk
|
|
||||||
openpgpsdk.file = openpgpsdk/src/openpgpsdk.pro
|
|
||||||
|
|
||||||
rs_jsonapi:isEmpty(JSONAPI_GENERATOR_EXE) {
|
rs_jsonapi:isEmpty(JSONAPI_GENERATOR_EXE) {
|
||||||
SUBDIRS += jsonapi-generator
|
SUBDIRS += jsonapi-generator
|
||||||
jsonapi-generator.file = jsonapi-generator/src/jsonapi-generator.pro
|
jsonapi-generator.file = jsonapi-generator/src/jsonapi-generator.pro
|
||||||
@ -36,7 +33,7 @@ rs_jsonapi:isEmpty(JSONAPI_GENERATOR_EXE) {
|
|||||||
|
|
||||||
SUBDIRS += libbitdht
|
SUBDIRS += libbitdht
|
||||||
libbitdht.file = libbitdht/src/libbitdht.pro
|
libbitdht.file = libbitdht/src/libbitdht.pro
|
||||||
libretroshare.depends += openpgpsdk libbitdht
|
libretroshare.depends += libbitdht
|
||||||
|
|
||||||
SUBDIRS += libretroshare
|
SUBDIRS += libretroshare
|
||||||
libretroshare.file = libretroshare/src/libretroshare.pro
|
libretroshare.file = libretroshare/src/libretroshare.pro
|
||||||
|
@ -40,18 +40,23 @@ RUN git clone --depth 1 https://github.com/aetilius/pHash.git && \
|
|||||||
rm -rf pHash-build pHash
|
rm -rf pHash-build pHash
|
||||||
|
|
||||||
ARG FRESHCLONE=0
|
ARG FRESHCLONE=0
|
||||||
ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git
|
ARG REPO_URL=https://github.com/RetroShare/RetroShare.git
|
||||||
ARG REPO_BRANCH=master
|
ARG REPO_BRANCH=master
|
||||||
ARG REPO_DEPTH="--depth 2000"
|
ARG REPO_DEPTH="--depth 2000"
|
||||||
RUN git clone $REPO_DEPTH $REPO_URL -b $REPO_BRANCH && cd RetroShare && \
|
RUN git clone $REPO_DEPTH $REPO_URL -b $REPO_BRANCH && \
|
||||||
|
cd RetroShare && \
|
||||||
git fetch --tags && \
|
git fetch --tags && \
|
||||||
git submodule update --init --remote --force \
|
git submodule update --init \
|
||||||
libbitdht/ libretroshare/ openpgpsdk/ && \
|
libbitdht/ libretroshare/ openpgpsdk/ retroshare-webui/ \
|
||||||
cd ..
|
supportlibs/restbed/ && \
|
||||||
|
cd supportlibs/restbed/ && \
|
||||||
|
git submodule update --init \
|
||||||
|
dependency/asio/ dependency/kashmir/ && \
|
||||||
|
cd ../../../
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
mkdir RetroShare-build && cd RetroShare-build && \
|
mkdir RetroShare-build && cd RetroShare-build && \
|
||||||
cmake -B. -S../RetroShare/retroshare-service \
|
cmake -B. -S../RetroShare/retroshare-service \
|
||||||
-DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON && \
|
-DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON -DRS_WEBUI=ON && \
|
||||||
make -j$(nproc) && make install && \
|
make -j$(nproc) && make install && \
|
||||||
cd .. && rm -rf RetroShare-build
|
cd .. && rm -rf RetroShare-build
|
||||||
|
@ -2,19 +2,19 @@ FROM registry.gitlab.com/retroshare/retroshare:base
|
|||||||
|
|
||||||
RUN apt-get update -y && apt-get upgrade -y
|
RUN apt-get update -y && apt-get upgrade -y
|
||||||
|
|
||||||
ARG REPO_URL=https://gitlab.com/RetroShare/RetroShare.git
|
ARG REPO_URL=https://github.com/RetroShare/RetroShare.git
|
||||||
ARG REPO_BRANCH=master
|
ARG REPO_BRANCH=master
|
||||||
RUN \
|
RUN \
|
||||||
cd RetroShare && git remote add testing $REPO_URL && \
|
cd RetroShare && git remote add testing $REPO_URL && \
|
||||||
git fetch --tags testing $REPO_BRANCH && \
|
git fetch --tags testing $REPO_BRANCH && \
|
||||||
git reset --hard testing/$REPO_BRANCH && \
|
git reset --hard testing/$REPO_BRANCH && \
|
||||||
git submodule update --init --remote --force \
|
git submodule update --init \
|
||||||
libbitdht/ libretroshare/ openpgpsdk/ && \
|
libbitdht/ libretroshare/ openpgpsdk/ retroshare-webui/ && \
|
||||||
git --no-pager log --max-count 1
|
git --no-pager log --max-count 1
|
||||||
RUN \
|
RUN \
|
||||||
mkdir RetroShare-build && cd RetroShare-build && \
|
mkdir RetroShare-build && cd RetroShare-build && \
|
||||||
cmake -B. -S../RetroShare/retroshare-service \
|
cmake -B. -S../RetroShare/retroshare-service \
|
||||||
-DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON \
|
-DRS_FORUM_DEEP_INDEX=ON -DRS_JSON_API=ON -DRS_WEBUI=ON \
|
||||||
-DRS_WARN_DEPRECATED=OFF -DRS_WARN_LESS=ON && \
|
-DRS_WARN_DEPRECATED=OFF -DRS_WARN_LESS=ON && \
|
||||||
make -j$(nproc) && make install && \
|
make -j$(nproc) && make install && \
|
||||||
cd .. && rm -rf RetroShare-build
|
cd .. && rm -rf RetroShare-build
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 353596b0ee5ea76611eb663b90bf3ab1c9f34ad7
|
Subproject commit 0a3997cc1355b2c848161dca015b7e2df039707b
|
@ -30,32 +30,22 @@ In GitHub Desktop -> Clone Repository -> URL
|
|||||||
|
|
||||||
Add Repository URL: https://github.com/RetroShare/RetroShare.git and Clone
|
Add Repository URL: https://github.com/RetroShare/RetroShare.git and Clone
|
||||||
|
|
||||||
## ***Choose if you use MacPort or HomeBrew***
|
## ***Get XCode & MacOSX SDK***
|
||||||
|
|
||||||
### MacPort Installation
|
Install XCode following this guide: [XCode](http://guide.macports.org/#installing.xcode)
|
||||||
|
|
||||||
Install MacPort and XCode following this guide: [MacPort and XCode](http://guide.macports.org/#installing.xcode)
|
To identify the correct version of Xcode to install, you need to know which OS you are running. Go to the [x] menu -> "About This Mac" and read the macOS version number.
|
||||||
|
|
||||||
Start XCode to get it updated and to able C compiler to create executables.
|
If you are running the macOS Catalina >= 10.15, you can install Xcode directly from App Store using the instructions below.
|
||||||
|
|
||||||
#### Install libraries
|
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
|
||||||
|
|
||||||
$ sudo port -v selfupdate
|
To install from App Store:
|
||||||
$ sudo port install openssl
|
|
||||||
$ sudo port install miniupnpc
|
|
||||||
$ sudo port install libmicrohttpd
|
|
||||||
|
|
||||||
For VOIP Plugin:
|
|
||||||
|
|
||||||
$ sudo port install speex-devel
|
Select [x] menu - > "App Store…".
|
||||||
$ sudo port install opencv
|
Search for Xcode. Download and install.
|
||||||
$ sudo port install ffmpeg
|
|
||||||
|
|
||||||
Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs)
|
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.
|
||||||
|
|
||||||
### HOMEBREW Installation
|
|
||||||
|
|
||||||
Install HomeBrew following this guide: [HomeBrew](http://brew.sh/)
|
|
||||||
|
|
||||||
Install XCode command line developer tools:
|
Install XCode command line developer tools:
|
||||||
|
|
||||||
@ -63,13 +53,48 @@ Install XCode command line developer tools:
|
|||||||
|
|
||||||
Start XCode to get it updated and to able C compiler to create executables.
|
Start XCode to get it updated and to able C compiler to create executables.
|
||||||
|
|
||||||
|
Get Your MacOSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs)
|
||||||
|
|
||||||
|
## ***Choose if you use MacPort or HomeBrew***
|
||||||
|
|
||||||
|
### MacPort Installation
|
||||||
|
|
||||||
|
Install MacPort following this guide: [MacPort](http://guide.macports.org/#installing.xcode)
|
||||||
|
|
||||||
|
#### Install libraries
|
||||||
|
|
||||||
|
$ sudo port -v selfupdate
|
||||||
|
$ sudo port install openssl
|
||||||
|
$ sudo port install miniupnpc
|
||||||
|
|
||||||
|
For VOIP Plugin:
|
||||||
|
|
||||||
|
$ sudo port install speex-devel
|
||||||
|
$ sudo port install opencv
|
||||||
|
$ sudo port install ffmpeg
|
||||||
|
|
||||||
|
|
||||||
|
### HOMEBREW Installation
|
||||||
|
|
||||||
|
Install HomeBrew following this guide: [HomeBrew](http://brew.sh/)
|
||||||
|
|
||||||
#### Install libraries
|
#### Install libraries
|
||||||
|
|
||||||
$ brew install openssl
|
$ brew install openssl
|
||||||
$ brew install miniupnpc
|
$ brew install miniupnpc
|
||||||
$ brew install libmicrohttpd
|
|
||||||
$ brew install rapidjson
|
$ brew install rapidjson
|
||||||
$ brew install sqlcipher
|
$ 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:
|
If you have error in linking, run this:
|
||||||
|
|
||||||
@ -85,8 +110,7 @@ For VOIP Plugin:
|
|||||||
For FeedReader Plugin:
|
For FeedReader Plugin:
|
||||||
|
|
||||||
$ brew install libxslt
|
$ brew install libxslt
|
||||||
|
$ brew install libxml2
|
||||||
Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs)
|
|
||||||
|
|
||||||
## Last Settings
|
## Last Settings
|
||||||
|
|
||||||
@ -104,11 +128,8 @@ In QtCreator Projects -> Build -> Build Settings -> Build Steps -> Add Additiona
|
|||||||
|
|
||||||
## Set your Mac OS SDK version
|
## Set your Mac OS SDK version
|
||||||
|
|
||||||
Edit RetroShare.pro
|
|
||||||
|
|
||||||
CONFIG += c++14 rs_macos11.1
|
Edit retroshare.pri and set your installed sdk version example for 11.1 -> rs_macos11.1 (line 135:)
|
||||||
|
|
||||||
and then retroshare.pri
|
|
||||||
|
|
||||||
macx:CONFIG *= rs_macos11.1
|
macx:CONFIG *= rs_macos11.1
|
||||||
rs_macos10.8:CONFIG -= rs_macos11.1
|
rs_macos10.8:CONFIG -= rs_macos11.1
|
||||||
@ -122,7 +143,7 @@ and then retroshare.pri
|
|||||||
|
|
||||||
## Link Include & Libraries
|
## Link Include & Libraries
|
||||||
|
|
||||||
Edit your retroshare.pri and add to macx-* section
|
When required edit your retroshare.pri macx-* section, check if the Include and Lib path are correct (macx-* section)
|
||||||
|
|
||||||
INCLUDEPATH += "/usr/local/opt/openssl/include"
|
INCLUDEPATH += "/usr/local/opt/openssl/include"
|
||||||
QMAKE_LIBDIR += "/usr/local/opt/openssl/lib"
|
QMAKE_LIBDIR += "/usr/local/opt/openssl/lib"
|
||||||
@ -131,13 +152,21 @@ Edit your retroshare.pri and add to macx-* section
|
|||||||
|
|
||||||
alternative via Terminal
|
alternative via Terminal
|
||||||
|
|
||||||
$ qmake INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib"
|
$ qmake
|
||||||
|
INCLUDEPATH+="/usr/local/opt/openssl/include" \
|
||||||
|
QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" \
|
||||||
|
QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" \
|
||||||
|
QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib" \
|
||||||
|
CONFIG+=rs_autologin \
|
||||||
|
CONFIG+=rs_use_native_dialogs \
|
||||||
|
CONFIG+=release \
|
||||||
|
..
|
||||||
|
|
||||||
For FeedReader Plugin:
|
For FeedReader Plugin:
|
||||||
|
|
||||||
INCLUDEPATH += "/usr/local/opt/libxml2/include/libxml2"
|
INCLUDEPATH += "/usr/local/opt/libxml2/include/libxml2"
|
||||||
|
|
||||||
For building RetroShare with plugins:
|
With plugins:
|
||||||
|
|
||||||
$ qmake \
|
$ qmake \
|
||||||
INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" \
|
INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" \
|
||||||
@ -159,13 +188,30 @@ For building RetroShare with plugins:
|
|||||||
|
|
||||||
You can now compile RetroShare into Qt Creator or with Terminal
|
You can now compile RetroShare into Qt Creator or with Terminal
|
||||||
|
|
||||||
cd retroshare
|
$ cd /path/to/retroshare
|
||||||
qmake; make
|
$ qmake ..
|
||||||
|
$ make
|
||||||
|
|
||||||
You can change Target and SDK in *./retroshare.pri:82* changing value of QMAKE_MACOSX_DEPLOYMENT_TARGET and QMAKE_MAC_SDK
|
You can change Target and SDK in *./retroshare.pri:82* changing value of QMAKE_MACOSX_DEPLOYMENT_TARGET and QMAKE_MAC_SDK
|
||||||
|
|
||||||
You can find the compiled application at *./retroshare/retroshare-gui/src/retroshare.app*
|
You can find the compiled application at *./retroshare/retroshare-gui/src/retroshare.app*
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
|
||||||
|
If you have issues with openssl (Undefined symbols for architecture x86_64) try to add to *~/.profile* file this or via Terminal
|
||||||
|
|
||||||
|
export PATH="/usr/local/opt/openssl/bin:$PATH"
|
||||||
|
export LDFLAGS="-L/usr/local/opt/openssl/lib"
|
||||||
|
export CPPFLAGS="-I/usr/local/opt/openssl/include"
|
||||||
|
export PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig"
|
||||||
|
|
||||||
|
For Qt Creator -> QtCreator Projects -> Build -> Build Settings -> Build Steps -> Add Additional arguments:
|
||||||
|
|
||||||
|
LDFLAGS="-L/usr/local/opt/openssl/lib"
|
||||||
|
CPPFLAGS="-I/usr/local/opt/openssl/include"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Copy Plugins
|
## Copy Plugins
|
||||||
|
|
||||||
$ cp \
|
$ cp \
|
||||||
@ -173,3 +219,13 @@ You can find the compiled application at *./retroshare/retroshare-gui/src/retros
|
|||||||
./plugins/VOIP/lib/libVOIP.dylib \
|
./plugins/VOIP/lib/libVOIP.dylib \
|
||||||
./plugins/RetroChess/lib/libRetroChess.dylib \
|
./plugins/RetroChess/lib/libRetroChess.dylib \
|
||||||
./retroshare-gui/src/RetroShare.app/Contents/Resources/
|
./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
|
||||||
|
51
build_scripts/OSX/makeOSXPackage.sh
Normal file
51
build_scripts/OSX/makeOSXPackage.sh
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#!/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"
|
@ -18,6 +18,8 @@ if errorlevel 1 goto error_env
|
|||||||
if not "%ParamNoupdate%"=="1" (
|
if not "%ParamNoupdate%"=="1" (
|
||||||
:: Install needed things
|
:: 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"
|
%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
|
:: Webui
|
||||||
if "%ParamWebui%"=="1" %EnvMSYS2Cmd% "pacman --noconfirm --needed -S mingw-w64-%RsMSYS2Architecture%-doxygen"
|
if "%ParamWebui%"=="1" %EnvMSYS2Cmd% "pacman --noconfirm --needed -S mingw-w64-%RsMSYS2Architecture%-doxygen"
|
||||||
|
@ -105,6 +105,7 @@ copy "%RsBuildPath%\retroshare-nogui\src\%RsBuildConfig%\retroshare*-nogui.exe"
|
|||||||
copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite%
|
copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite%
|
||||||
copy "%RsBuildPath%\supportlibs\cmark\build\src\libcmark.dll" "%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%\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" (
|
if exist "%RsBuildPath%\retroshare-friendserver\src\%RsBuildConfig%\retroshare-friendserver.exe" (
|
||||||
copy "%RsBuildPath%\retroshare-friendserver\src\%RsBuildConfig%\retroshare-friendserver.exe" "%RsDeployPath%" %Quite%
|
copy "%RsBuildPath%\retroshare-friendserver\src\%RsBuildConfig%\retroshare-friendserver.exe" "%RsDeployPath%" %Quite%
|
||||||
)
|
)
|
||||||
|
@ -16,7 +16,7 @@ if "%~1"=="clean" (
|
|||||||
goto exit
|
goto exit
|
||||||
)
|
)
|
||||||
|
|
||||||
set MSYS2Version=20231026
|
set MSYS2Version=20241208
|
||||||
|
|
||||||
set MSYS2Install=msys2-base-x86_64-%MSYS2Version%.sfx.exe
|
set MSYS2Install=msys2-base-x86_64-%MSYS2Version%.sfx.exe
|
||||||
set MSYS2Url=https://github.com/msys2/msys2-installer/releases/download/%MSYS2Version:~0,4%-%MSYS2Version:~4,2%-%MSYS2Version:~6,2%/%MSYS2Install%
|
set MSYS2Url=https://github.com/msys2/msys2-installer/releases/download/%MSYS2Version:~0,4%-%MSYS2Version:~4,2%-%MSYS2Version:~6,2%/%MSYS2Install%
|
||||||
|
@ -13,12 +13,18 @@ LIBMICROHTTPD_VERSION=0.9.75
|
|||||||
FFMPEG_VERSION=4.4
|
FFMPEG_VERSION=4.4
|
||||||
RAPIDJSON_VERSION=1.1.0
|
RAPIDJSON_VERSION=1.1.0
|
||||||
XAPIAN_VERSION=1.4.19
|
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
|
DOWNLOAD_PATH?=download
|
||||||
BUILD_PATH=build
|
BUILD_PATH=build
|
||||||
LIBS_PATH?=libs
|
LIBS_PATH?=libs
|
||||||
|
|
||||||
all: dirs zlib bzip2 miniupnpc openssl speex speexdsp libxml2 libxslt curl sqlcipher libmicrohttpd ffmpeg rapidjson xapian copylibs
|
all: dirs zlib bzip2 miniupnpc openssl speex speexdsp libxml2 libxslt curl sqlcipher libmicrohttpd ffmpeg rapidjson xapian jsonc botan copylibs
|
||||||
|
#rnp
|
||||||
|
|
||||||
download: \
|
download: \
|
||||||
$(DOWNLOAD_PATH)/zlib-$(ZLIB_VERSION).tar.gz \
|
$(DOWNLOAD_PATH)/zlib-$(ZLIB_VERSION).tar.gz \
|
||||||
@ -363,6 +369,57 @@ $(BUILD_PATH)/xapian-core-$(XAPIAN_VERSION): $(DOWNLOAD_PATH)/xapian-core-$(XAPI
|
|||||||
rm -r -f xapian-core-$(XAPIAN_VERSION)
|
rm -r -f xapian-core-$(XAPIAN_VERSION)
|
||||||
mv $(BUILD_PATH)/xapian-core-$(XAPIAN_VERSION).tmp $(BUILD_PATH)/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:
|
copylibs:
|
||||||
rm -r -f $(LIBS_PATH) ; \
|
rm -r -f $(LIBS_PATH) ; \
|
||||||
mkdir -p $(LIBS_PATH) ; \
|
mkdir -p $(LIBS_PATH) ; \
|
||||||
|
@ -96,6 +96,7 @@ copy nul "%RsDeployPath%\portable" %Quite%
|
|||||||
echo copy binaries
|
echo copy binaries
|
||||||
copy "%RsBuildPath%\retroshare-gui\src\%RsBuildConfig%\retroshare*.exe" "%RsDeployPath%" %Quite%
|
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%\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" (
|
if "%ParamService%"=="1" (
|
||||||
copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite%
|
copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite%
|
||||||
|
@ -16,13 +16,13 @@ if "%~1"=="clean" (
|
|||||||
goto exit
|
goto exit
|
||||||
)
|
)
|
||||||
|
|
||||||
set MSYS2Version=20231026
|
set MSYS2Version=20241208
|
||||||
|
|
||||||
set MSYS2Install=msys2-base-x86_64-%MSYS2Version%.sfx.exe
|
set MSYS2Install=msys2-base-x86_64-%MSYS2Version%.sfx.exe
|
||||||
set MSYS2Url=https://github.com/msys2/msys2-installer/releases/download/%MSYS2Version:~0,4%-%MSYS2Version:~4,2%-%MSYS2Version:~6,2%/%MSYS2Install%
|
set MSYS2Url=https://github.com/msys2/msys2-installer/releases/download/%MSYS2Version:~0,4%-%MSYS2Version:~4,2%-%MSYS2Version:~6,2%/%MSYS2Install%
|
||||||
set MSYS2UnpackPath=%EnvMSYS2Path%\msys64
|
set MSYS2UnpackPath=%EnvMSYS2Path%\msys64
|
||||||
set CMakeInstall=cmake-3.19.0-win32-x86.zip
|
set CMakeInstall=cmake-3.31.3-windows-i386.zip
|
||||||
set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.19.0/%CMakeInstall%
|
set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.31.3/%CMakeInstall%
|
||||||
|
|
||||||
if exist "%MSYS2UnpackPath%\usr\bin\pacman.exe" (
|
if exist "%MSYS2UnpackPath%\usr\bin\pacman.exe" (
|
||||||
if "%~1"=="reinstall" (
|
if "%~1"=="reinstall" (
|
||||||
|
@ -19,9 +19,9 @@ set MinGitInstallPath=%EnvToolsPath%\MinGit
|
|||||||
set DoxygenInstall=doxygen-1.9.6.windows.x64.bin.zip
|
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 DoxygenUrl=https://github.com/doxygen/doxygen/releases/download/Release_1_9_6/%DoxygenInstall%
|
||||||
set DoxygenInstallPath=%EnvToolsPath%\doxygen
|
set DoxygenInstallPath=%EnvToolsPath%\doxygen
|
||||||
set CMakeVersion=cmake-3.19.0-win32-x86
|
set CMakeVersion=cmake-3.31.3-windows-i386
|
||||||
set CMakeInstall=%CMakeVersion%.zip
|
set CMakeInstall=%CMakeVersion%.zip
|
||||||
set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.19.0/%CMakeInstall%
|
set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.31.3/%CMakeInstall%
|
||||||
set CMakeInstallPath=%EnvToolsPath%\cmake
|
set CMakeInstallPath=%EnvToolsPath%\cmake
|
||||||
set TorProjectUrl=https://www.torproject.org
|
set TorProjectUrl=https://www.torproject.org
|
||||||
set TorDownloadIndexUrl=%TorProjectUrl%/download/tor
|
set TorDownloadIndexUrl=%TorProjectUrl%/download/tor
|
||||||
|
@ -247,6 +247,7 @@ Section $(Section_Main) Section_Main
|
|||||||
|
|
||||||
; External binaries
|
; External binaries
|
||||||
File "${EXTERNAL_LIB_DIR}\bin\miniupnpc.dll"
|
File "${EXTERNAL_LIB_DIR}\bin\miniupnpc.dll"
|
||||||
|
File "${RELEASEDIR}\supportlibs\librnp\Build\src\lib\librnp.dll"
|
||||||
!if ${ARCHITECTURE} == "x86"
|
!if ${ARCHITECTURE} == "x86"
|
||||||
File "${EXTERNAL_LIB_DIR}\bin\libcrypto-1_1.dll"
|
File "${EXTERNAL_LIB_DIR}\bin\libcrypto-1_1.dll"
|
||||||
File "${EXTERNAL_LIB_DIR}\bin\libssl-1_1.dll"
|
File "${EXTERNAL_LIB_DIR}\bin\libssl-1_1.dll"
|
||||||
|
20
build_scripts/git_tag_cleaner.sh
Executable file
20
build_scripts/git_tag_cleaner.sh
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function git_del_tag()
|
||||||
|
{
|
||||||
|
mTag=$1
|
||||||
|
|
||||||
|
for mRemote in $(git remote); do
|
||||||
|
echo "Attempting tag $mTag removal from remote $mRemote"
|
||||||
|
GIT_TERMINAL_PROMPT=0 git push $mRemote :$mTag || true
|
||||||
|
done
|
||||||
|
git tag --delete $mTag
|
||||||
|
}
|
||||||
|
|
||||||
|
for mModule in . build_scripts/OBS/ libbitdht/ libretroshare/ openpgpsdk/ retroshare-webui/ ; do
|
||||||
|
pushd $mModule
|
||||||
|
git_del_tag v0.6.7a
|
||||||
|
git tag --list | grep untagged | while read mTag; do git_del_tag $mTag ; done
|
||||||
|
popd
|
||||||
|
done
|
||||||
|
|
@ -7,5 +7,5 @@ Exec=/usr/bin/retroshare %U
|
|||||||
Icon=/usr/share/pixmaps/retroshare.xpm
|
Icon=/usr/share/pixmaps/retroshare.xpm
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Application;Network;P2P;Feed;Chat;InstantMessaging
|
Categories=Application;Network;Email;InstantMessaging;Chat;Feed;FileTransfer;P2P
|
||||||
MimeType=x-scheme-handler/retroshare;
|
MimeType=x-scheme-handler/retroshare;
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit de2b4bd80c57ca757b5f878130f98becf710236d
|
Subproject commit 2a4df811f6bfe1904bc3956f285aa0fc891f9fd4
|
@ -1 +1 @@
|
|||||||
Subproject commit b41667912751a453e8e5d4733215a0609277a26f
|
Subproject commit df542663d8bd698a8b5541fc6db07da6c59f1c3a
|
@ -57,10 +57,10 @@
|
|||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QFrame" name="toolBarFrame">
|
<widget class="QFrame" name="toolBarFrame">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::Box</enum>
|
<enum>QFrame::StyledPanel</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Sunken</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
|
@ -848,6 +848,22 @@ RsFeedReaderErrorState p3FeedReaderThread::process(const RsFeedReaderFeed &feed,
|
|||||||
|
|
||||||
RsFeedReaderErrorState result = RS_FEED_ERRORSTATE_OK;
|
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;
|
XMLWrapper xml;
|
||||||
if (xml.readXML(feed.content.c_str())) {
|
if (xml.readXML(feed.content.c_str())) {
|
||||||
xmlNodePtr root = xml.getRootElement();
|
xmlNodePtr root = xml.getRootElement();
|
||||||
@ -1006,6 +1022,13 @@ 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);
|
entries.push_back(item);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1097,7 +1120,7 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
|
|||||||
std::string url;
|
std::string url;
|
||||||
if (feed.flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE) {
|
if (feed.flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE) {
|
||||||
#ifdef FEEDREADER_DEBUG
|
#ifdef FEEDREADER_DEBUG
|
||||||
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") download page " << msg->link << std::endl;
|
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") download page " << msg->link << std::endl;
|
||||||
#endif
|
#endif
|
||||||
std::string content;
|
std::string content;
|
||||||
CURLWrapper CURL(proxy);
|
CURLWrapper CURL(proxy);
|
||||||
@ -1134,7 +1157,7 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
|
|||||||
|
|
||||||
if (result != RS_FEED_ERRORSTATE_OK) {
|
if (result != RS_FEED_ERRORSTATE_OK) {
|
||||||
#ifdef FEEDREADER_DEBUG
|
#ifdef FEEDREADER_DEBUG
|
||||||
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot download page, CURLCode = " << code << ", error = " << errorString << std::endl;
|
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") cannot download page, CURLCode = " << code << ", error = " << errorString << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1280,7 +1303,7 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
|
|||||||
if (!src.empty()) {
|
if (!src.empty()) {
|
||||||
/* download image */
|
/* download image */
|
||||||
#ifdef FEEDREADER_DEBUG
|
#ifdef FEEDREADER_DEBUG
|
||||||
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") download image " << src << std::endl;
|
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") download image " << src << std::endl;
|
||||||
#endif
|
#endif
|
||||||
std::vector<unsigned char> data;
|
std::vector<unsigned char> data;
|
||||||
CURLWrapper CURL(proxy);
|
CURLWrapper CURL(proxy);
|
||||||
@ -1348,7 +1371,7 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
|
|||||||
if (!html.saveHTML(msg->postedDescriptionWithoutFirstImage)) {
|
if (!html.saveHTML(msg->postedDescriptionWithoutFirstImage)) {
|
||||||
errorString = html.lastError();
|
errorString = html.lastError();
|
||||||
#ifdef FEEDREADER_DEBUG
|
#ifdef FEEDREADER_DEBUG
|
||||||
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl;
|
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl;
|
||||||
std::cerr << " Error: " << errorString << std::endl;
|
std::cerr << " Error: " << errorString << std::endl;
|
||||||
#endif
|
#endif
|
||||||
result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR;
|
result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR;
|
||||||
@ -1357,7 +1380,7 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
|
|||||||
} else {
|
} else {
|
||||||
errorString = html.lastError();
|
errorString = html.lastError();
|
||||||
#ifdef FEEDREADER_DEBUG
|
#ifdef FEEDREADER_DEBUG
|
||||||
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl;
|
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl;
|
||||||
std::cerr << " Error: " << errorString << std::endl;
|
std::cerr << " Error: " << errorString << std::endl;
|
||||||
#endif
|
#endif
|
||||||
result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR;
|
result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR;
|
||||||
@ -1366,14 +1389,14 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef FEEDREADER_DEBUG
|
#ifdef FEEDREADER_DEBUG
|
||||||
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") no root element" << std::endl;
|
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") no root element" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR;
|
result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errorString = html.lastError();
|
errorString = html.lastError();
|
||||||
#ifdef FEEDREADER_DEBUG
|
#ifdef FEEDREADER_DEBUG
|
||||||
std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot read html" << std::endl;
|
std::cerr << "p3FeedReaderThread::processMsg - feed " << feed.feedId << " (" << feed.name << ") cannot read html" << std::endl;
|
||||||
std::cerr << " Error: " << errorString << std::endl;
|
std::cerr << " Error: " << errorString << std::endl;
|
||||||
#endif
|
#endif
|
||||||
result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR;
|
result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR;
|
||||||
|
@ -8,7 +8,11 @@
|
|||||||
|
|
||||||
#include "pgp/pgpkeyutil.h"
|
#include "pgp/pgpkeyutil.h"
|
||||||
#include "pgp/rscertificate.h"
|
#include "pgp/rscertificate.h"
|
||||||
|
#ifdef USE_OPENPGPSDK
|
||||||
#include "pgp/openpgpsdkhandler.h"
|
#include "pgp/openpgpsdkhandler.h"
|
||||||
|
#else
|
||||||
|
#include "pgp/rnppgphandler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "friendserver.h"
|
#include "friendserver.h"
|
||||||
#include "friend_server/fsitem.h"
|
#include "friend_server/fsitem.h"
|
||||||
@ -393,7 +397,11 @@ 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_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.
|
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);
|
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.
|
// Random bias. Should be cryptographically safe.
|
||||||
|
|
||||||
|
@ -2,17 +2,14 @@
|
|||||||
README for RetroShare
|
README for RetroShare
|
||||||
=======================================================================================
|
=======================================================================================
|
||||||
|
|
||||||
RetroShare web site . . . . http://retroshare.net/index.html
|
RetroShare web site . . . . https://retroshare.cc/
|
||||||
Developer's blog . . . . . https://retroshareteam.wordpress.com
|
Developer's blog . . . . . https://retroshareteam.wordpress.com
|
||||||
Documentation . . . . . . . https://retroshare.readthedocs.io/en/latest/
|
Documentation . . . . . . . https://retrosharedocs.readthedocs.io/en/latest/
|
||||||
Support . . . . . . . . . . http://retroshare.net/support.html
|
|
||||||
Forums . . . . . . . . . . http://retroshare.sourceforge.net/forum/
|
|
||||||
Wiki . . . . . . . . . . . https://github.com/RetroShare/documentation/wiki
|
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
|
Project site . . . . . . . https://github.com/RetroShare/RetroShare
|
||||||
Relted projects/plugins . . https://github.com/RetroShare
|
Related projects/plugins . .https://github.com/RetroShare
|
||||||
|
|
||||||
Contact: . . . . . . . . . retroshare@lunamutt.com ,defnax@users.sourceforge.net
|
Contact: . . . . . . . . . retroshare.project@gmail.com
|
||||||
|
|
||||||
=========================================================================================
|
=========================================================================================
|
||||||
Compiling RetroShare
|
Compiling RetroShare
|
||||||
@ -22,9 +19,9 @@ Build Scripts are avaible on GIT:
|
|||||||
https://github.com/RetroShare/RetroShare/tree/master/build_scripts
|
https://github.com/RetroShare/RetroShare/tree/master/build_scripts
|
||||||
|
|
||||||
You can find here instructions howto compile RetroShare:
|
You can find here instructions howto compile RetroShare:
|
||||||
https://retroshare.readthedocs.io/en/latest/developer/compilation/
|
https://retrosharedocs.readthedocs.io/en/latest/developer/compilation/
|
||||||
|
|
||||||
You can go on over to our forum or chat lobby when you have trouble with compiling:
|
You can go on over to our forum or chat room when you have trouble with compiling:
|
||||||
retroshare://forum?name=Developers%20Discussions&id=8fd22bd8f99754461e7ba1ca8a727995
|
retroshare://forum?name=Developers%20Discussions&id=8fd22bd8f99754461e7ba1ca8a727995
|
||||||
retroshare://chat_room?name=Retroshare%20Devel%20%28signed%29&id=L68DB0A1E09BDA3A5
|
retroshare://chat_room?name=Retroshare%20Devel%20%28signed%29&id=L68DB0A1E09BDA3A5
|
||||||
http://retroshare.sourceforge.net/forum/
|
|
||||||
|
@ -142,7 +142,7 @@ void AboutWidget::updateTitle()
|
|||||||
{
|
{
|
||||||
if (tWidget == NULL)
|
if (tWidget == NULL)
|
||||||
{
|
{
|
||||||
setWindowTitle(QString("%1 %2").arg(tr("About RetroShare"), Rshare::retroshareVersion(true)));
|
setWindowTitle(QString("%1 %2").arg(tr("About RetroShare"), RsApplication::retroshareVersion(true)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -228,7 +228,7 @@ void AWidget::initImages()
|
|||||||
#ifdef RS_ONLYHIDDENNODE
|
#ifdef RS_ONLYHIDDENNODE
|
||||||
p.drawText(QPointF(10, 50), QString("%1 : %2 (With embedded Tor)").arg(tr("Retroshare version"), Rshare::retroshareVersion(true)));
|
p.drawText(QPointF(10, 50), QString("%1 : %2 (With embedded Tor)").arg(tr("Retroshare version"), Rshare::retroshareVersion(true)));
|
||||||
#else
|
#else
|
||||||
p.drawText(QPointF(10, 50), QString("%1 : %2").arg(tr("Retroshare version"), Rshare::retroshareVersion(true)));
|
p.drawText(QPointF(10, 50), QString("%1 : %2").arg(tr("Retroshare version"), RsApplication::retroshareVersion(true)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Draw Qt's version number */
|
/* Draw Qt's version number */
|
||||||
@ -936,7 +936,7 @@ void AboutWidget::on_copy_button_clicked()
|
|||||||
{
|
{
|
||||||
QString verInfo;
|
QString verInfo;
|
||||||
QString rsVerString = "RetroShare Version: ";
|
QString rsVerString = "RetroShare Version: ";
|
||||||
rsVerString+=Rshare::retroshareVersion(true);
|
rsVerString+=RsApplication::retroshareVersion(true);
|
||||||
verInfo+=rsVerString;
|
verInfo+=rsVerString;
|
||||||
#ifdef RS_ONLYHIDDENNODE
|
#ifdef RS_ONLYHIDDENNODE
|
||||||
verInfo+=" " + tr("Only Hidden Node");
|
verInfo+=" " + tr("Only Hidden Node");
|
||||||
|
@ -143,28 +143,28 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
|
|||||||
QHeaderView_setSectionResizeModeColumn(header, COLUMN_TOPIC, QHeaderView::Interactive);
|
QHeaderView_setSectionResizeModeColumn(header, COLUMN_TOPIC, QHeaderView::Interactive);
|
||||||
|
|
||||||
privateSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
privateSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
||||||
privateSubLobbyItem->setText(COLUMN_NAME, tr("Private Subscribed chat rooms"));
|
privateSubLobbyItem->setText(COLUMN_NAME, tr("Private Subscribed"));
|
||||||
privateSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "1");
|
privateSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "1");
|
||||||
// privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE));
|
// privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE));
|
||||||
privateSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE);
|
privateSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE);
|
||||||
ui.lobbyTreeWidget->insertTopLevelItem(0, privateSubLobbyItem);
|
ui.lobbyTreeWidget->insertTopLevelItem(0, privateSubLobbyItem);
|
||||||
|
|
||||||
publicSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
publicSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
||||||
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed chat rooms"));
|
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed"));
|
||||||
publicSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "2");
|
publicSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "2");
|
||||||
// publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC));
|
// publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC));
|
||||||
publicSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC);
|
publicSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC);
|
||||||
ui.lobbyTreeWidget->insertTopLevelItem(1, publicSubLobbyItem);
|
ui.lobbyTreeWidget->insertTopLevelItem(1, publicSubLobbyItem);
|
||||||
|
|
||||||
privateLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
privateLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
||||||
privateLobbyItem->setText(COLUMN_NAME, tr("Private chat rooms"));
|
privateLobbyItem->setText(COLUMN_NAME, tr("Private"));
|
||||||
privateLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "3");
|
privateLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "3");
|
||||||
// privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE));
|
// privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE));
|
||||||
privateLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE);
|
privateLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE);
|
||||||
ui.lobbyTreeWidget->insertTopLevelItem(2, privateLobbyItem);
|
ui.lobbyTreeWidget->insertTopLevelItem(2, privateLobbyItem);
|
||||||
|
|
||||||
publicLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
publicLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
||||||
publicLobbyItem->setText(COLUMN_NAME, tr("Public chat rooms"));
|
publicLobbyItem->setText(COLUMN_NAME, tr("Public"));
|
||||||
publicLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "4");
|
publicLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "4");
|
||||||
// publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC));
|
// publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC));
|
||||||
publicLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC);
|
publicLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC);
|
||||||
@ -230,6 +230,8 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
|
|||||||
|
|
||||||
int ltwH = misc::getFontSizeFactor("LobbyTreeWidget", 1.5).height();
|
int ltwH = misc::getFontSizeFactor("LobbyTreeWidget", 1.5).height();
|
||||||
ui.lobbyTreeWidget->setIconSize(QSize(ltwH,ltwH));
|
ui.lobbyTreeWidget->setIconSize(QSize(ltwH,ltwH));
|
||||||
|
|
||||||
|
mFontSizeHandler.registerFontSize(ui.lobbyTreeWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatLobbyWidget::~ChatLobbyWidget()
|
ChatLobbyWidget::~ChatLobbyWidget()
|
||||||
@ -721,9 +723,9 @@ void ChatLobbyWidget::updateDisplay()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
publicSubLobbyItem->setHidden(publicSubLobbyItem->childCount()==0);
|
publicSubLobbyItem->setHidden(publicSubLobbyItem->childCount()==0);
|
||||||
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed chat rooms")+ QString(" (") + QString::number(publicSubLobbyItem->childCount())+QString(")"));
|
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed")+ QString(" (") + QString::number(publicSubLobbyItem->childCount())+QString(")"));
|
||||||
privateSubLobbyItem->setHidden(privateSubLobbyItem->childCount()==0);
|
privateSubLobbyItem->setHidden(privateSubLobbyItem->childCount()==0);
|
||||||
publicLobbyItem->setText(COLUMN_NAME, tr("Public chat rooms")+ " (" + QString::number(publicLobbyItem->childCount())+QString(")"));
|
publicLobbyItem->setText(COLUMN_NAME, tr("Public")+ " (" + QString::number(publicLobbyItem->childCount())+QString(")"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatLobbyWidget::createChatLobby()
|
void ChatLobbyWidget::createChatLobby()
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "chat/ChatLobbyUserNotify.h"
|
#include "chat/ChatLobbyUserNotify.h"
|
||||||
#include "gui/gxs/GxsIdChooser.h"
|
#include "gui/gxs/GxsIdChooser.h"
|
||||||
|
#include "util/FontSizeHandler.h"
|
||||||
|
|
||||||
|
|
||||||
#include <retroshare/rsmsgs.h>
|
#include <retroshare/rsmsgs.h>
|
||||||
@ -146,6 +147,8 @@ private:
|
|||||||
QAbstractButton* myInviteYesButton;
|
QAbstractButton* myInviteYesButton;
|
||||||
GxsIdChooser* myInviteIdChooser;
|
GxsIdChooser* myInviteIdChooser;
|
||||||
|
|
||||||
|
FontSizeHandler mFontSizeHandler;
|
||||||
|
|
||||||
/* UI - from Designer */
|
/* UI - from Designer */
|
||||||
Ui::ChatLobbyWidget ui;
|
Ui::ChatLobbyWidget ui;
|
||||||
};
|
};
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
<widget class="QLabel" name="titleBarLabel">
|
<widget class="QLabel" name="titleBarLabel">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<pointsize>12</pointsize>
|
<pointsize>12</pointsize>
|
||||||
<weight>75</weight>
|
<weight>75</weight>
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
@ -191,11 +191,6 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="RSTreeWidget" name="lobbyTreeWidget">
|
<widget class="RSTreeWidget" name="lobbyTreeWidget">
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<pointsize>11</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>16</width>
|
<width>16</width>
|
||||||
@ -464,7 +459,7 @@
|
|||||||
<customwidget>
|
<customwidget>
|
||||||
<class>LineEditClear</class>
|
<class>LineEditClear</class>
|
||||||
<extends>QLineEdit</extends>
|
<extends>QLineEdit</extends>
|
||||||
<header location="global">gui/common/LineEditClear.h</header>
|
<header>gui/common/LineEditClear.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>RSTreeWidget</class>
|
<class>RSTreeWidget</class>
|
||||||
|
16
retroshare-gui/src/gui/FileTransfer/DLListDelegate.cpp
Normal file → Executable file
16
retroshare-gui/src/gui/FileTransfer/DLListDelegate.cpp
Normal file → Executable file
@ -102,7 +102,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
|
|||||||
multi *= 1024.0;
|
multi *= 1024.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
|
||||||
break;
|
break;
|
||||||
case COLUMN_REMAINING:
|
case COLUMN_REMAINING:
|
||||||
remaining = index.data().toLongLong();
|
remaining = index.data().toLongLong();
|
||||||
@ -121,7 +121,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
|
|||||||
multi *= 1024.0;
|
multi *= 1024.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
|
||||||
break;
|
break;
|
||||||
case COLUMN_COMPLETED:
|
case COLUMN_COMPLETED:
|
||||||
completed = index.data().toLongLong();
|
completed = index.data().toLongLong();
|
||||||
@ -140,7 +140,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
|
|||||||
multi *= 1024.0;
|
multi *= 1024.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
|
||||||
break;
|
break;
|
||||||
case COLUMN_DLSPEED:
|
case COLUMN_DLSPEED:
|
||||||
dlspeed = index.data().toDouble();
|
dlspeed = index.data().toDouble();
|
||||||
@ -151,7 +151,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
|
|||||||
temp.sprintf("%.2f", dlspeed/1024.);
|
temp.sprintf("%.2f", dlspeed/1024.);
|
||||||
temp += " KB/s";
|
temp += " KB/s";
|
||||||
}
|
}
|
||||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
|
||||||
break;
|
break;
|
||||||
case COLUMN_PROGRESS:
|
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);
|
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));
|
pixmapRect = (pixmap.isNull() ? QRect(0, 0, 0, 0): QRect(QPoint(0, 0), option.decorationSize));
|
||||||
if (pixmapRect.isValid()){
|
if (pixmapRect.isValid()){
|
||||||
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft, pixmap.size(), option.rect).topLeft();
|
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft | Qt::AlignVCenter, pixmap.size(), option.rect).topLeft();
|
||||||
p.setX( p.x() + pixOffset);
|
p.setX( p.x() + pixOffset);
|
||||||
painter->drawPixmap(p, pixmap);
|
painter->drawPixmap(p, pixmap);
|
||||||
temp = " " + temp;
|
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);
|
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));
|
pixmapRect = (pixmap.isNull() ? QRect(0, 0, 0, 0): QRect(QPoint(0, 0), option.decorationSize));
|
||||||
if (pixmapRect.isValid()){
|
if (pixmapRect.isValid()){
|
||||||
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft, pixmap.size(), option.rect).topLeft();
|
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft | Qt::AlignVCenter, pixmap.size(), option.rect).topLeft();
|
||||||
p.setX( p.x() + pixOffset);
|
p.setX( p.x() + pixOffset);
|
||||||
painter->drawPixmap(p, pixmap);
|
painter->drawPixmap(p, pixmap);
|
||||||
temp = " " + temp;
|
temp = " " + temp;
|
||||||
pixOffset += pixmap.size().width();
|
pixOffset += pixmap.size().width();
|
||||||
}
|
}
|
||||||
painter->drawText(option.rect.translated(pixOffset, 0), Qt::AlignLeft, temp);
|
painter->drawText(option.rect.translated(pixOffset, 0), Qt::AlignLeft | Qt::AlignVCenter, temp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COLUMN_LASTDL:
|
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());
|
float w = QFontMetricsF(option.font).width(index.data(Qt::DisplayRole).toString());
|
||||||
|
|
||||||
int S = QFontMetricsF(option.font).height() ;
|
int S = QFontMetricsF(option.font).height()*1.5 ;
|
||||||
return QSize(w,S);
|
return QSize(w,S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include "gui/RetroShareLink.h"
|
#include "gui/RetroShareLink.h"
|
||||||
#include "retroshare-gui/RsAutoUpdatePage.h"
|
#include "retroshare-gui/RsAutoUpdatePage.h"
|
||||||
#include "gui/msgs/MessageComposer.h"
|
#include "gui/msgs/MessageComposer.h"
|
||||||
#include "gui/common/RsCollection.h"
|
#include "gui/common/RsCollectionDialog.h"
|
||||||
#include "gui/common/FilesDefs.h"
|
#include "gui/common/FilesDefs.h"
|
||||||
#include "gui/common/RsUrlHandler.h"
|
#include "gui/common/RsUrlHandler.h"
|
||||||
#include "gui/settings/rsharesettings.h"
|
#include "gui/settings/rsharesettings.h"
|
||||||
@ -38,6 +38,7 @@
|
|||||||
#include "gui/common/RSTreeWidgetItem.h"
|
#include "gui/common/RSTreeWidgetItem.h"
|
||||||
#include "util/QtVersion.h"
|
#include "util/QtVersion.h"
|
||||||
#include "util/qtthreadsutils.h"
|
#include "util/qtthreadsutils.h"
|
||||||
|
#include "util/misc.h"
|
||||||
|
|
||||||
#include <retroshare/rsfiles.h>
|
#include <retroshare/rsfiles.h>
|
||||||
#include <retroshare/rsturtle.h>
|
#include <retroshare/rsturtle.h>
|
||||||
@ -201,10 +202,6 @@ SearchDialog::SearchDialog(QWidget *parent)
|
|||||||
|
|
||||||
ui.searchResultWidget->sortItems(SR_NAME_COL, Qt::AscendingOrder);
|
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 */
|
/* Set initial size the splitter */
|
||||||
QList<int> sizes;
|
QList<int> sizes;
|
||||||
sizes << 250 << width(); // Qt calculates the right sizes
|
sizes << 250 << width(); // Qt calculates the right sizes
|
||||||
@ -239,6 +236,8 @@ SearchDialog::SearchDialog(QWidget *parent)
|
|||||||
RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this );
|
RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this );
|
||||||
}, mEventHandlerId, RsEventType::FILE_TRANSFER );
|
}, mEventHandlerId, RsEventType::FILE_TRANSFER );
|
||||||
|
|
||||||
|
mFontSizeHandler.registerFontSize(ui.searchSummaryWidget);
|
||||||
|
mFontSizeHandler.registerFontSize(ui.searchResultWidget, 1.4f);
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchDialog::~SearchDialog()
|
SearchDialog::~SearchDialog()
|
||||||
@ -325,7 +324,7 @@ void SearchDialog::checkText(const QString& txt)
|
|||||||
ui.searchButton->setDisabled(txt.length() < 3);
|
ui.searchButton->setDisabled(txt.length() < 3);
|
||||||
ui.searchLineFrame->setProperty("valid", (txt.length() >= 3));
|
ui.searchLineFrame->setProperty("valid", (txt.length() >= 3));
|
||||||
ui.searchLineFrame->style()->unpolish(ui.searchLineFrame);
|
ui.searchLineFrame->style()->unpolish(ui.searchLineFrame);
|
||||||
Rshare::refreshStyleSheet(ui.searchLineFrame, false);
|
RsApplication::refreshStyleSheet(ui.searchLineFrame, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchDialog::initialiseFileTypeMappings()
|
void SearchDialog::initialiseFileTypeMappings()
|
||||||
@ -497,25 +496,23 @@ void SearchDialog::collCreate()
|
|||||||
int selectedCount = selectedItems.size() ;
|
int selectedCount = selectedItems.size() ;
|
||||||
QTreeWidgetItem * item ;
|
QTreeWidgetItem * item ;
|
||||||
|
|
||||||
for (int i = 0; i < selectedCount; ++i) {
|
RsFileTree tree;
|
||||||
|
|
||||||
|
for (int i = 0; i < selectedCount; ++i)
|
||||||
|
{
|
||||||
item = selectedItems.at(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();
|
std::string name = item->text(SR_NAME_COL).toUtf8().constData();
|
||||||
RsFileHash hash( item->text(SR_HASH_COL).toStdString() );
|
RsFileHash hash( item->text(SR_HASH_COL).toStdString() );
|
||||||
uint64_t count = item->text(SR_SIZE_COL).toULongLong();
|
uint64_t count = item->text(SR_SIZE_COL).toULongLong();
|
||||||
|
|
||||||
DirDetails details;
|
tree.addFile(tree.root(),name,hash,count);
|
||||||
details.name = name;
|
|
||||||
details.hash = hash;
|
|
||||||
details.size = count;
|
|
||||||
details.type = DIR_TYPE_FILE;
|
|
||||||
|
|
||||||
dirVec.push_back(details);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RsCollection(dirVec,RS_FILE_HINTS_LOCAL).openNewColl(this);
|
RsCollectionDialog::openNewCollection(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchDialog::collModif()
|
void SearchDialog::collModif()
|
||||||
@ -542,12 +539,8 @@ void SearchDialog::collModif()
|
|||||||
/* open file with a suitable application */
|
/* open file with a suitable application */
|
||||||
QFileInfo qinfo;
|
QFileInfo qinfo;
|
||||||
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
||||||
if (qinfo.exists()) {
|
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
|
||||||
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath());
|
||||||
RsCollection collection;
|
|
||||||
collection.openColl(qinfo.absoluteFilePath());
|
|
||||||
}//if (qinfo.absoluteFilePath().endsWith(RsCollectionFile::ExtensionString))
|
|
||||||
}//if (qinfo.exists())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchDialog::collView()
|
void SearchDialog::collView()
|
||||||
@ -574,12 +567,8 @@ void SearchDialog::collView()
|
|||||||
/* open file with a suitable application */
|
/* open file with a suitable application */
|
||||||
QFileInfo qinfo;
|
QFileInfo qinfo;
|
||||||
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
||||||
if (qinfo.exists()) {
|
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
|
||||||
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath(), true);
|
||||||
RsCollection collection;
|
|
||||||
collection.openColl(qinfo.absoluteFilePath(), true);
|
|
||||||
}//if (qinfo.absoluteFilePath().endsWith(RsCollectionFile::ExtensionString))
|
|
||||||
}//if (qinfo.exists())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchDialog::collOpen()
|
void SearchDialog::collOpen()
|
||||||
@ -597,32 +586,35 @@ void SearchDialog::collOpen()
|
|||||||
|
|
||||||
if (rsFiles->FileDetails(hash, RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL
|
if (rsFiles->FileDetails(hash, RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL
|
||||||
| RS_FILE_HINTS_BROWSABLE | RS_FILE_HINTS_NETWORK_WIDE
|
| 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 */
|
/* make path for downloaded files */
|
||||||
std::string path;
|
std::string path;
|
||||||
path = info.path;
|
path = info.path;
|
||||||
|
|
||||||
/* open file with a suitable application */
|
/* open file with a suitable application */
|
||||||
QFileInfo qinfo;
|
QFileInfo qinfo;
|
||||||
|
RsCollection::RsCollectionErrorCode err;
|
||||||
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
||||||
if (qinfo.exists()) {
|
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
|
||||||
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
RsCollectionDialog::downloadFiles(RsCollection(qinfo.absoluteFilePath(),err));
|
||||||
RsCollection collection;
|
|
||||||
if (collection.load(qinfo.absoluteFilePath())) {
|
|
||||||
collection.downloadFiles();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RsCollection collection;
|
QString fileName;
|
||||||
if (collection.load(this)) {
|
if (!misc::getOpenFileName(nullptr, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName))
|
||||||
collection.downloadFiles();
|
return ;
|
||||||
}//if (collection.load(this))
|
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchDialog::downloadDirectory(const QTreeWidgetItem *item, const QString &base)
|
void SearchDialog::downloadDirectory(const QTreeWidgetItem *item, const QString &base)
|
||||||
@ -1048,7 +1040,7 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons
|
|||||||
|
|
||||||
child->setText(SR_SOURCES_COL, QString::number(1));
|
child->setText(SR_SOURCES_COL, QString::number(1));
|
||||||
child->setData(SR_SOURCES_COL, ROLE_SORT, 1);
|
child->setData(SR_SOURCES_COL, ROLE_SORT, 1);
|
||||||
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight );
|
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight | Qt::AlignVCenter );
|
||||||
|
|
||||||
child->setText(SR_SEARCH_ID_COL, sid_hexa);
|
child->setText(SR_SEARCH_ID_COL, sid_hexa);
|
||||||
setIconAndType(child, QString::fromUtf8(dir.name.c_str()));
|
setIconAndType(child, QString::fromUtf8(dir.name.c_str()));
|
||||||
@ -1073,7 +1065,7 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons
|
|||||||
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
|
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
|
||||||
child->setText(SR_SOURCES_COL, QString::number(1));
|
child->setText(SR_SOURCES_COL, QString::number(1));
|
||||||
child->setData(SR_SOURCES_COL, ROLE_SORT, 1);
|
child->setData(SR_SOURCES_COL, ROLE_SORT, 1);
|
||||||
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight );
|
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight | Qt::AlignVCenter );
|
||||||
child->setText(SR_SEARCH_ID_COL, sid_hexa);
|
child->setText(SR_SEARCH_ID_COL, sid_hexa);
|
||||||
child->setText(SR_TYPE_COL, tr("Folder"));
|
child->setText(SR_TYPE_COL, tr("Folder"));
|
||||||
|
|
||||||
@ -1142,7 +1134,7 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons
|
|||||||
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
|
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
|
||||||
child->setText(SR_SOURCES_COL, QString::number(1));
|
child->setText(SR_SOURCES_COL, QString::number(1));
|
||||||
child->setData(SR_SOURCES_COL, ROLE_SORT, 1);
|
child->setData(SR_SOURCES_COL, ROLE_SORT, 1);
|
||||||
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight );
|
child->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight | Qt::AlignVCenter );
|
||||||
child->setText(SR_SEARCH_ID_COL, sid_hexa);
|
child->setText(SR_SEARCH_ID_COL, sid_hexa);
|
||||||
child->setText(SR_TYPE_COL, tr("Folder"));
|
child->setText(SR_TYPE_COL, tr("Folder"));
|
||||||
|
|
||||||
@ -1332,11 +1324,13 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
|
|||||||
* to facilitate downloads we need to save the file size too
|
* to facilitate downloads we need to save the file size too
|
||||||
*/
|
*/
|
||||||
|
|
||||||
item->setText(SR_SIZE_COL, QString::number(file.size));
|
item->setText(SR_SIZE_COL, misc::friendlyUnit(file.size));
|
||||||
item->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) file.size);
|
item->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) file.size);
|
||||||
item->setText(SR_AGE_COL, QString::number(file.mtime));
|
item->setText(SR_AGE_COL, misc::timeRelativeToNow(file.mtime));
|
||||||
item->setData(SR_AGE_COL, ROLE_SORT, file.mtime);
|
item->setData(SR_AGE_COL, ROLE_SORT, file.mtime);
|
||||||
item->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
|
item->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
|
||||||
|
item->setTextAlignment( SR_AGE_COL, Qt::AlignCenter );
|
||||||
|
|
||||||
int friendSource = 0;
|
int friendSource = 0;
|
||||||
int anonymousSource = 0;
|
int anonymousSource = 0;
|
||||||
if(searchType == FRIEND_SEARCH)
|
if(searchType == FRIEND_SEARCH)
|
||||||
@ -1355,7 +1349,7 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
|
|||||||
item->setText(SR_SOURCES_COL,modifiedResult);
|
item->setText(SR_SOURCES_COL,modifiedResult);
|
||||||
item->setToolTip(SR_SOURCES_COL, tr("Obtained via ")+QString::fromStdString(rsPeers->getPeerName(file.id)) );
|
item->setToolTip(SR_SOURCES_COL, tr("Obtained via ")+QString::fromStdString(rsPeers->getPeerName(file.id)) );
|
||||||
item->setData(SR_SOURCES_COL, ROLE_SORT, fltRes);
|
item->setData(SR_SOURCES_COL, ROLE_SORT, fltRes);
|
||||||
item->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight );
|
item->setTextAlignment( SR_SOURCES_COL, Qt::AlignRight | Qt::AlignVCenter );
|
||||||
item->setText(SR_SEARCH_ID_COL, sid_hexa);
|
item->setText(SR_SEARCH_ID_COL, sid_hexa);
|
||||||
|
|
||||||
QColor foreground;
|
QColor foreground;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "retroshare/rsevents.h"
|
#include "retroshare/rsevents.h"
|
||||||
#include "ui_SearchDialog.h"
|
#include "ui_SearchDialog.h"
|
||||||
#include "retroshare-gui/mainpage.h"
|
#include "retroshare-gui/mainpage.h"
|
||||||
|
#include "util/FontSizeHandler.h"
|
||||||
|
|
||||||
class AdvancedSearchDialog;
|
class AdvancedSearchDialog;
|
||||||
class RSTreeWidgetItemCompareRole;
|
class RSTreeWidgetItemCompareRole;
|
||||||
@ -173,6 +174,8 @@ private:
|
|||||||
QAction *collViewAct;
|
QAction *collViewAct;
|
||||||
QAction *collOpenAct;
|
QAction *collOpenAct;
|
||||||
|
|
||||||
|
FontSizeHandler mFontSizeHandler;
|
||||||
|
|
||||||
/** Qt Designer generated object */
|
/** Qt Designer generated object */
|
||||||
Ui::SearchDialog ui;
|
Ui::SearchDialog ui;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "gui/RetroShareLink.h"
|
#include "gui/RetroShareLink.h"
|
||||||
#include "gui/ShareManager.h"
|
#include "gui/ShareManager.h"
|
||||||
#include "gui/common/PeerDefs.h"
|
#include "gui/common/PeerDefs.h"
|
||||||
#include "gui/common/RsCollection.h"
|
#include "gui/common/RsCollectionDialog.h"
|
||||||
#include "gui/msgs/MessageComposer.h"
|
#include "gui/msgs/MessageComposer.h"
|
||||||
#include "gui/gxschannels/GxsChannelDialog.h"
|
#include "gui/gxschannels/GxsChannelDialog.h"
|
||||||
#include "gui/gxsforums/GxsForumsDialog.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();
|
QString dir_name = QDir(QString::fromUtf8(details.name.c_str())).dirName();
|
||||||
|
|
||||||
RetroShareLink link = RetroShareLink::createFileTree(dir_name,ft->mTotalSize,ft->mTotalFiles,QString::fromStdString(ft->toRadix64())) ;
|
RetroShareLink link = RetroShareLink::createFileTree(dir_name,ft->totalFileSize(),ft->numFiles(),QString::fromStdString(ft->toRadix64())) ;
|
||||||
|
|
||||||
if(link.valid())
|
if(link.valid())
|
||||||
urls.push_back(link) ;
|
urls.push_back(link) ;
|
||||||
@ -734,7 +734,32 @@ void SharedFilesDialog::sendLinkTo()
|
|||||||
void SharedFilesDialog::collCreate()
|
void SharedFilesDialog::collCreate()
|
||||||
{
|
{
|
||||||
QModelIndexList lst = getSelected();
|
QModelIndexList lst = getSelected();
|
||||||
model->createCollectionFile(this, lst);
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedFilesDialog::collModif()
|
void SharedFilesDialog::collModif()
|
||||||
@ -759,12 +784,8 @@ void SharedFilesDialog::collModif()
|
|||||||
/* open file with a suitable application */
|
/* open file with a suitable application */
|
||||||
QFileInfo qinfo;
|
QFileInfo qinfo;
|
||||||
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
||||||
if (qinfo.exists()) {
|
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
|
||||||
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
RsCollectionDialog::editExistingCollection(qinfo.absoluteFilePath());
|
||||||
RsCollection collection;
|
|
||||||
collection.openColl(qinfo.absoluteFilePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedFilesDialog::collView()
|
void SharedFilesDialog::collView()
|
||||||
@ -789,12 +810,8 @@ void SharedFilesDialog::collView()
|
|||||||
/* open file with a suitable application */
|
/* open file with a suitable application */
|
||||||
QFileInfo qinfo;
|
QFileInfo qinfo;
|
||||||
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
||||||
if (qinfo.exists()) {
|
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
|
||||||
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath(), true);
|
||||||
RsCollection collection;
|
|
||||||
collection.openColl(qinfo.absoluteFilePath(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedFilesDialog::collOpen()
|
void SharedFilesDialog::collOpen()
|
||||||
@ -821,20 +838,24 @@ void SharedFilesDialog::collOpen()
|
|||||||
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
||||||
if (qinfo.exists()) {
|
if (qinfo.exists()) {
|
||||||
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
||||||
RsCollection collection;
|
|
||||||
if (collection.load(qinfo.absoluteFilePath())) {
|
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath(),true);
|
||||||
collection.downloadFiles();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RsCollection collection;
|
QString fileName;
|
||||||
if (collection.load(this)) {
|
if (!misc::getOpenFileName(nullptr, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName))
|
||||||
collection.downloadFiles();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalSharedFilesDialog::playselectedfiles()
|
void LocalSharedFilesDialog::playselectedfiles()
|
||||||
@ -1145,12 +1166,14 @@ void LocalSharedFilesDialog::spawnCustomPopupMenu( QPoint point )
|
|||||||
collViewAct->setEnabled(bIsRsColl);
|
collViewAct->setEnabled(bIsRsColl);
|
||||||
collOpenAct->setEnabled(true);
|
collOpenAct->setEnabled(true);
|
||||||
|
|
||||||
QMenu collectionMenu(tr("Collection"), this);
|
QMenu collectionMenu(tr("Retroshare Collection"), this);
|
||||||
collectionMenu.setIcon(QIcon(IMAGE_LIBRARY));
|
collectionMenu.setIcon(QIcon(IMAGE_LIBRARY));
|
||||||
collectionMenu.addAction(collCreateAct);
|
collectionMenu.addAction(collCreateAct);
|
||||||
collectionMenu.addAction(collModifAct);
|
|
||||||
collectionMenu.addAction(collViewAct);
|
if(bIsRsColl)
|
||||||
collectionMenu.addAction(collOpenAct);
|
collectionMenu.addAction(collModifAct);
|
||||||
|
//collectionMenu.addAction(collViewAct);
|
||||||
|
//collectionMenu.addAction(collOpenAct);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DIR_TYPE_DIR :
|
case DIR_TYPE_DIR :
|
||||||
@ -1688,12 +1711,16 @@ bool SharedFilesDialog::tree_FilterItem(const QModelIndex &index, const QString
|
|||||||
|
|
||||||
void SharedFilesDialog::updateFontSize()
|
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();
|
int customFontSize = Settings->valueFromGroup("File", "MinimumFontSize", 11).toInt();
|
||||||
|
#endif
|
||||||
QFont newFont = ui.dirTreeView->font();
|
QFont newFont = ui.dirTreeView->font();
|
||||||
if (newFont.pointSize() != customFontSize) {
|
if (newFont.pointSize() != customFontSize) {
|
||||||
newFont.setPointSize(customFontSize);
|
newFont.setPointSize(customFontSize);
|
||||||
QFontMetricsF fontMetrics(newFont);
|
QFontMetricsF fontMetrics(newFont);
|
||||||
int iconHeight = fontMetrics.height();
|
int iconHeight = fontMetrics.height()*1.5;
|
||||||
ui.dirTreeView->setFont(newFont);
|
ui.dirTreeView->setFont(newFont);
|
||||||
ui.dirTreeView->setIconSize(QSize(iconHeight, iconHeight));
|
ui.dirTreeView->setIconSize(QSize(iconHeight, iconHeight));
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,10 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::Box</enum>
|
<enum>QFrame::StyledPanel</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Sunken</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
@ -399,8 +399,8 @@ border-image: url(:/images/closepressed.png)
|
|||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc"/>
|
|
||||||
<include location="../icons.qrc"/>
|
<include location="../icons.qrc"/>
|
||||||
|
<include location="../images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include "gui/SoundManager.h"
|
#include "gui/SoundManager.h"
|
||||||
#include "gui/RetroShareLink.h"
|
#include "gui/RetroShareLink.h"
|
||||||
#include "gui/common/FilesDefs.h"
|
#include "gui/common/FilesDefs.h"
|
||||||
#include "gui/common/RsCollection.h"
|
#include "gui/common/RsCollectionDialog.h"
|
||||||
#include "gui/common/RSTreeView.h"
|
#include "gui/common/RSTreeView.h"
|
||||||
#include "gui/common/RsUrlHandler.h"
|
#include "gui/common/RsUrlHandler.h"
|
||||||
#include "gui/FileTransfer/DetailsDialog.h"
|
#include "gui/FileTransfer/DetailsDialog.h"
|
||||||
@ -1975,7 +1975,7 @@ void TransfersDialog::pasteLink()
|
|||||||
for(auto &it : links)
|
for(auto &it : links)
|
||||||
col.merge_in(it.name(),it.size(),RsFileHash(it.hash().toStdString())) ;
|
col.merge_in(it.name(),it.size(),RsFileHash(it.hash().toStdString())) ;
|
||||||
|
|
||||||
col.downloadFiles();
|
RsCollectionDialog::downloadFiles(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransfersDialog::getDLSelectedItems(std::set<RsFileHash> *ids, std::set<int> *rows)
|
void TransfersDialog::getDLSelectedItems(std::set<RsFileHash> *ids, std::set<int> *rows)
|
||||||
@ -2466,21 +2466,17 @@ void TransfersDialog::collCreate()
|
|||||||
std::set<RsFileHash>::iterator it ;
|
std::set<RsFileHash>::iterator it ;
|
||||||
getDLSelectedItems(&items, NULL);
|
getDLSelectedItems(&items, NULL);
|
||||||
|
|
||||||
|
RsFileTree tree;
|
||||||
|
|
||||||
for (it = items.begin(); it != items.end(); ++it)
|
for (it = items.begin(); it != items.end(); ++it)
|
||||||
{
|
{
|
||||||
FileInfo info;
|
FileInfo info;
|
||||||
if (!rsFiles->FileDetails(*it, RS_FILE_HINTS_DOWNLOAD, info)) continue;
|
if (!rsFiles->FileDetails(*it, RS_FILE_HINTS_DOWNLOAD, info)) continue;
|
||||||
|
|
||||||
DirDetails details;
|
tree.addFile(tree.root(),info.fname,info.hash,info.size);
|
||||||
details.name = info.fname;
|
|
||||||
details.hash = info.hash;
|
|
||||||
details.size = info.size;
|
|
||||||
details.type = DIR_TYPE_FILE;
|
|
||||||
|
|
||||||
dirVec.push_back(details);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RsCollection(dirVec,RS_FILE_HINTS_LOCAL).openNewColl(this);
|
RsCollectionDialog::openNewCollection(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransfersDialog::collModif()
|
void TransfersDialog::collModif()
|
||||||
@ -2504,12 +2500,8 @@ void TransfersDialog::collModif()
|
|||||||
/* open collection */
|
/* open collection */
|
||||||
QFileInfo qinfo;
|
QFileInfo qinfo;
|
||||||
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
||||||
if (qinfo.exists()) {
|
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
|
||||||
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath());
|
||||||
RsCollection collection;
|
|
||||||
collection.openColl(qinfo.absoluteFilePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2534,12 +2526,8 @@ void TransfersDialog::collView()
|
|||||||
/* open collection */
|
/* open collection */
|
||||||
QFileInfo qinfo;
|
QFileInfo qinfo;
|
||||||
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
||||||
if (qinfo.exists()) {
|
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
|
||||||
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
RsCollectionDialog::openExistingCollection(qinfo.absoluteFilePath(), true);
|
||||||
RsCollection collection;
|
|
||||||
collection.openColl(qinfo.absoluteFilePath(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2564,23 +2552,29 @@ void TransfersDialog::collOpen()
|
|||||||
/* open file with a suitable application */
|
/* open file with a suitable application */
|
||||||
QFileInfo qinfo;
|
QFileInfo qinfo;
|
||||||
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
||||||
if (qinfo.exists()) {
|
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
|
||||||
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
{
|
||||||
RsCollection collection;
|
RsCollection::RsCollectionErrorCode code;
|
||||||
if (collection.load(qinfo.absoluteFilePath())) {
|
RsCollectionDialog::downloadFiles(RsCollection(qinfo.absoluteFilePath(),code));
|
||||||
collection.downloadFiles();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RsCollection collection;
|
QString fileName;
|
||||||
if (collection.load(this)) {
|
if (!misc::getOpenFileName(nullptr, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName))
|
||||||
collection.downloadFiles();
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransfersDialog::collAutoOpen(const QString &fileHash)
|
void TransfersDialog::collAutoOpen(const QString &fileHash)
|
||||||
@ -2592,21 +2586,18 @@ void TransfersDialog::collAutoOpen(const QString &fileHash)
|
|||||||
if (rsFiles->FileDetails(hash, RS_FILE_HINTS_DOWNLOAD, info)) {
|
if (rsFiles->FileDetails(hash, RS_FILE_HINTS_DOWNLOAD, info)) {
|
||||||
|
|
||||||
/* make path for downloaded files */
|
/* make path for downloaded files */
|
||||||
if (info.downloadStatus == FT_STATE_COMPLETE) {
|
if (info.downloadStatus == FT_STATE_COMPLETE)
|
||||||
|
{
|
||||||
std::string path;
|
std::string path;
|
||||||
path = info.path + "/" + info.fname;
|
path = info.path + "/" + info.fname;
|
||||||
|
|
||||||
/* open file with a suitable application */
|
/* open file with a suitable application */
|
||||||
QFileInfo qinfo;
|
QFileInfo qinfo;
|
||||||
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
qinfo.setFile(QString::fromUtf8(path.c_str()));
|
||||||
if (qinfo.exists()) {
|
RsCollection::RsCollectionErrorCode err;
|
||||||
if (qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString)) {
|
|
||||||
RsCollection collection;
|
if (qinfo.exists() && qinfo.absoluteFilePath().endsWith(RsCollection::ExtensionString))
|
||||||
if (collection.load(qinfo.absoluteFilePath(), false)) {
|
RsCollectionDialog::downloadFiles(RsCollection(qinfo.absoluteFilePath(),err));
|
||||||
collection.autoDownloadFiles();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
retroshare-gui/src/gui/FileTransfer/ULListDelegate.cpp
Normal file → Executable file
12
retroshare-gui/src/gui/FileTransfer/ULListDelegate.cpp
Normal file → Executable file
@ -101,7 +101,7 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
|
|||||||
multi *= 1024.0;
|
multi *= 1024.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
|
||||||
break;
|
break;
|
||||||
case COLUMN_UTRANSFERRED:
|
case COLUMN_UTRANSFERRED:
|
||||||
transferred = index.data().toLongLong();
|
transferred = index.data().toLongLong();
|
||||||
@ -120,7 +120,7 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
|
|||||||
multi *= 1024.0;
|
multi *= 1024.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
|
||||||
break;
|
break;
|
||||||
case COLUMN_ULSPEED:
|
case COLUMN_ULSPEED:
|
||||||
ulspeed = index.data().toDouble();
|
ulspeed = index.data().toDouble();
|
||||||
@ -131,7 +131,7 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti
|
|||||||
temp.sprintf("%.2f", ulspeed/1024.);
|
temp.sprintf("%.2f", ulspeed/1024.);
|
||||||
temp += " KB/s";
|
temp += " KB/s";
|
||||||
}
|
}
|
||||||
painter->drawText(option.rect, Qt::AlignRight, temp);
|
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter, temp);
|
||||||
break;
|
break;
|
||||||
case COLUMN_UPROGRESS:
|
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);
|
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));
|
pixmapRect = (pixmap.isNull() ? QRect(0, 0, 0, 0): QRect(QPoint(0, 0), option.decorationSize));
|
||||||
if (pixmapRect.isValid()){
|
if (pixmapRect.isValid()){
|
||||||
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft, pixmap.size(), option.rect).topLeft();
|
QPoint p = QStyle::alignedRect(option.direction, Qt::AlignLeft | Qt::AlignVCenter, pixmap.size(), option.rect).topLeft();
|
||||||
painter->drawPixmap(p, pixmap);
|
painter->drawPixmap(p, pixmap);
|
||||||
}
|
}
|
||||||
painter->drawText(option.rect.translated(pixmap.size().width(), 0), Qt::AlignLeft, index.data().toString());
|
painter->drawText(option.rect.translated(pixmap.size().width(), 0), Qt::AlignLeft | Qt::AlignVCenter, index.data().toString());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
painter->drawText(option.rect, Qt::AlignCenter, index.data().toString());
|
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());
|
float w = QFontMetricsF(option.font).width(index.data(Qt::DisplayRole).toString());
|
||||||
|
|
||||||
int S = QFontMetricsF(option.font).height() ;
|
int S = QFontMetricsF(option.font).height()*1.5 ;
|
||||||
return QSize(w,S);
|
return QSize(w,S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ void GenCertDialog::initKeyList()
|
|||||||
|
|
||||||
void GenCertDialog::mouseMoveEvent(QMouseEvent *e)
|
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) ;
|
QDialog::mouseMoveEvent(e) ;
|
||||||
}
|
}
|
||||||
@ -649,7 +649,7 @@ void GenCertDialog::genPerson()
|
|||||||
{
|
{
|
||||||
/* complete the process */
|
/* complete the process */
|
||||||
RsInit::LoadPassword(sslPasswd);
|
RsInit::LoadPassword(sslPasswd);
|
||||||
if (Rshare::loadCertificate(sslId, false)) {
|
if (RsApplication::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.
|
// 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.
|
// (csoler) This is really bad: we have to guess that 30 secs will be enough. I have no better way to do this.
|
||||||
|
@ -421,7 +421,7 @@ void GetStartedDialog::emailSupport()
|
|||||||
sysVersion = "Linux";
|
sysVersion = "Linux";
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
text += QString("My RetroShare Configuration is: (%1, %2, %3)").arg(Rshare::retroshareVersion(true)
|
text += QString("My RetroShare Configuration is: (%1, %2, %3)").arg(RsApplication::retroshareVersion(true)
|
||||||
, sysVersion
|
, sysVersion
|
||||||
).arg(static_cast<typename std::underlying_type<RsConfigUserLvl>::type>(userLevel)) + "\n";
|
).arg(static_cast<typename std::underlying_type<RsConfigUserLvl>::type>(userLevel)) + "\n";
|
||||||
text += "\n";
|
text += "\n";
|
||||||
|
@ -80,7 +80,7 @@ HelpDialog::HelpDialog(QWidget *parent) :
|
|||||||
ui->thanks->setHtml(in.readAll());
|
ui->thanks->setHtml(in.readAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->version->setText(Rshare::retroshareVersion(true));
|
ui->version->setText(RsApplication::retroshareVersion(true));
|
||||||
|
|
||||||
/* Add version numbers of libretroshare */
|
/* Add version numbers of libretroshare */
|
||||||
std::list<RsLibraryInfo> libraries;
|
std::list<RsLibraryInfo> libraries;
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>Courier New</family>
|
<family>Courier New</family>
|
||||||
<pointsize>10</pointsize>
|
|
||||||
<weight>75</weight>
|
<weight>75</weight>
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
@ -88,7 +87,6 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<pointsize>11</pointsize>
|
|
||||||
<weight>75</weight>
|
<weight>75</weight>
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
@ -107,7 +105,7 @@
|
|||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="images.qrc">
|
<iconset resource="icons.qrc">
|
||||||
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
|
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
@ -233,11 +231,6 @@
|
|||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="5">
|
<item row="1" column="0" colspan="5">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<pointsize>12</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Open Source cross-platform,
|
<string>Open Source cross-platform,
|
||||||
private and secure decentralized communication platform.
|
private and secure decentralized communication platform.
|
||||||
@ -317,11 +310,6 @@ private and secure decentralized communication platform.
|
|||||||
</item>
|
</item>
|
||||||
<item row="0" column="0" colspan="3">
|
<item row="0" column="0" colspan="3">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<pointsize>11</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true"/>
|
<string notr="true"/>
|
||||||
</property>
|
</property>
|
||||||
@ -405,11 +393,6 @@ private and secure decentralized communication platform.
|
|||||||
</item>
|
</item>
|
||||||
<item row="0" column="0" colspan="3">
|
<item row="0" column="0" colspan="3">
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<pointsize>11</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Do you need help with Retroshare?</string>
|
<string>Do you need help with Retroshare?</string>
|
||||||
</property>
|
</property>
|
||||||
@ -424,8 +407,8 @@ private and secure decentralized communication platform.
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="images.qrc"/>
|
|
||||||
<include location="icons.qrc"/>
|
<include location="icons.qrc"/>
|
||||||
|
<include location="images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
#include "util/rsdebug.h"
|
#include "util/rsdebug.h"
|
||||||
|
|
||||||
#include "retroshare/rsgxsflags.h"
|
#include "retroshare/rsgxsflags.h"
|
||||||
#include "retroshare/rsmsgs.h"
|
#include "retroshare/rsmsgs.h"
|
||||||
#include "retroshare/rspeers.h"
|
#include "retroshare/rspeers.h"
|
||||||
#include "retroshare/rsservicecontrol.h"
|
#include "retroshare/rsservicecontrol.h"
|
||||||
|
|
||||||
@ -167,20 +167,17 @@ IdDialog::IdDialog(QWidget *parent)
|
|||||||
// This is used to grab the broadcast of changes from p3GxsCircles, which is discarded by the current dialog, since it expects data for p3Identity only.
|
// This is used to grab the broadcast of changes from p3GxsCircles, which is discarded by the current dialog, since it expects data for p3Identity only.
|
||||||
//mCirclesBroadcastBase = new RsGxsUpdateBroadcastBase(rsGxsCircles, this);
|
//mCirclesBroadcastBase = new RsGxsUpdateBroadcastBase(rsGxsCircles, this);
|
||||||
//connect(mCirclesBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateCirclesDisplay(bool)));
|
//connect(mCirclesBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateCirclesDisplay(bool)));
|
||||||
|
|
||||||
ownItem = new QTreeWidgetItem();
|
ownItem = new QTreeWidgetItem();
|
||||||
ownItem->setText(RSID_COL_NICKNAME, tr("My own identities"));
|
ownItem->setText(RSID_COL_NICKNAME, tr("My own identities"));
|
||||||
ownItem->setFont(RSID_COL_NICKNAME, ui->idTreeWidget->font());
|
|
||||||
ownItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff); // this is in order to prevent displaying a reputaiton icon next to these items.
|
ownItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff); // this is in order to prevent displaying a reputaiton icon next to these items.
|
||||||
|
|
||||||
allItem = new QTreeWidgetItem();
|
allItem = new QTreeWidgetItem();
|
||||||
allItem->setText(RSID_COL_NICKNAME, tr("All"));
|
allItem->setText(RSID_COL_NICKNAME, tr("All"));
|
||||||
allItem->setFont(RSID_COL_NICKNAME, ui->idTreeWidget->font());
|
|
||||||
allItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff);
|
allItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff);
|
||||||
|
|
||||||
contactsItem = new QTreeWidgetItem();
|
contactsItem = new QTreeWidgetItem();
|
||||||
contactsItem->setText(RSID_COL_NICKNAME, tr("My contacts"));
|
contactsItem->setText(RSID_COL_NICKNAME, tr("My contacts"));
|
||||||
contactsItem->setFont(RSID_COL_NICKNAME, ui->idTreeWidget->font());
|
|
||||||
contactsItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff);
|
contactsItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff);
|
||||||
|
|
||||||
|
|
||||||
@ -198,7 +195,7 @@ IdDialog::IdDialog(QWidget *parent)
|
|||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDLIST, ui->idTreeWidget, false);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDLIST, ui->idTreeWidget, false);
|
||||||
mStateHelper->addClear(IDDIALOG_IDLIST, ui->idTreeWidget);
|
mStateHelper->addClear(IDDIALOG_IDLIST, ui->idTreeWidget);
|
||||||
|
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
|
//mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_PublishTS);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_PublishTS);
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
||||||
@ -214,7 +211,7 @@ IdDialog::IdDialog(QWidget *parent)
|
|||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->label_positive);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->label_positive);
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->label_negative);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->label_negative);
|
||||||
|
|
||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
|
//mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
|
||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_PublishTS);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_PublishTS);
|
||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
|
||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
||||||
@ -225,7 +222,7 @@ IdDialog::IdDialog(QWidget *parent)
|
|||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->overallOpinion_TF);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->overallOpinion_TF);
|
||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->usageStatistics_TB);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->usageStatistics_TB);
|
||||||
|
|
||||||
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
|
//mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
|
||||||
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_PublishTS);
|
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_PublishTS);
|
||||||
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
|
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
|
||||||
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
||||||
@ -253,7 +250,7 @@ IdDialog::IdDialog(QWidget *parent)
|
|||||||
|
|
||||||
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
|
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
|
||||||
connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation()));
|
connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation()));
|
||||||
|
|
||||||
connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite()));
|
connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite()));
|
||||||
connect(ui->editButton, SIGNAL(clicked()), this, SLOT(editIdentity()));
|
connect(ui->editButton, SIGNAL(clicked()), this, SLOT(editIdentity()));
|
||||||
|
|
||||||
@ -269,7 +266,7 @@ IdDialog::IdDialog(QWidget *parent)
|
|||||||
/* Initialize splitter */
|
/* Initialize splitter */
|
||||||
ui->mainSplitter->setStretchFactor(0, 0);
|
ui->mainSplitter->setStretchFactor(0, 0);
|
||||||
ui->mainSplitter->setStretchFactor(1, 1);
|
ui->mainSplitter->setStretchFactor(1, 1);
|
||||||
|
|
||||||
clearPerson();
|
clearPerson();
|
||||||
|
|
||||||
/* Add filter types */
|
/* Add filter types */
|
||||||
@ -327,18 +324,18 @@ IdDialog::IdDialog(QWidget *parent)
|
|||||||
idTWHAction->setData(RSID_FILTER_BANNED);
|
idTWHAction->setData(RSID_FILTER_BANNED);
|
||||||
connect(idTWHAction, SIGNAL(toggled(bool)), this, SLOT(filterToggled(bool)));
|
connect(idTWHAction, SIGNAL(toggled(bool)), this, SLOT(filterToggled(bool)));
|
||||||
idTWHMenu->addAction(idTWHAction);
|
idTWHMenu->addAction(idTWHAction);
|
||||||
|
|
||||||
QAction *CreateIDAction = new QAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/person.png"),tr("Create new Identity"), this);
|
QAction *CreateIDAction = new QAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/person.png"),tr("Create new Identity"), this);
|
||||||
connect(CreateIDAction, SIGNAL(triggered()), this, SLOT(addIdentity()));
|
connect(CreateIDAction, SIGNAL(triggered()), this, SLOT(addIdentity()));
|
||||||
|
|
||||||
QAction *CreateCircleAction = new QAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/circles.png"),tr("Create new circle"), this);
|
QAction *CreateCircleAction = new QAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/circles.png"),tr("Create new circle"), this);
|
||||||
connect(CreateCircleAction, SIGNAL(triggered()), this, SLOT(createExternalCircle()));
|
connect(CreateCircleAction, SIGNAL(triggered()), this, SLOT(createExternalCircle()));
|
||||||
|
|
||||||
QMenu *menu = new QMenu();
|
QMenu *menu = new QMenu();
|
||||||
menu->addAction(CreateIDAction);
|
menu->addAction(CreateIDAction);
|
||||||
menu->addAction(CreateCircleAction);
|
menu->addAction(CreateCircleAction);
|
||||||
ui->toolButton_New->setMenu(menu);
|
ui->toolButton_New->setMenu(menu);
|
||||||
|
|
||||||
/* Add filter actions */
|
/* Add filter actions */
|
||||||
QTreeWidgetItem *headerItem = ui->idTreeWidget->headerItem();
|
QTreeWidgetItem *headerItem = ui->idTreeWidget->headerItem();
|
||||||
QString headerText = headerItem->text(RSID_COL_NICKNAME);
|
QString headerText = headerItem->text(RSID_COL_NICKNAME);
|
||||||
@ -361,14 +358,14 @@ IdDialog::IdDialog(QWidget *parent)
|
|||||||
|
|
||||||
ui->idTreeWidget->setColumnHidden(RSID_COL_IDTYPE, true);
|
ui->idTreeWidget->setColumnHidden(RSID_COL_IDTYPE, true);
|
||||||
ui->idTreeWidget->setColumnHidden(RSID_COL_KEYID, true);
|
ui->idTreeWidget->setColumnHidden(RSID_COL_KEYID, true);
|
||||||
|
|
||||||
/* Set initial column width */
|
/* Set initial column width */
|
||||||
int fontWidth = QFontMetricsF(ui->idTreeWidget->font()).width("W");
|
int fontWidth = QFontMetricsF(ui->idTreeWidget->font()).width("W");
|
||||||
ui->idTreeWidget->setColumnWidth(RSID_COL_NICKNAME, 14 * fontWidth);
|
ui->idTreeWidget->setColumnWidth(RSID_COL_NICKNAME, 14 * fontWidth);
|
||||||
ui->idTreeWidget->setColumnWidth(RSID_COL_KEYID, 20 * fontWidth);
|
ui->idTreeWidget->setColumnWidth(RSID_COL_KEYID, 20 * fontWidth);
|
||||||
ui->idTreeWidget->setColumnWidth(RSID_COL_IDTYPE, 18 * fontWidth);
|
ui->idTreeWidget->setColumnWidth(RSID_COL_IDTYPE, 18 * fontWidth);
|
||||||
ui->idTreeWidget->setColumnWidth(RSID_COL_VOTES, 2 * fontWidth);
|
ui->idTreeWidget->setColumnWidth(RSID_COL_VOTES, 2 * fontWidth);
|
||||||
|
|
||||||
ui->idTreeWidget->setItemDelegate(new RSElidedItemDelegate());
|
ui->idTreeWidget->setItemDelegate(new RSElidedItemDelegate());
|
||||||
ui->idTreeWidget->setItemDelegateForColumn(
|
ui->idTreeWidget->setItemDelegateForColumn(
|
||||||
RSID_COL_NICKNAME,
|
RSID_COL_NICKNAME,
|
||||||
@ -408,13 +405,52 @@ IdDialog::IdDialog(QWidget *parent)
|
|||||||
processSettings(true);
|
processSettings(true);
|
||||||
|
|
||||||
// circles stuff
|
// circles stuff
|
||||||
|
|
||||||
//connect(ui->treeWidget_membership, SIGNAL(itemSelectionChanged()), this, SLOT(circle_selected()));
|
//connect(ui->treeWidget_membership, SIGNAL(itemSelectionChanged()), this, SLOT(circle_selected()));
|
||||||
connect(ui->treeWidget_membership, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CircleListCustomPopupMenu(QPoint)));
|
connect(ui->treeWidget_membership, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(CircleListCustomPopupMenu(QPoint)));
|
||||||
connect(ui->autoBanIdentities_CB, SIGNAL(toggled(bool)), this, SLOT(toggleAutoBanIdentities(bool)));
|
connect(ui->autoBanIdentities_CB, SIGNAL(toggled(bool)), this, SLOT(toggleAutoBanIdentities(bool)));
|
||||||
|
|
||||||
updateIdTimer.setSingleShot(true);
|
updateIdTimer.setSingleShot(true);
|
||||||
connect(&updateIdTimer, SIGNAL(timeout()), this, SLOT(updateIdList()));
|
connect(&updateIdTimer, SIGNAL(timeout()), this, SLOT(updateIdList()));
|
||||||
|
|
||||||
|
mFontSizeHandler.registerFontSize(ui->idTreeWidget, 0, [this] (QAbstractItemView*, int fontSize) {
|
||||||
|
// Set new font size on all items
|
||||||
|
QTreeWidgetItemIterator it(ui->idTreeWidget);
|
||||||
|
while (*it) {
|
||||||
|
QTreeWidgetItem *item = *it;
|
||||||
|
if (item->parent()) {
|
||||||
|
QFont font = item->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME);
|
||||||
|
font.setPointSize(fontSize);
|
||||||
|
|
||||||
|
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, font);
|
||||||
|
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID, font);
|
||||||
|
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, font);
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mFontSizeHandler.registerFontSize(ui->treeWidget_membership, 0, [this] (QAbstractItemView*, int fontSize) {
|
||||||
|
// Set new font size on all items
|
||||||
|
QTreeWidgetItemIterator it(ui->treeWidget_membership);
|
||||||
|
while (*it) {
|
||||||
|
QTreeWidgetItem *item = *it;
|
||||||
|
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
|
||||||
|
if (item->parent())
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
QFont font = item->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME);
|
||||||
|
font.setPointSize(fontSize);
|
||||||
|
|
||||||
|
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, font);
|
||||||
|
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID, font);
|
||||||
|
item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, font);
|
||||||
|
|
||||||
|
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
void IdDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
||||||
@ -429,14 +465,23 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
|||||||
switch(e->mIdentityEventCode)
|
switch(e->mIdentityEventCode)
|
||||||
{
|
{
|
||||||
case RsGxsIdentityEventCode::DELETED_IDENTITY:
|
case RsGxsIdentityEventCode::DELETED_IDENTITY:
|
||||||
case RsGxsIdentityEventCode::NEW_IDENTITY:
|
if(mId == e->mIdentityId)
|
||||||
|
{
|
||||||
|
mId.clear();
|
||||||
|
updateIdentity();
|
||||||
|
}
|
||||||
|
updateIdList();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsGxsIdentityEventCode::NEW_IDENTITY:
|
||||||
case RsGxsIdentityEventCode::UPDATED_IDENTITY:
|
case RsGxsIdentityEventCode::UPDATED_IDENTITY:
|
||||||
if (isVisible())
|
if (isVisible())
|
||||||
{
|
{
|
||||||
if(rsIdentity->isOwnId(RsGxsId(e->mIdentityId)))
|
if(rsIdentity->isOwnId(RsGxsId(e->mIdentityId)))
|
||||||
updateIdList();
|
updateIdList();
|
||||||
else
|
else
|
||||||
updateIdTimer.start(3000); // use a timer for events not generated by local changes
|
updateIdTimer.start(3000); // use a timer for events not generated by local changes which generally
|
||||||
|
// come in large herds. Allows to group multiple changes into a single UI update.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
needUpdateIdsOnNextShow = true;
|
needUpdateIdsOnNextShow = true;
|
||||||
@ -479,13 +524,13 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
|||||||
|
|
||||||
void IdDialog::clearPerson()
|
void IdDialog::clearPerson()
|
||||||
{
|
{
|
||||||
QFontMetricsF f(ui->avLabel_Person->font()) ;
|
//QFontMetricsF f(ui->avLabel_Person->font()) ;
|
||||||
|
|
||||||
ui->avLabel_Person->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/people.png").scaled(f.height()*4,f.height()*4,Qt::KeepAspectRatio,Qt::SmoothTransformation));
|
|
||||||
ui->headerTextLabel_Person->setText(tr("People"));
|
ui->headerTextLabel_Person->setText(tr("People"));
|
||||||
|
|
||||||
ui->info_Frame_Invite->hide();
|
ui->info_Frame_Invite->hide();
|
||||||
ui->avatarLabel->clear();
|
ui->avatarLabel->clear();
|
||||||
|
ui->avatarLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/people.png"));
|
||||||
|
|
||||||
whileBlocking(ui->ownOpinion_CB)->setCurrentIndex(1);
|
whileBlocking(ui->ownOpinion_CB)->setCurrentIndex(1);
|
||||||
whileBlocking(ui->autoBanIdentities_CB)->setChecked(false);
|
whileBlocking(ui->autoBanIdentities_CB)->setChecked(false);
|
||||||
@ -507,10 +552,10 @@ void IdDialog::updateCirclesDisplay()
|
|||||||
{
|
{
|
||||||
if(RsAutoUpdatePage::eventsLocked())
|
if(RsAutoUpdatePage::eventsLocked())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
if(!isVisible())
|
if(!isVisible())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
#ifdef ID_DEBUG
|
#ifdef ID_DEBUG
|
||||||
std::cerr << "!!Updating circles display!" << std::endl;
|
std::cerr << "!!Updating circles display!" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
@ -655,7 +700,6 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
|
|||||||
{
|
{
|
||||||
mExternalOtherCircleItem = new QTreeWidgetItem();
|
mExternalOtherCircleItem = new QTreeWidgetItem();
|
||||||
mExternalOtherCircleItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Other circles"));
|
mExternalOtherCircleItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Other circles"));
|
||||||
mExternalOtherCircleItem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, ui->treeWidget_membership->font());
|
|
||||||
ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem);
|
ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,7 +707,6 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
|
|||||||
{
|
{
|
||||||
mExternalBelongingCircleItem = new QTreeWidgetItem();
|
mExternalBelongingCircleItem = new QTreeWidgetItem();
|
||||||
mExternalBelongingCircleItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Circles I belong to"));
|
mExternalBelongingCircleItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Circles I belong to"));
|
||||||
mExternalBelongingCircleItem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, ui->treeWidget_membership->font());
|
|
||||||
ui->treeWidget_membership->addTopLevelItem(mExternalBelongingCircleItem);
|
ui->treeWidget_membership->addTopLevelItem(mExternalBelongingCircleItem);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -920,16 +963,16 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
|
|||||||
|
|
||||||
bool IdDialog::getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id)
|
bool IdDialog::getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id)
|
||||||
{
|
{
|
||||||
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
|
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
|
||||||
if ((!item) || (!item->parent()))
|
if ((!item) || (!item->parent()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QString coltext = (item->parent()->parent())? (item->parent()->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString()) : (item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString());
|
QString coltext = (item->parent()->parent())? (item->parent()->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString()) : (item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString());
|
||||||
id = RsGxsCircleId( coltext.toStdString()) ;
|
id = RsGxsCircleId( coltext.toStdString()) ;
|
||||||
#else
|
#else
|
||||||
if(!item)
|
if(!item)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QString coltext = (item->parent())? (item->parent()->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString()) : (item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString());
|
QString coltext = (item->parent())? (item->parent()->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString()) : (item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString());
|
||||||
id = RsGxsCircleId( coltext.toStdString()) ;
|
id = RsGxsCircleId( coltext.toStdString()) ;
|
||||||
#endif
|
#endif
|
||||||
@ -958,19 +1001,19 @@ void IdDialog::createExternalCircle()
|
|||||||
void IdDialog::showEditExistingCircle()
|
void IdDialog::showEditExistingCircle()
|
||||||
{
|
{
|
||||||
RsGxsCircleId id ;
|
RsGxsCircleId id ;
|
||||||
|
|
||||||
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),id))
|
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),id))
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
uint32_t subscribe_flags = ui->treeWidget_membership->currentItem()->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
|
uint32_t subscribe_flags = ui->treeWidget_membership->currentItem()->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
|
||||||
|
|
||||||
CreateCircleDialog dlg;
|
CreateCircleDialog dlg;
|
||||||
|
|
||||||
dlg.editExistingId(RsGxsGroupId(id),true,!(subscribe_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) ;
|
dlg.editExistingId(RsGxsGroupId(id),true,!(subscribe_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) ;
|
||||||
dlg.exec();
|
dlg.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdDialog::grantCircleMembership()
|
void IdDialog::grantCircleMembership()
|
||||||
{
|
{
|
||||||
RsGxsCircleId circle_id ;
|
RsGxsCircleId circle_id ;
|
||||||
|
|
||||||
@ -987,7 +1030,7 @@ void IdDialog::grantCircleMembership()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdDialog::revokeCircleMembership()
|
void IdDialog::revokeCircleMembership()
|
||||||
{
|
{
|
||||||
RsGxsCircleId circle_id ;
|
RsGxsCircleId circle_id ;
|
||||||
|
|
||||||
@ -1016,22 +1059,22 @@ void IdDialog::revokeCircleMembership()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdDialog::acceptCircleSubscription()
|
void IdDialog::acceptCircleSubscription()
|
||||||
{
|
{
|
||||||
RsGxsCircleId circle_id ;
|
RsGxsCircleId circle_id ;
|
||||||
|
|
||||||
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
|
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RsGxsId own_id(qobject_cast<QAction*>(sender())->data().toString().toStdString());
|
RsGxsId own_id(qobject_cast<QAction*>(sender())->data().toString().toStdString());
|
||||||
|
|
||||||
rsGxsCircles->requestCircleMembership(own_id,circle_id) ;
|
rsGxsCircles->requestCircleMembership(own_id,circle_id) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdDialog::cancelCircleSubscription()
|
void IdDialog::cancelCircleSubscription()
|
||||||
{
|
{
|
||||||
RsGxsCircleId circle_id ;
|
RsGxsCircleId circle_id ;
|
||||||
|
|
||||||
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
|
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1039,14 +1082,14 @@ void IdDialog::cancelCircleSubscription()
|
|||||||
|
|
||||||
rsGxsCircles->cancelCircleMembership(own_id,circle_id) ;
|
rsGxsCircles->cancelCircleMembership(own_id,circle_id) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdDialog::CircleListCustomPopupMenu( QPoint )
|
void IdDialog::CircleListCustomPopupMenu( QPoint )
|
||||||
{
|
{
|
||||||
QMenu contextMnu( this );
|
QMenu contextMnu( this );
|
||||||
|
|
||||||
RsGxsCircleId circle_id ;
|
RsGxsCircleId circle_id ;
|
||||||
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
|
QTreeWidgetItem *item = ui->treeWidget_membership->currentItem();
|
||||||
|
|
||||||
if(!getItemCircleId(item,circle_id))
|
if(!getItemCircleId(item,circle_id))
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
@ -1054,7 +1097,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
|
|||||||
RsGxsId item_id(item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString());
|
RsGxsId item_id(item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString());
|
||||||
bool is_circle ;
|
bool is_circle ;
|
||||||
bool am_I_circle_admin = false ;
|
bool am_I_circle_admin = false ;
|
||||||
|
|
||||||
if(item_id == RsGxsId(circle_id)) // is it a circle?
|
if(item_id == RsGxsId(circle_id)) // is it a circle?
|
||||||
{
|
{
|
||||||
uint32_t group_flags = item->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
|
uint32_t group_flags = item->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
|
||||||
@ -1073,7 +1116,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
|
|||||||
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
|
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ID_DEBUG
|
#ifdef ID_DEBUG
|
||||||
std::cerr << " Item is a circle item. Adding Edit/Details menu entry." << std::endl;
|
std::cerr << " Item is a circle item. Adding Edit/Details menu entry." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
@ -1081,7 +1124,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
|
|||||||
|
|
||||||
contextMnu.addSeparator() ;
|
contextMnu.addSeparator() ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
current_gxs_id = RsGxsId(item_id);
|
current_gxs_id = RsGxsId(item_id);
|
||||||
is_circle =false ;
|
is_circle =false ;
|
||||||
@ -1096,9 +1139,9 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
|
|||||||
std::cerr << " Item is a GxsId item. Requesting flags/group id from parent: " << circle_id << std::endl;
|
std::cerr << " Item is a GxsId item. Requesting flags/group id from parent: " << circle_id << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RsGxsCircleDetails details ;
|
RsGxsCircleDetails details ;
|
||||||
|
|
||||||
if(!rsGxsCircles->getCircleDetails(circle_id,details))// grab real circle ID from parent. Make sure circle id is used correctly afterwards!
|
if(!rsGxsCircles->getCircleDetails(circle_id,details))// grab real circle ID from parent. Make sure circle id is used correctly afterwards!
|
||||||
{
|
{
|
||||||
std::cerr << " (EE) cannot get circle info for ID " << circle_id << ". Not in cache?" << std::endl;
|
std::cerr << " (EE) cannot get circle info for ID " << circle_id << ". Not in cache?" << std::endl;
|
||||||
@ -1135,7 +1178,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
|
|||||||
ids[REMOVE].push_back(*it) ;
|
ids[REMOVE].push_back(*it) ;
|
||||||
else
|
else
|
||||||
ids[CANCEL].push_back(*it) ;
|
ids[CANCEL].push_back(*it) ;
|
||||||
else
|
else
|
||||||
if(subscribe_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST)
|
if(subscribe_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST)
|
||||||
ids[ACCEPT].push_back(*it) ;
|
ids[ACCEPT].push_back(*it) ;
|
||||||
else
|
else
|
||||||
@ -1196,17 +1239,17 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
|
|||||||
contextMnu.addMenu(menu) ;
|
contextMnu.addMenu(menu) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_circle && am_I_circle_admin) // I am circle admin. I can therefore revoke/accept membership
|
if(!is_circle && am_I_circle_admin) // I am circle admin. I can therefore revoke/accept membership
|
||||||
{
|
{
|
||||||
std::map<RsGxsId,uint32_t>::const_iterator it = details.mSubscriptionFlags.find(current_gxs_id) ;
|
std::map<RsGxsId,uint32_t>::const_iterator it = details.mSubscriptionFlags.find(current_gxs_id) ;
|
||||||
|
|
||||||
if(!current_gxs_id.isNull() && it != details.mSubscriptionFlags.end())
|
if(!current_gxs_id.isNull() && it != details.mSubscriptionFlags.end())
|
||||||
{
|
{
|
||||||
contextMnu.addSeparator() ;
|
contextMnu.addSeparator() ;
|
||||||
|
|
||||||
if(it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST)
|
if(it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST)
|
||||||
{
|
{
|
||||||
QAction *action = new QAction(tr("Revoke this member"),this) ;
|
QAction *action = new QAction(tr("Revoke this member"),this) ;
|
||||||
action->setData(QString::fromStdString(current_gxs_id.toStdString()));
|
action->setData(QString::fromStdString(current_gxs_id.toStdString()));
|
||||||
QObject::connect(action,SIGNAL(triggered()), this, SLOT(revokeCircleMembership()));
|
QObject::connect(action,SIGNAL(triggered()), this, SLOT(revokeCircleMembership()));
|
||||||
@ -1251,7 +1294,7 @@ static QString getHumanReadableDuration(uint32_t seconds)
|
|||||||
return QString(QObject::tr("%1 hours ago")).arg(seconds/3600) ;
|
return QString(QObject::tr("%1 hours ago")).arg(seconds/3600) ;
|
||||||
else if(seconds < 2*24*3600)
|
else if(seconds < 2*24*3600)
|
||||||
return QString(QObject::tr("%1 day ago")).arg(seconds/86400) ;
|
return QString(QObject::tr("%1 day ago")).arg(seconds/86400) ;
|
||||||
else
|
else
|
||||||
return QString(QObject::tr("%1 days ago")).arg(seconds/86400) ;
|
return QString(QObject::tr("%1 days ago")).arg(seconds/86400) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1283,7 +1326,7 @@ void IdDialog::processSettings(bool load)
|
|||||||
|
|
||||||
// state of splitter
|
// state of splitter
|
||||||
Settings->setValue("splitter", ui->mainSplitter->saveState());
|
Settings->setValue("splitter", ui->mainSplitter->saveState());
|
||||||
|
|
||||||
//save expanding
|
//save expanding
|
||||||
Settings->setValue("ExpandAll", allItem->isExpanded());
|
Settings->setValue("ExpandAll", allItem->isExpanded());
|
||||||
Settings->setValue("ExpandContacts", contactsItem->isExpanded());
|
Settings->setValue("ExpandContacts", contactsItem->isExpanded());
|
||||||
@ -1330,6 +1373,7 @@ void IdDialog::updateSelection()
|
|||||||
void IdDialog::updateIdList()
|
void IdDialog::updateIdList()
|
||||||
{
|
{
|
||||||
//int accept = filter;
|
//int accept = filter;
|
||||||
|
std::cerr << "Updating ID list" << std::endl;
|
||||||
|
|
||||||
RsThread::async([this]()
|
RsThread::async([this]()
|
||||||
{
|
{
|
||||||
@ -1476,13 +1520,13 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
|
|||||||
rsPeers->getGPGDetails(data.mPgpId, details);
|
rsPeers->getGPGDetails(data.mPgpId, details);
|
||||||
item->setText(RSID_COL_IDTYPE, QString::fromUtf8(details.name.c_str()));
|
item->setText(RSID_COL_IDTYPE, QString::fromUtf8(details.name.c_str()));
|
||||||
item->setToolTip(RSID_COL_IDTYPE,"Verified signature from node "+QString::fromStdString(data.mPgpId.toStdString())) ;
|
item->setToolTip(RSID_COL_IDTYPE,"Verified signature from node "+QString::fromStdString(data.mPgpId.toStdString())) ;
|
||||||
|
|
||||||
|
|
||||||
QString tooltip = tr("Node name:")+" " + QString::fromUtf8(details.name.c_str()) + "\n";
|
QString tooltip = tr("Node name:")+" " + QString::fromUtf8(details.name.c_str()) + "\n";
|
||||||
tooltip += tr("Node Id :")+" " + QString::fromStdString(data.mPgpId.toStdString()) ;
|
tooltip += tr("Node Id :")+" " + QString::fromStdString(data.mPgpId.toStdString()) ;
|
||||||
item->setToolTip(RSID_COL_KEYID,tooltip) ;
|
item->setToolTip(RSID_COL_KEYID,tooltip) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString txt = tr("[Unknown node]");
|
QString txt = tr("[Unknown node]");
|
||||||
item->setText(RSID_COL_IDTYPE, txt);
|
item->setText(RSID_COL_IDTYPE, txt);
|
||||||
@ -1512,7 +1556,9 @@ void IdDialog::loadIdentities(const std::map<RsGxsGroupId,RsGxsIdGroup>& ids_set
|
|||||||
{
|
{
|
||||||
auto ids_set(ids_set_const);
|
auto ids_set(ids_set_const);
|
||||||
|
|
||||||
//First: Get current item to restore after
|
std::cerr << "Loading ID list" << std::endl;
|
||||||
|
|
||||||
|
//First: Get current item to restore after
|
||||||
RsGxsGroupId oldCurrentId = mIdToNavigate;
|
RsGxsGroupId oldCurrentId = mIdToNavigate;
|
||||||
{
|
{
|
||||||
QTreeWidgetItem *oldCurrent = ui->idTreeWidget->currentItem();
|
QTreeWidgetItem *oldCurrent = ui->idTreeWidget->currentItem();
|
||||||
@ -1535,13 +1581,13 @@ void IdDialog::loadIdentities(const std::map<RsGxsGroupId,RsGxsIdGroup>& ids_set
|
|||||||
|
|
||||||
RsPgpId ownPgpId = rsPeers->getGPGOwnId();
|
RsPgpId ownPgpId = rsPeers->getGPGOwnId();
|
||||||
|
|
||||||
// Update existing and remove not existing items
|
// Update existing and remove not existing items
|
||||||
// Also remove items that do not have the correct parent
|
// Also remove items that do not have the correct parent
|
||||||
|
|
||||||
QTreeWidgetItemIterator itemIterator(ui->idTreeWidget);
|
QTreeWidgetItemIterator itemIterator(ui->idTreeWidget);
|
||||||
QTreeWidgetItem *item = NULL;
|
QTreeWidgetItem *item = NULL;
|
||||||
|
|
||||||
while ((item = *itemIterator) != NULL)
|
while ((item = *itemIterator) != NULL)
|
||||||
{
|
{
|
||||||
++itemIterator;
|
++itemIterator;
|
||||||
auto it = ids_set.find(RsGxsGroupId(item->text(RSID_COL_KEYID).toStdString())) ;
|
auto it = ids_set.find(RsGxsGroupId(item->text(RSID_COL_KEYID).toStdString())) ;
|
||||||
@ -1589,18 +1635,18 @@ void IdDialog::loadIdentities(const std::map<RsGxsGroupId,RsGxsIdGroup>& ids_set
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count items */
|
/* count items */
|
||||||
int itemCount = contactsItem->childCount() + allItem->childCount() + ownItem->childCount();
|
int itemCount = contactsItem->childCount() + allItem->childCount() + ownItem->childCount();
|
||||||
ui->label_count->setText( "(" + QString::number( itemCount ) + ")" );
|
ui->label_count->setText( "(" + QString::number( itemCount ) + ")" );
|
||||||
|
|
||||||
int contactsCount = contactsItem->childCount() ;
|
int contactsCount = contactsItem->childCount() ;
|
||||||
int allCount = allItem->childCount() ;
|
int allCount = allItem->childCount() ;
|
||||||
int ownCount = ownItem->childCount();
|
int ownCount = ownItem->childCount();
|
||||||
|
|
||||||
contactsItem->setText(0, tr("My contacts") + " (" + QString::number( contactsCount ) + ")" );
|
contactsItem->setText(0, tr("My contacts") + ((contactsCount>0)?" (" + QString::number( contactsCount ) + ")":"") );
|
||||||
allItem->setText(0, tr("All") + " (" + QString::number( allCount ) + ")" );
|
allItem->setText(0, tr("All") + ((allCount>0)?" (" + QString::number( allCount ) + ")":"") );
|
||||||
ownItem->setText(0, tr("My own identities") + " (" + QString::number( ownCount ) + ")" );
|
ownItem->setText(0, tr("My own identities") + ((ownCount>0)?" (" + QString::number( ownCount ) + ")":"") );
|
||||||
|
|
||||||
|
|
||||||
//Restore expanding
|
//Restore expanding
|
||||||
@ -1675,7 +1721,7 @@ void IdDialog::loadIdentity(RsGxsIdGroup data)
|
|||||||
RsPgpId ownPgpId = rsPeers->getGPGOwnId();
|
RsPgpId ownPgpId = rsPeers->getGPGOwnId();
|
||||||
|
|
||||||
ui->lineEdit_PublishTS->setText(QDateTime::fromMSecsSinceEpoch(qint64(1000)*data.mMeta.mPublishTs).toString(Qt::SystemLocaleShortDate));
|
ui->lineEdit_PublishTS->setText(QDateTime::fromMSecsSinceEpoch(qint64(1000)*data.mMeta.mPublishTs).toString(Qt::SystemLocaleShortDate));
|
||||||
ui->lineEdit_Nickname->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE));
|
//ui->lineEdit_Nickname->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE));
|
||||||
ui->lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId.toStdString()));
|
ui->lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId.toStdString()));
|
||||||
//ui->lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash.toStdString()));
|
//ui->lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash.toStdString()));
|
||||||
if(data.mPgpKnown)
|
if(data.mPgpKnown)
|
||||||
@ -1701,8 +1747,8 @@ void IdDialog::loadIdentity(RsGxsIdGroup data)
|
|||||||
|
|
||||||
//ui->avLabel_Person->setPixmap(pixmap);
|
//ui->avLabel_Person->setPixmap(pixmap);
|
||||||
//ui->avatarLabel->setPixmap(pixmap);
|
//ui->avatarLabel->setPixmap(pixmap);
|
||||||
QFontMetricsF f(ui->avLabel_Person->font()) ;
|
//QFontMetricsF f(ui->avLabel_Person->font()) ;
|
||||||
ui->avLabel_Person->setPixmap(pixmap.scaled(f.height()*4,f.height()*4,Qt::KeepAspectRatio,Qt::SmoothTransformation));
|
//ui->avLabel_Person->setPixmap(pixmap.scaled(f.height()*4,f.height()*4,Qt::KeepAspectRatio,Qt::SmoothTransformation));
|
||||||
|
|
||||||
ui->avatarLabel->setPixmap(pixmap.scaled(ui->inviteButton->width(),ui->inviteButton->width(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
|
ui->avatarLabel->setPixmap(pixmap.scaled(ui->inviteButton->width(),ui->inviteButton->width(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
|
||||||
ui->avatarLabel->setScaledContents(true);
|
ui->avatarLabel->setScaledContents(true);
|
||||||
@ -1731,7 +1777,7 @@ void IdDialog::loadIdentity(RsGxsIdGroup data)
|
|||||||
ui->lineEdit_GpgId->show() ;
|
ui->lineEdit_GpgId->show() ;
|
||||||
ui->label_GpgId->show() ;
|
ui->label_GpgId->show() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data.mPgpKnown)
|
if(data.mPgpKnown)
|
||||||
{
|
{
|
||||||
ui->lineEdit_GpgName->show() ;
|
ui->lineEdit_GpgName->show() ;
|
||||||
@ -1771,7 +1817,6 @@ void IdDialog::loadIdentity(RsGxsIdGroup data)
|
|||||||
|
|
||||||
if (isOwnId)
|
if (isOwnId)
|
||||||
{
|
{
|
||||||
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, false);
|
|
||||||
mStateHelper->setWidgetEnabled(ui->autoBanIdentities_CB, false);
|
mStateHelper->setWidgetEnabled(ui->autoBanIdentities_CB, false);
|
||||||
// ui->editIdentity->setEnabled(true);
|
// ui->editIdentity->setEnabled(true);
|
||||||
// ui->removeIdentity->setEnabled(true);
|
// ui->removeIdentity->setEnabled(true);
|
||||||
@ -1781,8 +1826,6 @@ void IdDialog::loadIdentity(RsGxsIdGroup data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No Reputation yet!
|
|
||||||
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true);
|
|
||||||
mStateHelper->setWidgetEnabled(ui->autoBanIdentities_CB, true);
|
mStateHelper->setWidgetEnabled(ui->autoBanIdentities_CB, true);
|
||||||
// ui->editIdentity->setEnabled(false);
|
// ui->editIdentity->setEnabled(false);
|
||||||
// ui->removeIdentity->setEnabled(false);
|
// ui->removeIdentity->setEnabled(false);
|
||||||
@ -1826,7 +1869,7 @@ void IdDialog::loadIdentity(RsGxsIdGroup data)
|
|||||||
frep_string = tr("No votes from friends") ;
|
frep_string = tr("No votes from friends") ;
|
||||||
|
|
||||||
ui->neighborNodesOpinion_TF->setText(frep_string) ;
|
ui->neighborNodesOpinion_TF->setText(frep_string) ;
|
||||||
|
|
||||||
ui->label_positive->setText(QString::number(info.mFriendsPositiveVotes));
|
ui->label_positive->setText(QString::number(info.mFriendsPositiveVotes));
|
||||||
ui->label_negative->setText(QString::number(info.mFriendsNegativeVotes));
|
ui->label_negative->setText(QString::number(info.mFriendsNegativeVotes));
|
||||||
|
|
||||||
@ -2028,7 +2071,7 @@ void IdDialog::modifyReputation()
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdDialog::navigate(const RsGxsId& gxs_id)
|
void IdDialog::navigate(const RsGxsId& gxs_id)
|
||||||
{
|
{
|
||||||
#ifdef ID_DEBUG
|
#ifdef ID_DEBUG
|
||||||
@ -2086,14 +2129,12 @@ void IdDialog::removeIdentity()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((QMessageBox::question(this, tr("Really delete?"), tr("Do you really want to delete this identity?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No))== QMessageBox::Yes)
|
if ((QMessageBox::question(this, tr("Really delete?"), tr("Do you really want to delete this identity?\nThis cannot be undone."), QMessageBox::Yes|QMessageBox::No, QMessageBox::No))== QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
std::string keyId = item->text(RSID_COL_KEYID).toStdString();
|
std::string keyId = item->text(RSID_COL_KEYID).toStdString();
|
||||||
|
RsGxsId kid(keyId);
|
||||||
|
|
||||||
uint32_t dummyToken = 0;
|
rsIdentity->deleteIdentity(kid);
|
||||||
RsGxsIdGroup group;
|
|
||||||
group.mMeta.mGroupId=RsGxsGroupId(keyId);
|
|
||||||
rsIdentity->deleteIdentity(dummyToken, group);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2256,29 +2297,29 @@ void IdDialog::IdListCustomPopupMenu( QPoint )
|
|||||||
if(n_is_a_contact == 0)
|
if(n_is_a_contact == 0)
|
||||||
contextMenu->addAction(QIcon(), tr("Add to Contacts"), this, SLOT(addtoContacts()));
|
contextMenu->addAction(QIcon(), tr("Add to Contacts"), this, SLOT(addtoContacts()));
|
||||||
|
|
||||||
if (n_selected_items==1)
|
|
||||||
contextMenu->addAction(QIcon(""),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ;
|
|
||||||
|
|
||||||
if(n_is_not_a_contact == 0)
|
if(n_is_not_a_contact == 0)
|
||||||
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/cancel.svg"), tr("Remove from Contacts"), this, SLOT(removefromContacts()));
|
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/cancel.svg"), tr("Remove from Contacts"), this, SLOT(removefromContacts()));
|
||||||
|
|
||||||
contextMenu->addSeparator();
|
}
|
||||||
|
|
||||||
if(n_positive_reputations == 0) // only unban when all items are banned
|
if (n_selected_items==1)
|
||||||
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/thumbs-up.png"), tr("Set positive opinion"), this, SLOT(positivePerson()));
|
contextMenu->addAction(QIcon(""),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ;
|
||||||
|
|
||||||
if(n_neutral_reputations == 0) // only unban when all items are banned
|
contextMenu->addSeparator();
|
||||||
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/thumbs-neutral.png"), tr("Set neutral opinion"), this, SLOT(neutralPerson()));
|
|
||||||
|
|
||||||
if(n_negative_reputations == 0)
|
if(n_positive_reputations == 0) // only unban when all items are banned
|
||||||
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/thumbs-down.png"), tr("Set negative opinion"), this, SLOT(negativePerson()));
|
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/thumbs-up.png"), tr("Set positive opinion"), this, SLOT(positivePerson()));
|
||||||
}
|
|
||||||
|
if(n_neutral_reputations == 0) // only unban when all items are banned
|
||||||
|
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/thumbs-neutral.png"), tr("Set neutral opinion"), this, SLOT(neutralPerson()));
|
||||||
|
|
||||||
|
if(n_negative_reputations == 0)
|
||||||
|
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/thumbs-down.png"), tr("Set negative opinion"), this, SLOT(negativePerson()));
|
||||||
|
|
||||||
if(one_item_owned_by_you && n_selected_items==1)
|
if(one_item_owned_by_you && n_selected_items==1)
|
||||||
{
|
{
|
||||||
contextMenu->addSeparator();
|
contextMenu->addSeparator();
|
||||||
|
|
||||||
contextMenu->addAction(QIcon(""),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ;
|
|
||||||
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_EDIT),tr("Edit identity"),this,SLOT(editIdentity())) ;
|
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_EDIT),tr("Edit identity"),this,SLOT(editIdentity())) ;
|
||||||
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/cancel.svg"),tr("Delete identity"),this,SLOT(removeIdentity())) ;
|
contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/cancel.svg"),tr("Delete identity"),this,SLOT(removeIdentity())) ;
|
||||||
}
|
}
|
||||||
@ -2453,7 +2494,7 @@ void IdDialog::sendInvite()
|
|||||||
}
|
}
|
||||||
|
|
||||||
RsGxsId id(ui->lineEdit_KeyId->text().toStdString());
|
RsGxsId id(ui->lineEdit_KeyId->text().toStdString());
|
||||||
|
|
||||||
//if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want send a invite with your Certificate?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes)
|
//if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want send a invite with your Certificate?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
MessageComposer::sendInvite(id,false);
|
MessageComposer::sendInvite(id,false);
|
||||||
@ -2461,7 +2502,7 @@ void IdDialog::sendInvite()
|
|||||||
ui->info_Frame_Invite->show();
|
ui->info_Frame_Invite->show();
|
||||||
ui->inviteButton->setEnabled(false);
|
ui->inviteButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2592,4 +2633,3 @@ void IdDialog::restoreExpandedCircleItems(const std::vector<bool>& expanded_root
|
|||||||
restoreTopLevel(mExternalOtherCircleItem,1);
|
restoreTopLevel(mExternalOtherCircleItem,1);
|
||||||
restoreTopLevel(mMyCircleItem,2);
|
restoreTopLevel(mMyCircleItem,2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#define IDENTITYDIALOG_H
|
#define IDENTITYDIALOG_H
|
||||||
|
|
||||||
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
|
#include "gui/gxs/RsGxsUpdateBroadcastPage.h"
|
||||||
|
#include "util/FontSizeHandler.h"
|
||||||
|
|
||||||
#include <retroshare/rsidentity.h>
|
#include <retroshare/rsidentity.h>
|
||||||
|
|
||||||
@ -157,6 +158,8 @@ private:
|
|||||||
bool needUpdateIdsOnNextShow;
|
bool needUpdateIdsOnNextShow;
|
||||||
bool needUpdateCirclesOnNextShow;
|
bool needUpdateCirclesOnNextShow;
|
||||||
|
|
||||||
|
FontSizeHandler mFontSizeHandler;
|
||||||
|
|
||||||
/* UI - Designer */
|
/* UI - Designer */
|
||||||
Ui::IdDialog *ui;
|
Ui::IdDialog *ui;
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -703,7 +703,7 @@ void IdEditDialog::updateInterface()
|
|||||||
const QPixmap *pixmap = ui->avatarLabel->pixmap();
|
const QPixmap *pixmap = ui->avatarLabel->pixmap();
|
||||||
if (pixmap && !pixmap->isNull()) {
|
if (pixmap && !pixmap->isNull()) {
|
||||||
ui->removeButton->setEnabled(true);
|
ui->removeButton->setEnabled(true);
|
||||||
} else if (mEditGroup.mImage.mSize != NULL) {
|
} else if (mEditGroup.mImage.mSize > 0) {
|
||||||
ui->removeButton->setEnabled(true);
|
ui->removeButton->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
ui->removeButton->setEnabled(false);
|
ui->removeButton->setEnabled(false);
|
||||||
|
@ -28,9 +28,15 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
#include <QMenuBar>
|
||||||
|
|
||||||
#include <retroshare/rsplugin.h>
|
#include <retroshare/rsplugin.h>
|
||||||
#include <retroshare/rsconfig.h>
|
#include <retroshare/rsconfig.h>
|
||||||
|
#include <util/argstream.h>
|
||||||
|
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
#include "gui/common/MacDockIconHandler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MESSENGER_WINDOW
|
#ifdef MESSENGER_WINDOW
|
||||||
#include "MessengerWindow.h"
|
#include "MessengerWindow.h"
|
||||||
@ -114,7 +120,7 @@
|
|||||||
#include "gui/statistics/StatisticsWindow.h"
|
#include "gui/statistics/StatisticsWindow.h"
|
||||||
|
|
||||||
#include "gui/connect/ConnectFriendWizard.h"
|
#include "gui/connect/ConnectFriendWizard.h"
|
||||||
#include "gui/common/RsCollection.h"
|
#include "gui/common/RsCollectionDialog.h"
|
||||||
#include "settings/rsettingswin.h"
|
#include "settings/rsettingswin.h"
|
||||||
#include "settings/rsharesettings.h"
|
#include "settings/rsharesettings.h"
|
||||||
#include "common/StatusDefs.h"
|
#include "common/StatusDefs.h"
|
||||||
@ -206,7 +212,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags)
|
|||||||
hiddenmode = true;
|
hiddenmode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
setWindowTitle(tr("RetroShare %1 a secure decentralized communication platform").arg(Rshare::retroshareVersion(true)) + " - " + nameAndLocation);
|
setWindowTitle(tr("RetroShare %1 a secure decentralized communication platform").arg(RsApplication::retroshareVersion(true)) + " - " + nameAndLocation);
|
||||||
connect(rApp, SIGNAL(newArgsReceived(QStringList)), this, SLOT(receiveNewArgs(QStringList)));
|
connect(rApp, SIGNAL(newArgsReceived(QStringList)), this, SLOT(receiveNewArgs(QStringList)));
|
||||||
|
|
||||||
/* add url handler for RetroShare links */
|
/* add url handler for RetroShare links */
|
||||||
@ -354,6 +360,8 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags)
|
|||||||
|
|
||||||
connect(NotifyQt::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
|
connect(NotifyQt::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged()));
|
||||||
settingsChanged();
|
settingsChanged();
|
||||||
|
|
||||||
|
mFontSizeHandler.registerFontSize(ui->listWidget, 1.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
@ -377,6 +385,11 @@ MainWindow::~MainWindow()
|
|||||||
delete sysTrayStatus;
|
delete sysTrayStatus;
|
||||||
delete trayIcon;
|
delete trayIcon;
|
||||||
delete trayMenu;
|
delete trayMenu;
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
delete menuBar;
|
||||||
|
delete dockMenu;
|
||||||
|
MacDockIconHandler::cleanup();
|
||||||
|
#endif
|
||||||
// delete notifyMenu; // already deleted by the deletion of trayMenu
|
// delete notifyMenu; // already deleted by the deletion of trayMenu
|
||||||
StatisticsWindow::releaseInstance();
|
StatisticsWindow::releaseInstance();
|
||||||
|
|
||||||
@ -553,6 +566,11 @@ void MainWindow::addPage(MainPage *page, QActionGroup *grp, QList<QPair<MainPage
|
|||||||
QListWidgetItem *item = new QListWidgetItem(QIcon(page->iconPixmap()),page->pageName()) ;
|
QListWidgetItem *item = new QListWidgetItem(QIcon(page->iconPixmap()),page->pageName()) ;
|
||||||
ui->listWidget->addItem(item) ;
|
ui->listWidget->addItem(item) ;
|
||||||
|
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
QFont f = ui->toolBarPage->font();
|
||||||
|
action->setFont(f);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (notify)
|
if (notify)
|
||||||
{
|
{
|
||||||
QPair<QAction*, QListWidgetItem*> pair = QPair<QAction*, QListWidgetItem*>( action, item);
|
QPair<QAction*, QListWidgetItem*> pair = QPair<QAction*, QListWidgetItem*>( action, item);
|
||||||
@ -651,10 +669,75 @@ void MainWindow::createTrayIcon()
|
|||||||
trayIcon->setContextMenu(trayMenu);
|
trayIcon->setContextMenu(trayMenu);
|
||||||
trayIcon->setIcon(QIcon(IMAGE_NOONLINE));
|
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)));
|
connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleVisibility(QSystemTrayIcon::ActivationReason)));
|
||||||
trayIcon->show();
|
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()
|
void MainWindow::showBandwidthGraph()
|
||||||
{
|
{
|
||||||
if(_bandwidthGraph == NULL)
|
if(_bandwidthGraph == NULL)
|
||||||
@ -946,6 +1029,7 @@ void SetForegroundWindowInternal(HWND hWnd)
|
|||||||
|
|
||||||
/* Show the dialog. */
|
/* Show the dialog. */
|
||||||
raiseWindow();
|
raiseWindow();
|
||||||
|
|
||||||
/* Set the focus to the specified page. */
|
/* Set the focus to the specified page. */
|
||||||
_instance->ui->stackPages->setCurrentPage(page);
|
_instance->ui->stackPages->setCurrentPage(page);
|
||||||
}
|
}
|
||||||
@ -1178,10 +1262,91 @@ void MainWindow::doQuit()
|
|||||||
rApp->quit();
|
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)
|
void MainWindow::receiveNewArgs(QStringList args)
|
||||||
{
|
{
|
||||||
Rshare::parseArguments(args, false);
|
RsInfo() << "Received new arguments from operating system call.";
|
||||||
processLastArgs();
|
|
||||||
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::displayErrorMessage(int /*a*/,int /*b*/,const QString& error_msg)
|
void MainWindow::displayErrorMessage(int /*a*/,int /*b*/,const QString& error_msg)
|
||||||
@ -1220,7 +1385,11 @@ void MainWindow::updateMenu()
|
|||||||
|
|
||||||
void MainWindow::toggleVisibility(QSystemTrayIcon::ActivationReason e)
|
void MainWindow::toggleVisibility(QSystemTrayIcon::ActivationReason e)
|
||||||
{
|
{
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
if (e == QSystemTrayIcon::DoubleClick) {
|
||||||
|
#else
|
||||||
if (e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) {
|
if (e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) {
|
||||||
|
#endif
|
||||||
if (isHidden() || isMinimized()) {
|
if (isHidden() || isMinimized()) {
|
||||||
show();
|
show();
|
||||||
if (isMinimized()) {
|
if (isMinimized()) {
|
||||||
@ -1544,45 +1713,9 @@ void MainWindow::retroshareLinkActivated(const QUrl &url)
|
|||||||
void MainWindow::openRsCollection(const QString &filename)
|
void MainWindow::openRsCollection(const QString &filename)
|
||||||
{
|
{
|
||||||
QFileInfo qinfo(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)
|
void MainWindow::switchVisibilityStatus(StatusElement e,bool b)
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "gui/common/rwindow.h"
|
#include "gui/common/rwindow.h"
|
||||||
#include "gui/common/RSComboBox.h"
|
#include "gui/common/RSComboBox.h"
|
||||||
|
#include "util/FontSizeHandler.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
@ -214,7 +215,6 @@ public slots:
|
|||||||
void externalLinkActivated(const QUrl &url);
|
void externalLinkActivated(const QUrl &url);
|
||||||
void retroshareLinkActivated(const QUrl &url);
|
void retroshareLinkActivated(const QUrl &url);
|
||||||
void openRsCollection(const QString &filename);
|
void openRsCollection(const QString &filename);
|
||||||
void processLastArgs();
|
|
||||||
//! Go to a specific part of the control panel.
|
//! Go to a specific part of the control panel.
|
||||||
void setNewPage(int page);
|
void setNewPage(int page);
|
||||||
void setCompactStatusMode(bool compact);
|
void setCompactStatusMode(bool compact);
|
||||||
@ -265,6 +265,11 @@ private slots:
|
|||||||
void toggleVisibility(QSystemTrayIcon::ActivationReason e);
|
void toggleVisibility(QSystemTrayIcon::ActivationReason e);
|
||||||
void toggleVisibilitycontextmenu();
|
void toggleVisibilitycontextmenu();
|
||||||
|
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
void minimizeWindow();
|
||||||
|
void closeWindow();
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Toolbar fns. */
|
/** Toolbar fns. */
|
||||||
void addFriend();
|
void addFriend();
|
||||||
//void newRsCollection();
|
//void newRsCollection();
|
||||||
@ -308,6 +313,10 @@ private:
|
|||||||
void initStackedPage();
|
void initStackedPage();
|
||||||
void addPage(MainPage *page, QActionGroup *grp, QList<QPair<MainPage *, QPair<QAction *, QListWidgetItem *> > > *notify);
|
void addPage(MainPage *page, QActionGroup *grp, QList<QPair<MainPage *, QPair<QAction *, QListWidgetItem *> > > *notify);
|
||||||
void createTrayIcon();
|
void createTrayIcon();
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
/** Creates a default menubar on Mac */
|
||||||
|
void createMenuBar();
|
||||||
|
#endif
|
||||||
void createNotifyIcons();
|
void createNotifyIcons();
|
||||||
static MainWindow *_instance;
|
static MainWindow *_instance;
|
||||||
|
|
||||||
@ -324,6 +333,14 @@ private:
|
|||||||
|
|
||||||
QString nameAndLocation;
|
QString nameAndLocation;
|
||||||
|
|
||||||
|
#if defined(Q_OS_DARWIN)
|
||||||
|
/** The menubar (Mac OS X only). */
|
||||||
|
QMenuBar *menuBar;
|
||||||
|
QMenu *dockMenu;
|
||||||
|
QAction* actionMinimize;
|
||||||
|
QAction* actionCloseWindow;
|
||||||
|
#endif
|
||||||
|
|
||||||
QSystemTrayIcon *trayIcon;
|
QSystemTrayIcon *trayIcon;
|
||||||
QMenu *notifyMenu;
|
QMenu *notifyMenu;
|
||||||
QMenu *trayMenu;
|
QMenu *trayMenu;
|
||||||
@ -355,6 +372,8 @@ private:
|
|||||||
void setIdle(bool Idle);
|
void setIdle(bool Idle);
|
||||||
bool isIdle;
|
bool isIdle;
|
||||||
|
|
||||||
|
FontSizeHandler mFontSizeHandler;
|
||||||
|
|
||||||
Ui::MainWindow *ui ;
|
Ui::MainWindow *ui ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,11 +33,6 @@
|
|||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<pointsize>12</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -157,7 +152,7 @@
|
|||||||
</action>
|
</action>
|
||||||
<action name="actionOptions">
|
<action name="actionOptions">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="images.qrc">
|
<iconset>
|
||||||
<normaloff>:/images/kcmsystem24.png</normaloff>:/images/kcmsystem24.png</iconset>
|
<normaloff>:/images/kcmsystem24.png</normaloff>:/images/kcmsystem24.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -299,7 +299,7 @@ void NewsFeed::handleChannelEvent(std::shared_ptr<const RsEvent> event)
|
|||||||
addFeedItem(new GxsChannelPostItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId, false, true));
|
addFeedItem(new GxsChannelPostItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId, false, true));
|
||||||
break;
|
break;
|
||||||
case RsChannelEventCode::NEW_COMMENT:
|
case RsChannelEventCode::NEW_COMMENT:
|
||||||
addFeedItem(new ChannelsCommentsItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId, false, true));
|
addFeedItem(new ChannelsCommentsItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId,pe->mChannelThreadId, false, true));
|
||||||
break;
|
break;
|
||||||
case RsChannelEventCode::RECEIVED_PUBLISH_KEY:
|
case RsChannelEventCode::RECEIVED_PUBLISH_KEY:
|
||||||
addFeedItem(new GxsChannelGroupItem(this, NEWSFEED_CHANNELPUBKEYLIST, pe->mChannelGroupId, false, true));
|
addFeedItem(new GxsChannelGroupItem(this, NEWSFEED_CHANNELPUBKEYLIST, pe->mChannelGroupId, false, true));
|
||||||
|
@ -70,8 +70,8 @@
|
|||||||
<widget class="QLabel" name="titleBarLabel">
|
<widget class="QLabel" name="titleBarLabel">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<pointsize>12</pointsize>
|
<pointsize>12</pointsize>
|
||||||
<weight>75</weight>
|
<weight>75</weight>
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
PluginManager::PluginManager()
|
PluginManager::PluginManager()
|
||||||
{
|
{
|
||||||
baseFolder = //qApp->applicationDirPath()+"///plugins" ;
|
baseFolder = //qApp->applicationDirPath()+"///plugins" ;
|
||||||
Rshare::dataDirectory() + "/plugins" ;
|
RsApplication::dataDirectory() + "/plugins" ;
|
||||||
lastError = "No error.";
|
lastError = "No error.";
|
||||||
|
|
||||||
viewWidget = 0;
|
viewWidget = 0;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>MS Sans Serif</family>
|
<family>MS Sans Serif</family>
|
||||||
<pointsize>11</pointsize>
|
|
||||||
<weight>75</weight>
|
<weight>75</weight>
|
||||||
<italic>true</italic>
|
<italic>true</italic>
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
@ -103,7 +102,6 @@
|
|||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>MS Sans Serif</family>
|
<family>MS Sans Serif</family>
|
||||||
<pointsize>9</pointsize>
|
|
||||||
<weight>50</weight>
|
<weight>50</weight>
|
||||||
<bold>false</bold>
|
<bold>false</bold>
|
||||||
</font>
|
</font>
|
||||||
@ -114,7 +112,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="AvatarWidget" name="avatarWidget" native="true">
|
<widget class="AvatarWidget" name="avatarWidget">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>24</width>
|
<width>24</width>
|
||||||
@ -134,7 +132,6 @@
|
|||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>MS Sans Serif</family>
|
<family>MS Sans Serif</family>
|
||||||
<pointsize>11</pointsize>
|
|
||||||
<weight>75</weight>
|
<weight>75</weight>
|
||||||
<italic>true</italic>
|
<italic>true</italic>
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
@ -150,7 +147,6 @@
|
|||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>MS Sans Serif</family>
|
<family>MS Sans Serif</family>
|
||||||
<pointsize>9</pointsize>
|
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -163,7 +159,6 @@
|
|||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<family>MS Sans Serif</family>
|
<family>MS Sans Serif</family>
|
||||||
<pointsize>9</pointsize>
|
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -209,17 +204,17 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>AvatarWidget</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header>gui/common/AvatarWidget.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>GxsIdLabel</class>
|
<class>GxsIdLabel</class>
|
||||||
<extends>QLabel</extends>
|
<extends>QLabel</extends>
|
||||||
<header>gui/gxs/GxsIdLabel.h</header>
|
<header>gui/gxs/GxsIdLabel.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
|
||||||
<class>AvatarWidget</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>gui/common/AvatarWidget.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>AspectRatioPixmapLabel</class>
|
<class>AspectRatioPixmapLabel</class>
|
||||||
<extends>QLabel</extends>
|
<extends>QLabel</extends>
|
||||||
|
@ -262,7 +262,6 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<pointsize>11</pointsize>
|
|
||||||
<weight>75</weight>
|
<weight>75</weight>
|
||||||
<italic>true</italic>
|
<italic>true</italic>
|
||||||
<bold>true</bold>
|
<bold>true</bold>
|
||||||
@ -726,17 +725,17 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
|
||||||
<class>GxsIdLabel</class>
|
|
||||||
<extends>QLabel</extends>
|
|
||||||
<header>gui/gxs/GxsIdLabel.h</header>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>ElidedLabel</class>
|
<class>ElidedLabel</class>
|
||||||
<extends>QLabel</extends>
|
<extends>QLabel</extends>
|
||||||
<header>gui/common/ElidedLabel.h</header>
|
<header>gui/common/ElidedLabel.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>GxsIdLabel</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header>gui/gxs/GxsIdLabel.h</header>
|
||||||
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>ZoomableLabel</class>
|
<class>ZoomableLabel</class>
|
||||||
<extends>QLabel</extends>
|
<extends>QLabel</extends>
|
||||||
@ -744,9 +743,9 @@
|
|||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc"/>
|
|
||||||
<include location="Posted_images.qrc"/>
|
|
||||||
<include location="../icons.qrc"/>
|
<include location="../icons.qrc"/>
|
||||||
|
<include location="Posted_images.qrc"/>
|
||||||
|
<include location="../images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -619,12 +619,13 @@ void PostedListWidgetWithModel::updateGroupData()
|
|||||||
|
|
||||||
void PostedListWidgetWithModel::postPostLoad()
|
void PostedListWidgetWithModel::postPostLoad()
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_POSTED
|
||||||
std::cerr << "Post channel load..." << std::endl;
|
std::cerr << "Post channel load..." << std::endl;
|
||||||
|
#endif
|
||||||
whileBlocking(ui->filter_LE)->setText(QString()); //Clear it before navigate, as it will update it.
|
whileBlocking(ui->filter_LE)->setText(QString()); //Clear it before navigate, as it will update it.
|
||||||
|
|
||||||
if (!mNavigatePendingMsgId.isNull())
|
if (!mNavigatePendingMsgId.isNull())
|
||||||
navigate(mNavigatePendingMsgId);
|
navigate(mNavigatePendingMsgId);
|
||||||
|
|
||||||
#ifdef TO_REMOVE
|
#ifdef TO_REMOVE
|
||||||
else if( (mLastSelectedPosts.count(groupId()) > 0)
|
else if( (mLastSelectedPosts.count(groupId()) > 0)
|
||||||
&& !mLastSelectedPosts[groupId()].isNull())
|
&& !mLastSelectedPosts[groupId()].isNull())
|
||||||
@ -639,8 +640,10 @@ void PostedListWidgetWithModel::postPostLoad()
|
|||||||
ui->postsTree->setFocus();
|
ui->postsTree->setFocus();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef DEBUG_POSTED
|
||||||
else
|
else
|
||||||
std::cerr << "No pre-selected channel post." << std::endl;
|
std::cerr << "No pre-selected channel post." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
updateShowLabel();
|
updateShowLabel();
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'.AppleSystemUIFont'; font-size:13pt; font-weight:400; font-style:normal;">
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html></string>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="textInteractionFlags">
|
<property name="textInteractionFlags">
|
||||||
@ -355,10 +355,10 @@ p, li { white-space: pre-wrap; }
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="toolBarFrame">
|
<widget class="QFrame" name="toolBarFrame">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::Box</enum>
|
<enum>QFrame::StyledPanel</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Sunken</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
@ -576,37 +576,10 @@ p, li { white-space: pre-wrap; }
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<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>
|
<customwidget>
|
||||||
<class>LineEditClear</class>
|
<class>LineEditClear</class>
|
||||||
<extends>QLineEdit</extends>
|
<extends>QLineEdit</extends>
|
||||||
<header>gui/common/LineEditClear.h</header>
|
<header location="global">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>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>RSTreeView</class>
|
<class>RSTreeView</class>
|
||||||
@ -614,15 +587,42 @@ p, li { white-space: pre-wrap; }
|
|||||||
<header>gui/common/RSTreeView.h</header>
|
<header>gui/common/RSTreeView.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</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>
|
<customwidget>
|
||||||
<class>SubscribeToolButton</class>
|
<class>SubscribeToolButton</class>
|
||||||
<extends>QToolButton</extends>
|
<extends>QToolButton</extends>
|
||||||
<header>gui/common/SubscribeToolButton.h</header>
|
<header>gui/common/SubscribeToolButton.h</header>
|
||||||
</customwidget>
|
</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>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="Posted_images.qrc"/>
|
|
||||||
<include location="../icons.qrc"/>
|
<include location="../icons.qrc"/>
|
||||||
|
<include location="Posted_images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -88,11 +88,16 @@ class RSHumanReadableAgeDelegate: public RSHumanReadableDelegate
|
|||||||
public:
|
public:
|
||||||
virtual void paint(QPainter *painter,const QStyleOptionViewItem & option, const QModelIndex & index) const
|
virtual void paint(QPainter *painter,const QStyleOptionViewItem & option, const QModelIndex & index) const
|
||||||
{
|
{
|
||||||
|
painter->save();
|
||||||
QStyleOptionViewItem opt(option) ;
|
QStyleOptionViewItem opt(option) ;
|
||||||
setPainterOptions(painter,opt,index) ;
|
setPainterOptions(painter,opt,index) ;
|
||||||
|
|
||||||
if(index.data().toLongLong() > 0) // no date is present.
|
if(index.data().toLongLong() > 0) { // no date is present.
|
||||||
painter->drawText(opt.rect, Qt::AlignCenter, misc::timeRelativeToNow(index.data().toLongLong())) ;
|
painter->setFont(opt.font);
|
||||||
|
painter->drawText(opt.rect, opt.displayAlignment, misc::timeRelativeToNow(index.data().toLongLong())) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -101,10 +106,14 @@ class RSHumanReadableSizeDelegate: public RSHumanReadableDelegate
|
|||||||
public:
|
public:
|
||||||
virtual void paint(QPainter *painter,const QStyleOptionViewItem & option, const QModelIndex & index) const
|
virtual void paint(QPainter *painter,const QStyleOptionViewItem & option, const QModelIndex & index) const
|
||||||
{
|
{
|
||||||
|
painter->save();
|
||||||
QStyleOptionViewItem opt(option) ;
|
QStyleOptionViewItem opt(option) ;
|
||||||
setPainterOptions(painter,opt,index) ;
|
setPainterOptions(painter,opt,index) ;
|
||||||
|
|
||||||
painter->drawText(opt.rect, Qt::AlignRight, misc::friendlyUnit(index.data().toULongLong()));
|
painter->setFont(opt.font);
|
||||||
|
painter->drawText(opt.rect, opt.displayAlignment, misc::friendlyUnit(index.data().toULongLong()));
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include "gui/common/FilesDefs.h"
|
#include "gui/common/FilesDefs.h"
|
||||||
#include "gui/common/GroupDefs.h"
|
#include "gui/common/GroupDefs.h"
|
||||||
#include "gui/common/RsCollection.h"
|
#include "gui/common/RsCollectionDialog.h"
|
||||||
#include "gui/common/RsUrlHandler.h"
|
#include "gui/common/RsUrlHandler.h"
|
||||||
#include "gui/gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
#include "retroshare/rsfiles.h"
|
#include "retroshare/rsfiles.h"
|
||||||
@ -1233,31 +1233,6 @@ bool RetroshareDirModel::requestDirDetails(void *ref, bool remote,DirDetails& d)
|
|||||||
return false ;
|
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)
|
void RetroshareDirModel::downloadSelected(const QModelIndexList &list,bool interactive)
|
||||||
{
|
{
|
||||||
if (!RemoteMode)
|
if (!RemoteMode)
|
||||||
@ -1278,7 +1253,7 @@ void RetroshareDirModel::downloadSelected(const QModelIndexList &list,bool inter
|
|||||||
FileSearchFlags f = RemoteMode?RS_FILE_HINTS_REMOTE:RS_FILE_HINTS_LOCAL ;
|
FileSearchFlags f = RemoteMode?RS_FILE_HINTS_REMOTE:RS_FILE_HINTS_LOCAL ;
|
||||||
|
|
||||||
if(interactive)
|
if(interactive)
|
||||||
RsCollection(dirVec,f).downloadFiles() ;
|
RsCollectionDialog::downloadFiles(RsCollection(dirVec,f)) ;
|
||||||
else /* Fire off requests */
|
else /* Fire off requests */
|
||||||
for (int i = 0, n = dirVec.size(); i < n; ++i)
|
for (int i = 0, n = dirVec.size(); i < n; ++i)
|
||||||
{
|
{
|
||||||
|
@ -68,8 +68,6 @@ class RetroshareDirModel : public QAbstractItemModel
|
|||||||
|
|
||||||
/* Callback from GUI */
|
/* Callback from GUI */
|
||||||
void downloadSelected(const QModelIndexList &list, bool interactive);
|
void downloadSelected(const QModelIndexList &list, bool interactive);
|
||||||
void createCollectionFile(QWidget *parent, const QModelIndexList &list);
|
|
||||||
|
|
||||||
void getDirDetailsFromSelect (const QModelIndexList &list, std::vector <DirDetails>& dirVec);
|
void getDirDetailsFromSelect (const QModelIndexList &list, std::vector <DirDetails>& dirVec);
|
||||||
|
|
||||||
int getType ( const QModelIndex & index ) const ;
|
int getType ( const QModelIndex & index ) const ;
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "HomePage.h"
|
#include "HomePage.h"
|
||||||
#include "chat/ChatDialog.h"
|
#include "chat/ChatDialog.h"
|
||||||
#include "common/PeerDefs.h"
|
#include "common/PeerDefs.h"
|
||||||
#include "common/RsCollection.h"
|
#include "common/RsCollectionDialog.h"
|
||||||
#include "common/RsUrlHandler.h"
|
#include "common/RsUrlHandler.h"
|
||||||
#include "connect/ConfCertDialog.h"
|
#include "connect/ConfCertDialog.h"
|
||||||
#include "connect/ConnectFriendWizard.h"
|
#include "connect/ConnectFriendWizard.h"
|
||||||
@ -1143,11 +1143,13 @@ QString RetroShareLink::toHtmlSize() const
|
|||||||
|
|
||||||
if (type() == TYPE_FILE && RsCollection::isCollectionFile(name())) {
|
if (type() == TYPE_FILE && RsCollection::isCollectionFile(name())) {
|
||||||
FileInfo finfo;
|
FileInfo finfo;
|
||||||
if (rsFiles->FileDetails(RsFileHash(hash().toStdString()), RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL, finfo)) {
|
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)) {
|
RsCollection::RsCollectionErrorCode code;
|
||||||
|
RsCollection collection(QString::fromUtf8(finfo.path.c_str()), code) ;
|
||||||
|
|
||||||
|
if(code == RsCollection::RsCollectionErrorCode::COLLECTION_NO_ERROR)
|
||||||
size += QString(" [%1]").arg(misc::friendlyUnit(collection.size()));
|
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);
|
QString link = QString("<a href=\"%1\">%2</a> <font color=\"blue\">%3</font>").arg(toString()).arg(name()).arg(size);
|
||||||
@ -1722,10 +1724,9 @@ static void processList(const QStringList &list, const QString &textSingular, co
|
|||||||
|
|
||||||
case TYPE_FILE_TREE:
|
case TYPE_FILE_TREE:
|
||||||
{
|
{
|
||||||
auto ft = RsFileTree::fromRadix64(
|
auto ft = RsFileTree::fromRadix64(link.radix().toStdString() );
|
||||||
link.radix().toStdString() );
|
RsCollectionDialog::downloadFiles(RsCollection(*ft));
|
||||||
RsCollection(*ft).downloadFiles();
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case TYPE_CHAT_ROOM:
|
case TYPE_CHAT_ROOM:
|
||||||
@ -1776,7 +1777,7 @@ static void processList(const QStringList &list, const QString &textSingular, co
|
|||||||
|
|
||||||
// were single file links found?
|
// were single file links found?
|
||||||
if (fileLinkFound)
|
if (fileLinkFound)
|
||||||
col.downloadFiles();
|
RsCollectionDialog::downloadFiles(col);
|
||||||
|
|
||||||
int countProcessed = 0;
|
int countProcessed = 0;
|
||||||
int countError = 0;
|
int countError = 0;
|
||||||
@ -1919,7 +1920,9 @@ static void processList(const QStringList &list, const QString &textSingular, co
|
|||||||
void RSLinkClipboard::copyLinks(const QList<RetroShareLink>& links)
|
void RSLinkClipboard::copyLinks(const QList<RetroShareLink>& links)
|
||||||
{
|
{
|
||||||
QString res ;
|
QString res ;
|
||||||
for (int i = 0; i < links.size(); ++i)
|
if(links.size() == 1)
|
||||||
|
res += links[0].toString();
|
||||||
|
else for(int i = 0; i < links.size(); ++i)
|
||||||
res += links[i].toString() + "\n" ;
|
res += links[i].toString() + "\n" ;
|
||||||
|
|
||||||
QApplication::clipboard()->setText(res) ;
|
QApplication::clipboard()->setText(res) ;
|
||||||
@ -2035,4 +2038,3 @@ void RSLinkClipboard::parseText(QString text, QList<RetroShareLink> &links,Retro
|
|||||||
pos += rx.matchedLength();
|
pos += rx.matchedLength();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ void StartDialog::loadPerson()
|
|||||||
rsNotify->cachePgpPassphrase(ui.password_input->text().toUtf8().constData()) ;
|
rsNotify->cachePgpPassphrase(ui.password_input->text().toUtf8().constData()) ;
|
||||||
rsNotify->setDisableAskPassword(true);
|
rsNotify->setDisableAskPassword(true);
|
||||||
|
|
||||||
bool res = Rshare::loadCertificate(accountId, ui.autologin_checkbox->isChecked()) ;
|
bool res = RsApplication::loadCertificate(accountId, ui.autologin_checkbox->isChecked()) ;
|
||||||
|
|
||||||
rsNotify->setDisableAskPassword(false);
|
rsNotify->setDisableAskPassword(false);
|
||||||
rsNotify->clearPgpPassphrase();
|
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);
|
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
|
#else
|
||||||
// this handles all linux systems at once.
|
// 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 Gnome 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 desktop's keyring. \n\n Your PGP passwd will not be stored.\n\nThis choice can be reverted in settings."), QMessageBox::Ok);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -345,8 +345,8 @@ The current identities/locations will not be affected.</string>
|
|||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Sans'; font-size:13pt; font-weight:400; font-style:normal;">
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="Create new Profile..."><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;">New Profile/Node</span></a></p></body></html></string>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="Create new Profile..."><span style=" font-family:'MS Shell Dlg 2'; font-size:14pt; text-decoration: underline; color:#0000ff;">New Profile/Node</span></a></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -370,8 +370,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="images.qrc"/>
|
|
||||||
<include location="icons.qrc"/>
|
<include location="icons.qrc"/>
|
||||||
|
<include location="images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "gui/gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
#include "gui/common/FilesDefs.h"
|
#include "gui/common/FilesDefs.h"
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
|
#include "util/qtthreadsutils.h"
|
||||||
|
|
||||||
#include "PulseAddDialog.h"
|
#include "PulseAddDialog.h"
|
||||||
|
|
||||||
@ -98,11 +99,31 @@ void PulseAddDialog::setGroup(RsWireGroup &group)
|
|||||||
// set ReplyWith Group.
|
// set ReplyWith Group.
|
||||||
void PulseAddDialog::setGroup(const RsGxsGroupId &grpId)
|
void PulseAddDialog::setGroup(const RsGxsGroupId &grpId)
|
||||||
{
|
{
|
||||||
/* fetch in the background */
|
if(grpId.isNull()){
|
||||||
RsWireGroupSPtr pGroup;
|
return;
|
||||||
rsWire->getWireGroup(grpId, pGroup);
|
}
|
||||||
|
|
||||||
setGroup(*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 );
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PulseAddDialog::cleanup()
|
void PulseAddDialog::cleanup()
|
||||||
@ -194,7 +215,7 @@ void PulseAddDialog::setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse
|
|||||||
mReplyToPulse = pulse;
|
mReplyToPulse = pulse;
|
||||||
mReplyType = replyType;
|
mReplyType = replyType;
|
||||||
ui.frame_reply->setVisible(true);
|
ui.frame_reply->setVisible(true);
|
||||||
ui.pushButton_picture->show();
|
ui.pushButton_picture->hide();
|
||||||
ui.topheadshot->hide();
|
ui.topheadshot->hide();
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -223,10 +244,12 @@ void PulseAddDialog::setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse
|
|||||||
if (mReplyType & WIRE_PULSE_TYPE_REPUBLISH) {
|
if (mReplyType & WIRE_PULSE_TYPE_REPUBLISH) {
|
||||||
ui.postButton->setText(tr("Republish Pulse"));
|
ui.postButton->setText(tr("Republish Pulse"));
|
||||||
ui.pushButton_picture->hide();
|
ui.pushButton_picture->hide();
|
||||||
|
ui.pushButton_Browse->hide();
|
||||||
}
|
}
|
||||||
else if (mReplyType & WIRE_PULSE_TYPE_LIKE) {
|
else if (mReplyType & WIRE_PULSE_TYPE_LIKE) {
|
||||||
ui.postButton->setText(tr("Like Pulse"));
|
ui.postButton->setText(tr("Like Pulse"));
|
||||||
ui.pushButton_picture->hide();
|
ui.pushButton_picture->hide();
|
||||||
|
ui.pushButton_Browse->hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,30 +257,46 @@ void PulseAddDialog::setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse
|
|||||||
|
|
||||||
void PulseAddDialog::setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, uint32_t replyType)
|
void PulseAddDialog::setReplyTo(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId, uint32_t replyType)
|
||||||
{
|
{
|
||||||
|
if(grpId.isNull()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* fetch in the background */
|
/* fetch in the background */
|
||||||
RsWireGroupSPtr pGroup;
|
|
||||||
if (!rsWire->getWireGroup(grpId, pGroup))
|
|
||||||
{
|
|
||||||
std::cerr << "PulseAddDialog::setRplyTo() failed to fetch group";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RsWirePulseSPtr pPulse;
|
RsThread::async([this,grpId,msgId,replyType](){
|
||||||
if (!rsWire->getWirePulse(grpId, msgId, pPulse))
|
|
||||||
{
|
|
||||||
std::cerr << "PulseAddDialog::setRplyTo() failed to fetch pulse";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update GroupPtr
|
RsWireGroupSPtr pGroup;
|
||||||
// TODO - this should be handled in libretroshare if possible.
|
RsWirePulseSPtr pPulse;
|
||||||
if (pPulse->mGroupPtr == NULL) {
|
if(!rsWire->getWireGroup(grpId,pGroup))
|
||||||
pPulse->mGroupPtr = 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 );
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
setReplyTo(*pPulse, pPulse, pGroup->mMeta.mGroupName, replyType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PulseAddDialog::addURL()
|
void PulseAddDialog::addURL()
|
||||||
@ -307,26 +346,39 @@ void PulseAddDialog::postOriginalPulse()
|
|||||||
std::cerr << "PulseAddDialog::postOriginalPulse()";
|
std::cerr << "PulseAddDialog::postOriginalPulse()";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
|
||||||
RsWirePulseSPtr pPulse(new RsWirePulse());
|
RsWirePulseSPtr pPulse(new RsWirePulse());
|
||||||
|
|
||||||
pPulse->mSentiment = WIRE_PULSE_SENTIMENT_NO_SENTIMENT;
|
pPulse->mSentiment = WIRE_PULSE_SENTIMENT_NO_SENTIMENT;
|
||||||
pPulse->mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
|
pPulse->mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
|
||||||
// set images here too.
|
// set images here too.
|
||||||
pPulse->mImage1 = mImage1;
|
pPulse->mImage1 = mImage1;
|
||||||
pPulse->mImage2 = mImage2;
|
pPulse->mImage2 = mImage2;
|
||||||
pPulse->mImage3 = mImage3;
|
pPulse->mImage3 = mImage3;
|
||||||
pPulse->mImage4 = mImage4;
|
pPulse->mImage4 = mImage4;
|
||||||
|
|
||||||
// this should be in async thread, so doesn't block UI thread.
|
RsThread::async([this,pPulse](){
|
||||||
if (!rsWire->createOriginalPulse(mGroup.mMeta.mGroupId, pPulse))
|
|
||||||
{
|
if (!rsWire->createOriginalPulse(mGroup.mMeta.mGroupId, pPulse))
|
||||||
std::cerr << "PulseAddDialog::postOriginalPulse() FAILED";
|
{
|
||||||
std::cerr << std::endl;
|
std::cerr << "PulseAddDialog::postOriginalPulse() FAILED";
|
||||||
return;
|
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 );
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
clearDialog();
|
|
||||||
hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t PulseAddDialog::toPulseSentiment(int index)
|
uint32_t PulseAddDialog::toPulseSentiment(int index)
|
||||||
@ -356,15 +408,15 @@ void PulseAddDialog::postReplyPulse()
|
|||||||
std::cerr << "PulseAddDialog::postReplyPulse()";
|
std::cerr << "PulseAddDialog::postReplyPulse()";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
|
||||||
RsWirePulseSPtr pPulse(new RsWirePulse());
|
RsWirePulseSPtr pPulse(new RsWirePulse());
|
||||||
|
|
||||||
pPulse->mSentiment = toPulseSentiment(ui.comboBox_sentiment->currentIndex());
|
pPulse->mSentiment = toPulseSentiment(ui.comboBox_sentiment->currentIndex());
|
||||||
pPulse->mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
|
pPulse->mPulseText = ui.textEdit_Pulse->toPlainText().toStdString();
|
||||||
// set images here too.
|
// set images here too.
|
||||||
pPulse->mImage1 = mImage1;
|
pPulse->mImage1 = mImage1;
|
||||||
pPulse->mImage2 = mImage2;
|
pPulse->mImage2 = mImage2;
|
||||||
pPulse->mImage3 = mImage3;
|
pPulse->mImage3 = mImage3;
|
||||||
pPulse->mImage4 = mImage4;
|
pPulse->mImage4 = mImage4;
|
||||||
|
|
||||||
if (mReplyType & WIRE_PULSE_TYPE_REPUBLISH) {
|
if (mReplyType & WIRE_PULSE_TYPE_REPUBLISH) {
|
||||||
// Copy details from parent, and override
|
// Copy details from parent, and override
|
||||||
@ -378,20 +430,33 @@ void PulseAddDialog::postReplyPulse()
|
|||||||
pPulse->mImage4 = mReplyToPulse.mImage4;
|
pPulse->mImage4 = mReplyToPulse.mImage4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this should be in async thread, so doesn't block UI thread.
|
RsThread::async([this, pPulse](){
|
||||||
if (!rsWire->createReplyPulse(mReplyToPulse.mMeta.mGroupId,
|
|
||||||
mReplyToPulse.mMeta.mOrigMsgId,
|
if (!rsWire->createReplyPulse(mReplyToPulse.mMeta.mGroupId,
|
||||||
mGroup.mMeta.mGroupId,
|
mReplyToPulse.mMeta.mOrigMsgId,
|
||||||
mReplyType,
|
mGroup.mMeta.mGroupId,
|
||||||
pPulse))
|
mReplyType,
|
||||||
{
|
pPulse))
|
||||||
std::cerr << "PulseAddDialog::postReplyPulse() FAILED";
|
{
|
||||||
std::cerr << std::endl;
|
std::cerr << "PulseAddDialog::postReplyPulse() FAILED";
|
||||||
return;
|
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 );
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
clearDialog();
|
|
||||||
hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PulseAddDialog::clearDialog()
|
void PulseAddDialog::clearDialog()
|
||||||
|
@ -140,7 +140,7 @@
|
|||||||
<widget class="QWidget" name="widget_sentiment" native="true">
|
<widget class="QWidget" name="widget_sentiment" native="true">
|
||||||
<layout class="QHBoxLayout" name="widget_sentiment_HL">
|
<layout class="QHBoxLayout" name="widget_sentiment_HL">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>20</number>
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
|
@ -40,10 +40,7 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true">QFrame#frame{border: 2px solid #CCCCCC;
|
<string notr="true"/>
|
||||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
|
||||||
stop: 0 #EEEEEE, stop: 1 #CCCCCC);
|
|
||||||
border-radius: 10px}</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::StyledPanel</enum>
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
@ -140,6 +140,7 @@ WireDialog::~WireDialog()
|
|||||||
processSettings(false);
|
processSettings(false);
|
||||||
|
|
||||||
clearTwitterView();
|
clearTwitterView();
|
||||||
|
std::cerr << "WireDialog::~WireDialog()" << std::endl;
|
||||||
delete(mWireQueue);
|
delete(mWireQueue);
|
||||||
|
|
||||||
rsEvents->unregisterEventsHandler(mEventHandlerId);
|
rsEvents->unregisterEventsHandler(mEventHandlerId);
|
||||||
@ -154,9 +155,16 @@ void WireDialog::processSettings(bool load)
|
|||||||
|
|
||||||
// state of splitter
|
// state of splitter
|
||||||
ui.splitter->restoreState(Settings->value("SplitterWire").toByteArray());
|
ui.splitter->restoreState(Settings->value("SplitterWire").toByteArray());
|
||||||
|
|
||||||
|
// state of filter combobox
|
||||||
|
int index = Settings->value("ShowGroup", 0).toInt();
|
||||||
|
ui.comboBox_groupSet->setCurrentIndex(index);
|
||||||
} else {
|
} else {
|
||||||
// save settings
|
// save settings
|
||||||
|
|
||||||
|
// state of filter combobox
|
||||||
|
Settings->setValue("ShowGroup", ui.comboBox_groupSet->currentIndex());
|
||||||
|
|
||||||
// state of splitter
|
// state of splitter
|
||||||
Settings->setValue("SplitterWire", ui.splitter->saveState());
|
Settings->setValue("SplitterWire", ui.splitter->saveState());
|
||||||
}
|
}
|
||||||
@ -467,13 +475,13 @@ bool WireDialog::loadGroupData(const uint32_t &token)
|
|||||||
std::cerr << "WireDialog::loadGroupData()";
|
std::cerr << "WireDialog::loadGroupData()";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
|
||||||
std::vector<RsWireGroup> groups;
|
std::vector<RsWireGroup> groups;
|
||||||
rsWire->getGroupData(token, groups);
|
rsWire->getGroupData(token, groups);
|
||||||
|
|
||||||
// save list of groups.
|
// save list of groups.
|
||||||
updateGroups(groups);
|
updateGroups(groups);
|
||||||
showGroups();
|
showGroups();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
rstime_t WireDialog::getFilterTimestamp()
|
rstime_t WireDialog::getFilterTimestamp()
|
||||||
@ -681,6 +689,7 @@ void WireDialog::PVHrate(const RsGxsId &authorId)
|
|||||||
void WireDialog::postTestTwitterView()
|
void WireDialog::postTestTwitterView()
|
||||||
{
|
{
|
||||||
clearTwitterView();
|
clearTwitterView();
|
||||||
|
std::cerr << "WireDialog::postTestTwitterView()" << std::endl;
|
||||||
|
|
||||||
addTwitterView(new PulseTopLevel(NULL,RsWirePulseSPtr()));
|
addTwitterView(new PulseTopLevel(NULL,RsWirePulseSPtr()));
|
||||||
addTwitterView(new PulseReply(NULL,RsWirePulseSPtr()));
|
addTwitterView(new PulseReply(NULL,RsWirePulseSPtr()));
|
||||||
@ -837,6 +846,7 @@ void WireDialog::requestPulseFocus(const RsGxsGroupId groupId, const RsGxsMessag
|
|||||||
void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId msgId)
|
void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId msgId)
|
||||||
{
|
{
|
||||||
clearTwitterView();
|
clearTwitterView();
|
||||||
|
std::cerr << "WireDialog::showPulseFocus()" << std::endl;
|
||||||
|
|
||||||
// background thread for loading.
|
// background thread for loading.
|
||||||
RsThread::async([this, groupId, msgId]()
|
RsThread::async([this, groupId, msgId]()
|
||||||
@ -866,6 +876,8 @@ void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId
|
|||||||
void WireDialog::postPulseFocus(RsWirePulseSPtr pPulse)
|
void WireDialog::postPulseFocus(RsWirePulseSPtr pPulse)
|
||||||
{
|
{
|
||||||
clearTwitterView();
|
clearTwitterView();
|
||||||
|
std::cerr << "WireDialog::postPulseFocus()" << std::endl;
|
||||||
|
|
||||||
if (!pPulse)
|
if (!pPulse)
|
||||||
{
|
{
|
||||||
std::cerr << "WireDialog::postPulseFocus() Invalid pulse";
|
std::cerr << "WireDialog::postPulseFocus() Invalid pulse";
|
||||||
@ -938,7 +950,7 @@ void WireDialog::requestGroupFocus(const RsGxsGroupId groupId)
|
|||||||
void WireDialog::showGroupFocus(const RsGxsGroupId groupId)
|
void WireDialog::showGroupFocus(const RsGxsGroupId groupId)
|
||||||
{
|
{
|
||||||
clearTwitterView();
|
clearTwitterView();
|
||||||
|
std::cerr << "WireDialog::showGroupFocus()" << std::endl;
|
||||||
// background thread for loading.
|
// background thread for loading.
|
||||||
RsThread::async([this, groupId]()
|
RsThread::async([this, groupId]()
|
||||||
{
|
{
|
||||||
@ -1015,6 +1027,7 @@ void WireDialog::requestGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
|
|||||||
void WireDialog::showGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
|
void WireDialog::showGroupsPulses(const std::list<RsGxsGroupId>& groupIds)
|
||||||
{
|
{
|
||||||
clearTwitterView();
|
clearTwitterView();
|
||||||
|
std::cerr << "WireDialog::showGroupPulses()" << std::endl;
|
||||||
|
|
||||||
// background thread for loading.
|
// background thread for loading.
|
||||||
RsThread::async([this, groupIds]()
|
RsThread::async([this, groupIds]()
|
||||||
@ -1064,4 +1077,3 @@ void WireDialog::postGroupsPulses(std::list<RsWirePulseSPtr> pulses)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ private:
|
|||||||
|
|
||||||
// Loading Data.
|
// Loading Data.
|
||||||
void requestGroupData();
|
void requestGroupData();
|
||||||
bool loadGroupData(const uint32_t &token);
|
bool loadGroupData(const uint32_t &token);
|
||||||
void acknowledgeGroup(const uint32_t &token, const uint32_t &userType);
|
void acknowledgeGroup(const uint32_t &token, const uint32_t &userType);
|
||||||
|
|
||||||
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) override;
|
virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) override;
|
||||||
|
@ -123,21 +123,21 @@ void WireGroupItem::setup()
|
|||||||
void WireGroupItem::setGroupSet()
|
void WireGroupItem::setGroupSet()
|
||||||
{
|
{
|
||||||
if (mGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) {
|
if (mGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) {
|
||||||
toolButton_type->setText("Own");
|
toolButton_type->setText(tr("Own"));
|
||||||
toolButton_subscribe->setText("N/A");
|
toolButton_subscribe->setText(tr("N/A"));
|
||||||
toolButton_subscribe->setEnabled(false);
|
toolButton_subscribe->setEnabled(false);
|
||||||
editButton->show();
|
editButton->show();
|
||||||
}
|
}
|
||||||
else if (mGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
|
else if (mGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
|
||||||
{
|
{
|
||||||
toolButton_type->setText("Following");
|
toolButton_type->setText(tr("Following"));
|
||||||
toolButton_subscribe->setText("Unfollow");
|
toolButton_subscribe->setText(tr("Unfollow"));
|
||||||
editButton->hide();
|
editButton->hide();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
toolButton_type->setText("Other");
|
toolButton_type->setText(tr("Other"));
|
||||||
toolButton_subscribe->setText("Follow");
|
toolButton_subscribe->setText(tr("Follow"));
|
||||||
editButton->hide();
|
editButton->hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,6 +208,8 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
|
|||||||
connect(unsubscribeButton, SIGNAL(clicked()), this , SLOT(leaveLobby()));
|
connect(unsubscribeButton, SIGNAL(clicked()), this , SLOT(leaveLobby()));
|
||||||
|
|
||||||
getChatWidget()->addTitleBarWidget(unsubscribeButton) ;
|
getChatWidget()->addTitleBarWidget(unsubscribeButton) ;
|
||||||
|
|
||||||
|
mFontSizeHandler.registerFontSize(ui.participantsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatLobbyDialog::leaveLobby()
|
void ChatLobbyDialog::leaveLobby()
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "gui/common/RSTreeWidgetItem.h"
|
#include "gui/common/RSTreeWidgetItem.h"
|
||||||
#include "ChatDialog.h"
|
#include "ChatDialog.h"
|
||||||
#include "PopupChatWindow.h"
|
#include "PopupChatWindow.h"
|
||||||
|
#include "util/FontSizeHandler.h"
|
||||||
|
|
||||||
// Q_DECLARE_METATYPE(RsGxsId)
|
// Q_DECLARE_METATYPE(RsGxsId)
|
||||||
// Q_DECLARE_METATYPE(QList<RsGxsId>)
|
// Q_DECLARE_METATYPE(QList<RsGxsId>)
|
||||||
@ -115,6 +116,8 @@ private:
|
|||||||
bool mWindowedSetted;
|
bool mWindowedSetted;
|
||||||
PopupChatWindow* mPCWindow;
|
PopupChatWindow* mPCWindow;
|
||||||
|
|
||||||
|
FontSizeHandler mFontSizeHandler;
|
||||||
|
|
||||||
/** Qt Designer generated object */
|
/** Qt Designer generated object */
|
||||||
Ui::ChatLobbyDialog ui;
|
Ui::ChatLobbyDialog ui;
|
||||||
|
|
||||||
|
@ -146,8 +146,48 @@ QString ChatLobbyUserNotify::getNotifyMessage(bool plural)
|
|||||||
|
|
||||||
void ChatLobbyUserNotify::iconClicked()
|
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 ///
|
/// Tray icon Menu ///
|
||||||
QMenu* trayMenu = new QMenu(MainWindow::getInstance());
|
QMenu* trayMenu = createMenu();
|
||||||
std::list<ChatLobbyId> lobbies;
|
std::list<ChatLobbyId> lobbies;
|
||||||
rsMsgs->getChatLobbyList(lobbies);
|
rsMsgs->getChatLobbyList(lobbies);
|
||||||
bool doUpdate=false;
|
bool doUpdate=false;
|
||||||
@ -186,27 +226,25 @@ 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");
|
QString strName=tr("Remove All");
|
||||||
QAction *pAction = new QAction( QIcon(), strName, trayMenu);
|
QAction *pAction = new QAction( QIcon(), strName, trayMenu);
|
||||||
ActionTag actionTag={0x0, "", true};
|
ActionTag actionTag={0x0, "", true};
|
||||||
pAction->setData(qVariantFromValue(actionTag));
|
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->addAction(pAction);
|
||||||
|
|
||||||
trayMenu->exec(QCursor::pos());
|
trayMenu->exec(QCursor::pos());
|
||||||
|
delete(trayMenu);
|
||||||
if (doUpdate) updateIcon();
|
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)
|
void ChatLobbyUserNotify::makeSubMenu(QMenu* parentMenu, QIcon icoLobby, QString strLobbyName, ChatLobbyId id)
|
||||||
@ -217,11 +255,7 @@ void ChatLobbyUserNotify::makeSubMenu(QMenu* parentMenu, QIcon icoLobby, QString
|
|||||||
|
|
||||||
unsigned int msgCount=msgMap.size();
|
unsigned int msgCount=msgMap.size();
|
||||||
|
|
||||||
if(!parentMenu) parentMenu = new QMenu(MainWindow::getInstance());
|
|
||||||
QMenu *lobbyMenu = parentMenu->addMenu(icoLobby, strLobbyName);
|
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));
|
lobbyMenu->setToolTip(getNotifyMessage(msgCount>1).arg(msgCount));
|
||||||
|
|
||||||
for (msg_map::iterator itMsg=msgMap.begin(); itMsg!=msgMap.end(); ++itMsg) {
|
for (msg_map::iterator itMsg=msgMap.begin(); itMsg!=msgMap.end(); ++itMsg) {
|
||||||
@ -243,7 +277,6 @@ void ChatLobbyUserNotify::makeSubMenu(QMenu* parentMenu, QIcon icoLobby, QString
|
|||||||
ActionTag actionTag={itCL->first, "", true};
|
ActionTag actionTag={itCL->first, "", true};
|
||||||
pAction->setData(qVariantFromValue(actionTag));
|
pAction->setData(qVariantFromValue(actionTag));
|
||||||
lobbyMenu->addAction(pAction);
|
lobbyMenu->addAction(pAction);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatLobbyUserNotify::iconHovered()
|
void ChatLobbyUserNotify::iconHovered()
|
||||||
@ -251,7 +284,6 @@ void ChatLobbyUserNotify::iconHovered()
|
|||||||
iconClicked();
|
iconClicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ChatLobbyUserNotify::chatLobbyNewMessage(ChatLobbyId lobby_id, QDateTime time, QString senderName, QString msg)
|
void ChatLobbyUserNotify::chatLobbyNewMessage(ChatLobbyId lobby_id, QDateTime time, QString senderName, QString msg)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ public:
|
|||||||
ChatLobbyUserNotify(QObject *parent = 0);
|
ChatLobbyUserNotify(QObject *parent = 0);
|
||||||
|
|
||||||
virtual bool hasSetting(QString *name, QString *group);
|
virtual bool hasSetting(QString *name, QString *group);
|
||||||
|
QMenu* createMenu();
|
||||||
void makeSubMenu(QMenu* parentMenu, QIcon icoLobby, QString strLobbyName, ChatLobbyId id);
|
void makeSubMenu(QMenu* parentMenu, QIcon icoLobby, QString strLobbyName, ChatLobbyId id);
|
||||||
void chatLobbyNewMessage(ChatLobbyId lobby_id, QDateTime time, QString senderName, QString msg);
|
void chatLobbyNewMessage(ChatLobbyId lobby_id, QDateTime time, QString senderName, QString msg);
|
||||||
void chatLobbyCleared(ChatLobbyId lobby_id, QString anchor, bool onlyUnread=false);
|
void chatLobbyCleared(ChatLobbyId lobby_id, QString anchor, bool onlyUnread=false);
|
||||||
|
@ -76,7 +76,7 @@ bool ChatUserNotify::hasSetting(QString *name, QString *group)
|
|||||||
|
|
||||||
QIcon ChatUserNotify::getIcon()
|
QIcon ChatUserNotify::getIcon()
|
||||||
{
|
{
|
||||||
return FilesDefs::getIconFromQtResourcePath(":/images/chat.png");
|
return FilesDefs::getIconFromQtResourcePath(":/images/orange-bubble-64.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon ChatUserNotify::getMainIcon(bool hasNew)
|
QIcon ChatUserNotify::getMainIcon(bool hasNew)
|
||||||
|
@ -982,11 +982,12 @@ void ChatWidget::on_notifyButton_clicked()
|
|||||||
if(!notify) return;
|
if(!notify) return;
|
||||||
if (chatType() != CHATTYPE_LOBBY) return;
|
if (chatType() != CHATTYPE_LOBBY) return;
|
||||||
|
|
||||||
QMenu* menu = new QMenu(MainWindow::getInstance());
|
QMenu* menu = notify->createMenu();
|
||||||
QIcon icoLobby=(ui->notifyButton->icon());
|
QIcon icoLobby=(ui->notifyButton->icon());
|
||||||
|
|
||||||
notify->makeSubMenu(menu, icoLobby, title, chatId.toLobbyId());
|
notify->makeSubMenu(menu, icoLobby, title, chatId.toLobbyId());
|
||||||
menu->exec(ui->notifyButton->mapToGlobal(QPoint(0,ui->notifyButton->geometry().height())));
|
menu->exec(ui->notifyButton->mapToGlobal(QPoint(0,ui->notifyButton->geometry().height())));
|
||||||
|
delete(menu);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,9 @@ bool AvatarDefs::getAvatarFromSslId(const RsPeerId& sslId, QPixmap &avatar, cons
|
|||||||
/* get avatar */
|
/* get avatar */
|
||||||
rsMsgs->getAvatarData(RsPeerId(sslId), data, size);
|
rsMsgs->getAvatarData(RsPeerId(sslId), data, size);
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
avatar = FilesDefs::getPixmapFromQtResourcePath(defaultImage);
|
if (!defaultImage.isEmpty()) {
|
||||||
|
avatar = FilesDefs::getPixmapFromQtResourcePath(defaultImage);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ void AvatarWidget::setFrameType(FrameType type)
|
|||||||
|
|
||||||
//refreshAvatarImage();
|
//refreshAvatarImage();
|
||||||
refreshStatus();
|
refreshStatus();
|
||||||
Rshare::refreshStyleSheet(this, false);
|
RsApplication::refreshStyleSheet(this, false);
|
||||||
}
|
}
|
||||||
void AvatarWidget::setId(const ChatId &id)
|
void AvatarWidget::setId(const ChatId &id)
|
||||||
{
|
{
|
||||||
@ -174,7 +174,7 @@ void AvatarWidget::refreshStatus()
|
|||||||
case NO_FRAME:
|
case NO_FRAME:
|
||||||
case NORMAL_FRAME:
|
case NORMAL_FRAME:
|
||||||
{
|
{
|
||||||
Rshare::refreshStyleSheet(this, false);
|
RsApplication::refreshStyleSheet(this, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STATUS_FRAME:
|
case STATUS_FRAME:
|
||||||
@ -252,7 +252,7 @@ void AvatarWidget::updateStatus(int status)
|
|||||||
mPeerState = status;
|
mPeerState = status;
|
||||||
|
|
||||||
setEnabled(((uint32_t) status == RS_STATUS_OFFLINE) ? false : true);
|
setEnabled(((uint32_t) status == RS_STATUS_OFFLINE) ? false : true);
|
||||||
Rshare::refreshStyleSheet(this, false);
|
RsApplication::refreshStyleSheet(this, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarWidget::updateAvatar(const QString &peerId)
|
void AvatarWidget::updateAvatar(const QString &peerId)
|
||||||
|
@ -65,7 +65,7 @@ static const uint32_t NODE_DETAILS_UPDATE_DELAY = 5; // update each node every 5
|
|||||||
|
|
||||||
RsFriendListModel::RsFriendListModel(QObject *parent)
|
RsFriendListModel::RsFriendListModel(QObject *parent)
|
||||||
: QAbstractItemModel(parent)
|
: QAbstractItemModel(parent)
|
||||||
, mDisplayGroups(true), mDisplayStatusString(true)
|
, mDisplayGroups(true), mDisplayStatusString(true), mDisplayStatusIcon (false)
|
||||||
, mLastInternalDataUpdate(0), mLastNodeUpdate(0)
|
, mLastInternalDataUpdate(0), mLastNodeUpdate(0)
|
||||||
{
|
{
|
||||||
mFilterStrings.clear();
|
mFilterStrings.clear();
|
||||||
@ -141,13 +141,39 @@ template<> bool RsFriendListModel::convertInternalIdToIndex<8>(quintptr ref,Entr
|
|||||||
return true;
|
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 RsFriendListModel::setDisplayStatusString(bool b)
|
void RsFriendListModel::setDisplayStatusString(bool b)
|
||||||
{
|
{
|
||||||
|
preMods();
|
||||||
mDisplayStatusString = b;
|
mDisplayStatusString = b;
|
||||||
postMods();
|
postMods();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RsFriendListModel::setDisplayStatusIcon(bool b)
|
||||||
|
{
|
||||||
|
preMods();
|
||||||
|
mDisplayStatusIcon = b;
|
||||||
|
postMods();
|
||||||
|
}
|
||||||
|
|
||||||
void RsFriendListModel::setDisplayGroups(bool b)
|
void RsFriendListModel::setDisplayGroups(bool b)
|
||||||
{
|
{
|
||||||
mDisplayGroups = b;
|
mDisplayGroups = b;
|
||||||
@ -287,7 +313,7 @@ uint32_t RsFriendListModel::EntryIndex::parentRow(uint32_t nb_groups) const
|
|||||||
|
|
||||||
QModelIndex RsFriendListModel::index(int row, int column, const QModelIndex& parent) const
|
QModelIndex RsFriendListModel::index(int row, int column, const QModelIndex& parent) const
|
||||||
{
|
{
|
||||||
if(row < 0 || column < 0 || column >= COLUMN_THREAD_NB_COLUMNS)
|
if(row < 0 || column < 0 || column >= columnCount(parent) || row >= rowCount(parent))
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
|
|
||||||
if(parent.internalId() == 0)
|
if(parent.internalId() == 0)
|
||||||
@ -413,17 +439,28 @@ QVariant RsFriendListModel::textColorRole(const EntryIndex& fmpe,int column) con
|
|||||||
{
|
{
|
||||||
switch(fmpe.type)
|
switch(fmpe.type)
|
||||||
{
|
{
|
||||||
case ENTRY_TYPE_GROUP: return QVariant(QBrush(mTextColorGroup));
|
case ENTRY_TYPE_GROUP: return QVariant(QBrush(mTextColorGroup));
|
||||||
case ENTRY_TYPE_PROFILE:
|
case ENTRY_TYPE_PROFILE: return QVariant(QBrush(mTextColorStatus[onlineRole(fmpe,column).toInt()]));
|
||||||
case ENTRY_TYPE_NODE: return QVariant(QBrush(mTextColorStatus[onlineRole(fmpe,column).toInt()]));
|
case ENTRY_TYPE_NODE: return QVariant(QBrush(mTextColorStatus[statusRole(fmpe,column).toInt()]));
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant RsFriendListModel::statusRole(const EntryIndex& /*fmpe*/,int /*column*/) const
|
// statusRole returns the status (e.g. RS_STATUS_BUSY). It is used only to change the font color
|
||||||
|
|
||||||
|
QVariant RsFriendListModel::statusRole(const EntryIndex& fmpe,int /*column*/) const
|
||||||
{
|
{
|
||||||
return QVariant();//fmpe.mMsgStatus);
|
const HierarchicalNodeInformation *node = getNodeInfo(fmpe);
|
||||||
|
|
||||||
|
if(node)
|
||||||
|
{
|
||||||
|
StatusInfo status;
|
||||||
|
rsStatus->getStatus(node->node_info.id, status);
|
||||||
|
|
||||||
|
return QVariant(status.status);
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsFriendListModel::passesFilter(const EntryIndex& e,int /*column*/) const
|
bool RsFriendListModel::passesFilter(const EntryIndex& e,int /*column*/) const
|
||||||
@ -548,6 +585,9 @@ QVariant RsFriendListModel::sortRole(const EntryIndex& entry,int column) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only returns two values: RS_STATUS_ONLINE, or RS_STATUS_OFFLINE. This is used to decide on text font (bold)
|
||||||
|
// and whether profiles have children or not when offline nodes are shown.
|
||||||
|
|
||||||
QVariant RsFriendListModel::onlineRole(const EntryIndex& e, int /*col*/) const
|
QVariant RsFriendListModel::onlineRole(const EntryIndex& e, int /*col*/) const
|
||||||
{
|
{
|
||||||
switch(e.type)
|
switch(e.type)
|
||||||
@ -585,13 +625,10 @@ QVariant RsFriendListModel::onlineRole(const EntryIndex& e, int /*col*/) const
|
|||||||
{
|
{
|
||||||
const HierarchicalNodeInformation *node = getNodeInfo(e);
|
const HierarchicalNodeInformation *node = getNodeInfo(e);
|
||||||
|
|
||||||
if(node)
|
if(node && bool(node->node_info.state & RS_PEER_STATE_CONNECTED))
|
||||||
{
|
return QVariant(RS_STATUS_ONLINE);
|
||||||
StatusInfo status;
|
else
|
||||||
rsStatus->getStatus(node->node_info.id, status);
|
return QVariant(RS_STATUS_OFFLINE);
|
||||||
|
|
||||||
return QVariant(status.status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QVariant(RS_STATUS_OFFLINE);
|
return QVariant(RS_STATUS_OFFLINE);
|
||||||
@ -626,12 +663,6 @@ QVariant RsFriendListModel::fontRole(const EntryIndex& e, int col) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AutoEndel
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~AutoEndel() { std::cerr << std::endl;}
|
|
||||||
};
|
|
||||||
|
|
||||||
QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const
|
QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_MODEL_INDEX
|
#ifdef DEBUG_MODEL_INDEX
|
||||||
@ -750,7 +781,7 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return QVariant(QString::fromUtf8(node->node_info.location.c_str())+"\n"
|
return QVariant(QString::fromUtf8(node->node_info.location.c_str())+"\n"
|
||||||
+ "(" + StatusDefs::name(onlineRole(e,col).toInt()) + ")");
|
+ "(" + StatusDefs::name(statusRole(e,col).toInt()) + ")");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return QVariant(QString::fromUtf8(node->node_info.location.c_str()));
|
return QVariant(QString::fromUtf8(node->node_info.location.c_str()));
|
||||||
@ -869,6 +900,69 @@ bool RsFriendListModel::getPeerOnlineStatus(const EntryIndex& e) const
|
|||||||
return (noded && (noded->node_info.state & RS_PEER_STATE_CONNECTED));
|
return (noded && (noded->node_info.state & RS_PEER_STATE_CONNECTED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RsFriendListModel::HierarchicalNodeInformation *RsFriendListModel::getBestNodeInformation(const HierarchicalProfileInformation *profileInfo, uint32_t *status) const
|
||||||
|
{
|
||||||
|
if (status) {
|
||||||
|
*status = RS_STATUS_OFFLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!profileInfo) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RsFriendListModel::HierarchicalNodeInformation *bestNodeInformation = NULL;
|
||||||
|
int bestStatusIndex = 0;
|
||||||
|
|
||||||
|
/* Find the best status */
|
||||||
|
for (uint32_t i = 0; i < profileInfo->child_node_indices.size(); ++i) {
|
||||||
|
const RsFriendListModel::HierarchicalNodeInformation &nodeInformation = mLocations[profileInfo->child_node_indices[i]];
|
||||||
|
StatusInfo statusInfo;
|
||||||
|
rsStatus->getStatus(nodeInformation.node_info.id, statusInfo);
|
||||||
|
|
||||||
|
int statusIndex = 0;
|
||||||
|
switch (statusInfo.status) {
|
||||||
|
case RS_STATUS_OFFLINE:
|
||||||
|
statusIndex = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RS_STATUS_INACTIVE:
|
||||||
|
statusIndex = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RS_STATUS_AWAY:
|
||||||
|
statusIndex = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RS_STATUS_BUSY:
|
||||||
|
statusIndex = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RS_STATUS_ONLINE:
|
||||||
|
statusIndex = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
std::cerr << "FriendListModel: Unknown status " << statusInfo.status << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestStatusIndex == 0 || statusIndex > bestStatusIndex) {
|
||||||
|
/* first status or better status */
|
||||||
|
bestStatusIndex = statusIndex;
|
||||||
|
bestNodeInformation = &nodeInformation;
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
*status = statusInfo.status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestStatusIndex == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestNodeInformation;
|
||||||
|
}
|
||||||
|
|
||||||
QVariant RsFriendListModel::decorationRole(const EntryIndex& entry,int col) const
|
QVariant RsFriendListModel::decorationRole(const EntryIndex& entry,int col) const
|
||||||
{
|
{
|
||||||
if(col > 0)
|
if(col > 0)
|
||||||
@ -902,13 +996,42 @@ QVariant RsFriendListModel::decorationRole(const EntryIndex& entry,int col) cons
|
|||||||
{
|
{
|
||||||
if(!isProfileExpanded(entry))
|
if(!isProfileExpanded(entry))
|
||||||
{
|
{
|
||||||
QPixmap sslAvatar = FilesDefs::getPixmapFromQtResourcePath(AVATAR_DEFAULT_IMAGE);
|
QPixmap sslAvatar;
|
||||||
|
bool foundAvatar = false;
|
||||||
const HierarchicalProfileInformation *hn = getProfileInfo(entry);
|
const HierarchicalProfileInformation *hn = getProfileInfo(entry);
|
||||||
|
uint32_t status = RS_STATUS_OFFLINE;
|
||||||
|
const HierarchicalNodeInformation *bestNodeInformation = NULL;
|
||||||
|
|
||||||
for(uint32_t i=0;i<hn->child_node_indices.size();++i)
|
if (mDisplayStatusIcon) {
|
||||||
if(AvatarDefs::getAvatarFromSslId(RsPeerId(mLocations[hn->child_node_indices[i]].node_info.id.toStdString()), sslAvatar))
|
bestNodeInformation = getBestNodeInformation(hn, &status);
|
||||||
return QVariant(QIcon(sslAvatar));
|
if (bestNodeInformation) {
|
||||||
|
if (AvatarDefs::getAvatarFromSslId(RsPeerId(bestNodeInformation->node_info.id.toStdString()), sslAvatar, "")) {
|
||||||
|
/* Use avatar from best node */
|
||||||
|
foundAvatar = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundAvatar) {
|
||||||
|
/* Use first available avatar */
|
||||||
|
for(uint32_t i=0;i<hn->child_node_indices.size();++i) {
|
||||||
|
if(AvatarDefs::getAvatarFromSslId(RsPeerId(mLocations[hn->child_node_indices[i]].node_info.id.toStdString()), sslAvatar, "")) {
|
||||||
|
foundAvatar = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundAvatar || sslAvatar.isNull()) {
|
||||||
|
sslAvatar = FilesDefs::getPixmapFromQtResourcePath(AVATAR_DEFAULT_IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mDisplayStatusIcon) {
|
||||||
|
if (bestNodeInformation) {
|
||||||
|
QPixmap sslOverlayIcon = FilesDefs::getPixmapFromQtResourcePath(StatusDefs::imageStatus(status));
|
||||||
|
return QVariant(QIcon(createAvatar(sslAvatar, sslOverlayIcon)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return QVariant(QIcon(sslAvatar));
|
return QVariant(QIcon(sslAvatar));
|
||||||
}
|
}
|
||||||
@ -925,6 +1048,10 @@ QVariant RsFriendListModel::decorationRole(const EntryIndex& entry,int col) cons
|
|||||||
|
|
||||||
QPixmap sslAvatar;
|
QPixmap sslAvatar;
|
||||||
AvatarDefs::getAvatarFromSslId(RsPeerId(hn->node_info.id.toStdString()), sslAvatar);
|
AvatarDefs::getAvatarFromSslId(RsPeerId(hn->node_info.id.toStdString()), sslAvatar);
|
||||||
|
if (mDisplayStatusIcon) {
|
||||||
|
QPixmap sslOverlayIcon = FilesDefs::getPixmapFromQtResourcePath(StatusDefs::imageStatus(statusRole(entry, col).toInt()));
|
||||||
|
return QVariant(QIcon(createAvatar(sslAvatar, sslOverlayIcon)));
|
||||||
|
}
|
||||||
|
|
||||||
return QVariant(QIcon(sslAvatar));
|
return QVariant(QIcon(sslAvatar));
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,10 @@ public:
|
|||||||
|
|
||||||
void setDisplayStatusString(bool b);
|
void setDisplayStatusString(bool b);
|
||||||
bool getDisplayStatusString() const { return mDisplayStatusString; }
|
bool getDisplayStatusString() const { return mDisplayStatusString; }
|
||||||
|
void setDisplayStatusIcon(bool b);
|
||||||
|
bool getDisplayStatusIcon() const { return mDisplayStatusIcon; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EntryType getType(const QModelIndex&) const;
|
EntryType getType(const QModelIndex&) const;
|
||||||
|
|
||||||
@ -219,11 +223,14 @@ private:
|
|||||||
|
|
||||||
uint32_t updateFilterStatus(ForumModelIndex i,int column,const QStringList& strings);
|
uint32_t updateFilterStatus(ForumModelIndex i,int column,const QStringList& strings);
|
||||||
|
|
||||||
|
const HierarchicalNodeInformation *getBestNodeInformation(const HierarchicalProfileInformation *profileInfo, uint32_t *status = NULL) const;
|
||||||
|
|
||||||
QStringList mFilterStrings;
|
QStringList mFilterStrings;
|
||||||
FilterType mFilterType;
|
FilterType mFilterType;
|
||||||
|
|
||||||
bool mDisplayGroups ;
|
bool mDisplayGroups ;
|
||||||
bool mDisplayStatusString ;
|
bool mDisplayStatusString ;
|
||||||
|
bool mDisplayStatusIcon ;
|
||||||
rstime_t mLastInternalDataUpdate;
|
rstime_t mLastInternalDataUpdate;
|
||||||
rstime_t mLastNodeUpdate;;
|
rstime_t mLastNodeUpdate;;
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ FriendSelectionWidget::FriendSelectionWidget(QWidget *parent)
|
|||||||
ui->filterLineEdit->showFilterIcon();
|
ui->filterLineEdit->showFilterIcon();
|
||||||
|
|
||||||
/* Refresh style to have the correct text color */
|
/* Refresh style to have the correct text color */
|
||||||
Rshare::refreshStyleSheet(this, false);
|
RsApplication::refreshStyleSheet(this, false);
|
||||||
|
|
||||||
mEventHandlerId_identities = 0;
|
mEventHandlerId_identities = 0;
|
||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) {
|
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) {
|
||||||
@ -135,6 +135,8 @@ FriendSelectionWidget::FriendSelectionWidget(QWidget *parent)
|
|||||||
mEventHandlerId_peers = 0;
|
mEventHandlerId_peers = 0;
|
||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) {
|
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> event) {
|
||||||
RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }) ;}, mEventHandlerId_peers, RsEventType::PEER_CONNECTION );
|
RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }) ;}, mEventHandlerId_peers, RsEventType::PEER_CONNECTION );
|
||||||
|
|
||||||
|
mFontSizeHandler.registerFontSize(ui->friendList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FriendSelectionWidget::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
void FriendSelectionWidget::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
||||||
@ -1225,7 +1227,7 @@ std::string FriendSelectionWidget::idFromItem(QTreeWidgetItem *item)
|
|||||||
return item->data(COLUMN_DATA, ROLE_ID).toString().toStdString();
|
return item->data(COLUMN_DATA, ROLE_ID).toString().toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FriendSelectionWidget::sortByChecked(bool sort)
|
void FriendSelectionWidget::sortByChecked(bool)
|
||||||
{
|
{
|
||||||
mCompareRole->clear();
|
mCompareRole->clear();
|
||||||
mCompareRole->setRole(COLUMN_NAME,ROLE_SORT_SELECTED);
|
mCompareRole->setRole(COLUMN_NAME,ROLE_SORT_SELECTED);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "retroshare/rsevents.h"
|
#include "retroshare/rsevents.h"
|
||||||
#include <gui/gxs/RsGxsUpdateBroadcastPage.h>
|
#include <gui/gxs/RsGxsUpdateBroadcastPage.h>
|
||||||
|
#include "util/FontSizeHandler.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class FriendSelectionWidget;
|
class FriendSelectionWidget;
|
||||||
@ -178,6 +179,8 @@ private:
|
|||||||
|
|
||||||
std::set<std::string> mPreSelectedIds; // because loading of GxsIds is asynchroneous we keep selected Ids from the client in a list here and use it to initialize after loading them.
|
std::set<std::string> mPreSelectedIds; // because loading of GxsIds is asynchroneous we keep selected Ids from the client in a list here and use it to initialize after loading them.
|
||||||
|
|
||||||
|
FontSizeHandler mFontSizeHandler;
|
||||||
|
|
||||||
RsEventsHandlerId_t mEventHandlerId_identities;
|
RsEventsHandlerId_t mEventHandlerId_identities;
|
||||||
RsEventsHandlerId_t mEventHandlerId_peers;
|
RsEventsHandlerId_t mEventHandlerId_peers;
|
||||||
};
|
};
|
||||||
|
@ -38,11 +38,6 @@
|
|||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<pointsize>11</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="contextMenuPolicy">
|
<property name="contextMenuPolicy">
|
||||||
<enum>Qt::CustomContextMenu</enum>
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -71,7 +66,7 @@
|
|||||||
<customwidget>
|
<customwidget>
|
||||||
<class>LineEditClear</class>
|
<class>LineEditClear</class>
|
||||||
<extends>QLineEdit</extends>
|
<extends>QLineEdit</extends>
|
||||||
<header location="global">gui/common/LineEditClear.h</header>
|
<header>gui/common/LineEditClear.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>RSTreeWidget</class>
|
<class>RSTreeWidget</class>
|
||||||
|
@ -148,7 +148,19 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) :
|
|||||||
|
|
||||||
connect(ui->distantSearchLineEdit,SIGNAL(returnPressed()),this,SLOT(distantSearch())) ;
|
connect(ui->distantSearchLineEdit,SIGNAL(returnPressed()),this,SLOT(distantSearch())) ;
|
||||||
|
|
||||||
ui->treeWidget->setIconSize(QSize(H*1.8,H*1.8));
|
mFontSizeHandler.registerFontSize(ui->treeWidget, 1.8f, [this] (QAbstractItemView*, int fontSize) {
|
||||||
|
// Set new font size on all items
|
||||||
|
QTreeWidgetItemIterator it(ui->treeWidget);
|
||||||
|
while (*it) {
|
||||||
|
QTreeWidgetItem *item = *it;
|
||||||
|
|
||||||
|
QFont font = item->font(GTW_COLUMN_NAME);
|
||||||
|
font.setPointSize(fontSize);
|
||||||
|
item->setFont(GTW_COLUMN_NAME, font);
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupTreeWidget::~GroupTreeWidget()
|
GroupTreeWidget::~GroupTreeWidget()
|
||||||
@ -254,8 +266,8 @@ QTreeWidgetItem *GroupTreeWidget::addCategoryItem(const QString &name, const QIc
|
|||||||
RSTreeWidgetItem *item = new RSTreeWidgetItem();
|
RSTreeWidgetItem *item = new RSTreeWidgetItem();
|
||||||
ui->treeWidget->addTopLevelItem(item);
|
ui->treeWidget->addTopLevelItem(item);
|
||||||
// To get StyleSheet for Items
|
// To get StyleSheet for Items
|
||||||
ui->treeWidget->style()->unpolish(ui->treeWidget);
|
// ui->treeWidget->style()->unpolish(ui->treeWidget);
|
||||||
ui->treeWidget->style()->polish(ui->treeWidget);
|
// ui->treeWidget->style()->polish(ui->treeWidget);
|
||||||
|
|
||||||
item->setText(GTW_COLUMN_NAME, name);
|
item->setText(GTW_COLUMN_NAME, name);
|
||||||
item->setData(GTW_COLUMN_DATA, ROLE_NAME, name);
|
item->setData(GTW_COLUMN_DATA, ROLE_NAME, name);
|
||||||
@ -390,7 +402,7 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList<
|
|||||||
if (item == NULL) {
|
if (item == NULL) {
|
||||||
item = new RSTreeWidgetItem(compareRole);
|
item = new RSTreeWidgetItem(compareRole);
|
||||||
item->setData(GTW_COLUMN_DATA, ROLE_ID, itemInfo.id);
|
item->setData(GTW_COLUMN_DATA, ROLE_ID, itemInfo.id);
|
||||||
item->setFont(GTW_COLUMN_DATA, ui->treeWidget->font());
|
item->setFont(GTW_COLUMN_NAME, ui->treeWidget->font());
|
||||||
//static_cast<RSTreeWidgetItem*>(item)->setNoDataAsLast(true); //Uncomment this to sort data with QVariant() always at end.
|
//static_cast<RSTreeWidgetItem*>(item)->setNoDataAsLast(true); //Uncomment this to sort data with QVariant() always at end.
|
||||||
categoryItem->addChild(item);
|
categoryItem->addChild(item);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include "util/FontSizeHandler.h"
|
||||||
|
|
||||||
class QToolButton;
|
class QToolButton;
|
||||||
class RshareSettings;
|
class RshareSettings;
|
||||||
@ -163,6 +164,7 @@ private:
|
|||||||
|
|
||||||
// Compare role used for each column
|
// Compare role used for each column
|
||||||
RSTreeWidgetItemCompareRole *compareRole;
|
RSTreeWidgetItemCompareRole *compareRole;
|
||||||
|
FontSizeHandler mFontSizeHandler;
|
||||||
|
|
||||||
Ui::GroupTreeWidget *ui;
|
Ui::GroupTreeWidget *ui;
|
||||||
};
|
};
|
||||||
|
@ -35,10 +35,10 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::Box</enum>
|
<enum>QFrame::StyledPanel</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Sunken</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
@ -70,11 +70,6 @@
|
|||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<pointsize>11</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="contextMenuPolicy">
|
<property name="contextMenuPolicy">
|
||||||
<enum>Qt::CustomContextMenu</enum>
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -234,8 +234,10 @@ void LineEditClear::setFilterButtonIcon(const QIcon &icon)
|
|||||||
mFilterButton->setIcon(icon);
|
mFilterButton->setIcon(icon);
|
||||||
|
|
||||||
ensurePolished();
|
ensurePolished();
|
||||||
|
#if !defined(Q_OS_DARWIN)
|
||||||
QFontMetrics fm(this->font());
|
QFontMetrics fm(this->font());
|
||||||
QSize size(fm.width("___"), fm.height());
|
QSize size(fm.width("___"), fm.height());
|
||||||
mFilterButton->setFixedSize(size);
|
mFilterButton->setFixedSize(size);
|
||||||
mFilterButton->setIconSize(size);
|
mFilterButton->setIconSize(size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
27
retroshare-gui/src/gui/common/MacDockIconHandler.h
Normal file
27
retroshare-gui/src/gui/common/MacDockIconHandler.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (c) 2011-2018 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef MACDOCKICONHANDLER_H
|
||||||
|
#define MACDOCKICONHANDLER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
/** macOS-specific Dock icon handler.
|
||||||
|
*/
|
||||||
|
class MacDockIconHandler : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
static MacDockIconHandler *instance();
|
||||||
|
static void cleanup();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void dockIconClicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
MacDockIconHandler();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MACDOCKICONHANDLER_H
|
53
retroshare-gui/src/gui/common/MacDockIconHandler.mm
Normal file
53
retroshare-gui/src/gui/common/MacDockIconHandler.mm
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright (c) 2011-2019 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "MacDockIconHandler.h"
|
||||||
|
|
||||||
|
#include <AppKit/AppKit.h>
|
||||||
|
#include <objc/runtime.h>
|
||||||
|
|
||||||
|
static MacDockIconHandler *s_instance = nullptr;
|
||||||
|
|
||||||
|
bool dockClickHandler(id self, SEL _cmd, ...) {
|
||||||
|
Q_UNUSED(self)
|
||||||
|
Q_UNUSED(_cmd)
|
||||||
|
|
||||||
|
Q_EMIT s_instance->dockIconClicked();
|
||||||
|
|
||||||
|
// Return NO (false) to suppress the default macOS actions
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupDockClickHandler() {
|
||||||
|
Class delClass = (Class)[[[NSApplication sharedApplication] delegate] class];
|
||||||
|
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
|
||||||
|
class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
|
||||||
|
}
|
||||||
|
|
||||||
|
MacDockIconHandler::MacDockIconHandler() : QObject()
|
||||||
|
{
|
||||||
|
setupDockClickHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
MacDockIconHandler *MacDockIconHandler::instance()
|
||||||
|
{
|
||||||
|
if (!s_instance)
|
||||||
|
s_instance = new MacDockIconHandler();
|
||||||
|
return s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacDockIconHandler::cleanup()
|
||||||
|
{
|
||||||
|
delete s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force application activation on macOS. With Qt 5.5.1 this is required when
|
||||||
|
* an action in the Dock menu is triggered.
|
||||||
|
* TODO: Define a Qt version where it's no-longer necessary.
|
||||||
|
*/
|
||||||
|
void ForceActivation()
|
||||||
|
{
|
||||||
|
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||||
|
}
|
@ -54,6 +54,7 @@
|
|||||||
#include "gui/chat/ChatUserNotify.h"
|
#include "gui/chat/ChatUserNotify.h"
|
||||||
#include "gui/connect/ConnectProgressDialog.h"
|
#include "gui/connect/ConnectProgressDialog.h"
|
||||||
#include "gui/common/ElidedLabel.h"
|
#include "gui/common/ElidedLabel.h"
|
||||||
|
#include "gui/notifyqt.h"
|
||||||
|
|
||||||
#include "NewFriendList.h"
|
#include "NewFriendList.h"
|
||||||
#include "ui_NewFriendList.h"
|
#include "ui_NewFriendList.h"
|
||||||
@ -202,6 +203,9 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par
|
|||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> e) { handleEvent(e); }, mEventHandlerId_peer, RsEventType::PEER_CONNECTION );
|
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> e) { handleEvent(e); }, mEventHandlerId_peer, RsEventType::PEER_CONNECTION );
|
||||||
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> e) { handleEvent(e); }, mEventHandlerId_gssp, RsEventType::GOSSIP_DISCOVERY );
|
rsEvents->registerEventsHandler( [this](std::shared_ptr<const RsEvent> e) { handleEvent(e); }, mEventHandlerId_gssp, RsEventType::GOSSIP_DISCOVERY );
|
||||||
|
|
||||||
|
connect(NotifyQt::getInstance(), SIGNAL(peerHasNewAvatar(QString)), this, SLOT(forceUpdateDisplay()));
|
||||||
|
connect(NotifyQt::getInstance(), SIGNAL(peerStatusChanged(QString,int)), this, SLOT(forceUpdateDisplay()));
|
||||||
|
|
||||||
mModel = new RsFriendListModel(ui->peerTreeWidget);
|
mModel = new RsFriendListModel(ui->peerTreeWidget);
|
||||||
mProxyModel = new FriendListSortFilterProxyModel(ui->peerTreeWidget->header(),this);
|
mProxyModel = new FriendListSortFilterProxyModel(ui->peerTreeWidget->header(),this);
|
||||||
|
|
||||||
@ -261,6 +265,7 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par
|
|||||||
|
|
||||||
connect(ui->actionShowOfflineFriends, SIGNAL(triggered(bool)), this, SLOT(setShowUnconnected(bool)));
|
connect(ui->actionShowOfflineFriends, SIGNAL(triggered(bool)), this, SLOT(setShowUnconnected(bool)));
|
||||||
connect(ui->actionShowState, SIGNAL(triggered(bool)), this, SLOT(setShowState(bool)) );
|
connect(ui->actionShowState, SIGNAL(triggered(bool)), this, SLOT(setShowState(bool)) );
|
||||||
|
connect(ui->actionShowStateIcon, SIGNAL(triggered(bool)), this, SLOT(setShowStateIcon(bool)) );
|
||||||
connect(ui->actionShowGroups, SIGNAL(triggered(bool)), this, SLOT(setShowGroups(bool)) );
|
connect(ui->actionShowGroups, SIGNAL(triggered(bool)), this, SLOT(setShowGroups(bool)) );
|
||||||
connect(ui->actionExportFriendlist, SIGNAL(triggered()) , this, SLOT(exportFriendlistClicked()));
|
connect(ui->actionExportFriendlist, SIGNAL(triggered()) , this, SLOT(exportFriendlistClicked()));
|
||||||
connect(ui->actionImportFriendlist, SIGNAL(triggered()) , this, SLOT(importFriendlistClicked()));
|
connect(ui->actionImportFriendlist, SIGNAL(triggered()) , this, SLOT(importFriendlistClicked()));
|
||||||
@ -268,6 +273,8 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par
|
|||||||
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString)),Qt::QueuedConnection);
|
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString)),Qt::QueuedConnection);
|
||||||
connect(h, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(headerContextMenuRequested(QPoint)));
|
connect(h, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(headerContextMenuRequested(QPoint)));
|
||||||
|
|
||||||
|
mFontSizeHandler.registerFontSize(ui->peerTreeWidget,1.5f);
|
||||||
|
|
||||||
// #ifdef RS_DIRECT_CHAT
|
// #ifdef RS_DIRECT_CHAT
|
||||||
// connect(ui->peerTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(chatNode()));
|
// connect(ui->peerTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(chatNode()));
|
||||||
// #endif
|
// #endif
|
||||||
@ -341,10 +348,12 @@ void NewFriendList::headerContextMenuRequested(QPoint /*p*/)
|
|||||||
|
|
||||||
displayMenu.addAction(ui->actionShowOfflineFriends);
|
displayMenu.addAction(ui->actionShowOfflineFriends);
|
||||||
displayMenu.addAction(ui->actionShowState);
|
displayMenu.addAction(ui->actionShowState);
|
||||||
|
displayMenu.addAction(ui->actionShowStateIcon);
|
||||||
displayMenu.addAction(ui->actionShowGroups);
|
displayMenu.addAction(ui->actionShowGroups);
|
||||||
|
|
||||||
ui->actionShowOfflineFriends->setChecked(mProxyModel->showOfflineNodes());
|
ui->actionShowOfflineFriends->setChecked(mProxyModel->showOfflineNodes());
|
||||||
ui->actionShowState->setChecked(mModel->getDisplayStatusString());
|
ui->actionShowState->setChecked(mModel->getDisplayStatusString());
|
||||||
|
ui->actionShowStateIcon->setChecked(mModel->getDisplayStatusIcon());
|
||||||
ui->actionShowGroups->setChecked(mModel->getDisplayGroups());
|
ui->actionShowGroups->setChecked(mModel->getDisplayGroups());
|
||||||
|
|
||||||
QHeaderView *header = ui->peerTreeWidget->header();
|
QHeaderView *header = ui->peerTreeWidget->header();
|
||||||
@ -505,6 +514,8 @@ void NewFriendList::processSettings(bool load)
|
|||||||
|
|
||||||
mModel->setDisplayStatusString(Settings->value("showState", mModel->getDisplayStatusString()).toBool());
|
mModel->setDisplayStatusString(Settings->value("showState", mModel->getDisplayStatusString()).toBool());
|
||||||
mModel->setDisplayGroups(Settings->value("showGroups", mModel->getDisplayGroups()).toBool());
|
mModel->setDisplayGroups(Settings->value("showGroups", mModel->getDisplayGroups()).toBool());
|
||||||
|
mModel->setDisplayStatusIcon(Settings->value("showStateIcon", mModel->getDisplayStatusIcon()).toBool());
|
||||||
|
|
||||||
|
|
||||||
setColumnVisible(RsFriendListModel::COLUMN_THREAD_IP,Settings->value("showIP", isColumnVisible(RsFriendListModel::COLUMN_THREAD_IP)).toBool());
|
setColumnVisible(RsFriendListModel::COLUMN_THREAD_IP,Settings->value("showIP", isColumnVisible(RsFriendListModel::COLUMN_THREAD_IP)).toBool());
|
||||||
setColumnVisible(RsFriendListModel::COLUMN_THREAD_ID,Settings->value("showID", isColumnVisible(RsFriendListModel::COLUMN_THREAD_ID)).toBool());
|
setColumnVisible(RsFriendListModel::COLUMN_THREAD_ID,Settings->value("showID", isColumnVisible(RsFriendListModel::COLUMN_THREAD_ID)).toBool());
|
||||||
@ -528,6 +539,8 @@ void NewFriendList::processSettings(bool load)
|
|||||||
Settings->setValue("hideUnconnected", !mProxyModel->showOfflineNodes());
|
Settings->setValue("hideUnconnected", !mProxyModel->showOfflineNodes());
|
||||||
Settings->setValue("showState", mModel->getDisplayStatusString());
|
Settings->setValue("showState", mModel->getDisplayStatusString());
|
||||||
Settings->setValue("showGroups", mModel->getDisplayGroups());
|
Settings->setValue("showGroups", mModel->getDisplayGroups());
|
||||||
|
Settings->setValue("showStateIcon", mModel->getDisplayStatusIcon());
|
||||||
|
|
||||||
|
|
||||||
Settings->setValue("showIP",isColumnVisible(RsFriendListModel::COLUMN_THREAD_IP));
|
Settings->setValue("showIP",isColumnVisible(RsFriendListModel::COLUMN_THREAD_IP));
|
||||||
Settings->setValue("showID",isColumnVisible(RsFriendListModel::COLUMN_THREAD_ID));
|
Settings->setValue("showID",isColumnVisible(RsFriendListModel::COLUMN_THREAD_ID));
|
||||||
@ -1643,6 +1656,12 @@ void NewFriendList::setShowState(bool show)
|
|||||||
processSettings(false);
|
processSettings(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NewFriendList::setShowStateIcon(bool show)
|
||||||
|
{
|
||||||
|
applyWhileKeepingTree([show,this]() { mModel->setDisplayStatusIcon(show) ; });
|
||||||
|
processSettings(false);
|
||||||
|
}
|
||||||
|
|
||||||
void NewFriendList::setShowGroups(bool show)
|
void NewFriendList::setShowGroups(bool show)
|
||||||
{
|
{
|
||||||
applyWhileKeepingTree([show,this]() { mModel->setDisplayGroups(show) ; });
|
applyWhileKeepingTree([show,this]() { mModel->setDisplayGroups(show) ; });
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "FriendListModel.h"
|
#include "FriendListModel.h"
|
||||||
#include "retroshare/rsstatus.h"
|
#include "retroshare/rsstatus.h"
|
||||||
|
#include "util/FontSizeHandler.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class NewFriendList;
|
class NewFriendList;
|
||||||
@ -87,7 +88,9 @@ public slots:
|
|||||||
void setShowGroups(bool show);
|
void setShowGroups(bool show);
|
||||||
void setShowUnconnected(bool hidden);
|
void setShowUnconnected(bool hidden);
|
||||||
void setShowState(bool show);
|
void setShowState(bool show);
|
||||||
void headerContextMenuRequested(QPoint);
|
void setShowStateIcon(bool show);
|
||||||
|
void headerContextMenuRequested(QPoint);
|
||||||
|
void exportFriendlistClicked();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void sortColumn(int col,Qt::SortOrder so);
|
void sortColumn(int col,Qt::SortOrder so);
|
||||||
@ -102,6 +105,7 @@ private:
|
|||||||
Ui::NewFriendList *ui;
|
Ui::NewFriendList *ui;
|
||||||
RsFriendListModel *mModel;
|
RsFriendListModel *mModel;
|
||||||
QAction *mActionSortByState;
|
QAction *mActionSortByState;
|
||||||
|
FontSizeHandler mFontSizeHandler;
|
||||||
|
|
||||||
void applyWhileKeepingTree(std::function<void()> predicate);
|
void applyWhileKeepingTree(std::function<void()> predicate);
|
||||||
|
|
||||||
@ -164,6 +168,5 @@ private slots:
|
|||||||
void editGroup();
|
void editGroup();
|
||||||
void removeGroup();
|
void removeGroup();
|
||||||
|
|
||||||
void exportFriendlistClicked();
|
|
||||||
void importFriendlistClicked();
|
void importFriendlistClicked();
|
||||||
};
|
};
|
||||||
|
@ -29,10 +29,10 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="toolBarFrame">
|
<widget class="QFrame" name="toolBarFrame">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::Box</enum>
|
<enum>QFrame::StyledPanel</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Sunken</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="toolBarFrame_HL">
|
<layout class="QHBoxLayout" name="toolBarFrame_HL">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
@ -58,11 +58,6 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTreeView" name="peerTreeWidget">
|
<widget class="QTreeView" name="peerTreeWidget">
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<pointsize>12</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="contextMenuPolicy">
|
<property name="contextMenuPolicy">
|
||||||
<enum>Qt::CustomContextMenu</enum>
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -124,6 +119,17 @@
|
|||||||
<string>import your friendlist including groups</string>
|
<string>import your friendlist including groups</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionShowStateIcon">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Status icons</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Show status icons</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
@ -37,534 +37,411 @@
|
|||||||
|
|
||||||
const QString RsCollection::ExtensionString = QString("rscollection") ;
|
const QString RsCollection::ExtensionString = QString("rscollection") ;
|
||||||
|
|
||||||
RsCollection::RsCollection(QObject *parent)
|
RsCollection::RsCollection()
|
||||||
: QObject(parent), _xml_doc("RsCollection")
|
|
||||||
{
|
{
|
||||||
_root = _xml_doc.createElement("RsCollection");
|
mFileTree = std::unique_ptr<RsFileTree>(new RsFileTree());
|
||||||
_xml_doc.appendChild(_root);
|
}
|
||||||
|
RsCollection::RsCollection(const RsFileTree& ft)
|
||||||
|
{
|
||||||
|
mFileTree = std::unique_ptr<RsFileTree>(new RsFileTree(ft));
|
||||||
|
|
||||||
|
for(uint64_t i=0;i<mFileTree->numFiles();++i)
|
||||||
|
mHashes.insert(std::make_pair(mFileTree->fileData(i).hash,i ));
|
||||||
}
|
}
|
||||||
|
|
||||||
RsCollection::RsCollection(const RsFileTree& fr)
|
RsCollection::RsCollection(const std::vector<DirDetails>& file_infos,FileSearchFlags flags)
|
||||||
: _xml_doc("RsCollection")
|
: mFileTree(new RsFileTree)
|
||||||
{
|
{
|
||||||
_root = _xml_doc.createElement("RsCollection");
|
if(! ( (flags & RS_FILE_HINTS_LOCAL) || (flags & RS_FILE_HINTS_REMOTE)))
|
||||||
_xml_doc.appendChild(_root);
|
{
|
||||||
|
std::cerr << "(EE) Wrong flags passed to RsCollection constructor. Please fix the code!" << std::endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
recursAddElements(_xml_doc,fr,0,_root) ;
|
for(uint32_t i = 0;i<file_infos.size();++i)
|
||||||
}
|
recursAddElements(mFileTree->root(),file_infos[i],flags) ;
|
||||||
|
|
||||||
RsCollection::RsCollection(const std::vector<DirDetails>& file_infos,FileSearchFlags flags, QObject *parent)
|
for(uint64_t i=0;i<mFileTree->numFiles();++i)
|
||||||
: QObject(parent), _xml_doc("RsCollection")
|
mHashes.insert(std::make_pair(mFileTree->fileData(i).hash,i ));
|
||||||
{
|
|
||||||
_root = _xml_doc.createElement("RsCollection");
|
|
||||||
_xml_doc.appendChild(_root);
|
|
||||||
|
|
||||||
if(! ( (flags & RS_FILE_HINTS_LOCAL) || (flags & RS_FILE_HINTS_REMOTE)))
|
|
||||||
{
|
|
||||||
std::cerr << "(EE) Wrong flags passed to RsCollection constructor. Please fix the code!" << std::endl;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint32_t i = 0;i<file_infos.size();++i)
|
|
||||||
recursAddElements(_xml_doc,file_infos[i],_root,flags) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RsCollection::~RsCollection()
|
RsCollection::~RsCollection()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsCollection::downloadFiles() const
|
|
||||||
{
|
|
||||||
// print out the element names of all elements that are direct children
|
|
||||||
// of the outermost element.
|
|
||||||
QDomElement docElem = _xml_doc.documentElement();
|
|
||||||
|
|
||||||
std::vector<ColFileInfo> colFileInfos ;
|
|
||||||
|
|
||||||
recursCollectColFileInfos(docElem,colFileInfos,QString(),false) ;
|
|
||||||
|
|
||||||
RsCollectionDialog(_fileName, colFileInfos, false).exec() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RsCollection::autoDownloadFiles() const
|
|
||||||
{
|
|
||||||
QDomElement docElem = _xml_doc.documentElement();
|
|
||||||
|
|
||||||
std::vector<ColFileInfo> colFileInfos;
|
|
||||||
|
|
||||||
recursCollectColFileInfos(docElem,colFileInfos,QString(),false);
|
|
||||||
|
|
||||||
QString dlDir = QString::fromUtf8(rsFiles->getDownloadDirectory().c_str());
|
|
||||||
|
|
||||||
foreach(ColFileInfo colFileInfo, colFileInfos)
|
|
||||||
{
|
|
||||||
autoDownloadFiles(colFileInfo, dlDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RsCollection::autoDownloadFiles(ColFileInfo colFileInfo, QString dlDir) const
|
void RsCollection::autoDownloadFiles(ColFileInfo colFileInfo, QString dlDir) const
|
||||||
{
|
{
|
||||||
if (!colFileInfo.filename_has_wrong_characters)
|
if (!colFileInfo.filename_has_wrong_characters)
|
||||||
{
|
{
|
||||||
QString cleanPath = dlDir + colFileInfo.path ;
|
QString cleanPath = dlDir + colFileInfo.path ;
|
||||||
std::cout << "making directory " << cleanPath.toStdString() << std::endl;
|
std::cout << "making directory " << cleanPath.toStdString() << std::endl;
|
||||||
|
|
||||||
if(!QDir(QApplication::applicationDirPath()).mkpath(cleanPath))
|
if(!QDir(QApplication::applicationDirPath()).mkpath(cleanPath))
|
||||||
std::cerr << "Unable to make path: " + cleanPath.toStdString() << std::endl;
|
std::cerr << "Unable to make path: " + cleanPath.toStdString() << std::endl;
|
||||||
|
|
||||||
if (colFileInfo.type==DIR_TYPE_FILE)
|
if (colFileInfo.type==DIR_TYPE_FILE)
|
||||||
rsFiles->FileRequest(colFileInfo.name.toUtf8().constData(),
|
rsFiles->FileRequest(colFileInfo.name.toUtf8().constData(),
|
||||||
RsFileHash(colFileInfo.hash.toStdString()),
|
RsFileHash(colFileInfo.hash.toStdString()),
|
||||||
colFileInfo.size,
|
colFileInfo.size,
|
||||||
cleanPath.toUtf8().constData(),
|
cleanPath.toUtf8().constData(),
|
||||||
RS_FILE_REQ_ANONYMOUS_ROUTING,
|
RS_FILE_REQ_ANONYMOUS_ROUTING,
|
||||||
std::list<RsPeerId>());
|
std::list<RsPeerId>());
|
||||||
}
|
}
|
||||||
foreach(ColFileInfo colFileInfoChild, colFileInfo.children)
|
foreach(ColFileInfo colFileInfoChild, colFileInfo.children)
|
||||||
{
|
{
|
||||||
autoDownloadFiles(colFileInfoChild, dlDir);
|
autoDownloadFiles(colFileInfoChild, dlDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString purifyFileName(const QString& input,bool& bad)
|
static QString purifyFileName(const QString& input,bool& bad)
|
||||||
{
|
{
|
||||||
static const QString bad_chars = "/\\\"*:?<>|" ;
|
static const QString bad_chars = "/\\\"*:?<>|" ;
|
||||||
bad = false ;
|
bad = false ;
|
||||||
QString output = input ;
|
QString output = input ;
|
||||||
|
|
||||||
for(int i=0;i<output.length();++i)
|
for(int i=0;i<output.length();++i)
|
||||||
for(int j=0;j<bad_chars.length();++j)
|
for(int j=0;j<bad_chars.length();++j)
|
||||||
if(output[i] == bad_chars[j])
|
if(output[i] == bad_chars[j])
|
||||||
{
|
{
|
||||||
output[i] = '_' ;
|
output[i] = '_' ;
|
||||||
bad = true ;
|
bad = true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output ;
|
return output ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsCollection::merge_in(const QString& fname,uint64_t size,const RsFileHash& hash)
|
void RsCollection::merge_in(const QString& fname,uint64_t size,const RsFileHash& hash,RsFileTree::DirIndex parent_index)
|
||||||
{
|
{
|
||||||
ColFileInfo info ;
|
mHashes[hash]= mFileTree->addFile(parent_index,fname.toStdString(),hash,size);
|
||||||
info.type = DIR_TYPE_FILE ;
|
|
||||||
info.name = fname ;
|
|
||||||
info.size = size ;
|
|
||||||
info.hash = QString::fromStdString(hash.toStdString()) ;
|
|
||||||
|
|
||||||
recursAddElements(_xml_doc,info,_root) ;
|
|
||||||
}
|
}
|
||||||
void RsCollection::merge_in(const RsFileTree& tree)
|
void RsCollection::merge_in(const RsFileTree& tree, RsFileTree::DirIndex parent_index)
|
||||||
{
|
{
|
||||||
recursAddElements(_xml_doc,tree,0,_root) ;
|
recursMergeTree(mFileTree->root(),tree,tree.directoryData(parent_index)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsCollection::recursCollectColFileInfos(const QDomElement& e,std::vector<ColFileInfo>& colFileInfos,const QString& current_path, bool bad_chars_in_parent) const
|
void RsCollection::recursMergeTree(RsFileTree::DirIndex parent,const RsFileTree& tree,const RsFileTree::DirData& dd)
|
||||||
{
|
{
|
||||||
QDomNode n = e.firstChild() ;
|
for(uint32_t i=0;i<dd.subfiles.size();++i)
|
||||||
#ifdef COLLECTION_DEBUG
|
{
|
||||||
std::cerr << "Parsing element " << e.tagName().toStdString() << std::endl;
|
const RsFileTree::FileData& fd(tree.fileData(dd.subfiles[i]));
|
||||||
#endif
|
mHashes[fd.hash] = mFileTree->addFile(parent,fd.name,fd.hash,fd.size);
|
||||||
|
}
|
||||||
|
for(uint32_t i=0;i<dd.subdirs.size();++i)
|
||||||
|
{
|
||||||
|
const RsFileTree::DirData& ld(tree.directoryData(dd.subdirs[i]));
|
||||||
|
|
||||||
while(!n.isNull())
|
auto new_dir_index = mFileTree->addDirectory(parent,ld.name);
|
||||||
{
|
recursMergeTree(new_dir_index,tree,ld);
|
||||||
QDomElement ee = n.toElement(); // try to convert the node to an element.
|
}
|
||||||
|
|
||||||
#ifdef COLLECTION_DEBUG
|
|
||||||
std::cerr << " Seeing child " << ee.tagName().toStdString() << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(ee.tagName() == QString("File"))
|
|
||||||
{
|
|
||||||
ColFileInfo newChild ;
|
|
||||||
newChild.hash = ee.attribute(QString("sha1")) ;
|
|
||||||
bool bad_chars_detected = false ;
|
|
||||||
newChild.name = purifyFileName(ee.attribute(QString("name")), bad_chars_detected) ;
|
|
||||||
newChild.filename_has_wrong_characters = bad_chars_detected || bad_chars_in_parent ;
|
|
||||||
newChild.size = ee.attribute(QString("size")).toULongLong() ;
|
|
||||||
newChild.path = current_path ;
|
|
||||||
newChild.type = DIR_TYPE_FILE ;
|
|
||||||
|
|
||||||
colFileInfos.push_back(newChild) ;
|
|
||||||
}
|
|
||||||
else if(ee.tagName() == QString("Directory"))
|
|
||||||
{
|
|
||||||
ColFileInfo newParent ;
|
|
||||||
bool bad_chars_detected = false ;
|
|
||||||
QString cleanDirName = purifyFileName(ee.attribute(QString("name")),bad_chars_detected) ;
|
|
||||||
newParent.name=cleanDirName;
|
|
||||||
newParent.filename_has_wrong_characters = bad_chars_detected || bad_chars_in_parent ;
|
|
||||||
newParent.size = 0;
|
|
||||||
newParent.path = current_path ;
|
|
||||||
newParent.type = DIR_TYPE_DIR ;
|
|
||||||
|
|
||||||
recursCollectColFileInfos(ee,newParent.children,current_path + "/" + cleanDirName, bad_chars_in_parent || bad_chars_detected) ;
|
|
||||||
uint32_t size = newParent.children.size();
|
|
||||||
for(uint32_t i=0;i<size;++i)
|
|
||||||
{
|
|
||||||
const ColFileInfo &colFileInfo = newParent.children[i];
|
|
||||||
newParent.size +=colFileInfo.size ;
|
|
||||||
}
|
|
||||||
|
|
||||||
colFileInfos.push_back(newParent) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = n.nextSibling() ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RsCollection::recursAddElements(RsFileTree::DirIndex parent, const DirDetails& dd, FileSearchFlags flags)
|
||||||
void RsCollection::recursAddElements(QDomDocument& doc,const DirDetails& details,QDomElement& e,FileSearchFlags flags) const
|
|
||||||
{
|
{
|
||||||
if (details.type == DIR_TYPE_FILE)
|
if (dd.type == DIR_TYPE_FILE)
|
||||||
{
|
mHashes[dd.hash] = mFileTree->addFile(parent,dd.name,dd.hash,dd.size);
|
||||||
QDomElement f = doc.createElement("File") ;
|
else if (dd.type == DIR_TYPE_DIR)
|
||||||
|
{
|
||||||
|
RsFileTree::DirIndex new_dir_index = mFileTree->addDirectory(parent,dd.name);
|
||||||
|
|
||||||
f.setAttribute(QString("name"),QString::fromUtf8(details.name.c_str())) ;
|
for(uint32_t i=0;i<dd.children.size();++i)
|
||||||
f.setAttribute(QString("sha1"),QString::fromStdString(details.hash.toStdString())) ;
|
{
|
||||||
f.setAttribute(QString("size"),QString::number(details.size)) ;
|
if (!dd.children[i].ref)
|
||||||
|
continue;
|
||||||
|
|
||||||
e.appendChild(f) ;
|
DirDetails subDirDetails;
|
||||||
}
|
|
||||||
else if (details.type == DIR_TYPE_DIR)
|
|
||||||
{
|
|
||||||
QDomElement d = doc.createElement("Directory") ;
|
|
||||||
|
|
||||||
d.setAttribute(QString("name"),QString::fromUtf8(details.name.c_str())) ;
|
if (!rsFiles->RequestDirDetails(dd.children[i].ref, subDirDetails, flags))
|
||||||
|
continue;
|
||||||
|
|
||||||
for(uint32_t i=0;i<details.children.size();++i)
|
recursAddElements(new_dir_index,subDirDetails,flags) ;
|
||||||
{
|
}
|
||||||
if (!details.children[i].ref)
|
}
|
||||||
continue;
|
|
||||||
|
|
||||||
DirDetails subDirDetails;
|
|
||||||
|
|
||||||
if (!rsFiles->RequestDirDetails(details.children[i].ref, subDirDetails, flags))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
recursAddElements(doc,subDirDetails,d,flags) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.appendChild(d) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsCollection::recursAddElements(QDomDocument& doc,const ColFileInfo& colFileInfo,QDomElement& e) const
|
QString RsCollection::errorString(RsCollectionErrorCode code)
|
||||||
{
|
{
|
||||||
if (colFileInfo.type == DIR_TYPE_FILE)
|
switch(code)
|
||||||
{
|
{
|
||||||
QDomElement f = doc.createElement("File") ;
|
default: [[fallthrough]] ;
|
||||||
|
case RsCollectionErrorCode::UNKNOWN_ERROR: return QObject::tr("Unknown error");
|
||||||
f.setAttribute(QString("name"),colFileInfo.name) ;
|
case RsCollectionErrorCode::COLLECTION_NO_ERROR: return QObject::tr("No error");
|
||||||
f.setAttribute(QString("sha1"),colFileInfo.hash) ;
|
case RsCollectionErrorCode::FILE_READ_ERROR: return QObject::tr("Error while openning file");
|
||||||
f.setAttribute(QString("size"),QString::number(colFileInfo.size)) ;
|
case RsCollectionErrorCode::FILE_CONTAINS_HARMFUL_STRINGS: return QObject::tr("Collection file contains potentially harmful code");
|
||||||
|
case RsCollectionErrorCode::INVALID_ROOT_NODE: return QObject::tr("Invalid root node. RsCollection node was expected.");
|
||||||
e.appendChild(f) ;
|
case RsCollectionErrorCode::XML_PARSING_ERROR: return QObject::tr("XML parsing error in collection file");
|
||||||
}
|
}
|
||||||
else if (colFileInfo.type == DIR_TYPE_DIR)
|
|
||||||
{
|
|
||||||
QDomElement d = doc.createElement("Directory") ;
|
|
||||||
|
|
||||||
d.setAttribute(QString("name"),colFileInfo.name) ;
|
|
||||||
|
|
||||||
for (std::vector<ColFileInfo>::const_iterator it = colFileInfo.children.begin(); it != colFileInfo.children.end(); ++it)
|
|
||||||
recursAddElements(doc,(*it),d) ;
|
|
||||||
|
|
||||||
e.appendChild(d) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsCollection::recursAddElements(
|
RsCollection::RsCollection(const RsCollection& col)
|
||||||
QDomDocument& doc, const RsFileTree& ft, uint32_t index,
|
: mFileTree(new RsFileTree(*col.mFileTree)),mHashes(col.mHashes)
|
||||||
QDomElement& e ) const
|
|
||||||
{
|
{
|
||||||
std::vector<uint64_t> subdirs;
|
|
||||||
std::vector<RsFileTree::FileData> subfiles ;
|
|
||||||
std::string name;
|
|
||||||
if(!ft.getDirectoryContent(name, subdirs, subfiles, index)) return;
|
|
||||||
|
|
||||||
QDomElement d = doc.createElement("Directory") ;
|
|
||||||
d.setAttribute(QString("name"),QString::fromUtf8(name.c_str())) ;
|
|
||||||
e.appendChild(d) ;
|
|
||||||
|
|
||||||
for (uint32_t i=0;i<subdirs.size();++i)
|
|
||||||
recursAddElements(doc,ft,subdirs[i],d) ;
|
|
||||||
|
|
||||||
for(uint32_t i=0;i<subfiles.size();++i)
|
|
||||||
{
|
|
||||||
QDomElement f = doc.createElement("File") ;
|
|
||||||
|
|
||||||
f.setAttribute(QString("name"),QString::fromUtf8(subfiles[i].name.c_str())) ;
|
|
||||||
f.setAttribute(QString("sha1"),QString::fromStdString(subfiles[i].hash.toStdString())) ;
|
|
||||||
f.setAttribute(QString("size"),QString::number(subfiles[i].size)) ;
|
|
||||||
|
|
||||||
d.appendChild(f) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void showErrorBox(const QString& fileName, const QString& error)
|
RsCollection::RsCollection(const QString& fileName, RsCollectionErrorCode& error)
|
||||||
|
: mFileTree(new RsFileTree)
|
||||||
{
|
{
|
||||||
QMessageBox mb(QMessageBox::Warning, QObject::tr("Failed to process collection file"), QObject::tr("The collection file %1 could not be opened.\nReported error is: \n\n%2").arg(fileName).arg(error), QMessageBox::Ok);
|
if (!checkFile(fileName,error))
|
||||||
mb.exec();
|
return ;
|
||||||
|
|
||||||
|
QFile file(fileName);
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot open file " << fileName.toStdString() << " !!" << std::endl;
|
||||||
|
error = RsCollectionErrorCode::FILE_READ_ERROR;
|
||||||
|
//showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Cannot open file %1").arg(fileName));
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDomDocument xml_doc;
|
||||||
|
bool ok = xml_doc.setContent(&file) ;
|
||||||
|
|
||||||
|
if(!ok)
|
||||||
|
{
|
||||||
|
error = RsCollectionErrorCode::XML_PARSING_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
QDomNode root = xml_doc.elementsByTagName("RsCollection").at(0).toElement();
|
||||||
|
|
||||||
|
if(root.isNull())
|
||||||
|
{
|
||||||
|
error = RsCollectionErrorCode::INVALID_ROOT_NODE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!recursParseXml(xml_doc,root,0))
|
||||||
|
error = RsCollectionErrorCode::XML_PARSING_ERROR;
|
||||||
|
else
|
||||||
|
error = RsCollectionErrorCode::COLLECTION_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsCollection::load(const QString& fileName, bool showError /* = true*/)
|
// check that the file is a valid rscollection file, and not a lol bomb or some shit like this
|
||||||
|
|
||||||
|
bool RsCollection::checkFile(const QString& fileName, RsCollectionErrorCode& error)
|
||||||
{
|
{
|
||||||
|
QFile file(fileName);
|
||||||
|
error = RsCollectionErrorCode::COLLECTION_NO_ERROR;
|
||||||
|
|
||||||
if (!checkFile(fileName,showError)) return false;
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
QFile file(fileName);
|
{
|
||||||
|
std::cerr << "Cannot open file " << fileName.toStdString() << " !!" << std::endl;
|
||||||
|
error = RsCollectionErrorCode::FILE_READ_ERROR;
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadOnly))
|
//showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Cannot open file %1").arg(fileName));
|
||||||
{
|
return false;
|
||||||
std::cerr << "Cannot open file " << fileName.toStdString() << " !!" << std::endl;
|
}
|
||||||
if (showError) {
|
if (file.reset()){
|
||||||
showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Cannot open file %1").arg(fileName));
|
std::cerr << "Checking this file for bomb elements and various wrong stuff" << std::endl;
|
||||||
}
|
char c ;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ok = _xml_doc.setContent(&file) ;
|
std::vector<std::string> bad_strings ;
|
||||||
file.close();
|
bad_strings.push_back(std::string("<!entity ")) ;
|
||||||
|
static const int max_size = 12 ; // should be as large as the largest element in bad_strings
|
||||||
|
char current[max_size] = { 0,0,0,0,0,0,0,0,0,0,0,0 } ;
|
||||||
|
int n=0 ;
|
||||||
|
|
||||||
if (ok) {
|
while( !file.atEnd() || n >= 0)
|
||||||
_fileName = fileName;
|
{
|
||||||
} else {
|
if (!file.atEnd())
|
||||||
if (showError) {
|
file.getChar(&c);
|
||||||
showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Error parsing xml file"));
|
else
|
||||||
}
|
c=0;
|
||||||
}
|
|
||||||
|
|
||||||
return ok;
|
if(c == '\t' || c == '\n' || c == '\b' || c == '\r')
|
||||||
}
|
continue ;
|
||||||
|
|
||||||
// check that the file is a valid rscollection file, and not a lol bomb or some shit like this
|
if (n == max_size || file.atEnd())
|
||||||
bool RsCollection::checkFile(const QString& fileName, bool showError)
|
for(int i=0;i<n-1;++i)
|
||||||
{
|
current[i] = current[i+1] ;
|
||||||
QFile file(fileName);
|
|
||||||
|
|
||||||
if (!file.open(QIODevice::ReadOnly))
|
if(n == max_size)
|
||||||
{
|
--n ;
|
||||||
std::cerr << "Cannot open file " << fileName.toStdString() << " !!" << std::endl;
|
|
||||||
if (showError) {
|
|
||||||
showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Cannot open file %1").arg(fileName));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (file.reset()){
|
|
||||||
std::cerr << "Checking this file for bomb elements and various wrong stuff" << std::endl;
|
|
||||||
char c ;
|
|
||||||
|
|
||||||
std::vector<std::string> bad_strings ;
|
if(c >= 'A' && c <= 'Z') c += 'a' - 'A' ;
|
||||||
bad_strings.push_back(std::string("<!entity ")) ;
|
|
||||||
static const int max_size = 12 ; // should be as large as the largest element in bad_strings
|
|
||||||
char current[max_size] = { 0,0,0,0,0,0,0,0,0,0,0,0 } ;
|
|
||||||
int n=0 ;
|
|
||||||
|
|
||||||
while( !file.atEnd() || n >= 0)
|
if(!file.atEnd())
|
||||||
{
|
current[n] = c ;
|
||||||
if (!file.atEnd())
|
else
|
||||||
file.getChar(&c);
|
current[n] = 0 ;
|
||||||
else
|
|
||||||
c=0;
|
|
||||||
|
|
||||||
if(c == '\t' || c == '\n' || c == '\b' || c == '\r')
|
//std::cerr << "n==" << n <<" Checking string " << std::string(current,n+1) << " c = " << std::hex << (int)c << std::dec << std::endl;
|
||||||
continue ;
|
|
||||||
|
|
||||||
if (n == max_size || file.atEnd())
|
for(uint i=0;i<bad_strings.size();++i)
|
||||||
for(int i=0;i<n-1;++i)
|
if(std::string(current,bad_strings[i].length()) == bad_strings[i])
|
||||||
current[i] = current[i+1] ;
|
{
|
||||||
|
//showErrorBox(file.fileName(), QApplication::translate("RsCollectionFile", "This file contains the string \"%1\" and is therefore an invalid collection file. \n\nIf you believe it is correct, remove the corresponding line from the file and re-open it with Retroshare.").arg(bad_strings[i].c_str()));
|
||||||
|
error = RsCollectionErrorCode::FILE_CONTAINS_HARMFUL_STRINGS;
|
||||||
|
file.close();
|
||||||
|
return false ;
|
||||||
|
//std::cerr << "Bad string detected" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
if(n == max_size)
|
if(file.atEnd())
|
||||||
--n ;
|
n-- ;
|
||||||
|
else if(n < max_size)
|
||||||
if(c >= 'A' && c <= 'Z') c += 'a' - 'A' ;
|
++n ;
|
||||||
|
}
|
||||||
if(!file.atEnd())
|
file.close();
|
||||||
current[n] = c ;
|
return true;
|
||||||
else
|
}
|
||||||
current[n] = 0 ;
|
error = RsCollectionErrorCode::UNKNOWN_ERROR;
|
||||||
|
return false;
|
||||||
//std::cerr << "n==" << n <<" Checking string " << std::string(current,n+1) << " c = " << std::hex << (int)c << std::dec << std::endl;
|
|
||||||
|
|
||||||
for(uint i=0;i<bad_strings.size();++i)
|
|
||||||
if(std::string(current,bad_strings[i].length()) == bad_strings[i])
|
|
||||||
{
|
|
||||||
showErrorBox(file.fileName(), QApplication::translate("RsCollectionFile", "This file contains the string \"%1\" and is therefore an invalid collection file. \n\nIf you believe it is correct, remove the corresponding line from the file and re-open it with Retroshare.").arg(bad_strings[i].c_str()));
|
|
||||||
file.close();
|
|
||||||
return false ;
|
|
||||||
//std::cerr << "Bad string detected" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(file.atEnd())
|
|
||||||
n-- ;
|
|
||||||
else if(n < max_size)
|
|
||||||
++n ;
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool RsCollection::load(QWidget *parent)
|
|
||||||
{
|
|
||||||
QString fileName;
|
|
||||||
if (!misc::getOpenFileName(parent, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::cerr << "Got file name: " << fileName.toStdString() << std::endl;
|
|
||||||
|
|
||||||
return load(fileName, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsCollection::save(const QString& fileName) const
|
bool RsCollection::save(const QString& fileName) const
|
||||||
{
|
{
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
|
|
||||||
if (!file.open(QIODevice::WriteOnly))
|
if (!file.open(QIODevice::WriteOnly))
|
||||||
{
|
{
|
||||||
std::cerr << "Cannot write to file " << fileName.toStdString() << " !!" << std::endl;
|
std::cerr << "Cannot write to file " << fileName.toStdString() << " !!" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream stream(&file) ;
|
QDomDocument xml_doc ;
|
||||||
stream.setCodec("UTF-8") ;
|
QDomElement root = xml_doc.createElement("RsCollection");
|
||||||
|
|
||||||
stream << _xml_doc.toString() ;
|
const RsFileTree::DirData& root_data(mFileTree->directoryData(mFileTree->root()));
|
||||||
|
|
||||||
file.close();
|
if(!recursExportToXml(xml_doc,root,root_data))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
xml_doc.appendChild(root);
|
||||||
|
|
||||||
|
QTextStream stream(&file) ;
|
||||||
|
stream.setCodec("UTF-8") ;
|
||||||
|
|
||||||
|
stream << xml_doc.toString() ;
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsCollection::save(QWidget *parent) const
|
bool RsCollection::recursParseXml(QDomDocument& doc,const QDomNode& e,const RsFileTree::DirIndex parent)
|
||||||
{
|
{
|
||||||
QString fileName;
|
mHashes.clear();
|
||||||
if(!misc::getSaveFileName(parent, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Create collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")", fileName))
|
QDomNode n = e.firstChild() ;
|
||||||
return false;
|
#ifdef COLLECTION_DEBUG
|
||||||
|
std::cerr << "Parsing element " << e.tagName().toStdString() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!fileName.endsWith("." + RsCollection::ExtensionString))
|
while(!n.isNull())
|
||||||
fileName += "." + RsCollection::ExtensionString ;
|
{
|
||||||
|
QDomElement ee = n.toElement(); // try to convert the node to an element.
|
||||||
|
|
||||||
std::cerr << "Got file name: " << fileName.toStdString() << std::endl;
|
#ifdef COLLECTION_DEBUG
|
||||||
|
std::cerr << " Seeing child " << ee.tagName().toStdString() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
return save(fileName);
|
if(ee.tagName() == QString("File"))
|
||||||
|
{
|
||||||
|
RsFileHash hash(ee.attribute(QString("sha1")).toStdString()) ;
|
||||||
|
|
||||||
|
bool bad_chars_detected = false;
|
||||||
|
std::string name = purifyFileName(ee.attribute(QString("name")), bad_chars_detected).toUtf8().constData() ;
|
||||||
|
uint64_t size = ee.attribute(QString("size")).toULongLong() ;
|
||||||
|
|
||||||
|
mHashes[hash] = mFileTree->addFile(parent,name,hash,size);
|
||||||
|
}
|
||||||
|
else if(ee.tagName() == QString("Directory"))
|
||||||
|
{
|
||||||
|
bool bad_chars_detected = false ;
|
||||||
|
std::string cleanDirName = purifyFileName(ee.attribute(QString("name")),bad_chars_detected).toUtf8().constData() ;
|
||||||
|
|
||||||
|
RsFileTree::DirIndex new_dir_index = mFileTree->addDirectory(parent,cleanDirName);
|
||||||
|
|
||||||
|
recursParseXml(doc,ee,new_dir_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
n = n.nextSibling() ;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
bool RsCollection::recursExportToXml(QDomDocument& doc,QDomElement& e,const RsFileTree::DirData& dd) const
|
||||||
|
|
||||||
bool RsCollection::openNewColl(QWidget *parent, QString fileName)
|
|
||||||
{
|
{
|
||||||
if(!misc::getSaveFileName(parent, RshareSettings::LASTDIR_EXTRAFILE
|
for(uint32_t i=0;i<dd.subfiles.size();++i)
|
||||||
, QApplication::translate("RsCollectionFile", "Create collection file")
|
{
|
||||||
, QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollection::ExtensionString + ")"
|
QDomElement f = doc.createElement("File") ;
|
||||||
, fileName,0, QFileDialog::DontConfirmOverwrite))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!fileName.endsWith("." + RsCollection::ExtensionString))
|
const RsFileTree::FileData& fd(mFileTree->fileData(dd.subfiles[i]));
|
||||||
fileName += "." + RsCollection::ExtensionString ;
|
|
||||||
|
|
||||||
std::cerr << "Got file name: " << fileName.toStdString() << std::endl;
|
f.setAttribute(QString("name"),QString::fromUtf8(fd.name.c_str())) ;
|
||||||
|
f.setAttribute(QString("sha1"),QString::fromStdString(fd.hash.toStdString())) ;
|
||||||
|
f.setAttribute(QString("size"),QString::number(fd.size)) ;
|
||||||
|
|
||||||
QFile file(fileName) ;
|
e.appendChild(f) ;
|
||||||
|
}
|
||||||
|
|
||||||
if(file.exists())
|
for(uint32_t i=0;i<dd.subdirs.size();++i)
|
||||||
{
|
{
|
||||||
if (!checkFile(fileName,true)) return false;
|
const RsFileTree::DirData& di(mFileTree->directoryData(dd.subdirs[i]));
|
||||||
|
|
||||||
QMessageBox mb;
|
QDomElement d = doc.createElement("Directory") ;
|
||||||
mb.setText(tr("Save Collection File."));
|
d.setAttribute(QString("name"),QString::fromUtf8(di.name.c_str())) ;
|
||||||
mb.setInformativeText(tr("File already exists.")+"\n"+tr("What do you want to do?"));
|
|
||||||
QAbstractButton *btnOwerWrite = mb.addButton(tr("Overwrite"), QMessageBox::YesRole);
|
|
||||||
QAbstractButton *btnMerge = mb.addButton(tr("Merge"), QMessageBox::NoRole);
|
|
||||||
QAbstractButton *btnCancel = mb.addButton(tr("Cancel"), QMessageBox::ResetRole);
|
|
||||||
mb.setIcon(QMessageBox::Question);
|
|
||||||
mb.exec();
|
|
||||||
|
|
||||||
if (mb.clickedButton()==btnOwerWrite) {
|
if(!recursExportToXml(doc,d,di))
|
||||||
//Nothing to do _xml_doc already up to date
|
return false;
|
||||||
} else if (mb.clickedButton()==btnMerge) {
|
|
||||||
//Open old file to merge it with _xml_doc
|
|
||||||
QDomDocument qddOldFile("RsCollection");
|
|
||||||
if (qddOldFile.setContent(&file)) {
|
|
||||||
QDomElement docOldElem = qddOldFile.elementsByTagName("RsCollection").at(0).toElement();
|
|
||||||
std::vector<ColFileInfo> colOldFileInfos;
|
|
||||||
recursCollectColFileInfos(docOldElem,colOldFileInfos,QString(),false);
|
|
||||||
|
|
||||||
QDomElement root = _xml_doc.elementsByTagName("RsCollection").at(0).toElement();
|
e.appendChild(d) ;
|
||||||
for(uint32_t i = 0;i<colOldFileInfos.size();++i){
|
}
|
||||||
recursAddElements(_xml_doc,colOldFileInfos[i],root) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (mb.clickedButton()==btnCancel) {
|
return true;
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}//if(file.exists())
|
|
||||||
|
|
||||||
_fileName=fileName;
|
|
||||||
std::vector<ColFileInfo> colFileInfos ;
|
|
||||||
|
|
||||||
recursCollectColFileInfos(_xml_doc.documentElement(),colFileInfos,QString(),false) ;
|
|
||||||
|
|
||||||
RsCollectionDialog* rcd = new RsCollectionDialog(fileName, colFileInfos,true);
|
|
||||||
connect(rcd,SIGNAL(saveColl(std::vector<ColFileInfo>, QString)),this,SLOT(saveColl(std::vector<ColFileInfo>, QString))) ;
|
|
||||||
_saved=false;
|
|
||||||
rcd->exec() ;
|
|
||||||
delete rcd;
|
|
||||||
|
|
||||||
return _saved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsCollection::openColl(const QString& fileName, bool readOnly /* = false */, bool showError /* = true*/)
|
qulonglong RsCollection::count() const
|
||||||
{
|
{
|
||||||
if (load(fileName, showError)) {
|
return mFileTree->numFiles();
|
||||||
std::vector<ColFileInfo> colFileInfos ;
|
|
||||||
|
|
||||||
recursCollectColFileInfos(_xml_doc.documentElement(),colFileInfos,QString(),false) ;
|
|
||||||
|
|
||||||
RsCollectionDialog* rcd = new RsCollectionDialog(fileName, colFileInfos, true, readOnly);
|
|
||||||
connect(rcd,SIGNAL(saveColl(std::vector<ColFileInfo>, QString)),this,SLOT(saveColl(std::vector<ColFileInfo>, QString))) ;
|
|
||||||
_saved=false;
|
|
||||||
rcd->exec() ;
|
|
||||||
delete rcd;
|
|
||||||
|
|
||||||
return _saved;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qulonglong RsCollection::size()
|
qulonglong RsCollection::size()
|
||||||
{
|
{
|
||||||
QDomElement docElem = _xml_doc.documentElement();
|
return mFileTree->totalFileSize();
|
||||||
|
|
||||||
std::vector<ColFileInfo> colFileInfos;
|
|
||||||
recursCollectColFileInfos(docElem, colFileInfos, QString(),false);
|
|
||||||
|
|
||||||
uint64_t size = 0;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < colFileInfos.size(); ++i) {
|
|
||||||
size += colFileInfos[i].size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsCollection::isCollectionFile(const QString &fileName)
|
bool RsCollection::isCollectionFile(const QString &fileName)
|
||||||
{
|
{
|
||||||
QString ext = QFileInfo(fileName).suffix().toLower();
|
QString ext = QFileInfo(fileName).suffix().toLower();
|
||||||
|
|
||||||
return (ext == RsCollection::ExtensionString);
|
return (ext == RsCollection::ExtensionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsCollection::saveColl(std::vector<ColFileInfo> colFileInfos, const QString &fileName)
|
void RsCollection::updateHashes(const std::map<RsFileHash,RsFileHash>& old_to_new_hashes)
|
||||||
{
|
{
|
||||||
|
for(auto it:old_to_new_hashes)
|
||||||
|
{
|
||||||
|
auto fit = mHashes.find(it.first);
|
||||||
|
|
||||||
QDomElement root = _xml_doc.elementsByTagName("RsCollection").at(0).toElement();
|
if(fit == mHashes.end())
|
||||||
while (root.childNodes().count()>0) root.removeChild(root.firstChild());
|
{
|
||||||
for(uint32_t i = 0;i<colFileInfos.size();++i)
|
RsErr() << "Could not find hash " << it.first << " in RsCollection list of hashes. This is a bug." ;
|
||||||
recursAddElements(_xml_doc,colFileInfos[i],root) ;
|
return ;
|
||||||
|
}
|
||||||
_saved=save(fileName);
|
const auto& fd(mFileTree->fileData(fit->second));
|
||||||
|
|
||||||
|
if(fd.hash != it.first)
|
||||||
|
{
|
||||||
|
RsErr() << "Mismatch hash for file " << fd.name << " (found " << fd.hash << " instead of " << it.first << ") in RsCollection list of hashes. This is a bug." ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
mFileTree->updateFile(fit->second,fd.name,it.second,fd.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsCollection::removeFile(RsFileTree::FileIndex index_to_remove,RsFileTree::DirIndex parent_index)
|
||||||
|
{
|
||||||
|
return mFileTree->removeFile(index_to_remove,parent_index);
|
||||||
|
}
|
||||||
|
bool RsCollection::removeDirectory(RsFileTree::DirIndex index_to_remove,RsFileTree::DirIndex parent_index)
|
||||||
|
{
|
||||||
|
return mFileTree->removeDirectory(index_to_remove,parent_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsCollection::cleanup()
|
||||||
|
{
|
||||||
|
RsDbg() << "Cleaning up RsCollection with " << mFileTree->numDirs() << " dirs and " << mFileTree->numFiles() << " files." ;
|
||||||
|
|
||||||
|
mFileTree = RsFileTree::fromTreeCleaned(*mFileTree);
|
||||||
|
|
||||||
|
RsDbg() << "Simplified to " << mFileTree->numDirs() << " dirs and " << mFileTree->numFiles() << " files.";
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QDomDocument>
|
#include <QDomDocument>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
@ -53,66 +52,70 @@ public:
|
|||||||
};
|
};
|
||||||
Q_DECLARE_METATYPE(ColFileInfo)
|
Q_DECLARE_METATYPE(ColFileInfo)
|
||||||
|
|
||||||
class RsCollection : public QObject
|
class RsCollection
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class RsCollectionErrorCode:uint8_t {
|
||||||
|
COLLECTION_NO_ERROR = 0x00,
|
||||||
|
UNKNOWN_ERROR = 0x01,
|
||||||
|
FILE_READ_ERROR = 0x02,
|
||||||
|
FILE_CONTAINS_HARMFUL_STRINGS = 0x03,
|
||||||
|
INVALID_ROOT_NODE = 0x04,
|
||||||
|
XML_PARSING_ERROR = 0x05
|
||||||
|
};
|
||||||
|
|
||||||
RsCollection(QObject *parent = 0) ;
|
RsCollection();
|
||||||
// create from list of files and directories
|
RsCollection(const RsCollection&);
|
||||||
RsCollection(const std::vector<DirDetails>& file_entries, FileSearchFlags flags, QObject *parent = 0) ;
|
RsCollection(const std::vector<DirDetails>& file_entries, FileSearchFlags flags) ;
|
||||||
RsCollection(const RsFileTree& fr);
|
RsCollection(const RsFileTree& ft);
|
||||||
virtual ~RsCollection() ;
|
RsCollection(const QString& filename,RsCollectionErrorCode& error_code);
|
||||||
|
|
||||||
void merge_in(const QString& fname,uint64_t size,const RsFileHash& hash) ;
|
static QString errorString(RsCollectionErrorCode code);
|
||||||
void merge_in(const RsFileTree& tree) ;
|
|
||||||
|
virtual ~RsCollection() ;
|
||||||
|
|
||||||
|
void merge_in(const QString& fname,uint64_t size,const RsFileHash& hash,RsFileTree::DirIndex parent_index=0) ;
|
||||||
|
void merge_in(const RsFileTree& tree,RsFileTree::DirIndex parent_index=0) ;
|
||||||
|
|
||||||
|
bool removeFile(RsFileTree::FileIndex index_to_remove,RsFileTree::DirIndex parent_index);
|
||||||
|
bool removeDirectory(RsFileTree::DirIndex index_to_remove,RsFileTree::DirIndex parent_index);
|
||||||
|
|
||||||
|
void cleanup(); // cleans up the collection, which may contain unreferenced files/dirs after lazy editing.
|
||||||
|
|
||||||
static const QString ExtensionString ;
|
static const QString ExtensionString ;
|
||||||
|
|
||||||
// Loads file from disk.
|
|
||||||
bool load(QWidget *parent);
|
|
||||||
bool load(const QString& fileName, bool showError = true);
|
|
||||||
|
|
||||||
// Save to disk
|
// Save to disk
|
||||||
bool save(QWidget *parent) const ;
|
|
||||||
bool save(const QString& fileName) const ;
|
bool save(const QString& fileName) const ;
|
||||||
|
|
||||||
// Open new collection
|
// returns the file tree
|
||||||
bool openNewColl(QWidget *parent, QString fileName = "");
|
const RsFileTree& fileTree() const { return *mFileTree; }
|
||||||
// Open existing collection
|
// total size of files in the collection
|
||||||
bool openColl(const QString& fileName, bool readOnly = false, bool showError = true);
|
qulonglong size();
|
||||||
|
// total number of files in the collection
|
||||||
// Download the content.
|
qulonglong count() const;
|
||||||
void downloadFiles() const ;
|
|
||||||
// Auto Download all the content.
|
|
||||||
void autoDownloadFiles() const ;
|
|
||||||
|
|
||||||
qulonglong size();
|
|
||||||
|
|
||||||
static bool isCollectionFile(const QString& fileName);
|
static bool isCollectionFile(const QString& fileName);
|
||||||
|
|
||||||
private slots:
|
void updateHashes(const std::map<RsFileHash,RsFileHash>& old_to_new_hashes);
|
||||||
void saveColl(std::vector<ColFileInfo> colFileInfos, const QString& fileName);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void recursAddElements(QDomDocument&, const DirDetails&, QDomElement&, FileSearchFlags flags) const ;
|
bool recursExportToXml(QDomDocument& doc,QDomElement& e,const RsFileTree::DirData& dd) const;
|
||||||
void recursAddElements(QDomDocument&,const ColFileInfo&,QDomElement&) const;
|
bool recursParseXml(QDomDocument& doc, const QDomNode &e, RsFileTree::DirIndex dd) ;
|
||||||
void recursAddElements(
|
|
||||||
QDomDocument& doc, const RsFileTree& ft, uint32_t index,
|
// This function is used to populate a RsCollection from locally or remotly shared files.
|
||||||
QDomElement& e ) const;
|
void recursAddElements(RsFileTree::DirIndex parent, const DirDetails& dd, FileSearchFlags flags) ;
|
||||||
|
|
||||||
|
// This function is used to merge an existing RsFileTree into the RsCollection
|
||||||
|
void recursMergeTree(RsFileTree::DirIndex parent, const RsFileTree& tree, const RsFileTree::DirData &dd);
|
||||||
|
|
||||||
|
// check that the file is a valid rscollection file, and not a lol bomb or some shit like this
|
||||||
|
static bool checkFile(const QString &fileName, RsCollectionErrorCode &error);
|
||||||
|
|
||||||
void recursCollectColFileInfos(const QDomElement&,std::vector<ColFileInfo>& colFileInfos,const QString& current_dir,bool bad_chars_in_parent) const ;
|
|
||||||
// check that the file is a valid rscollection file, and not a lol bomb or some shit like this
|
|
||||||
static bool checkFile(const QString &fileName, bool showError);
|
|
||||||
// Auto Download recursively.
|
// Auto Download recursively.
|
||||||
void autoDownloadFiles(ColFileInfo colFileInfo, QString dlDir) const ;
|
void autoDownloadFiles(ColFileInfo colFileInfo, QString dlDir) const ;
|
||||||
|
|
||||||
QDomDocument _xml_doc ;
|
std::unique_ptr<RsFileTree> mFileTree;
|
||||||
QString _fileName ;
|
std::map<RsFileHash,RsFileTree::FileIndex> mHashes; // used to efficiently update files being hashed
|
||||||
bool _saved;
|
|
||||||
QDomElement _root ;
|
|
||||||
|
|
||||||
friend class RsCollectionDialog ;
|
friend class RsCollectionDialog ;
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,8 +18,10 @@
|
|||||||
* *
|
* *
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include "ui_RsCollectionDialog.h"
|
#include "ui_RsCollectionDialog.h"
|
||||||
#include "RsCollection.h"
|
#include "RsCollection.h"
|
||||||
|
#include "RsCollectionModel.h"
|
||||||
#include <QFileSystemModel>
|
#include <QFileSystemModel>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
@ -30,33 +32,45 @@ class RsCollectionDialog: public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RsCollectionDialog(const QString& filename
|
|
||||||
, const std::vector<ColFileInfo> &colFileInfos
|
|
||||||
, const bool& creation
|
|
||||||
, const bool& readOnly = false) ;
|
|
||||||
virtual ~RsCollectionDialog();
|
virtual ~RsCollectionDialog();
|
||||||
|
|
||||||
|
// Open new collection
|
||||||
|
static bool openNewCollection(const RsFileTree &tree = RsFileTree());
|
||||||
|
|
||||||
|
// Edit existing collection
|
||||||
|
static bool editExistingCollection(const QString& fileName, bool showError = true);
|
||||||
|
|
||||||
|
// Open existing collection for download
|
||||||
|
static bool openExistingCollection(const QString& fileName, bool showError = true);
|
||||||
|
|
||||||
|
// Open existing collection for download
|
||||||
|
static bool downloadFiles(const RsCollection& collection);
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *obj, QEvent *ev);
|
static QString errorString(RsCollection::RsCollectionErrorCode code);
|
||||||
|
|
||||||
|
void init(const QString& collectionFileName);
|
||||||
|
|
||||||
|
enum RsCollectionDialogMode {
|
||||||
|
UNKNOWN = 0x00,
|
||||||
|
EDIT = 0x01,
|
||||||
|
DOWNLOAD = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
RsCollectionDialog(const QString& filename, RsCollectionDialogMode mode) ;
|
||||||
|
RsCollectionDialog(const RsCollection& coll, RsCollectionDialogMode mode) ;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void directoryLoaded(QString dirLoaded);
|
void directoryLoaded(QString dirLoaded);
|
||||||
void updateSizes() ;
|
void updateSizes() ;
|
||||||
void changeFileName() ;
|
void changeFileName() ;
|
||||||
void add() ;
|
void addSelection() ;
|
||||||
void addRecursive() ;
|
void addSelectionRecursive() ;
|
||||||
void remove() ;
|
void remove() ;
|
||||||
void chooseDestinationDirectory();
|
void chooseDestinationDirectory();
|
||||||
void setDestinationDirectory();
|
void setDestinationDirectory();
|
||||||
void openDestinationDirectoryMenu();
|
void openDestinationDirectoryMenu();
|
||||||
void processItem(QMap<QString, QString> &dirToAdd
|
|
||||||
, int &index
|
|
||||||
, ColFileInfo &parent
|
|
||||||
) ;
|
|
||||||
void makeDir() ;
|
void makeDir() ;
|
||||||
void fileHashingFinished(QList<HashedFile> hashedFiles) ;
|
void fileHashingFinished(QList<HashedFile> hashedFiles) ;
|
||||||
void itemChanged(QTreeWidgetItem* item,int col) ;
|
|
||||||
void updateRemoveDuplicate(bool checked);
|
|
||||||
void cancel() ;
|
void cancel() ;
|
||||||
void download() ;
|
void download() ;
|
||||||
void save() ;
|
void save() ;
|
||||||
@ -66,26 +80,20 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void processSettings(bool bLoad) ;
|
void processSettings(bool bLoad) ;
|
||||||
QTreeWidgetItem* getRootItem();
|
void addSelection(bool recursive) ;
|
||||||
bool updateList();
|
|
||||||
bool addChild(QTreeWidgetItem *parent, const std::vector<ColFileInfo> &child);
|
|
||||||
bool removeItem(QTreeWidgetItem *item, bool &removeOnlyFile) ;
|
|
||||||
void addRecursive(bool recursive) ;
|
|
||||||
bool addAllChild(QFileInfo &fileInfoParent
|
|
||||||
, QMap<QString, QString > &dirToAdd
|
|
||||||
, QStringList &fileToHash
|
|
||||||
, int &count);
|
|
||||||
void saveChild(QTreeWidgetItem *parentItem, ColFileInfo *parentInfo = NULL);
|
|
||||||
|
|
||||||
Ui::RsCollectionDialog ui;
|
Ui::RsCollectionDialog ui;
|
||||||
QString _fileName ;
|
|
||||||
const bool _creationMode ;
|
RsCollectionDialogMode _mode;
|
||||||
const bool _readOnly;
|
|
||||||
std::vector<ColFileInfo> _newColFileInfos ;
|
|
||||||
|
|
||||||
QFileSystemModel *_dirModel;
|
QFileSystemModel *_dirModel;
|
||||||
QSortFilterProxyModel *_tree_proxyModel;
|
QSortFilterProxyModel *_tree_proxyModel;
|
||||||
QItemSelectionModel *_selectionProxy;
|
QItemSelectionModel *_selectionProxy;
|
||||||
bool _dirLoaded;
|
bool _dirLoaded;
|
||||||
QHash<QString,QString> _listOfFilesAddedInDir;
|
QHash<QString,QString> _listOfFilesAddedInDir;
|
||||||
|
|
||||||
|
RsCollectionModel *mCollectionModel;
|
||||||
|
RsCollection *mCollection;
|
||||||
|
|
||||||
|
std::map<QString,RsFileHash> mFilesBeingHashed; // map of file path vs. temporary ID used for the file while hashing
|
||||||
};
|
};
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>600</width>
|
<width>761</width>
|
||||||
<height>400</height>
|
<height>434</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="contextMenuPolicy">
|
<property name="contextMenuPolicy">
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<string>Collection</string>
|
<string>Collection</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowIcon">
|
<property name="windowIcon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset>
|
||||||
<normaloff>:/images/mimetypes/rscollection-16.png</normaloff>:/images/mimetypes/rscollection-16.png</iconset>
|
<normaloff>:/images/mimetypes/rscollection-16.png</normaloff>:/images/mimetypes/rscollection-16.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeGripEnabled">
|
<property name="sizeGripEnabled">
|
||||||
@ -157,7 +157,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="_changeFile">
|
<widget class="QToolButton" name="_changeFile">
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>21</width>
|
<width>21</width>
|
||||||
@ -170,6 +170,10 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/browsable_blue_128.png</normaloff>:/icons/browsable_blue_128.png</iconset>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@ -283,7 +287,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/feedback_arrow.png</normaloff>:/images/feedback_arrow.png</iconset>
|
<normaloff>:/images/start.png</normaloff>:/images/start.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -309,7 +313,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/update.png</normaloff>:/images/update.png</iconset>
|
<normaloff>:/images/startall.png</normaloff>:/images/startall.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -334,8 +338,8 @@
|
|||||||
<string notr="true"/>
|
<string notr="true"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/deletemail24.png</normaloff>:/images/deletemail24.png</iconset>
|
<normaloff>:/images/delete.png</normaloff>:/images/delete.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -382,7 +386,7 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QTreeWidget" name="_fileEntriesTW">
|
<widget class="QTreeView" name="_fileEntriesTW">
|
||||||
<property name="editTriggers">
|
<property name="editTriggers">
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
</property>
|
</property>
|
||||||
@ -398,11 +402,6 @@
|
|||||||
<property name="allColumnsShowFocus">
|
<property name="allColumnsShowFocus">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">1</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -411,26 +410,6 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="buttons_HL">
|
<layout class="QHBoxLayout" name="buttons_HL">
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="_removeDuplicate_CB">
|
|
||||||
<property name="text">
|
|
||||||
<string>Remove Duplicate</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="buttons_HSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="downloadFolder_LB">
|
<widget class="QLabel" name="downloadFolder_LB">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -451,6 +430,12 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="downloadFolder_LE">
|
<widget class="QLineEdit" name="downloadFolder_LE">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="contextMenuPolicy">
|
<property name="contextMenuPolicy">
|
||||||
<enum>Qt::CustomContextMenu</enum>
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -462,6 +447,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="_cancel_PB">
|
<widget class="QPushButton" name="_cancel_PB">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -517,7 +515,7 @@
|
|||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc"/>
|
<include location="../images.qrc"/>
|
||||||
<include location="../../../../plugins/FeedReader/gui/FeedReader_images.qrc"/>
|
<include location="../icons.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
616
retroshare-gui/src/gui/common/RsCollectionModel.cpp
Normal file
616
retroshare-gui/src/gui/common/RsCollectionModel.cpp
Normal file
@ -0,0 +1,616 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <QBrush>
|
||||||
|
|
||||||
|
#include "RsCollectionModel.h"
|
||||||
|
|
||||||
|
// #define DEBUG_COLLECTION_MODEL 1
|
||||||
|
|
||||||
|
static const int COLLECTION_MODEL_FILENAME = 0;
|
||||||
|
static const int COLLECTION_MODEL_SIZE = 1;
|
||||||
|
static const int COLLECTION_MODEL_HASH = 2;
|
||||||
|
static const int COLLECTION_MODEL_COUNT = 3;
|
||||||
|
static const int COLLECTION_MODEL_NB_COLUMN = 4;
|
||||||
|
|
||||||
|
RsCollectionModel::RsCollectionModel(const RsCollection& col, QObject *parent)
|
||||||
|
: QAbstractItemModel(parent),mCollection(col)
|
||||||
|
{
|
||||||
|
postMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::ostream& operator<<(std::ostream& o,const RsCollectionModel::EntryIndex& i)
|
||||||
|
{
|
||||||
|
return o << ((i.is_file)?("File"):"Dir") << " with index " << (int)i.index ;
|
||||||
|
}
|
||||||
|
static std::ostream& operator<<(std::ostream& o,const QModelIndex& i)
|
||||||
|
{
|
||||||
|
return o << "QModelIndex (row " << i.row() << ", ref " << i.internalId() << ")" ;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Indernal Id is always a quintptr_t (basically a uint with the size of a pointer). Depending on the
|
||||||
|
// Indernal Id is always a quintptr_t (basically a uint with the size of a pointer). Depending on the
|
||||||
|
// architecture, the pointer may have 4 or 8 bytes. We use the low-level bit for type (0=dir, 1=file) and
|
||||||
|
// the remaining bits for the index (which will be accordingly understood as a FileIndex or a DirIndex)
|
||||||
|
// This way, index 0 is always the top dir.
|
||||||
|
|
||||||
|
bool RsCollectionModel::convertIndexToInternalId(const EntryIndex& e,quintptr& ref)
|
||||||
|
{
|
||||||
|
ref = (e.index << 1) | e.is_file;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsCollectionModel::convertInternalIdToIndex(quintptr ref, EntryIndex& e)
|
||||||
|
{
|
||||||
|
e.is_file = (bool)(ref & 1);
|
||||||
|
e.index = ref >> 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RsCollectionModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << "Asking rowCount of " << parent << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(parent.column() >= COLLECTION_MODEL_NB_COLUMN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!parent.isValid())
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << " root! returning " << mCollection.fileTree().directoryData(0).subdirs.size()
|
||||||
|
+ mCollection.fileTree().directoryData(0).subfiles.size() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return mCollection.fileTree().directoryData(0).subdirs.size()
|
||||||
|
+ mCollection.fileTree().directoryData(0).subfiles.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntryIndex i;
|
||||||
|
if(!convertInternalIdToIndex(parent.internalId(),i))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(i.is_file)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << " file: returning 0" << std::endl;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << " dir: returning " << mCollection.fileTree().directoryData(i.index).subdirs.size() + mCollection.fileTree().directoryData(i.index).subfiles.size()
|
||||||
|
<< std::endl;
|
||||||
|
#endif
|
||||||
|
return mCollection.fileTree().directoryData(i.index).subdirs.size() + mCollection.fileTree().directoryData(i.index).subfiles.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsCollectionModel::hasChildren(const QModelIndex & parent) const
|
||||||
|
{
|
||||||
|
if(!parent.isValid())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
EntryIndex i;
|
||||||
|
if(!convertInternalIdToIndex(parent.internalId(),i))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(i.is_file)
|
||||||
|
return false;
|
||||||
|
else if(mCollection.fileTree().directoryData(i.index).subdirs.size() + mCollection.fileTree().directoryData(i.index).subfiles.size() > 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RsCollectionModel::columnCount(const QModelIndex&) const
|
||||||
|
{
|
||||||
|
return COLLECTION_MODEL_NB_COLUMN;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RsCollectionModel::headerData(int section, Qt::Orientation,int role) const
|
||||||
|
{
|
||||||
|
if(role == Qt::DisplayRole)
|
||||||
|
switch(section)
|
||||||
|
{
|
||||||
|
case 0: return tr("File");
|
||||||
|
case 1: return tr("Size");
|
||||||
|
case 2: return tr("Hash");
|
||||||
|
case 3: return tr("Count");
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex RsCollectionModel::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;
|
||||||
|
|
||||||
|
if(!parent.isValid()) // root
|
||||||
|
{
|
||||||
|
parent_index.is_file = false;
|
||||||
|
parent_index.index = 0;
|
||||||
|
}
|
||||||
|
else if(!convertInternalIdToIndex(parent.internalId(),parent_index))
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
if(parent_index.is_file || parent_index.index >= mCollection.fileTree().numDirs())
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
const auto& parentData(mCollection.fileTree().directoryData(parent_index.index));
|
||||||
|
|
||||||
|
if((size_t)row < parentData.subdirs.size())
|
||||||
|
{
|
||||||
|
EntryIndex e;
|
||||||
|
e.is_file = false;
|
||||||
|
e.index = parentData.subdirs[row];
|
||||||
|
|
||||||
|
quintptr ref;
|
||||||
|
convertIndexToInternalId(e,ref);
|
||||||
|
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << "creating index for row " << row << " of parent " << parent << ". result is " << createIndex(row,column,ref) << std::endl;
|
||||||
|
#endif
|
||||||
|
return createIndex(row,column,ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((size_t)row < parentData.subdirs.size() + parentData.subfiles.size())
|
||||||
|
{
|
||||||
|
EntryIndex e;
|
||||||
|
e.is_file = true;
|
||||||
|
e.index = parentData.subfiles[row - parentData.subdirs.size()];
|
||||||
|
|
||||||
|
quintptr ref;
|
||||||
|
convertIndexToInternalId(e,ref);
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << "creating index for row " << row << " of parent " << parent << ". result is " << createIndex(row,column,ref) << std::endl;
|
||||||
|
#endif
|
||||||
|
return createIndex(row,column,ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags RsCollectionModel::flags ( const QModelIndex & index ) const
|
||||||
|
{
|
||||||
|
if(index.isValid() && index.column() == COLLECTION_MODEL_FILENAME)
|
||||||
|
{
|
||||||
|
EntryIndex e;
|
||||||
|
|
||||||
|
if(!convertInternalIdToIndex(index.internalId(),e))
|
||||||
|
return QAbstractItemModel::flags(index) ;
|
||||||
|
|
||||||
|
if(e.is_file)
|
||||||
|
return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
|
||||||
|
else
|
||||||
|
return QAbstractItemModel::flags(index) | Qt::ItemIsAutoTristate | Qt::ItemIsUserCheckable;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QAbstractItemModel::flags(index) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex RsCollectionModel::parent(const QModelIndex & index) const
|
||||||
|
{
|
||||||
|
if(!index.isValid())
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
EntryIndex i;
|
||||||
|
if(index.internalId()==0 || !convertInternalIdToIndex(index.internalId(),i))
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
EntryIndex p;
|
||||||
|
p.is_file = false; // all parents are directories
|
||||||
|
int row;
|
||||||
|
|
||||||
|
if(i.is_file)
|
||||||
|
{
|
||||||
|
p.index = mFileInfos[i.index].parent_index;
|
||||||
|
row = mFileInfos[i.index].parent_row;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p.index = mDirInfos[i.index].parent_index;
|
||||||
|
row = mDirInfos[i.index].parent_row;
|
||||||
|
}
|
||||||
|
|
||||||
|
quintptr ref;
|
||||||
|
convertIndexToInternalId(p,ref);
|
||||||
|
|
||||||
|
return createIndex(row,0,ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RsCollectionModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
EntryIndex i;
|
||||||
|
if(!convertInternalIdToIndex(index.internalId(),i))
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << "Asking data of " << i << std::endl;
|
||||||
|
#endif
|
||||||
|
switch(role)
|
||||||
|
{
|
||||||
|
case Qt::DisplayRole: return displayRole(i,index.column());
|
||||||
|
case Qt::DecorationRole: return decorationRole(i,index.column());
|
||||||
|
case Qt::CheckStateRole: return checkStateRole(i,index.column());
|
||||||
|
case Qt::TextColorRole: return textColorRole(i,index.column());
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsCollectionModel::setData(const QModelIndex& index,const QVariant& value,int role)
|
||||||
|
{
|
||||||
|
if(!index.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
EntryIndex e;
|
||||||
|
|
||||||
|
if(role==Qt::CheckStateRole && convertInternalIdToIndex(index.internalId(), e))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << "Setting check state of item " << index << " to " << value.toBool() << std::endl;
|
||||||
|
#endif
|
||||||
|
RsFileTree::DirIndex dir_index ;
|
||||||
|
|
||||||
|
if(e.is_file)
|
||||||
|
{
|
||||||
|
mFileInfos[e.index].is_checked = value.toBool();
|
||||||
|
dir_index = mFileInfos[e.index].parent_index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::function<void(RsFileTree::DirIndex,bool)> recursSetCheckFlag = [&](RsFileTree::DirIndex index,bool s) -> void
|
||||||
|
{
|
||||||
|
mDirInfos[index].check_state = (s)?SELECTED:UNSELECTED;
|
||||||
|
auto& dir_data(mCollection.fileTree().directoryData(index));
|
||||||
|
|
||||||
|
mDirInfos[index].total_size = 0;
|
||||||
|
mDirInfos[index].total_count = 0;
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<dir_data.subdirs.size();++i)
|
||||||
|
{
|
||||||
|
recursSetCheckFlag(dir_data.subdirs[i],s);
|
||||||
|
mDirInfos[index].total_size += mDirInfos[dir_data.subdirs[i]].total_size ;
|
||||||
|
mDirInfos[index].total_count+= mDirInfos[dir_data.subdirs[i]].total_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<dir_data.subfiles.size();++i)
|
||||||
|
{
|
||||||
|
mFileInfos[dir_data.subfiles[i]].is_checked = s;
|
||||||
|
|
||||||
|
if(s)
|
||||||
|
{
|
||||||
|
mDirInfos[index].total_size += mCollection.fileTree().fileData(dir_data.subfiles[i]).size;
|
||||||
|
++mDirInfos[index].total_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recursSetCheckFlag(e.index,value.toBool());
|
||||||
|
dir_index = mDirInfos[e.index].parent_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now go up the directories and update the check tristate flag, depending on whether the children are all checked/unchecked or mixed.
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
auto& dit(mDirInfos[dir_index]);
|
||||||
|
|
||||||
|
const RsFileTree::DirData& dir_data(mCollection.fileTree().directoryData(dir_index)); // get the directory data
|
||||||
|
|
||||||
|
bool locally_all_checked = true;
|
||||||
|
bool locally_all_unchecked = true;
|
||||||
|
|
||||||
|
dit.total_size = 0;
|
||||||
|
dit.total_count = 0;
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<dir_data.subdirs.size();++i)
|
||||||
|
{
|
||||||
|
const auto& dit2(mDirInfos[dir_data.subdirs[i]]);
|
||||||
|
dit.total_size += dit2.total_size;
|
||||||
|
dit.total_count += dit2.total_count;
|
||||||
|
|
||||||
|
if(dit2.check_state == UNSELECTED || dit2.check_state == PARTIALLY_SELECTED)
|
||||||
|
locally_all_checked = false;
|
||||||
|
|
||||||
|
if(dit2.check_state == SELECTED || dit2.check_state == PARTIALLY_SELECTED)
|
||||||
|
locally_all_unchecked = false;
|
||||||
|
}
|
||||||
|
for(uint32_t i=0;i<dir_data.subfiles.size();++i)
|
||||||
|
{
|
||||||
|
const auto& fit2(mFileInfos[dir_data.subfiles[i]]);
|
||||||
|
|
||||||
|
if(fit2.is_checked)
|
||||||
|
{
|
||||||
|
dit.total_size += mCollection.fileTree().fileData(dir_data.subfiles[i]).size;
|
||||||
|
++dit.total_count;
|
||||||
|
locally_all_unchecked = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
locally_all_checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(locally_all_checked)
|
||||||
|
dit.check_state = SELECTED;
|
||||||
|
else if(locally_all_unchecked)
|
||||||
|
dit.check_state = UNSELECTED;
|
||||||
|
else
|
||||||
|
dit.check_state = PARTIALLY_SELECTED;
|
||||||
|
|
||||||
|
if(dir_index == mCollection.fileTree().root())
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
dir_index = dit.parent_index; // get the directory data
|
||||||
|
|
||||||
|
}
|
||||||
|
while(true);
|
||||||
|
|
||||||
|
const auto& top_dir(mCollection.fileTree().directoryData(mCollection.fileTree().root()));
|
||||||
|
emit dataChanged(createIndex(0,0,(void*)NULL),
|
||||||
|
createIndex(top_dir.subdirs.size() + top_dir.subfiles.size() - 1,
|
||||||
|
COLLECTION_MODEL_NB_COLUMN-1,
|
||||||
|
(void*)NULL),
|
||||||
|
{ Qt::CheckStateRole });
|
||||||
|
|
||||||
|
emit sizesChanged();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return QAbstractItemModel::setData(index,value,role);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RsCollectionModel::textColorRole(const EntryIndex& i,int col) const
|
||||||
|
{
|
||||||
|
if(i.is_file && mFilesBeingHashed.find(mCollection.fileTree().fileData(i.index).hash) != mFilesBeingHashed.end())
|
||||||
|
return QVariant(QBrush(QColor::fromRgbF(0.1,0.9,0.2)));
|
||||||
|
else
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
QVariant RsCollectionModel::checkStateRole(const EntryIndex& i,int col) const
|
||||||
|
{
|
||||||
|
if(col == COLLECTION_MODEL_FILENAME)
|
||||||
|
{
|
||||||
|
if(i.is_file)
|
||||||
|
{
|
||||||
|
if(mFileInfos[i.index].is_checked)
|
||||||
|
return QVariant(Qt::Checked);
|
||||||
|
else
|
||||||
|
return QVariant(Qt::Unchecked);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(mDirInfos[i.index].check_state)
|
||||||
|
{
|
||||||
|
case SELECTED: return QVariant::fromValue((int)Qt::Checked);
|
||||||
|
case PARTIALLY_SELECTED: return QVariant::fromValue((int)Qt::PartiallyChecked);
|
||||||
|
default:
|
||||||
|
case UNSELECTED: return QVariant::fromValue((int)Qt::Unchecked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
QVariant RsCollectionModel::displayRole(const EntryIndex& i,int col) const
|
||||||
|
{
|
||||||
|
switch(col)
|
||||||
|
{
|
||||||
|
case COLLECTION_MODEL_FILENAME: if(i.is_file)
|
||||||
|
return QString::fromUtf8(mCollection.fileTree().fileData(i.index).name.c_str());
|
||||||
|
else
|
||||||
|
return QString::fromUtf8(mCollection.fileTree().directoryData(i.index).name.c_str());
|
||||||
|
|
||||||
|
case COLLECTION_MODEL_SIZE: if(i.is_file)
|
||||||
|
return QVariant((qulonglong)mCollection.fileTree().fileData(i.index).size) ;
|
||||||
|
else
|
||||||
|
return QVariant((qulonglong)mDirInfos[i.index].total_size);
|
||||||
|
|
||||||
|
case COLLECTION_MODEL_HASH: if(i.is_file)
|
||||||
|
{
|
||||||
|
if(mFilesBeingHashed.find(mCollection.fileTree().fileData(i.index).hash)!=mFilesBeingHashed.end())
|
||||||
|
return tr("[File is being hashed]");
|
||||||
|
else
|
||||||
|
return QString::fromStdString(mCollection.fileTree().fileData(i.index).hash.toStdString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
case COLLECTION_MODEL_COUNT: if(i.is_file)
|
||||||
|
return (qulonglong)mFileInfos[i.index].is_checked;
|
||||||
|
else
|
||||||
|
return (qulonglong)(mDirInfos[i.index].total_count);
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
QVariant RsCollectionModel::sortRole(const EntryIndex& i,int col) const
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
QVariant RsCollectionModel::decorationRole(const EntryIndex& i,int col) const
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
RsCollectionModel::EntryIndex RsCollectionModel::getIndex(const QModelIndex& i) const
|
||||||
|
{
|
||||||
|
EntryIndex res;
|
||||||
|
res.is_file = false;
|
||||||
|
res.index = 0;
|
||||||
|
|
||||||
|
convertInternalIdToIndex(i.internalId(),res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
bool RsCollectionModel::isChecked(EntryIndex i)
|
||||||
|
{
|
||||||
|
if(i.is_file)
|
||||||
|
return mFileInfos[i.index].is_checked;
|
||||||
|
else
|
||||||
|
return mDirInfos[i.index].check_state != DirCheckState::UNSELECTED;
|
||||||
|
}
|
||||||
|
void RsCollectionModel::notifyFilesBeingHashed(const std::list<RsFileHash>& files)
|
||||||
|
{
|
||||||
|
mFilesBeingHashed.insert(files.begin(),files.end());
|
||||||
|
}
|
||||||
|
void RsCollectionModel::fileHashingFinished(const RsFileHash& hash)
|
||||||
|
{
|
||||||
|
mFilesBeingHashed.erase(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsCollectionModel::preMods()
|
||||||
|
{
|
||||||
|
mUpdating = true;
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
}
|
||||||
|
void RsCollectionModel::postMods()
|
||||||
|
{
|
||||||
|
// update all the local structures
|
||||||
|
|
||||||
|
mDirInfos.clear();
|
||||||
|
mFileInfos.clear();
|
||||||
|
|
||||||
|
mDirInfos.resize(mCollection.fileTree().numDirs());
|
||||||
|
mFileInfos.resize(mCollection.fileTree().numFiles());
|
||||||
|
|
||||||
|
mDirInfos[0].parent_index = 0;
|
||||||
|
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
std::cerr << "Updating from tree: " << std::endl;
|
||||||
|
#endif
|
||||||
|
recursUpdateLocalStructures(mCollection.fileTree().root(),0);
|
||||||
|
|
||||||
|
mUpdating = false;
|
||||||
|
emit layoutChanged();
|
||||||
|
emit sizesChanged();
|
||||||
|
|
||||||
|
// debugDump();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsCollectionModel::recursUpdateLocalStructures(RsFileTree::DirIndex dir_index,int depth)
|
||||||
|
{
|
||||||
|
uint64_t total_size = 0;
|
||||||
|
uint64_t total_count = 0;
|
||||||
|
bool all_checked = true;
|
||||||
|
bool all_unchecked = false;
|
||||||
|
|
||||||
|
const auto& dd(mCollection.fileTree().directoryData(dir_index));
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<dd.subdirs.size();++i)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
for(int j=0;j<depth;++j) std::cerr << " ";
|
||||||
|
std::cerr << "Dir \"" << mCollection.fileTree().directoryData(dd.subdirs[i]).name << "\"" << std::endl ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
recursUpdateLocalStructures(dd.subdirs[i],depth+1);
|
||||||
|
|
||||||
|
auto& ref(mDirInfos[dd.subdirs[i]]);
|
||||||
|
|
||||||
|
total_size += ref.total_size;
|
||||||
|
total_count += ref.total_count;
|
||||||
|
|
||||||
|
ref.parent_index = dir_index;
|
||||||
|
ref.parent_row = i;
|
||||||
|
|
||||||
|
all_checked = all_checked && (ref.check_state == SELECTED);
|
||||||
|
all_unchecked = all_unchecked && (ref.check_state == UNSELECTED);
|
||||||
|
}
|
||||||
|
for(uint32_t i=0;i<dd.subfiles.size();++i)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_COLLECTION_MODEL
|
||||||
|
for(int j=0;j<depth;++j) std::cerr << " ";
|
||||||
|
std::cerr << "File \"" << mCollection.fileTree().fileData(dd.subfiles[i]).name << "\"" << std::endl;
|
||||||
|
#endif
|
||||||
|
auto& ref(mFileInfos[dd.subfiles[i]]);
|
||||||
|
|
||||||
|
if(ref.is_checked)
|
||||||
|
{
|
||||||
|
total_size += mCollection.fileTree().fileData(dd.subfiles[i]).size;
|
||||||
|
++total_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
ref.parent_index = dir_index;
|
||||||
|
ref.parent_row = i + dd.subdirs.size();
|
||||||
|
|
||||||
|
all_checked = all_checked && ref.is_checked;
|
||||||
|
all_unchecked = all_unchecked && !ref.is_checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& r(mDirInfos[dir_index]);
|
||||||
|
|
||||||
|
r.total_size = total_size;
|
||||||
|
r.total_count = total_count;
|
||||||
|
|
||||||
|
if(all_checked)
|
||||||
|
r.check_state = SELECTED;
|
||||||
|
else if(all_unchecked)
|
||||||
|
r.check_state = UNSELECTED;
|
||||||
|
else
|
||||||
|
r.check_state = PARTIALLY_SELECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsCollectionModel::debugDump()
|
||||||
|
{
|
||||||
|
std::function<void(RsFileTree::DirIndex,int)> recursDump = [&](RsFileTree::DirIndex indx,int depth) {
|
||||||
|
const auto& dir_data(mCollection.fileTree().directoryData(indx));
|
||||||
|
|
||||||
|
for(int i=0;i<depth;++i) std::cerr << " ";
|
||||||
|
std::cerr << "Directory: \"" << dir_data.name << "\" total_size: " << mDirInfos[indx].total_size << " cnt: " << mDirInfos[indx].total_count << std::endl;
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<dir_data.subdirs.size();++i)
|
||||||
|
recursDump(dir_data.subdirs[i],depth+1);
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<dir_data.subfiles.size();++i)
|
||||||
|
{
|
||||||
|
for(int i=0;i<depth+1;++i) std::cerr << " ";
|
||||||
|
std::cerr << "File: \"" << mCollection.fileTree().fileData(dir_data.subfiles[i]).name << "\"" << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::cerr << "mCollectionModel data: " << std::endl;
|
||||||
|
|
||||||
|
recursDump(mCollection.fileTree().root(),0);
|
||||||
|
|
||||||
|
std::function<void(QModelIndex index,int)> recursDump2 = [&](QModelIndex indx,int depth) {
|
||||||
|
|
||||||
|
for(int i=0;i<depth;++i) std::cerr << " ";
|
||||||
|
|
||||||
|
EntryIndex entry;
|
||||||
|
convertInternalIdToIndex(indx.internalId(),entry);
|
||||||
|
|
||||||
|
std::cerr << "Index: " << indx << " has_children: " << RsCollectionModel::hasChildren(indx)
|
||||||
|
<< ", rowCount: " << RsCollectionModel::rowCount(indx)
|
||||||
|
<< ", internalId: " << (uint64_t)indx.internalId()
|
||||||
|
<< ", type: " << (entry.is_file?"file":"dir") << " number " << entry.index
|
||||||
|
<< ", prow: " << (entry.is_file?mFileInfos[entry.index].parent_row:mDirInfos[entry.index].parent_row)
|
||||||
|
<< ", parent: " << RsCollectionModel::parent(indx)
|
||||||
|
<< ", display role: \"" << displayRole(entry,0).toString().toStdString()
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
for(int i=0;i<RsCollectionModel::rowCount(indx);++i)
|
||||||
|
recursDump2(RsCollectionModel::index(i,0,indx),depth+1);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::cerr << "mCollectionModel index structure: " << std::endl;
|
||||||
|
|
||||||
|
recursDump2(QModelIndex(),0);
|
||||||
|
|
||||||
|
std::cerr << "mCollectionModel internal data: " << std::endl;
|
||||||
|
std::cerr << "Directories: "<< std::endl;
|
||||||
|
for(uint32_t i=0;i<mCollection.fileTree().numDirs();++i)
|
||||||
|
std::cerr << " " << i << ": "<< mCollection.fileTree().directoryData(i).name << std::endl;
|
||||||
|
std::cerr << "Files: "<< std::endl;
|
||||||
|
for(uint32_t i=0;i<mCollection.fileTree().numFiles();++i)
|
||||||
|
std::cerr << " " << i << ": " << mCollection.fileTree().fileData(i).name << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
108
retroshare-gui/src/gui/common/RsCollectionModel.h
Normal file
108
retroshare-gui/src/gui/common/RsCollectionModel.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
|
#include "RsCollection.h"
|
||||||
|
|
||||||
|
class RsCollectionModel: public QAbstractItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Roles{ FileNameRole = Qt::UserRole+1, SortRole = Qt::UserRole+2, FilterRole = Qt::UserRole+3 };
|
||||||
|
|
||||||
|
RsCollectionModel(const RsCollection& col, QObject *parent = 0);
|
||||||
|
virtual ~RsCollectionModel() = default;
|
||||||
|
|
||||||
|
/* Callback from Core */
|
||||||
|
void preMods(); // always call this before updating the RsCollection!
|
||||||
|
void postMods(); // always call this after updating the RsCollection!
|
||||||
|
|
||||||
|
/* Callback from GUI */
|
||||||
|
|
||||||
|
void update() ;
|
||||||
|
void filterItems(const std::list<std::string>& keywords, uint32_t& found) ;
|
||||||
|
|
||||||
|
// Overloaded from QAbstractItemModel
|
||||||
|
virtual QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex() ) const override;
|
||||||
|
virtual QModelIndex parent ( const QModelIndex & index ) const override;
|
||||||
|
|
||||||
|
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
virtual bool hasChildren(const QModelIndex & parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||||
|
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
virtual bool setData(const QModelIndex& index,const QVariant& value,int role) override;
|
||||||
|
virtual Qt::ItemFlags flags ( const QModelIndex & index ) const override;
|
||||||
|
#ifdef TODO
|
||||||
|
virtual QStringList mimeTypes () const override;
|
||||||
|
virtual QMimeData * mimeData ( const QModelIndexList & indexes ) const override;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
|
||||||
|
virtual Qt::DropActions supportedDragActions() const override;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct EntryIndex {
|
||||||
|
bool is_file; // false=dir, true=file
|
||||||
|
uint64_t index;
|
||||||
|
};
|
||||||
|
uint64_t totalSize() const { return mDirInfos[0].total_size; }
|
||||||
|
uint64_t totalSelected() const { return mDirInfos[0].total_count; }
|
||||||
|
|
||||||
|
void notifyFilesBeingHashed(const std::list<RsFileHash>& files);
|
||||||
|
void fileHashingFinished(const RsFileHash& hash);
|
||||||
|
bool isChecked(EntryIndex);
|
||||||
|
|
||||||
|
EntryIndex getIndex(const QModelIndex& i) const;
|
||||||
|
signals:
|
||||||
|
void sizesChanged(); // tells that the total size of the top level dir has changed (due to selection)
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool convertIndexToInternalId(const EntryIndex& e,quintptr& ref);
|
||||||
|
static bool convertInternalIdToIndex(quintptr ref, EntryIndex& e);
|
||||||
|
|
||||||
|
void recursUpdateLocalStructures(RsFileTree::DirIndex dir_index, int depth);
|
||||||
|
|
||||||
|
QVariant displayRole(const EntryIndex&,int col) const ;
|
||||||
|
QVariant sortRole(const EntryIndex&,int col) const ;
|
||||||
|
QVariant decorationRole(const EntryIndex&,int col) const ;
|
||||||
|
QVariant checkStateRole(const EntryIndex& i,int col) const;
|
||||||
|
QVariant textColorRole(const EntryIndex& i,int col) const;
|
||||||
|
//QVariant filterRole(const DirDetails& details,int coln) const;
|
||||||
|
|
||||||
|
void debugDump();
|
||||||
|
|
||||||
|
bool mUpdating ;
|
||||||
|
|
||||||
|
const RsCollection& mCollection;
|
||||||
|
|
||||||
|
enum DirCheckState: uint8_t {
|
||||||
|
UNSELECTED = 0x00,
|
||||||
|
PARTIALLY_SELECTED = 0x01,
|
||||||
|
SELECTED = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ModelDirInfo {
|
||||||
|
ModelDirInfo() :parent_index(0),parent_row(0),check_state(SELECTED),total_size(0),total_count(0){}
|
||||||
|
|
||||||
|
RsFileTree::DirIndex parent_index; // index of the parent
|
||||||
|
RsFileTree::DirIndex parent_row; // row of that child, in this parent
|
||||||
|
DirCheckState check_state;
|
||||||
|
uint64_t total_size;
|
||||||
|
uint64_t total_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ModelFileInfo {
|
||||||
|
ModelFileInfo() :parent_index(0),parent_row(0),is_checked(true){}
|
||||||
|
|
||||||
|
RsFileTree::DirIndex parent_index; // index of the parent
|
||||||
|
RsFileTree::DirIndex parent_row; // row of that child, in this parent
|
||||||
|
bool is_checked;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<ModelFileInfo> mFileInfos;
|
||||||
|
std::vector<ModelDirInfo> mDirInfos;
|
||||||
|
|
||||||
|
std::set<RsFileHash> mFilesBeingHashed;
|
||||||
|
|
||||||
|
// std::set<void*> mFilteredPointers ;
|
||||||
|
};
|
@ -21,19 +21,13 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include "RsCollection.h"
|
#include "RsCollectionDialog.h"
|
||||||
#include "RsUrlHandler.h"
|
#include "RsUrlHandler.h"
|
||||||
|
|
||||||
bool RsUrlHandler::openUrl(const QUrl& url)
|
bool RsUrlHandler::openUrl(const QUrl& url)
|
||||||
{
|
{
|
||||||
if(url.scheme() == QString("file") && url.toLocalFile().endsWith("."+RsCollection::ExtensionString))
|
if(url.scheme() == QString("file") && url.toLocalFile().endsWith("."+RsCollection::ExtensionString))
|
||||||
{
|
return RsCollectionDialog::openExistingCollection(url.toLocalFile());
|
||||||
RsCollection collection ;
|
|
||||||
if(collection.load(url.toLocalFile()))
|
|
||||||
{
|
|
||||||
collection.downloadFiles() ;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QDesktopServices::openUrl(url) ;
|
return QDesktopServices::openUrl(url) ;
|
||||||
}
|
}
|
||||||
|
@ -49,46 +49,41 @@
|
|||||||
* #define DEBUG_ITEM 1
|
* #define DEBUG_ITEM 1
|
||||||
****/
|
****/
|
||||||
|
|
||||||
ChannelsCommentsItem::ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData& group_meta, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
|
// ChannelsCommentsItem::ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData& group_meta, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
|
||||||
GxsFeedItem(feedHolder, feedId, group_meta.mGroupId, messageId, isHome, rsGxsChannels, autoUpdate),
|
// GxsFeedItem(feedHolder, feedId, group_meta.mGroupId, messageId, isHome, rsGxsChannels, autoUpdate),
|
||||||
mGroupMeta(group_meta)
|
// mGroupMeta(group_meta)
|
||||||
|
// {
|
||||||
|
// mLoadingGroup = false;
|
||||||
|
// mLoadingMessage = false;
|
||||||
|
// mLoadingComment = false;
|
||||||
|
//
|
||||||
|
// mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
|
||||||
|
// mPost.mMeta.mGroupId = mGroupMeta.mGroupId;
|
||||||
|
//
|
||||||
|
// QVector<RsGxsMessageId> v;
|
||||||
|
// //bool self = false;
|
||||||
|
//
|
||||||
|
// for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
|
||||||
|
// v.push_back(*it) ;
|
||||||
|
//
|
||||||
|
// if(older_versions.find(messageId) == older_versions.end())
|
||||||
|
// v.push_back(messageId);
|
||||||
|
//
|
||||||
|
// setMessageVersions(v) ;
|
||||||
|
// setup();
|
||||||
|
//
|
||||||
|
// // no call to loadGroup() here because we have it already.
|
||||||
|
// }
|
||||||
|
|
||||||
|
ChannelsCommentsItem::ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &commentId, const RsGxsMessageId &threadId, bool isHome, bool autoUpdate) :
|
||||||
|
GxsFeedItem(feedHolder, feedId, groupId, commentId, isHome, rsGxsChannels, autoUpdate), // this one should be in GxsFeedItem
|
||||||
|
mThreadId(threadId)
|
||||||
{
|
{
|
||||||
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
|
mLoading= false;
|
||||||
mPost.mMeta.mGroupId = mGroupMeta.mGroupId;
|
|
||||||
|
|
||||||
QVector<RsGxsMessageId> v;
|
QVector<RsGxsMessageId> v;
|
||||||
//bool self = false;
|
|
||||||
|
|
||||||
for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
|
|
||||||
v.push_back(*it) ;
|
|
||||||
|
|
||||||
if(older_versions.find(messageId) == older_versions.end())
|
|
||||||
v.push_back(messageId);
|
|
||||||
|
|
||||||
setMessageVersions(v) ;
|
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
// no call to loadGroup() here because we have it already.
|
|
||||||
}
|
|
||||||
|
|
||||||
ChannelsCommentsItem::ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
|
|
||||||
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, autoUpdate) // this one should be in GxsFeedItem
|
|
||||||
{
|
|
||||||
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
|
|
||||||
|
|
||||||
QVector<RsGxsMessageId> v;
|
|
||||||
//bool self = false;
|
|
||||||
|
|
||||||
for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
|
|
||||||
v.push_back(*it) ;
|
|
||||||
|
|
||||||
if(older_versions.find(messageId) == older_versions.end())
|
|
||||||
v.push_back(messageId);
|
|
||||||
|
|
||||||
setMessageVersions(v) ;
|
|
||||||
setup();
|
|
||||||
|
|
||||||
loadGroup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsCommentsItem::paintEvent(QPaintEvent *e)
|
void ChannelsCommentsItem::paintEvent(QPaintEvent *e)
|
||||||
@ -99,21 +94,22 @@ void ChannelsCommentsItem::paintEvent(QPaintEvent *e)
|
|||||||
if(!mLoaded)
|
if(!mLoaded)
|
||||||
{
|
{
|
||||||
mLoaded = true ;
|
mLoaded = true ;
|
||||||
|
load();
|
||||||
std::set<RsGxsMessageId> older_versions; // not so nice. We need to use std::set everywhere
|
}
|
||||||
for(auto& m:messageVersions())
|
|
||||||
older_versions.insert(m);
|
|
||||||
|
|
||||||
fill();
|
|
||||||
requestMessage();
|
|
||||||
requestComment();
|
|
||||||
}
|
|
||||||
|
|
||||||
GxsFeedItem::paintEvent(e) ;
|
GxsFeedItem::paintEvent(e) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelsCommentsItem::~ChannelsCommentsItem()
|
ChannelsCommentsItem::~ChannelsCommentsItem()
|
||||||
{
|
{
|
||||||
|
auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(300);
|
||||||
|
|
||||||
|
while( mLoading && std::chrono::steady_clock::now() < timeout )
|
||||||
|
{
|
||||||
|
RsDbg() << __PRETTY_FUNCTION__ << " is Waiting for data to load " << std::endl;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
|
||||||
delete(ui);
|
delete(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,21 +178,19 @@ void ChannelsCommentsItem::setup()
|
|||||||
ui->expandFrame->hide();
|
ui->expandFrame->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChannelsCommentsItem::setPost(const RsGxsChannelPost &post, bool doFill)
|
bool ChannelsCommentsItem::setPost(const RsGxsChannelPost& post, bool doFill)
|
||||||
{
|
{
|
||||||
if (groupId() != post.mMeta.mGroupId || messageId() != post.mMeta.mMsgId) {
|
|
||||||
std::cerr << "ChannelsCommentsItem::setPost() - Wrong id, cannot set post";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mPost = post;
|
mPost = post;
|
||||||
|
|
||||||
if (doFill) {
|
if (doFill)
|
||||||
fill();
|
fill();
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
bool ChannelsCommentsItem::setMissingPost()
|
||||||
|
{
|
||||||
|
fill(true);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ChannelsCommentsItem::getTitleLabel()
|
QString ChannelsCommentsItem::getTitleLabel()
|
||||||
@ -230,168 +224,148 @@ void ChannelsCommentsItem::loadComments()
|
|||||||
|
|
||||||
void ChannelsCommentsItem::loadGroup()
|
void ChannelsCommentsItem::loadGroup()
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_ITEM
|
//#ifdef DEBUG_ITEM
|
||||||
std::cerr << "GxsChannelGroupItem::loadGroup()";
|
// std::cerr << "GxsChannelGroupItem::loadGroup()";
|
||||||
std::cerr << std::endl;
|
// std::cerr << std::endl;
|
||||||
#endif
|
//#endif
|
||||||
|
// if(mLoading)
|
||||||
RsThread::async([this]()
|
// return;
|
||||||
{
|
//
|
||||||
// 1 - get group data
|
// mLoading= true;
|
||||||
|
//
|
||||||
std::vector<RsGxsChannelGroup> groups;
|
// std::cerr << "Loading group" << std::endl;
|
||||||
const std::list<RsGxsGroupId> groupIds = { groupId() };
|
// RsThread::async([this]()
|
||||||
|
// {
|
||||||
if(!rsGxsChannels->getChannelsInfo(groupIds,groups)) // would be better to call channel Summaries for a single group
|
// // 1 - get group data
|
||||||
{
|
//
|
||||||
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
|
// std::vector<RsGxsChannelGroup> groups;
|
||||||
return;
|
// const std::list<RsGxsGroupId> groupIds = { groupId() };
|
||||||
}
|
//
|
||||||
|
// if(!rsGxsChannels->getChannelsInfo(groupIds,groups)) // would be better to call channel Summaries for a single group
|
||||||
if (groups.size() != 1)
|
// {
|
||||||
{
|
// RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
|
||||||
std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items";
|
// return;
|
||||||
std::cerr << std::endl;
|
// }
|
||||||
return;
|
//
|
||||||
}
|
// if (groups.size() != 1)
|
||||||
RsGxsChannelGroup group(groups[0]);
|
// {
|
||||||
|
// std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items";
|
||||||
RsQThreadUtils::postToObject( [group,this]()
|
// std::cerr << std::endl;
|
||||||
{
|
// return;
|
||||||
/* 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
|
// RsGxsChannelGroup group(groups[0]);
|
||||||
* after a blocking call to RetroShare API complete */
|
//
|
||||||
|
// RsQThreadUtils::postToObject( [group,this]()
|
||||||
mGroupMeta = group.mMeta;
|
// {
|
||||||
|
// /* Here it goes any code you want to be executed on the Qt Gui
|
||||||
}, this );
|
// * thread, for example to update the data model with new information
|
||||||
});
|
// * after a blocking call to RetroShare API complete */
|
||||||
|
//
|
||||||
|
// mGroupMeta = group.mMeta;
|
||||||
|
// mLoading= false;
|
||||||
|
//
|
||||||
|
// std::cerr << "End loading group" << std::endl;
|
||||||
|
// }, this );
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
void ChannelsCommentsItem::loadMessage()
|
void ChannelsCommentsItem::load()
|
||||||
{
|
{
|
||||||
|
// This function loads everything that's needed:
|
||||||
|
// - the comment text
|
||||||
|
// - the comment parent message
|
||||||
|
|
||||||
#ifdef DEBUG_ITEM
|
#ifdef DEBUG_ITEM
|
||||||
std::cerr << "ChannelsCommentsItem::loadMessage()";
|
std::cerr << "ChannelsCommentsItem::loadMessage()";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
RsThread::async([this]()
|
if(mLoading)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mLoading= true;
|
||||||
|
|
||||||
|
RsThread::async([this]()
|
||||||
{
|
{
|
||||||
// 1 - get group data
|
// 1 - get group meta data
|
||||||
|
|
||||||
|
std::vector<RsGxsChannelGroup> groups;
|
||||||
|
const std::list<RsGxsGroupId> groupIds = { groupId() };
|
||||||
|
|
||||||
|
if(!rsGxsChannels->getChannelsInfo(groupIds,groups)) // would be better to call channel Summaries for a single group
|
||||||
|
{
|
||||||
|
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groups.size() != 1)
|
||||||
|
{
|
||||||
|
std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RsGxsChannelGroup group(groups[0]);
|
||||||
|
|
||||||
|
// 2 - get message and comment data
|
||||||
|
|
||||||
std::vector<RsGxsChannelPost> posts;
|
std::vector<RsGxsChannelPost> posts;
|
||||||
std::vector<RsGxsComment> comments;
|
std::vector<RsGxsComment> comments;
|
||||||
std::vector<RsGxsVote> votes;
|
std::vector<RsGxsVote> votes;
|
||||||
|
|
||||||
if(! rsGxsChannels->getChannelContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments,votes))
|
if(! rsGxsChannels->getChannelContent( groupId(), std::set<RsGxsMessageId>( { messageId(),mThreadId } ),posts,comments,votes))
|
||||||
{
|
{
|
||||||
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
|
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (posts.size() == 1)
|
// now that everything is in place, update the UI
|
||||||
{
|
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl;
|
|
||||||
#endif
|
|
||||||
RsGxsChannelPost post(posts[0]); // no reference to temporary here, because we pass this to a thread
|
|
||||||
|
|
||||||
RsQThreadUtils::postToObject( [post,this]() { setPost(post); }, this );
|
RsQThreadUtils::postToObject( [group,posts,comments,this]()
|
||||||
}
|
{
|
||||||
else if(comments.size() == 1)
|
/* 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
|
||||||
RsGxsComment cmt(comments[0]);
|
* after a blocking call to RetroShare API complete */
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << (void*)this << ": Obtained comment, setting messageId to threadID = " << cmt.mMeta.mThreadId << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RsQThreadUtils::postToObject( [cmt,this]()
|
mGroupMeta = group.mMeta;
|
||||||
{
|
|
||||||
uint32_t autorized_lines = (int)floor( (ui->avatarLabel->height() - ui->button_HL->sizeHint().height())
|
|
||||||
/ QFontMetricsF(ui->subjectLabel->font()).height());
|
|
||||||
|
|
||||||
ui->commLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(cmt.mComment.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_LINKS));
|
if(comments.size()==1)
|
||||||
|
{
|
||||||
|
RsGxsComment cmt(comments[0]);
|
||||||
|
|
||||||
ui->nameLabel->setId(cmt.mMeta.mAuthorId);
|
uint32_t autorized_lines = (int)floor( (ui->avatarLabel->height() - ui->button_HL->sizeHint().height())
|
||||||
ui->datetimeLabel->setText(DateTime::formatLongDateTime(cmt.mMeta.mPublishTs));
|
/ QFontMetricsF(ui->subjectLabel->font()).height());
|
||||||
|
|
||||||
RsIdentityDetails idDetails ;
|
ui->commLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(cmt.mComment.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_LINKS));
|
||||||
rsIdentity->getIdDetails(cmt.mMeta.mAuthorId,idDetails);
|
ui->nameLabel->setId(cmt.mMeta.mAuthorId);
|
||||||
QPixmap pixmap ;
|
ui->datetimeLabel->setText(DateTime::formatLongDateTime(cmt.mMeta.mPublishTs));
|
||||||
|
|
||||||
if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL))
|
RsIdentityDetails idDetails ;
|
||||||
pixmap = GxsIdDetails::makeDefaultIcon(cmt.mMeta.mAuthorId,GxsIdDetails::LARGE);
|
rsIdentity->getIdDetails(cmt.mMeta.mAuthorId,idDetails);
|
||||||
ui->avatarLabel->setPixmap(pixmap);
|
QPixmap pixmap ;
|
||||||
|
|
||||||
//Change this item to be uploaded with thread element.
|
if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL))
|
||||||
setMessageId(cmt.mMeta.mThreadId);
|
pixmap = GxsIdDetails::makeDefaultIcon(cmt.mMeta.mAuthorId,GxsIdDetails::LARGE);
|
||||||
requestMessage();
|
ui->avatarLabel->setPixmap(pixmap);
|
||||||
|
|
||||||
}, this );
|
//Change this item to be uploaded with thread element. This is really bad practice.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLoading=false;
|
||||||
|
removeItem();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
if (posts.size() == 1)
|
||||||
else
|
setPost(posts[0]);
|
||||||
{
|
else
|
||||||
#ifdef DEBUG_ITEM
|
setMissingPost();
|
||||||
std::cerr << "ChannelsCommentsItem::loadMessage() Wrong number of Items. Remove It.";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RsQThreadUtils::postToObject( [this]() { removeItem(); }, this );
|
emit sizeChanged(this);
|
||||||
}
|
mLoading=false;
|
||||||
});
|
|
||||||
|
}, this );
|
||||||
emit sizeChanged(this);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsCommentsItem::loadComment()
|
void ChannelsCommentsItem::fill(bool missing_post)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_ITEM
|
|
||||||
std::cerr << "ChannelsCommentsItem::loadComment()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RsThread::async([this]()
|
|
||||||
{
|
|
||||||
// 1 - get group data
|
|
||||||
|
|
||||||
std::set<RsGxsMessageId> msgIds;
|
|
||||||
|
|
||||||
for(auto MsgId: messageVersions())
|
|
||||||
msgIds.insert(MsgId);
|
|
||||||
|
|
||||||
std::vector<RsGxsChannelPost> posts;
|
|
||||||
std::vector<RsGxsComment> comments;
|
|
||||||
|
|
||||||
if(! rsGxsChannels->getChannelComments( groupId(),msgIds,comments))
|
|
||||||
{
|
|
||||||
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int comNb = comments.size();
|
|
||||||
|
|
||||||
RsQThreadUtils::postToObject( [comNb]()
|
|
||||||
{
|
|
||||||
QString sComButText = tr("Comment");
|
|
||||||
if (comNb == 1)
|
|
||||||
sComButText = sComButText.append("(1)");
|
|
||||||
else if(comNb > 1)
|
|
||||||
sComButText = tr("Comments ").append("(%1)").arg(comNb);
|
|
||||||
|
|
||||||
//ui->commentButton->setText(sComButText);
|
|
||||||
|
|
||||||
}, this );
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChannelsCommentsItem::fill()
|
|
||||||
{
|
|
||||||
/* fill in */
|
|
||||||
|
|
||||||
// if (isLoading()) {
|
|
||||||
// /* Wait for all requests */
|
|
||||||
//return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
#ifdef DEBUG_ITEM
|
#ifdef DEBUG_ITEM
|
||||||
std::cerr << "ChannelsCommentsItem::fill()";
|
std::cerr << "ChannelsCommentsItem::fill()";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
@ -399,9 +373,6 @@ void ChannelsCommentsItem::fill()
|
|||||||
|
|
||||||
mInFill = true;
|
mInFill = true;
|
||||||
|
|
||||||
//QString title;
|
|
||||||
//float f = QFontMetricsF(font()).height()/14.0 ;
|
|
||||||
|
|
||||||
if (!mIsHome)
|
if (!mIsHome)
|
||||||
{
|
{
|
||||||
if (mCloseOnRead && !IS_MSG_NEW(mPost.mMeta.mMsgStatus)) {
|
if (mCloseOnRead && !IS_MSG_NEW(mPost.mMeta.mMsgStatus)) {
|
||||||
@ -412,19 +383,14 @@ void ChannelsCommentsItem::fill()
|
|||||||
//title += link.toHtml();
|
//title += link.toHtml();
|
||||||
//ui->titleLabel->setText(title);
|
//ui->titleLabel->setText(title);
|
||||||
|
|
||||||
RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_CHANNEL, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, messageName());
|
RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_CHANNEL, mPost.mMeta.mGroupId, mPost.mMeta.mMsgId, messageName());
|
||||||
ui->subjectLabel->setText(msgLink.toHtml());
|
|
||||||
|
if(missing_post)
|
||||||
|
ui->subjectLabel->setText("[" + QObject::tr("Missing channel post")+"]");
|
||||||
|
else
|
||||||
|
ui->subjectLabel->setText(msgLink.toHtml());
|
||||||
|
|
||||||
if (IS_GROUP_SUBSCRIBED(mGroupMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroupMeta.mSubscribeFlags))
|
|
||||||
{
|
|
||||||
//ui->unsubscribeButton->setEnabled(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//ui->unsubscribeButton->setEnabled(false);
|
|
||||||
}
|
|
||||||
ui->readButton->hide();
|
ui->readButton->hide();
|
||||||
//ui->titleLabel->hide();
|
|
||||||
|
|
||||||
if (IS_MSG_NEW(mPost.mMeta.mMsgStatus)) {
|
if (IS_MSG_NEW(mPost.mMeta.mMsgStatus)) {
|
||||||
mCloseOnRead = true;
|
mCloseOnRead = true;
|
||||||
@ -432,19 +398,10 @@ void ChannelsCommentsItem::fill()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* subject */
|
if(missing_post)
|
||||||
//ui->titleLabel->setText(QString::fromUtf8(mPost.mMeta.mMsgName.c_str()));
|
ui->subjectLabel->setText("[" + QObject::tr("Missing channel post")+"]");
|
||||||
|
else
|
||||||
//uint32_t autorized_lines = (int)floor( (ui->avatarLabel->height() - ui->button_HL->sizeHint().height())
|
ui->subjectLabel->setText(RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), 2)) ;
|
||||||
// / QFontMetricsF(ui->subjectLabel->font()).height());
|
|
||||||
|
|
||||||
// fill first 4 lines of message. (csoler) Disabled the replacement of smileys and links, because the cost is too crazy
|
|
||||||
//ui->subjectLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
|
|
||||||
|
|
||||||
ui->subjectLabel->setText(RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), 2)) ;
|
|
||||||
|
|
||||||
//QString score = QString::number(post.mTopScore);
|
|
||||||
// scoreLabel->setText(score);
|
|
||||||
|
|
||||||
/* disable buttons: deletion facility not enabled with cache services yet */
|
/* disable buttons: deletion facility not enabled with cache services yet */
|
||||||
ui->clearButton->setEnabled(false);
|
ui->clearButton->setEnabled(false);
|
||||||
@ -467,50 +424,9 @@ void ChannelsCommentsItem::fill()
|
|||||||
mCloseOnRead = false;
|
mCloseOnRead = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// differences between Feed or Top of Comment.
|
|
||||||
if (mFeedHolder)
|
|
||||||
{
|
|
||||||
//ui->commentButton->show();
|
|
||||||
|
|
||||||
// Not yet functional
|
|
||||||
/*if (mPost.mCommentCount)
|
|
||||||
{
|
|
||||||
QString commentText = QString::number(mPost.mCommentCount);
|
|
||||||
commentText += " ";
|
|
||||||
commentText += tr("Comments");
|
|
||||||
ui->commentButton->setText(commentText);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui->commentButton->setText(tr("Comment"));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//ui->commentButton->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
// disable voting buttons - if they have already voted.
|
|
||||||
/*if (post.mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK)
|
|
||||||
{
|
|
||||||
voteUpButton->setEnabled(false);
|
|
||||||
voteDownButton->setEnabled(false);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (wasExpanded() || ui->expandFrame->isVisible()) {
|
|
||||||
fillExpandFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
mInFill = false;
|
mInFill = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsCommentsItem::fillExpandFrame()
|
|
||||||
{
|
|
||||||
//ui->msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ChannelsCommentsItem::messageName()
|
QString ChannelsCommentsItem::messageName()
|
||||||
{
|
{
|
||||||
return QString::fromUtf8(mPost.mMeta.mMsgName.c_str());
|
return QString::fromUtf8(mPost.mMeta.mMsgName.c_str());
|
||||||
@ -574,10 +490,6 @@ void ChannelsCommentsItem::doExpand(bool open)
|
|||||||
void ChannelsCommentsItem::expandFill(bool first)
|
void ChannelsCommentsItem::expandFill(bool first)
|
||||||
{
|
{
|
||||||
GxsFeedItem::expandFill(first);
|
GxsFeedItem::expandFill(first);
|
||||||
|
|
||||||
if (first) {
|
|
||||||
fillExpandFrame();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelsCommentsItem::toggle()
|
void ChannelsCommentsItem::toggle()
|
||||||
|
@ -42,12 +42,17 @@ public:
|
|||||||
// It can be used for all apparences of channel posts. But in rder to merge comments from the previous versions of the post, the list of
|
// It can be used for all apparences of channel posts. But in rder to merge comments from the previous versions of the post, the list of
|
||||||
// previous posts should be supplied. It's optional. If not supplied only the comments of the new version will be displayed.
|
// previous posts should be supplied. It's optional. If not supplied only the comments of the new version will be displayed.
|
||||||
|
|
||||||
ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
|
ChannelsCommentsItem(FeedHolder *feedHolder,
|
||||||
|
uint32_t feedId,
|
||||||
|
const RsGxsGroupId& groupId,
|
||||||
|
const RsGxsMessageId& commentId,
|
||||||
|
const RsGxsMessageId& threadId,
|
||||||
|
bool isHome,
|
||||||
|
bool autoUpdate);
|
||||||
|
|
||||||
// This one is used in channel thread widget. We don't want the group data to reload at every post, so we load it in the hosting
|
// This one is used in channel thread widget. We don't want the group data to reload at every post, so we load it in the hosting
|
||||||
// GxsChannelsPostsWidget and pass it to created items.
|
// GxsChannelsPostsWidget and pass it to created items.
|
||||||
|
// ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData& group, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
|
||||||
ChannelsCommentsItem(FeedHolder *feedHolder, uint32_t feedId, const RsGroupMetaData& group, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
|
|
||||||
|
|
||||||
virtual ~ChannelsCommentsItem();
|
virtual ~ChannelsCommentsItem();
|
||||||
|
|
||||||
@ -55,6 +60,7 @@ public:
|
|||||||
|
|
||||||
bool setGroup(const RsGxsChannelGroup& group, bool doFill = true);
|
bool setGroup(const RsGxsChannelGroup& group, bool doFill = true);
|
||||||
bool setPost(const RsGxsChannelPost& post, bool doFill = true);
|
bool setPost(const RsGxsChannelPost& post, bool doFill = true);
|
||||||
|
bool setMissingPost();
|
||||||
|
|
||||||
QString getTitleLabel();
|
QString getTitleLabel();
|
||||||
QString getMsgLabel();
|
QString getMsgLabel();
|
||||||
@ -85,8 +91,8 @@ protected:
|
|||||||
|
|
||||||
/* GxsFeedItem */
|
/* GxsFeedItem */
|
||||||
virtual QString messageName();
|
virtual QString messageName();
|
||||||
virtual void loadMessage();
|
virtual void loadMessage() override {}
|
||||||
virtual void loadComment();
|
virtual void loadComment() override {}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/* default stuff */
|
/* default stuff */
|
||||||
@ -104,17 +110,20 @@ signals:
|
|||||||
void vote(const RsGxsGrpMsgIdPair& msgId, bool up);
|
void vote(const RsGxsGrpMsgIdPair& msgId, bool up);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setup();
|
void load();
|
||||||
void fill();
|
void setup();
|
||||||
void fillExpandFrame();
|
void fill(bool missing_post=false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mInFill;
|
bool mInFill;
|
||||||
bool mCloseOnRead;
|
bool mCloseOnRead;
|
||||||
bool mLoaded;
|
bool mLoaded;
|
||||||
|
|
||||||
|
bool mLoading;
|
||||||
|
|
||||||
RsGroupMetaData mGroupMeta;
|
RsGroupMetaData mGroupMeta;
|
||||||
RsGxsChannelPost mPost;
|
RsGxsChannelPost mPost;
|
||||||
|
RsGxsMessageId mThreadId;
|
||||||
|
|
||||||
/** Qt Designer generated object */
|
/** Qt Designer generated object */
|
||||||
Ui::ChannelsCommentsItem *ui;
|
Ui::ChannelsCommentsItem *ui;
|
||||||
|
@ -131,15 +131,19 @@ void GxsCommentDialog::idChooserReady()
|
|||||||
|
|
||||||
void GxsCommentDialog::voterSelectionChanged( int index )
|
void GxsCommentDialog::voterSelectionChanged( int index )
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_COMMENT_DIALOG
|
||||||
std::cerr << "GxsCommentDialog::voterSelectionChanged(" << index << ")";
|
std::cerr << "GxsCommentDialog::voterSelectionChanged(" << index << ")";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
RsGxsId voterId;
|
RsGxsId voterId;
|
||||||
switch (ui->idChooser->getChosenId(voterId)) {
|
switch (ui->idChooser->getChosenId(voterId)) {
|
||||||
case GxsIdChooser::KnowId:
|
case GxsIdChooser::KnowId:
|
||||||
case GxsIdChooser::UnKnowId:
|
case GxsIdChooser::UnKnowId:
|
||||||
std::cerr << "GxsCommentDialog::voterSelectionChanged() => " << voterId;
|
#ifdef DEBUG_COMMENT_DIALOG
|
||||||
|
std::cerr << "GxsCommentDialog::voterSelectionChanged() => " << voterId;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
ui->treeWidget->setVoteId(voterId);
|
ui->treeWidget->setVoteId(voterId);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -160,8 +164,10 @@ void GxsCommentDialog::setCommentHeader(QWidget *header)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "GxsCommentDialog::setCommentHeader() Adding header to ui,postFrame";
|
#ifdef DEBUG_COMMENT_DIALOG
|
||||||
|
std::cerr << "GxsCommentDialog::setCommentHeader() Adding header to ui,postFrame";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
//header->setParent(ui->postFrame);
|
//header->setParent(ui->postFrame);
|
||||||
//ui->postFrame->setVisible(true);
|
//ui->postFrame->setVisible(true);
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include "GxsCommentTreeWidget.h"
|
#include "GxsCommentTreeWidget.h"
|
||||||
|
|
||||||
#include "gui/common/FilesDefs.h"
|
#include "gui/common/FilesDefs.h"
|
||||||
|
#include "gui/Identity/IdDialog.h"
|
||||||
|
#include "gui/MainWindow.h"
|
||||||
#include "gui/common/RSElidedItemDelegate.h"
|
#include "gui/common/RSElidedItemDelegate.h"
|
||||||
#include "gui/common/RSTreeWidgetItem.h"
|
#include "gui/common/RSTreeWidgetItem.h"
|
||||||
#include "gui/gxs/GxsCreateCommentDialog.h"
|
#include "gui/gxs/GxsCreateCommentDialog.h"
|
||||||
@ -346,6 +348,10 @@ void GxsCommentTreeWidget::customPopUpMenu(const QPoint& point)
|
|||||||
action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_VOTEDOWN), tr("Vote Down"), this, SLOT(voteDown()));
|
action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_VOTEDOWN), tr("Vote Down"), this, SLOT(voteDown()));
|
||||||
action->setDisabled(!item || mCurrentCommentMsgId.isNull() || mVoterId.isNull());
|
action->setDisabled(!item || mCurrentCommentMsgId.isNull() || mVoterId.isNull());
|
||||||
|
|
||||||
|
contextMnu.addSeparator();
|
||||||
|
|
||||||
|
action = contextMnu.addAction(tr("Show Author"), this, SLOT(showAuthor()));
|
||||||
|
action->setDisabled(!item || mCurrentCommentMsgId.isNull() || mVoterId.isNull());
|
||||||
|
|
||||||
if (!mCurrentCommentMsgId.isNull())
|
if (!mCurrentCommentMsgId.isNull())
|
||||||
{
|
{
|
||||||
@ -464,6 +470,19 @@ void GxsCommentTreeWidget::replyToComment()
|
|||||||
pcc.exec();
|
pcc.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GxsCommentTreeWidget::showAuthor()
|
||||||
|
{
|
||||||
|
/* window will destroy itself! */
|
||||||
|
IdDialog *idDialog = dynamic_cast<IdDialog*>(MainWindow::getPage(MainWindow::People));
|
||||||
|
|
||||||
|
if (!idDialog)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
MainWindow::showWindow(MainWindow::People);
|
||||||
|
idDialog->navigate(RsGxsId(mCurrentCommentAuthorId));
|
||||||
|
}
|
||||||
|
|
||||||
void GxsCommentTreeWidget::copyComment()
|
void GxsCommentTreeWidget::copyComment()
|
||||||
{
|
{
|
||||||
QString txt = dynamic_cast<QAction*>(sender())->data().toString();
|
QString txt = dynamic_cast<QAction*>(sender())->data().toString();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user