mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2026-04-03 09:11:33 +02:00
Compare commits
299 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
477614b8c9 | ||
|
|
9d060e5e55 | ||
|
|
50be2e067c | ||
|
|
ae28be4a10 | ||
|
|
fa2f52b551 | ||
|
|
658f6817ce | ||
|
|
28c401236b | ||
|
|
7d700a3c84 | ||
|
|
2c2cc5c23e | ||
|
|
94db2f82a2 | ||
|
|
d967ebac9a | ||
|
|
6b5b3c96cf | ||
|
|
a8bf75d496 | ||
|
|
bb34de2bd8 | ||
|
|
b146654474 | ||
|
|
c897564d28 | ||
|
|
ae9bc786ad | ||
|
|
b2d85cc4bf | ||
|
|
ac505aac0e | ||
|
|
4eac71a032 | ||
|
|
fa29fc4028 | ||
|
|
f352af7ffb | ||
|
|
d7098343a2 | ||
|
|
908f4d34e3 | ||
|
|
78c7aed3b9 | ||
|
|
a8986124b8 | ||
|
|
57ec1cdda4 | ||
|
|
9dc47438c9 | ||
|
|
d6a0a5272a | ||
|
|
47ac10fb8e | ||
|
|
459a17bd7e | ||
|
|
de65b6fb7e | ||
|
|
6ddfc80672 | ||
|
|
048cf3b23e | ||
|
|
3c958dea20 | ||
|
|
0b420c5fe6 | ||
|
|
bb7d330516 | ||
|
|
795c29d5bd | ||
|
|
ad04116c00 | ||
|
|
42b9dec1d0 | ||
|
|
51e398d4f4 | ||
|
|
feee0bf62b | ||
|
|
f6dee2b10f | ||
|
|
57fc438b91 | ||
|
|
aa5b62c931 | ||
|
|
f089fa34fc | ||
|
|
200032c9cb | ||
|
|
6a294bb4a0 | ||
|
|
4aa2e2e8c3 | ||
|
|
4cd7095a40 | ||
|
|
eb28fe9990 | ||
|
|
fa5c1eff25 | ||
|
|
1dca017537 | ||
|
|
9ff1a30dc4 | ||
|
|
4f0ff154d3 | ||
|
|
981a4ee240 | ||
|
|
378dd744fb | ||
|
|
d38e829330 | ||
|
|
ad65b6fdf3 | ||
|
|
ea6f3be374 | ||
|
|
85d217ec95 | ||
|
|
e8213242a9 | ||
|
|
0c603944b8 | ||
|
|
559187df6c | ||
|
|
eb00500b0b | ||
|
|
876f69dc7d | ||
|
|
33605d7f65 | ||
|
|
492fc846df | ||
|
|
febf206704 | ||
|
|
e1eeaadaff | ||
|
|
4f17366262 | ||
|
|
a8ac89c20c | ||
|
|
e0f421ac7a | ||
|
|
b6c0f9db5d | ||
|
|
50755d0295 | ||
|
|
9dc0027304 | ||
|
|
37ee52a930 | ||
|
|
692d885b55 | ||
|
|
6c0d796b4b | ||
|
|
db7e5e01b3 | ||
|
|
ae0b1ce3d6 | ||
|
|
419b8a3ff9 | ||
|
|
bdfc5dcd14 | ||
|
|
c0704cd500 | ||
|
|
1b36dbc435 | ||
|
|
188374f60c | ||
|
|
fd9d7563c2 | ||
|
|
bd9fcd88d8 | ||
|
|
b6ff17c50b | ||
|
|
2d3bac4e53 | ||
|
|
7af786fde9 | ||
|
|
1f1a7a27f0 | ||
|
|
c2e3cbca31 | ||
|
|
92a5e64487 | ||
|
|
9153f710df | ||
|
|
8151eb4837 | ||
|
|
a5b65a73a8 | ||
|
|
26b9bf0281 | ||
|
|
19c968de76 | ||
|
|
9b3fa62b2d | ||
|
|
68983c54bb | ||
|
|
d9af9b895f | ||
|
|
50f332eac7 | ||
|
|
ad095efe3a | ||
|
|
3c947819c1 | ||
|
|
f52f9f0abe | ||
|
|
75ccffa5a2 | ||
|
|
f0035b95bb | ||
|
|
955f54cdef | ||
|
|
c5b8cda323 | ||
|
|
ae0dbcde5b | ||
|
|
f32d83e993 | ||
|
|
d7b881feb6 | ||
|
|
6bd98518e4 | ||
|
|
54d80bbc9b | ||
|
|
5f9ec1762a | ||
|
|
1c8dfd701b | ||
|
|
f520d7364d | ||
|
|
4d61a7c263 | ||
|
|
ac6ef500cc | ||
|
|
b5b2ef3120 | ||
|
|
7f3c3f6eb6 | ||
|
|
936bdd04a8 | ||
|
|
33baf40061 | ||
|
|
6a63d8f2b9 | ||
|
|
b11a4217c7 | ||
|
|
35114cf45c | ||
|
|
e07c472057 | ||
|
|
0fed1cc54d | ||
|
|
ac257cd65f | ||
|
|
088b0817d8 | ||
|
|
b0c75723e2 | ||
|
|
b368a93e2e | ||
|
|
c75cb390dd | ||
|
|
d39f826e0e | ||
|
|
1ea8b18893 | ||
|
|
8491ef428e | ||
|
|
42ce5c0c0d | ||
|
|
acca019afe | ||
|
|
4591f9c09f | ||
|
|
088a5a9771 | ||
|
|
19079c65c1 | ||
|
|
3804410949 | ||
|
|
b8e874a3a7 | ||
|
|
3a03568ec8 | ||
|
|
40da5630e1 | ||
|
|
b36626d50a | ||
|
|
26f897d22c | ||
|
|
1b4cb6483b | ||
|
|
9312c18c57 | ||
|
|
96434aabe9 | ||
|
|
95ec0777ca | ||
|
|
283423f1bd | ||
|
|
3a893d6179 | ||
|
|
6a83b31c5a | ||
|
|
9a3667c1de | ||
|
|
90fa47bbe6 | ||
|
|
44c265e2a7 | ||
|
|
bb9017d3a6 | ||
|
|
9d87f707a6 | ||
|
|
89cda9a1b4 | ||
|
|
653e56268d | ||
|
|
56c905819e | ||
|
|
0d5120e7cc | ||
|
|
1c76dd5859 | ||
|
|
37f709fe34 | ||
|
|
a362f32402 | ||
|
|
7ecab308f2 | ||
|
|
d7314adcf1 | ||
|
|
f64035339b | ||
|
|
0e70b8ab9f | ||
|
|
e805184726 | ||
|
|
b0d1e34df3 | ||
|
|
0862d6cfb0 | ||
|
|
9032b1c491 | ||
|
|
e9111d745c | ||
|
|
0e3a8856e5 | ||
|
|
3084b85229 | ||
|
|
f7f0a3249f | ||
|
|
4419a51a5d | ||
|
|
1d37e96999 | ||
|
|
158c6e8136 | ||
|
|
423e4ef92e | ||
|
|
4645adda0a | ||
|
|
0252ad9a08 | ||
|
|
089625c9fd | ||
|
|
e63fd9b894 | ||
|
|
9be32355f9 | ||
|
|
984c02546e | ||
|
|
c60b4afafb | ||
|
|
55ff37a454 | ||
|
|
bb2f179342 | ||
|
|
28afe8c323 | ||
|
|
9393626ec2 | ||
|
|
c0d0d39d8d | ||
|
|
d06db158a0 | ||
|
|
1698c39223 | ||
|
|
42ad97de8c | ||
|
|
29230412ed | ||
|
|
e4bcc1a9ee | ||
|
|
ca624def40 | ||
|
|
bb912ecc0a | ||
|
|
e2309362e1 | ||
|
|
a20ac05357 | ||
|
|
c9d4360fb6 | ||
|
|
63fe2a7098 | ||
|
|
9931977266 | ||
|
|
d4a77be3f8 | ||
|
|
79dd8397d7 | ||
|
|
d564279254 | ||
|
|
97c54249d5 | ||
|
|
652304e82e | ||
|
|
86251ff2e3 | ||
|
|
ae7ad8fb4f | ||
|
|
822c386709 | ||
|
|
50ebc49d69 | ||
|
|
eb3245b241 | ||
|
|
af443461e3 | ||
|
|
e2293eddce | ||
|
|
b34708da29 | ||
|
|
0c21852bc3 | ||
|
|
944f9e9668 | ||
|
|
5c2996deb7 | ||
|
|
33d272e941 | ||
|
|
bf81a473af | ||
|
|
a46548fc04 | ||
|
|
21b7257150 | ||
|
|
7c1401da1c | ||
|
|
c53e9cb417 | ||
|
|
e3731e40aa | ||
|
|
218ffd0cd8 | ||
|
|
9195452878 | ||
|
|
67c25ca4b9 | ||
|
|
75ddd315e3 | ||
|
|
179ab90fce | ||
|
|
198b95676a | ||
|
|
63e5e4e92d | ||
|
|
107bf5db6d | ||
|
|
38449bf179 | ||
|
|
8710d70a0a | ||
|
|
b0e8837b94 | ||
|
|
aadd2ff7ac | ||
|
|
7dfe21fe35 | ||
|
|
310266f9fa | ||
|
|
33e3b7098f | ||
|
|
e5b5573711 | ||
|
|
5e4abbc0c1 | ||
|
|
9e6e6dd5db | ||
|
|
79e196a22f | ||
|
|
d73c4273ad | ||
|
|
86a1bc36cb | ||
|
|
aa600b4a24 | ||
|
|
27298a2056 | ||
|
|
5ebee92991 | ||
|
|
9ec61a84ce | ||
|
|
cacf3e9924 | ||
|
|
dc993d3ebe | ||
|
|
51829bfb47 | ||
|
|
6dfe160cef | ||
|
|
a2f1ee05ba | ||
|
|
76b9d5c0c3 | ||
|
|
51d349f527 | ||
|
|
188125dd88 | ||
|
|
d8aed94ab1 | ||
|
|
86d7d41e40 | ||
|
|
74454d0452 | ||
|
|
0dcf6c6024 | ||
|
|
0a14f6eeb1 | ||
|
|
b59b633a3d | ||
|
|
d6b34323c5 | ||
|
|
716517db98 | ||
|
|
76c515b09c | ||
|
|
ac367b21bc | ||
|
|
1361c3053a | ||
|
|
b46ee79081 | ||
|
|
9cea77b0fb | ||
|
|
c04addc5c4 | ||
|
|
c2f4326908 | ||
|
|
f6d3229b38 | ||
|
|
3451970751 | ||
|
|
09b0055dc3 | ||
|
|
24907acc2a | ||
|
|
01bbfaacf3 | ||
|
|
6d5da44947 | ||
|
|
071709ab5e | ||
|
|
1295884420 | ||
|
|
6d661e0b3d | ||
|
|
e0430288ce | ||
|
|
a7b16e3c28 | ||
|
|
abe22d8fe6 | ||
|
|
1ad7116045 | ||
|
|
72777be571 | ||
|
|
840904d527 | ||
|
|
f91678ef24 | ||
|
|
6cf390f753 | ||
|
|
20b9404539 | ||
|
|
0ff23eabca | ||
|
|
72901a4ed8 | ||
|
|
ee8bcb2a5b |
561
.drone.yml
561
.drone.yml
@@ -1,228 +1,347 @@
|
||||
clone:
|
||||
git:
|
||||
image: plugins/git
|
||||
tags: true
|
||||
depth: 1
|
||||
kind: pipeline
|
||||
name: qt-5.7
|
||||
|
||||
pipeline:
|
||||
qt-5.7:
|
||||
image: nextcloudci/client-5.7:client-5.7-4
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
source /opt/qt57/bin/qt57-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
source /opt/qt57/bin/qt57-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
when:
|
||||
matrix:
|
||||
TESTS: qt-5.7
|
||||
qt-5.8:
|
||||
image: nextcloudci/client-5.8:client-5.8-4
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
source /opt/qt58/bin/qt58-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
source /opt/qt58/bin/qt58-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
when:
|
||||
matrix:
|
||||
TESTS: qt-5.8
|
||||
qt-5.9:
|
||||
image: nextcloudci/client-5.9:client-5.9-5
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
source /opt/qt59/bin/qt59-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
source /opt/qt59/bin/qt59-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
when:
|
||||
matrix:
|
||||
TESTS: qt-5.9
|
||||
qt-5.10:
|
||||
image: nextcloudci/client-5.10:client-5.10-3
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
export CC=gcc-7 &&
|
||||
export CXX=g++-7 &&
|
||||
source /opt/qt510/bin/qt510-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
export CC=gcc-7 &&
|
||||
export CXX=g++-7 &&
|
||||
source /opt/qt510/bin/qt510-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
when:
|
||||
matrix:
|
||||
TESTS: qt-5.10
|
||||
qt-5.11:
|
||||
image: nextcloudci/client-5.11:client-5.11-3
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
export CC=gcc-7 &&
|
||||
export CXX=g++-7 &&
|
||||
source /opt/qt511/bin/qt511-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
export CC=gcc-7 &&
|
||||
export CXX=g++-7 &&
|
||||
source /opt/qt511/bin/qt511-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
when:
|
||||
matrix:
|
||||
TESTS: qt-5.11
|
||||
steps:
|
||||
- name: build and test
|
||||
image: nextcloudci/client-5.7:client-5.7-4
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
source /opt/qt57/bin/qt57-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
source /opt/qt57/bin/qt57-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
qt-5.11-clang:
|
||||
image: nextcloudci/client-5.11:client-5.11-3
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
export CC=clang-6.0 &&
|
||||
export CXX=clang++-6.0 &&
|
||||
source /opt/qt511/bin/qt511-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
export CC=clang-6.0 &&
|
||||
export CXX=clang++-6.0 &&
|
||||
source /opt/qt511/bin/qt511-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
when:
|
||||
matrix:
|
||||
TESTS: qt-5.11-clang
|
||||
---
|
||||
kind: pipeline
|
||||
name: qt-5.8
|
||||
|
||||
AppImage:
|
||||
image: nextcloudci/client-5.11:client-5.11-3
|
||||
commands:
|
||||
- /bin/bash -c "./admin/linux/build-appimage.sh"
|
||||
when:
|
||||
matrix:
|
||||
BUILD: AppImage
|
||||
steps:
|
||||
- name: build and test
|
||||
image: nextcloudci/client-5.8:client-5.8-4
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
source /opt/qt58/bin/qt58-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
source /opt/qt58/bin/qt58-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
Debian:
|
||||
image: nextcloudci/client-debian-ci:client-debian-ci-2
|
||||
commands:
|
||||
- /bin/bash -c "./admin/linux/debian/drone-build.sh"
|
||||
secrets: [ DEBIAN_SECRET_KEY, DEBIAN_SECRET_IV ]
|
||||
when:
|
||||
matrix:
|
||||
BUILD: Debian
|
||||
---
|
||||
kind: pipeline
|
||||
name: qt-5.9
|
||||
|
||||
documentation:
|
||||
image: nextcloudci/documentation:documentation-5
|
||||
commands:
|
||||
- cd doc
|
||||
- make html
|
||||
when:
|
||||
matrix:
|
||||
TESTS: documentation
|
||||
steps:
|
||||
- name: build and test
|
||||
image: nextcloudci/client-5.9:client-5.9-5
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
source /opt/qt59/bin/qt59-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
source /opt/qt59/bin/qt59-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- TESTS: qt-5.7
|
||||
- TESTS: qt-5.8
|
||||
- TESTS: qt-5.9
|
||||
- TESTS: qt-5.10
|
||||
- TESTS: qt-5.11
|
||||
- TESTS: qt-5.11-clang
|
||||
- BUILD: AppImage
|
||||
- BUILD: Debian
|
||||
- TESTS: documentation
|
||||
---
|
||||
kind: pipeline
|
||||
name: qt-5.10
|
||||
|
||||
branches: [ master, 2.* ]
|
||||
steps:
|
||||
- name: build and test
|
||||
image: nextcloudci/client-5.10:client-5.10-3
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
export CC=gcc-7 &&
|
||||
export CXX=g++-7 &&
|
||||
source /opt/qt510/bin/qt510-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
export CC=gcc-7 &&
|
||||
export CXX=g++-7 &&
|
||||
source /opt/qt510/bin/qt510-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: qt-5.11
|
||||
|
||||
steps:
|
||||
- name: build and test
|
||||
image: nextcloudci/client-5.11:client-5.11-3
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
export CC=gcc-7 &&
|
||||
export CXX=g++-7 &&
|
||||
source /opt/qt511/bin/qt511-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
export CC=gcc-7 &&
|
||||
export CXX=g++-7 &&
|
||||
source /opt/qt511/bin/qt511-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: qt-5.11-clang
|
||||
|
||||
steps:
|
||||
- name: build and test
|
||||
image: nextcloudci/client-5.11:client-5.11-3
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
export CC=clang-6.0 &&
|
||||
export CXX=clang++-6.0 &&
|
||||
source /opt/qt511/bin/qt511-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
export CC=clang-6.0 &&
|
||||
export CXX=clang++-6.0 &&
|
||||
source /opt/qt511/bin/qt511-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: qt-5.12
|
||||
|
||||
steps:
|
||||
- name: build and test
|
||||
image: nextcloudci/client-5.12:client-5.12-2
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
export CC=gcc-7 &&
|
||||
export CXX=g++-7 &&
|
||||
source /opt/qt512/bin/qt512-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
export CC=gcc-7 &&
|
||||
export CXX=g++-7 &&
|
||||
source /opt/qt512/bin/qt512-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: qt-5.12-clang
|
||||
|
||||
steps:
|
||||
- name: build and test
|
||||
image: nextcloudci/client-5.12:client-5.12-2
|
||||
commands:
|
||||
# Install QtKeyChain
|
||||
- /bin/bash -c "
|
||||
export CC=clang-6.0 &&
|
||||
export CXX=clang++-6.0 &&
|
||||
source /opt/qt512/bin/qt512-env.sh &&
|
||||
cd /tmp &&
|
||||
git clone https://github.com/frankosterfeld/qtkeychain.git &&
|
||||
cd qtkeychain &&
|
||||
git checkout v0.9.1 &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake ../ &&
|
||||
make &&
|
||||
make install"
|
||||
# Build client
|
||||
- /bin/bash -c "
|
||||
export CC=clang-6.0 &&
|
||||
export CXX=clang++-6.0 &&
|
||||
source /opt/qt512/bin/qt512-env.sh &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -D NO_SHIBBOLETH=1 -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=1 ../ &&
|
||||
make &&
|
||||
useradd -m -s /bin/bash test &&
|
||||
chown -R test:test . &&
|
||||
su -c 'ctest --output-on-failure' test"
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: AppImage
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: nextcloudci/client-5.12:client-5.12-2
|
||||
commands:
|
||||
- /bin/bash -c "./admin/linux/build-appimage.sh"
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: Documentation
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: nextcloudci/documentation:documentation-5
|
||||
commands:
|
||||
- cd doc
|
||||
- make html
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
33
.github/issue_template.md
vendored
33
.github/issue_template.md
vendored
@@ -1,9 +1,14 @@
|
||||
<!---
|
||||
Please try to only report a bug if it happens with the latest version
|
||||
The latest version can be seen by checking https://download.nextcloud.com/desktop/
|
||||
For support try our forums: https://help.nextcloud.com
|
||||
--->
|
||||
|
||||
<!--
|
||||
Dear user,
|
||||
Please understand that at the moment, we are very busy with customer issues
|
||||
and some high priority development work. A lot of issues are getting reported.
|
||||
Right now we can't keep up and timely respond to all of them.
|
||||
We're sorry for that and are expanding our team, if you're looking for a C++
|
||||
job or know somebody who is, please point them to https://nextcloud.com/jobs
|
||||
Don't forget that Github is not a support system or a place to ask for
|
||||
features but only a place to report verified bugs - see nextcloud.com/support
|
||||
for support options!
|
||||
-->
|
||||
|
||||
### Expected behaviour
|
||||
Tell us what should happen
|
||||
@@ -18,6 +23,11 @@ Tell us what happens instead
|
||||
|
||||
### Client configuration
|
||||
Client version:
|
||||
<!---
|
||||
Please try to only report a bug if it happens with the latest version
|
||||
The latest version can be seen by checking https://download.nextcloud.com/desktop/
|
||||
For support try our forums: https://help.nextcloud.com
|
||||
--->
|
||||
|
||||
Operating system:
|
||||
|
||||
@@ -34,15 +44,6 @@ Installation path of client:
|
||||
<!---
|
||||
Optional section. It depends on the issue.
|
||||
--->
|
||||
|
||||
Operating system:
|
||||
|
||||
Web server:
|
||||
|
||||
Database:
|
||||
|
||||
PHP version:
|
||||
|
||||
Nextcloud version:
|
||||
|
||||
Storage backend (external storage):
|
||||
@@ -52,8 +53,6 @@ Storage backend (external storage):
|
||||
Please use Gist (https://gist.github.com/) or a similar code paster for longer
|
||||
logs.
|
||||
|
||||
```Template for output < 10 lines```
|
||||
|
||||
1. Client logfile: Output of `nextcloud --logwindow` or `nextcloud --logfile log.txt`
|
||||
(On Windows using `cmd.exe`, you might need to first `cd` into the Nextcloud directory)
|
||||
(See also https://docs.nextcloud.com/desktop/2.3/troubleshooting.html#log-files)
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -171,3 +171,4 @@ CPackConfig.cmake
|
||||
CPackOptions.cmake
|
||||
CPackSourceConfig.cmake
|
||||
|
||||
compile_commands.json
|
||||
|
||||
201
.tx/nextcloud.client-desktop/ar_translation
Normal file
201
.tx/nextcloud.client-desktop/ar_translation
Normal file
@@ -0,0 +1,201 @@
|
||||
[Desktop Entry]
|
||||
Categories=Utility;X-SuSE-SyncUtility;
|
||||
Type=Application
|
||||
Exec=@APPLICATION_EXECUTABLE@
|
||||
Name=@APPLICATION_NAME@ desktop sync client
|
||||
Comment=@APPLICATION_NAME@ desktop synchronization client
|
||||
GenericName=Folder Sync
|
||||
Icon=@APPLICATION_ICON_NAME@
|
||||
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
|
||||
X-GNOME-Autostart-Delay=3
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
GenericName[ar]=مزامنة المجلد
|
||||
204
.tx/nextcloud.client-desktop/bg_translation
Normal file
204
.tx/nextcloud.client-desktop/bg_translation
Normal file
@@ -0,0 +1,204 @@
|
||||
[Desktop Entry]
|
||||
Categories=Utility;X-SuSE-SyncUtility;
|
||||
Type=Application
|
||||
Exec=@APPLICATION_EXECUTABLE@
|
||||
Name=@APPLICATION_NAME@ desktop sync client
|
||||
Comment=@APPLICATION_NAME@ desktop synchronization client
|
||||
GenericName=Folder Sync
|
||||
Icon=@APPLICATION_ICON_NAME@
|
||||
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
|
||||
X-GNOME-Autostart-Delay=3
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
Icon[bg_BG]=@APPLICATION_ICON_NAME@
|
||||
Name[bg_BG]=@APPLICATION_NAME@ клиент за синхронизиране на десктоп
|
||||
Comment[bg_BG]=@APPLICATION_NAME@ клиент за синхронизиране на десктоп
|
||||
GenericName[bg_BG]=Синхронизиране на папка
|
||||
@@ -199,6 +199,6 @@ X-GNOME-Autostart-Delay=3
|
||||
|
||||
# Translations
|
||||
Icon[ca]=@APPLICATION_ICON_NAME@
|
||||
Name[ca]=@APPLICATION_NAME@ client de sincro d'escriptori
|
||||
Name[ca]=@APPLICATION_NAME@ client de sincronització d'escriptori
|
||||
Comment[ca]=@APPLICATION_NAME@ client de sincronització d'escriptori
|
||||
GenericName[ca]=Directori de sincronització
|
||||
|
||||
204
.tx/nextcloud.client-desktop/da_translation
Normal file
204
.tx/nextcloud.client-desktop/da_translation
Normal file
@@ -0,0 +1,204 @@
|
||||
[Desktop Entry]
|
||||
Categories=Utility;X-SuSE-SyncUtility;
|
||||
Type=Application
|
||||
Exec=@APPLICATION_EXECUTABLE@
|
||||
Name=@APPLICATION_NAME@ desktop sync client
|
||||
Comment=@APPLICATION_NAME@ desktop synchronization client
|
||||
GenericName=Folder Sync
|
||||
Icon=@APPLICATION_ICON_NAME@
|
||||
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
|
||||
X-GNOME-Autostart-Delay=3
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
Icon[da]=@APPLICATION_ICON_NAME@
|
||||
Name[da]=@APPLICATION_NAME@ Arbejdsstationsssynkroniseringsklient
|
||||
Comment[da]=@APPLICATION_NAME@ Arbejdsstationsssynkroniseringsklient
|
||||
GenericName[da]=Mappesynkronisering
|
||||
204
.tx/nextcloud.client-desktop/eo_translation
Normal file
204
.tx/nextcloud.client-desktop/eo_translation
Normal file
@@ -0,0 +1,204 @@
|
||||
[Desktop Entry]
|
||||
Categories=Utility;X-SuSE-SyncUtility;
|
||||
Type=Application
|
||||
Exec=@APPLICATION_EXECUTABLE@
|
||||
Name=@APPLICATION_NAME@ desktop sync client
|
||||
Comment=@APPLICATION_NAME@ desktop synchronization client
|
||||
GenericName=Folder Sync
|
||||
Icon=@APPLICATION_ICON_NAME@
|
||||
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
|
||||
X-GNOME-Autostart-Delay=3
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
Icon[eo]=@APPLICATION_ICON_NAME@
|
||||
Name[eo]=@APPLICATION_NAME@ sinkroniga kliento
|
||||
Comment[eo]=@APPLICATION_NAME@ sinkroniga kliento
|
||||
GenericName[eo]=Dosieruja sinkronigo
|
||||
204
.tx/nextcloud.client-desktop/eu_translation
Normal file
204
.tx/nextcloud.client-desktop/eu_translation
Normal file
@@ -0,0 +1,204 @@
|
||||
[Desktop Entry]
|
||||
Categories=Utility;X-SuSE-SyncUtility;
|
||||
Type=Application
|
||||
Exec=@APPLICATION_EXECUTABLE@
|
||||
Name=@APPLICATION_NAME@ desktop sync client
|
||||
Comment=@APPLICATION_NAME@ desktop synchronization client
|
||||
GenericName=Folder Sync
|
||||
Icon=@APPLICATION_ICON_NAME@
|
||||
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
|
||||
X-GNOME-Autostart-Delay=3
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
Icon[eu]=@APPLICATION_ICON_NAME@
|
||||
Name[eu]=@APPLICATION_NAME@ mahaigainerako sinkronizazio bezeroa
|
||||
Comment[eu]=@APPLICATION_NAME@ mahaigainerako sinkronizazio bezeroa
|
||||
GenericName[eu]=Karpeta-sinkronizazioa
|
||||
@@ -199,6 +199,6 @@ X-GNOME-Autostart-Delay=3
|
||||
|
||||
# Translations
|
||||
Icon[fr]=@APPLICATION_ICON_NAME@
|
||||
Name[fr]=Client desktop de synchronisation @APPLICATION_NAME@
|
||||
Comment[fr]=Client de synchronisation @APPLICATION_NAME@ desktop
|
||||
Name[fr]=Client de synchro @APPLICATION_NAME@
|
||||
Comment[fr]=Client de synchronisation @APPLICATION_NAME@
|
||||
GenericName[fr]=Synchronisation du dossier
|
||||
|
||||
@@ -198,6 +198,7 @@ X-GNOME-Autostart-Delay=3
|
||||
|
||||
|
||||
# Translations
|
||||
Icon[he]=@APPLICATION_ICON_NAME@
|
||||
Name[he]=@APPLICATION_NAME@ לקוח סנכרון לשולחן העבודה
|
||||
Comment[he]=@APPLICATION_NAME@ לקוח סנכרון לשולחן העבודה
|
||||
GenericName[he]=סנכרון תיקיות
|
||||
|
||||
@@ -199,6 +199,6 @@ X-GNOME-Autostart-Delay=3
|
||||
|
||||
# Translations
|
||||
Icon[hu_HU]=@APPLICATION_ICON_NAME@
|
||||
Name[hu_HU]=@APPLICATION_NAME@ deszktop szinkronizációs kliens
|
||||
Comment[hu_HU]=@APPLICATION_NAME@ deszktop szinkronizációs kliens
|
||||
GenericName[hu_HU]=Mappa szinkronizáció
|
||||
Name[hu_HU]=@APPLICATION_NAME@ asztali szinkronizálási kliens
|
||||
Comment[hu_HU]=@APPLICATION_NAME@ asztali szinkronizálási kliens
|
||||
GenericName[hu_HU]=Mappaszinkronizálás
|
||||
|
||||
@@ -198,4 +198,6 @@ X-GNOME-Autostart-Delay=3
|
||||
|
||||
|
||||
# Translations
|
||||
Icon[ko]=@APPLICATION_ICON_NAME@
|
||||
Comment[ko]=@APPLICATION_NAME@ 데스크톱 동기화 클라이언트
|
||||
GenericName[ko]=폴더 동기화
|
||||
|
||||
@@ -198,6 +198,7 @@ X-GNOME-Autostart-Delay=3
|
||||
|
||||
|
||||
# Translations
|
||||
Icon[nb_NO]=@APPLICATION_ICON_NAME@
|
||||
Name[nb_NO]=@APPLICATION_NAME@ klient for synkroinisering
|
||||
Comment[nb_NO]=@APPLICATION_NAME@ klient for synkroinisering
|
||||
GenericName[nb_NO]=Mappe synkroinisering
|
||||
|
||||
@@ -201,4 +201,4 @@ X-GNOME-Autostart-Delay=3
|
||||
Icon[pt_BR]=@APPLICATION_ICON_NAME@
|
||||
Name[pt_BR]=@APPLICATION_NAME@ cliente de sincronização desktop
|
||||
Comment[pt_BR]=@APPLICATION_NAME@ cliente de sincronização desktop
|
||||
GenericName[pt_BR]=Sincronizar Pasta
|
||||
GenericName[pt_BR]=Sincronizar pasta
|
||||
|
||||
@@ -198,6 +198,7 @@ X-GNOME-Autostart-Delay=3
|
||||
|
||||
|
||||
# Translations
|
||||
Icon[pt_PT]=@APPLICATION_ICON_NAME@
|
||||
Name[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização da Área de Trabalho
|
||||
Comment[pt_PT]=@APPLICATION_NAME@ - Cliente de Sincronização da Área de Trabalho
|
||||
GenericName[pt_PT]=Sincronização de Pasta
|
||||
|
||||
204
.tx/nextcloud.client-desktop/ro_translation
Normal file
204
.tx/nextcloud.client-desktop/ro_translation
Normal file
@@ -0,0 +1,204 @@
|
||||
[Desktop Entry]
|
||||
Categories=Utility;X-SuSE-SyncUtility;
|
||||
Type=Application
|
||||
Exec=@APPLICATION_EXECUTABLE@
|
||||
Name=@APPLICATION_NAME@ desktop sync client
|
||||
Comment=@APPLICATION_NAME@ desktop synchronization client
|
||||
GenericName=Folder Sync
|
||||
Icon=@APPLICATION_ICON_NAME@
|
||||
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
|
||||
X-GNOME-Autostart-Delay=3
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
Icon[ro]=@APPLICATION_ICON_NAME@
|
||||
Name[ro]=@APPLICATION_NAME@ client de sincronizare pentru desktop
|
||||
Comment[ro]=@APPLICATION_NAME@ client de sincronizare pentru desktop
|
||||
GenericName[ro]=Sincronizare dosare
|
||||
@@ -199,6 +199,6 @@ X-GNOME-Autostart-Delay=3
|
||||
|
||||
# Translations
|
||||
Icon[sk_SK]=@APPLICATION_ICON_NAME@
|
||||
Name[sk_SK]=@APPLICATION_NAME@ Synchronizačný klient pre PC
|
||||
Comment[sk_SK]=@APPLICATION_NAME@ Synchronizačný klient pre PC
|
||||
GenericName[sk_SK]=Synchnonizácia priečinka
|
||||
Name[sk_SK]=@APPLICATION_NAME@ synchronizačný klient pre PC
|
||||
Comment[sk_SK]=@APPLICATION_NAME@ synchronizačný klient pre PC
|
||||
GenericName[sk_SK]=Synchnonizácia priečinkov
|
||||
|
||||
202
.tx/nextcloud.client-desktop/sv_translation
Normal file
202
.tx/nextcloud.client-desktop/sv_translation
Normal file
@@ -0,0 +1,202 @@
|
||||
[Desktop Entry]
|
||||
Categories=Utility;X-SuSE-SyncUtility;
|
||||
Type=Application
|
||||
Exec=@APPLICATION_EXECUTABLE@
|
||||
Name=@APPLICATION_NAME@ desktop sync client
|
||||
Comment=@APPLICATION_NAME@ desktop synchronization client
|
||||
GenericName=Folder Sync
|
||||
Icon=@APPLICATION_ICON_NAME@
|
||||
Keywords=@APPLICATION_NAME@;syncing;file;sharing;
|
||||
X-GNOME-Autostart-Delay=3
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
|
||||
|
||||
# Translations
|
||||
Icon[sv]=@APPLICATION_ICON_NAME@
|
||||
GenericName[sv]=Mappsynkronisering
|
||||
@@ -21,7 +21,7 @@ If your issue appears to be a bug, and hasn't been reported, open a new issue.
|
||||
Help us to maximize the effort we can spend fixing issues and adding new
|
||||
features, by not reporting duplicate issues.
|
||||
|
||||
[template]: https://raw.githubusercontent.com/nextcloud/appstore/master/.github/issue_template.md
|
||||
[template]: https://raw.githubusercontent.com/nextcloud/desktop/master/.github/issue_template.md
|
||||
[support]: https://nextcloud.com/support/
|
||||
[forum]: https://help.nextcloud.com/categories
|
||||
[irc]: https://webchat.freenode.net/?channels=nextcloud
|
||||
|
||||
@@ -4,7 +4,9 @@ set( APPLICATION_EXECUTABLE "nextcloud" )
|
||||
set( APPLICATION_DOMAIN "nextcloud.com" )
|
||||
set( APPLICATION_VENDOR "Nextcloud GmbH" )
|
||||
set( APPLICATION_UPDATE_URL "https://updates.nextcloud.org/client/" CACHE string "URL for updater" )
|
||||
set( APPLICATION_HELP_URL "" CACHE string "URL for the help menu" )
|
||||
set( APPLICATION_ICON_NAME "Nextcloud" )
|
||||
set( APPLICATION_SERVER_URL "" CACHE string "URL for the server to use. If entered the server can only connect to this instance" )
|
||||
|
||||
set( LINUX_PACKAGE_SHORTNAME "nextcloud" )
|
||||
|
||||
@@ -22,3 +24,10 @@ option( WITH_CRASHREPORTER "Build crashreporter" OFF )
|
||||
#set( CRASHREPORTER_ICON ":/owncloud-icon.png" )
|
||||
|
||||
option( WITH_PROVIDERS "Build with providers list" ON )
|
||||
|
||||
|
||||
## Theming options
|
||||
set( APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR "#0082c9" CACHE string "Hex color of the wizard header background")
|
||||
set( APPLICATION_WIZARD_HEADER_TITLE_COLOR "#ffffff" CACHE string "Hex color of the text in the wizard header")
|
||||
option( APPLICATION_WIZARD_USE_CUSTOM_LOGO "Use the logo from ':/client/theme/colored/wizard_logo.png' else the default application icon is used" ON )
|
||||
|
||||
|
||||
24
README.md
24
README.md
@@ -24,33 +24,27 @@ $ cd build
|
||||
```
|
||||
##### Compile and install
|
||||
|
||||
For development reasons it is better to install the client on user space
|
||||
instead on the global system. For example you could use in the next
|
||||
instructions `path-to-install-folder/` as `~/.local/` in a linux system. If
|
||||
you want to install system wide you could use `/usr/local` or `/opt/nextcloud/`.
|
||||
:warning: For development reasons it is better to **install the client on user space** instead on the global system. Mixing up libs/dll's of different version can lead to undefined behavior and crashes:
|
||||
|
||||
##### Linux
|
||||
* You could use the **cmake flag** ```CMAKE_INSTALL_PREFIX``` as ```~/.local/``` in a **Linux** system. If you want to install system wide you could use ```/usr/local``` or ```/opt/nextcloud/```.
|
||||
|
||||
* On **Windows 10** [```$USERPROFILE```](https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables#a-href-idbkmk-2avariables-that-are-recognized-only-in-the-user-context) refers to ```C:\Users\<USERNAME>```.
|
||||
|
||||
##### Linux & Mac OS
|
||||
|
||||
```
|
||||
$ cmake .. -DCMAKE_INSTALL_PREFIX=path-to-install-folder/ -DCMAKE_BUILD_TYPE=Debug -DNO_SHIBBOLETH=1 -DQTKEYCHAIN_LIBRARY=/path-to-qt5keychain-folder/lib64/libqt5keychain.so -DQTKEYCHAIN_INCLUDE_DIR=/path-to-qt5keychain-folder/include/qt5keychain/ -DOPENSSL_ROOT_DIR=/path-to-openssl-folder/ -DOPENSSL_INCLUDE_DIR=path-to-openssl-folder/include -DOPENSSL_LIBRARIES=path-to-openssl-folder/lib
|
||||
$ cmake .. -DCMAKE_INSTALL_PREFIX=~/nextcloud-desktop-client -DCMAKE_BUILD_TYPE=Debug -DNO_SHIBBOLETH=1
|
||||
$ make install
|
||||
```
|
||||
|
||||
##### Windows
|
||||
|
||||
```
|
||||
$ cmake -G "Visual Studio 15 2017 Win64" .. -DCMAKE_INSTALL_PREFIX=path-to-install-folder/ -DCMAKE_BUILD_TYPE=Debug -DNO_SHIBBOLETH=1 -DPng2Ico_EXECUTABLE=/path-to-install-png2ico/png2ico.exe -DQTKEYCHAIN_LIBRARY=/path-to-qt5keychain-folder/lib/qt5keychain.lib -DQTKEYCHAIN_INCLUDE_DIR=/path-to-qt5keychain-folder/include/qt5keychain/ -DOPENSSL_ROOT_DIR=/path-to-openssl-folder/ -DOPENSSL_INCLUDE_DIR=path-to-openssl-folder/include -DOPENSSL_LIBRARIES=path-to-openssl-folder/lib
|
||||
$ cmake -G "Visual Studio 15 2017 Win64" .. -DCMAKE_INSTALL_PREFIX=$USERPROFILE\nextcloud-desktop-client -DCMAKE_BUILD_TYPE=Debug -DNO_SHIBBOLETH=1
|
||||
$ cmake --build . --config Debug --target install
|
||||
```
|
||||
|
||||
##### Mac OS
|
||||
|
||||
```
|
||||
$ cmake .. -DCMAKE_INSTALL_PREFIX=path-to-install-folder/ -DCMAKE_BUILD_TYPE=Debug -DNO_SHIBBOLETH=1 -DQTKEYCHAIN_LIBRARY=/path-to-qt5keychain-folder/lib/libqt5keychain.dylib -DQTKEYCHAIN_INCLUDE_DIR=/path-to-qt5keychain-folder/include/qt5keychain/ -DOPENSSL_ROOT_DIR=/path-to-openssl-folder/ -DOPENSSL_INCLUDE_DIR=path-to-openssl-folder/include -DOPENSSL_LIBRARIES=path-to-openssl-folder/lib
|
||||
$ make install
|
||||
```
|
||||
|
||||
More detailed instructions can be found at the [Desktop Client Wiki](https://github.com/nextcloud/desktop/wiki).
|
||||
:information_source: More detailed instructions can be found at the [Desktop Client Wiki](https://github.com/nextcloud/desktop/wiki).
|
||||
|
||||
### :inbox_tray: Where to find binaries to download
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
set( MIRALL_VERSION_MAJOR 2 )
|
||||
set( MIRALL_VERSION_MINOR 5 )
|
||||
set( MIRALL_VERSION_PATCH 1 )
|
||||
set( MIRALL_VERSION_YEAR 2018 )
|
||||
set( MIRALL_VERSION_PATCH 3 )
|
||||
set( MIRALL_VERSION_YEAR 2019 )
|
||||
set( MIRALL_SOVERSION 0 )
|
||||
|
||||
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
|
||||
@@ -5,8 +5,8 @@ set -xe
|
||||
mkdir /app
|
||||
mkdir /build
|
||||
|
||||
#Set Qt-5.11
|
||||
export QT_BASE_DIR=/opt/qt511
|
||||
#Set Qt-5.12
|
||||
export QT_BASE_DIR=/opt/qt512
|
||||
export QTDIR=$QT_BASE_DIR
|
||||
export PATH=$QT_BASE_DIR/bin:$PATH
|
||||
export LD_LIBRARY_PATH=$QT_BASE_DIR/lib/x86_64-linux-gnu:$QT_BASE_DIR/lib:$LD_LIBRARY_PATH
|
||||
|
||||
23
admin/linux/debian/debian.disco/changelog
Normal file
23
admin/linux/debian/debian.disco/changelog
Normal file
@@ -0,0 +1,23 @@
|
||||
nextcloud-client (2.3.3-1.0~disco1) disco; urgency=medium
|
||||
|
||||
* Debian build support for the forked client.
|
||||
|
||||
-- István Váradi <ivaradi@varadiistvan.hu> Mon, 6 Nov 2017 20:20:04 +0100
|
||||
|
||||
nextcloud-client (2.3.1-1.0~disco1) disco; urgency=medium
|
||||
|
||||
* New upstream version
|
||||
|
||||
-- István Váradi <ivaradi@varadiistvan.hu> Thu, 23 Mar 2017 19:07:36 +0100
|
||||
|
||||
nextcloud-client (2.3.0-1.0~disco1) disco; urgency=medium
|
||||
|
||||
* New upstream version
|
||||
|
||||
-- István Váradi <ivaradi@varadiistvan.hu> Tue, 21 Mar 2017 19:34:13 +0100
|
||||
|
||||
nextcloud-client (2.2.4-1.4~disco1) disco; urgency=medium
|
||||
|
||||
* The locale-specific icon names are correct too
|
||||
|
||||
-- István Váradi <ivaradi@varadiistvan.hu> Tue, 7 Feb 2017 19:55:40 +0100
|
||||
@@ -51,7 +51,7 @@ if ! wget http://ppa.launchpad.net/${repo}/ubuntu/pool/main/n/nextcloud-client/n
|
||||
origsourceopt="-sa"
|
||||
fi
|
||||
|
||||
for distribution in xenial bionic cosmic stable; do
|
||||
for distribution in xenial bionic cosmic disco stable; do
|
||||
rm -rf nextcloud-client_${basever}
|
||||
cp -a ${DRONE_WORKSPACE} nextcloud-client_${basever}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<file>resources/confirm.svg</file>
|
||||
<file>resources/copy.svg</file>
|
||||
<file>resources/state-sync.svg</file>
|
||||
<file>resources/add.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/"/>
|
||||
</RCC>
|
||||
|
||||
@@ -18,7 +18,12 @@
|
||||
#cmakedefine APPLICATION_SHORTNAME "@APPLICATION_SHORTNAME@"
|
||||
#cmakedefine APPLICATION_EXECUTABLE "@APPLICATION_EXECUTABLE@"
|
||||
#cmakedefine APPLICATION_UPDATE_URL "@APPLICATION_UPDATE_URL@"
|
||||
#cmakedefine APPLICATION_HELP_URL "@APPLICATION_HELP_URL@"
|
||||
#cmakedefine APPLICATION_ICON_NAME "@APPLICATION_ICON_NAME@"
|
||||
#cmakedefine APPLICATION_SERVER_URL "@APPLICATION_SERVER_URL@"
|
||||
#cmakedefine APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR "@APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR@"
|
||||
#cmakedefine APPLICATION_WIZARD_HEADER_TITLE_COLOR "@APPLICATION_WIZARD_HEADER_TITLE_COLOR@"
|
||||
#cmakedefine APPLICATION_WIZARD_USE_CUSTOM_LOGO "@APPLICATION_WIZARD_USE_CUSTOM_LOGO@"
|
||||
|
||||
#cmakedefine ZLIB_FOUND @ZLIB_FOUND@
|
||||
|
||||
|
||||
BIN
resources/add.png
Normal file
BIN
resources/add.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -20,7 +20,12 @@ set_package_properties(DolphinVcs PROPERTIES
|
||||
PURPOSE "Provides plugin interfaces for Dolphin."
|
||||
)
|
||||
|
||||
set(KDE_INSTALL_DIRS_NO_DEPRECATED TRUE)
|
||||
include(KDEInstallDirs)
|
||||
# Before KF5 5.54, kcoreaddons_add_plugin uses deprecated VAR PLUGIN_INSTALL_DIR
|
||||
# when that is fixed and you want to remove this workaround,
|
||||
# you need to _require_ the new enough kcoreaddons
|
||||
set(PLUGIN_INSTALL_DIR "${KDE_INSTALL_PLUGINDIR}")
|
||||
include(KDECMakeSettings)
|
||||
include(KDECompilerSettings)
|
||||
include(ECMMarkNonGuiExecutable)
|
||||
|
||||
@@ -41,6 +41,7 @@ macro(libcloudproviders_add_config _sources)
|
||||
endmacro(libcloudproviders_add_config _sources)
|
||||
|
||||
|
||||
find_package(Qt5 5.6 COMPONENTS DBus)
|
||||
IF (UNIX AND Qt5DBus_FOUND AND LIBCLOUDPROVIDERS_FOUND)
|
||||
STRING(TOLOWER "${APPLICATION_VENDOR}" DBUS_VENDOR)
|
||||
STRING(REGEX REPLACE "[^A-z0-9]" "" DBUS_VENDOR "${DBUS_VENDOR}")
|
||||
|
||||
512
src/3rdparty/kmessagewidget/kmessagewidget.cpp
vendored
Normal file
512
src/3rdparty/kmessagewidget/kmessagewidget.cpp
vendored
Normal file
@@ -0,0 +1,512 @@
|
||||
/* This file is part of the KDE libraries
|
||||
*
|
||||
* Copyright (c) 2011 Aurélien Gâteau <agateau@kde.org>
|
||||
* Copyright (c) 2014 Dominik Haumann <dhaumann@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
#include "kmessagewidget.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QEvent>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
#include <QShowEvent>
|
||||
#include <QTimeLine>
|
||||
#include <QToolButton>
|
||||
#include <QStyle>
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// KMessageWidgetPrivate
|
||||
//---------------------------------------------------------------------
|
||||
class KMessageWidgetPrivate
|
||||
{
|
||||
public:
|
||||
void init(KMessageWidget *);
|
||||
|
||||
KMessageWidget *q;
|
||||
QFrame *content = nullptr;
|
||||
QLabel *iconLabel = nullptr;
|
||||
QLabel *textLabel = nullptr;
|
||||
QToolButton *closeButton = nullptr;
|
||||
QTimeLine *timeLine = nullptr;
|
||||
QIcon icon;
|
||||
bool ignoreShowEventDoingAnimatedShow = false;
|
||||
|
||||
KMessageWidget::MessageType messageType;
|
||||
bool wordWrap;
|
||||
QList<QToolButton *> buttons;
|
||||
QPixmap contentSnapShot;
|
||||
|
||||
void createLayout();
|
||||
void applyStyleSheet();
|
||||
void updateSnapShot();
|
||||
void updateLayout();
|
||||
void slotTimeLineChanged(qreal);
|
||||
void slotTimeLineFinished();
|
||||
|
||||
int bestContentHeight() const;
|
||||
};
|
||||
|
||||
void KMessageWidgetPrivate::init(KMessageWidget *q_ptr)
|
||||
{
|
||||
q = q_ptr;
|
||||
|
||||
q->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
|
||||
// Note: when changing the value 500, also update KMessageWidgetTest
|
||||
timeLine = new QTimeLine(500, q);
|
||||
QObject::connect(timeLine, SIGNAL(valueChanged(qreal)), q, SLOT(slotTimeLineChanged(qreal)));
|
||||
QObject::connect(timeLine, SIGNAL(finished()), q, SLOT(slotTimeLineFinished()));
|
||||
|
||||
content = new QFrame(q);
|
||||
content->setObjectName(QStringLiteral("contentWidget"));
|
||||
content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
|
||||
wordWrap = false;
|
||||
|
||||
iconLabel = new QLabel(content);
|
||||
iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
iconLabel->hide();
|
||||
|
||||
textLabel = new QLabel(content);
|
||||
textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
textLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
QObject::connect(textLabel, &QLabel::linkActivated, q, &KMessageWidget::linkActivated);
|
||||
QObject::connect(textLabel, &QLabel::linkHovered, q, &KMessageWidget::linkHovered);
|
||||
|
||||
QAction *closeAction = new QAction(q);
|
||||
closeAction->setText(KMessageWidget::tr("&Close"));
|
||||
closeAction->setToolTip(KMessageWidget::tr("Close message"));
|
||||
closeAction->setIcon(QIcon(":/client/resources/close.svg")); // ivan: NC customization
|
||||
|
||||
QObject::connect(closeAction, &QAction::triggered, q, &KMessageWidget::animatedHide);
|
||||
|
||||
closeButton = new QToolButton(content);
|
||||
closeButton->setAutoRaise(true);
|
||||
closeButton->setDefaultAction(closeAction);
|
||||
|
||||
q->setMessageType(KMessageWidget::Information);
|
||||
}
|
||||
|
||||
void KMessageWidgetPrivate::createLayout()
|
||||
{
|
||||
delete content->layout();
|
||||
|
||||
content->resize(q->size());
|
||||
|
||||
qDeleteAll(buttons);
|
||||
buttons.clear();
|
||||
|
||||
Q_FOREACH (QAction *action, q->actions()) {
|
||||
QToolButton *button = new QToolButton(content);
|
||||
button->setDefaultAction(action);
|
||||
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
buttons.append(button);
|
||||
}
|
||||
|
||||
// AutoRaise reduces visual clutter, but we don't want to turn it on if
|
||||
// there are other buttons, otherwise the close button will look different
|
||||
// from the others.
|
||||
closeButton->setAutoRaise(buttons.isEmpty());
|
||||
|
||||
if (wordWrap) {
|
||||
QGridLayout *layout = new QGridLayout(content);
|
||||
// Set alignment to make sure icon does not move down if text wraps
|
||||
layout->addWidget(iconLabel, 0, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
|
||||
layout->addWidget(textLabel, 0, 1);
|
||||
|
||||
if (buttons.isEmpty()) {
|
||||
// Use top-vertical alignment like the icon does.
|
||||
layout->addWidget(closeButton, 0, 2, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
|
||||
} else {
|
||||
// Use an additional layout in row 1 for the buttons.
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addStretch();
|
||||
Q_FOREACH (QToolButton *button, buttons) {
|
||||
// For some reason, calling show() is necessary if wordwrap is true,
|
||||
// otherwise the buttons do not show up. It is not needed if
|
||||
// wordwrap is false.
|
||||
button->show();
|
||||
buttonLayout->addWidget(button);
|
||||
}
|
||||
buttonLayout->addWidget(closeButton);
|
||||
layout->addItem(buttonLayout, 1, 0, 1, 2);
|
||||
}
|
||||
} else {
|
||||
QHBoxLayout *layout = new QHBoxLayout(content);
|
||||
layout->addWidget(iconLabel);
|
||||
layout->addWidget(textLabel);
|
||||
|
||||
for (QToolButton *button : qAsConst(buttons)) {
|
||||
layout->addWidget(button);
|
||||
}
|
||||
|
||||
layout->addWidget(closeButton);
|
||||
};
|
||||
|
||||
if (q->isVisible()) {
|
||||
q->setFixedHeight(content->sizeHint().height());
|
||||
}
|
||||
q->updateGeometry();
|
||||
}
|
||||
|
||||
void KMessageWidgetPrivate::applyStyleSheet()
|
||||
{
|
||||
QColor bgBaseColor;
|
||||
|
||||
// We have to hardcode colors here because KWidgetsAddons is a tier 1 framework
|
||||
// and therefore can't depend on any other KDE Frameworks
|
||||
// The following RGB color values come from the "default" scheme in kcolorscheme.cpp
|
||||
switch (messageType) {
|
||||
case KMessageWidget::Positive:
|
||||
bgBaseColor.setRgb(39, 174, 96); // Window: ForegroundPositive
|
||||
break;
|
||||
case KMessageWidget::Information:
|
||||
bgBaseColor.setRgb(61, 174, 233); // Window: ForegroundActive
|
||||
break;
|
||||
case KMessageWidget::Warning:
|
||||
bgBaseColor.setRgb(246, 116, 0); // Window: ForegroundNeutral
|
||||
break;
|
||||
case KMessageWidget::Error:
|
||||
bgBaseColor.setRgb(218, 68, 83); // Window: ForegroundNegative
|
||||
break;
|
||||
}
|
||||
const qreal bgBaseColorAlpha = 0.2;
|
||||
bgBaseColor.setAlphaF(bgBaseColorAlpha);
|
||||
|
||||
const QPalette palette = QGuiApplication::palette();
|
||||
const QColor windowColor = palette.window().color();
|
||||
const QColor textColor = palette.text().color();
|
||||
const QColor border = bgBaseColor;
|
||||
|
||||
// Generate a final background color from overlaying bgBaseColor over windowColor
|
||||
const int newRed = (bgBaseColor.red() * bgBaseColorAlpha) + (windowColor.red() * (1 - bgBaseColorAlpha));
|
||||
const int newGreen = (bgBaseColor.green() * bgBaseColorAlpha) + (windowColor.green() * (1 - bgBaseColorAlpha));
|
||||
const int newBlue = (bgBaseColor.blue() * bgBaseColorAlpha) + (windowColor.blue() * (1 - bgBaseColorAlpha));
|
||||
|
||||
const QColor bgFinalColor = QColor(newRed, newGreen, newBlue);
|
||||
|
||||
content->setStyleSheet(
|
||||
QString::fromLatin1(".QFrame {"
|
||||
"background-color: %1;"
|
||||
"border-radius: 4px;"
|
||||
"border: 2px solid %2;"
|
||||
"margin: %3px;"
|
||||
"}"
|
||||
".QLabel { color: %4; }"
|
||||
)
|
||||
.arg(bgFinalColor.name())
|
||||
.arg(border.name())
|
||||
// DefaultFrameWidth returns the size of the external margin + border width. We know our border is 1px, so we subtract this from the frame normal QStyle FrameWidth to get our margin
|
||||
.arg(q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, nullptr, q) - 1)
|
||||
.arg(textColor.name())
|
||||
);
|
||||
}
|
||||
|
||||
void KMessageWidgetPrivate::updateLayout()
|
||||
{
|
||||
if (content->layout()) {
|
||||
createLayout();
|
||||
}
|
||||
}
|
||||
|
||||
void KMessageWidgetPrivate::updateSnapShot()
|
||||
{
|
||||
// Attention: updateSnapShot calls QWidget::render(), which causes the whole
|
||||
// window layouts to be activated. Calling this method from resizeEvent()
|
||||
// can lead to infinite recursion, see:
|
||||
// https://bugs.kde.org/show_bug.cgi?id=311336
|
||||
contentSnapShot = QPixmap(content->size() * q->devicePixelRatio());
|
||||
contentSnapShot.setDevicePixelRatio(q->devicePixelRatio());
|
||||
contentSnapShot.fill(Qt::transparent);
|
||||
content->render(&contentSnapShot, QPoint(), QRegion(), QWidget::DrawChildren);
|
||||
}
|
||||
|
||||
void KMessageWidgetPrivate::slotTimeLineChanged(qreal value)
|
||||
{
|
||||
q->setFixedHeight(qMin(value * 2, qreal(1.0)) * content->height());
|
||||
q->update();
|
||||
}
|
||||
|
||||
void KMessageWidgetPrivate::slotTimeLineFinished()
|
||||
{
|
||||
if (timeLine->direction() == QTimeLine::Forward) {
|
||||
// Show
|
||||
// We set the whole geometry here, because it may be wrong if a
|
||||
// KMessageWidget is shown right when the toplevel window is created.
|
||||
content->setGeometry(0, 0, q->width(), bestContentHeight());
|
||||
|
||||
// notify about finished animation
|
||||
emit q->showAnimationFinished();
|
||||
} else {
|
||||
// hide and notify about finished animation
|
||||
q->hide();
|
||||
emit q->hideAnimationFinished();
|
||||
}
|
||||
}
|
||||
|
||||
int KMessageWidgetPrivate::bestContentHeight() const
|
||||
{
|
||||
int height = content->heightForWidth(q->width());
|
||||
if (height == -1) {
|
||||
height = content->sizeHint().height();
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// KMessageWidget
|
||||
//---------------------------------------------------------------------
|
||||
KMessageWidget::KMessageWidget(QWidget *parent)
|
||||
: QFrame(parent)
|
||||
, d(new KMessageWidgetPrivate)
|
||||
{
|
||||
d->init(this);
|
||||
}
|
||||
|
||||
KMessageWidget::KMessageWidget(const QString &text, QWidget *parent)
|
||||
: QFrame(parent)
|
||||
, d(new KMessageWidgetPrivate)
|
||||
{
|
||||
d->init(this);
|
||||
setText(text);
|
||||
}
|
||||
|
||||
KMessageWidget::~KMessageWidget()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString KMessageWidget::text() const
|
||||
{
|
||||
return d->textLabel->text();
|
||||
}
|
||||
|
||||
void KMessageWidget::setText(const QString &text)
|
||||
{
|
||||
d->textLabel->setText(text);
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
KMessageWidget::MessageType KMessageWidget::messageType() const
|
||||
{
|
||||
return d->messageType;
|
||||
}
|
||||
|
||||
void KMessageWidget::setMessageType(KMessageWidget::MessageType type)
|
||||
{
|
||||
d->messageType = type;
|
||||
d->applyStyleSheet();
|
||||
}
|
||||
|
||||
QSize KMessageWidget::sizeHint() const
|
||||
{
|
||||
ensurePolished();
|
||||
return d->content->sizeHint();
|
||||
}
|
||||
|
||||
QSize KMessageWidget::minimumSizeHint() const
|
||||
{
|
||||
ensurePolished();
|
||||
return d->content->minimumSizeHint();
|
||||
}
|
||||
|
||||
bool KMessageWidget::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Polish && !d->content->layout()) {
|
||||
d->createLayout();
|
||||
} else if (event->type() == QEvent::PaletteChange) {
|
||||
d->applyStyleSheet();
|
||||
} else if (event->type() == QEvent::Show && !d->ignoreShowEventDoingAnimatedShow) {
|
||||
if ((height() != d->content->height()) || (d->content->pos().y() != 0)) {
|
||||
d->content->move(0, 0);
|
||||
setFixedHeight(d->content->height());
|
||||
}
|
||||
}
|
||||
return QFrame::event(event);
|
||||
}
|
||||
|
||||
void KMessageWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QFrame::resizeEvent(event);
|
||||
|
||||
if (d->timeLine->state() == QTimeLine::NotRunning) {
|
||||
d->content->resize(width(), d->bestContentHeight());
|
||||
}
|
||||
}
|
||||
|
||||
int KMessageWidget::heightForWidth(int width) const
|
||||
{
|
||||
ensurePolished();
|
||||
return d->content->heightForWidth(width);
|
||||
}
|
||||
|
||||
void KMessageWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QFrame::paintEvent(event);
|
||||
if (d->timeLine->state() == QTimeLine::Running) {
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(d->timeLine->currentValue() * d->timeLine->currentValue());
|
||||
painter.drawPixmap(0, 0, d->contentSnapShot);
|
||||
}
|
||||
}
|
||||
|
||||
bool KMessageWidget::wordWrap() const
|
||||
{
|
||||
return d->wordWrap;
|
||||
}
|
||||
|
||||
void KMessageWidget::setWordWrap(bool wordWrap)
|
||||
{
|
||||
d->wordWrap = wordWrap;
|
||||
d->textLabel->setWordWrap(wordWrap);
|
||||
QSizePolicy policy = sizePolicy();
|
||||
policy.setHeightForWidth(wordWrap);
|
||||
setSizePolicy(policy);
|
||||
d->updateLayout();
|
||||
// Without this, when user does wordWrap -> !wordWrap -> wordWrap, a minimum
|
||||
// height is set, causing the widget to be too high.
|
||||
// Mostly visible in test programs.
|
||||
if (wordWrap) {
|
||||
setMinimumHeight(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool KMessageWidget::isCloseButtonVisible() const
|
||||
{
|
||||
return d->closeButton->isVisible();
|
||||
}
|
||||
|
||||
void KMessageWidget::setCloseButtonVisible(bool show)
|
||||
{
|
||||
d->closeButton->setVisible(show);
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void KMessageWidget::addAction(QAction *action)
|
||||
{
|
||||
QFrame::addAction(action);
|
||||
d->updateLayout();
|
||||
}
|
||||
|
||||
void KMessageWidget::removeAction(QAction *action)
|
||||
{
|
||||
QFrame::removeAction(action);
|
||||
d->updateLayout();
|
||||
}
|
||||
|
||||
void KMessageWidget::animatedShow()
|
||||
{
|
||||
// Test before styleHint, as there might have been a style change while animation was running
|
||||
if (isHideAnimationRunning()) {
|
||||
d->timeLine->stop();
|
||||
emit hideAnimationFinished();
|
||||
}
|
||||
|
||||
if (!style()->styleHint(QStyle::SH_Widget_Animate, nullptr, this)
|
||||
|| (parentWidget() && !parentWidget()->isVisible())) {
|
||||
show();
|
||||
emit showAnimationFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isVisible() && (d->timeLine->state() == QTimeLine::NotRunning) && (height() == d->bestContentHeight()) && (d->content->pos().y() == 0)) {
|
||||
emit showAnimationFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
d->ignoreShowEventDoingAnimatedShow = true;
|
||||
show();
|
||||
d->ignoreShowEventDoingAnimatedShow = false;
|
||||
setFixedHeight(0);
|
||||
int wantedHeight = d->bestContentHeight();
|
||||
d->content->setGeometry(0, -wantedHeight, width(), wantedHeight);
|
||||
|
||||
d->updateSnapShot();
|
||||
|
||||
d->timeLine->setDirection(QTimeLine::Forward);
|
||||
if (d->timeLine->state() == QTimeLine::NotRunning) {
|
||||
d->timeLine->start();
|
||||
}
|
||||
}
|
||||
|
||||
void KMessageWidget::animatedHide()
|
||||
{
|
||||
// test this before isVisible, as animatedShow might have been called directly before,
|
||||
// so the first timeline event is not yet done and the widget is still hidden
|
||||
// And before styleHint, as there might have been a style change while animation was running
|
||||
if (isShowAnimationRunning()) {
|
||||
d->timeLine->stop();
|
||||
emit showAnimationFinished();
|
||||
}
|
||||
|
||||
if (!style()->styleHint(QStyle::SH_Widget_Animate, nullptr, this)) {
|
||||
hide();
|
||||
emit hideAnimationFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isVisible()) {
|
||||
// explicitly hide it, so it stays hidden in case it is only not visible due to the parents
|
||||
hide();
|
||||
emit hideAnimationFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
d->content->move(0, -d->content->height());
|
||||
d->updateSnapShot();
|
||||
|
||||
d->timeLine->setDirection(QTimeLine::Backward);
|
||||
if (d->timeLine->state() == QTimeLine::NotRunning) {
|
||||
d->timeLine->start();
|
||||
}
|
||||
}
|
||||
|
||||
bool KMessageWidget::isHideAnimationRunning() const
|
||||
{
|
||||
return (d->timeLine->direction() == QTimeLine::Backward)
|
||||
&& (d->timeLine->state() == QTimeLine::Running);
|
||||
}
|
||||
|
||||
bool KMessageWidget::isShowAnimationRunning() const
|
||||
{
|
||||
return (d->timeLine->direction() == QTimeLine::Forward)
|
||||
&& (d->timeLine->state() == QTimeLine::Running);
|
||||
}
|
||||
|
||||
QIcon KMessageWidget::icon() const
|
||||
{
|
||||
return d->icon;
|
||||
}
|
||||
|
||||
void KMessageWidget::setIcon(const QIcon &icon)
|
||||
{
|
||||
d->icon = icon;
|
||||
if (d->icon.isNull()) {
|
||||
d->iconLabel->hide();
|
||||
} else {
|
||||
const int size = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
|
||||
d->iconLabel->setPixmap(d->icon.pixmap(size));
|
||||
d->iconLabel->show();
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_kmessagewidget.cpp"
|
||||
|
||||
346
src/3rdparty/kmessagewidget/kmessagewidget.h
vendored
Normal file
346
src/3rdparty/kmessagewidget/kmessagewidget.h
vendored
Normal file
@@ -0,0 +1,346 @@
|
||||
/* This file is part of the KDE libraries
|
||||
*
|
||||
* Copyright (c) 2011 Aurélien Gâteau <agateau@kde.org>
|
||||
* Copyright (c) 2014 Dominik Haumann <dhaumann@kde.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
#ifndef KMESSAGEWIDGET_H
|
||||
#define KMESSAGEWIDGET_H
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
class KMessageWidgetPrivate;
|
||||
|
||||
/**
|
||||
* @class KMessageWidget kmessagewidget.h KMessageWidget
|
||||
*
|
||||
* @short A widget to provide feedback or propose opportunistic interactions.
|
||||
*
|
||||
* KMessageWidget can be used to provide inline positive or negative
|
||||
* feedback, or to implement opportunistic interactions.
|
||||
*
|
||||
* As a feedback widget, KMessageWidget provides a less intrusive alternative
|
||||
* to "OK Only" message boxes. If you want to avoid a modal KMessageBox,
|
||||
* consider using KMessageWidget instead.
|
||||
*
|
||||
* Examples of KMessageWidget look as follows, all of them having an icon set
|
||||
* with setIcon(), and the first three show a close button:
|
||||
*
|
||||
* \image html kmessagewidget.png "KMessageWidget with different message types"
|
||||
*
|
||||
* <b>Negative feedback</b>
|
||||
*
|
||||
* The KMessageWidget can be used as a secondary indicator of failure: the
|
||||
* first indicator is usually the fact the action the user expected to happen
|
||||
* did not happen.
|
||||
*
|
||||
* Example: User fills a form, clicks "Submit".
|
||||
*
|
||||
* @li Expected feedback: form closes
|
||||
* @li First indicator of failure: form stays there
|
||||
* @li Second indicator of failure: a KMessageWidget appears on top of the
|
||||
* form, explaining the error condition
|
||||
*
|
||||
* When used to provide negative feedback, KMessageWidget should be placed
|
||||
* close to its context. In the case of a form, it should appear on top of the
|
||||
* form entries.
|
||||
*
|
||||
* KMessageWidget should get inserted in the existing layout. Space should not
|
||||
* be reserved for it, otherwise it becomes "dead space", ignored by the user.
|
||||
* KMessageWidget should also not appear as an overlay to prevent blocking
|
||||
* access to elements the user needs to interact with to fix the failure.
|
||||
*
|
||||
* <b>Positive feedback</b>
|
||||
*
|
||||
* KMessageWidget can be used for positive feedback but it shouldn't be
|
||||
* overused. It is often enough to provide feedback by simply showing the
|
||||
* results of an action.
|
||||
*
|
||||
* Examples of acceptable uses:
|
||||
*
|
||||
* @li Confirm success of "critical" transactions
|
||||
* @li Indicate completion of background tasks
|
||||
*
|
||||
* Example of unadapted uses:
|
||||
*
|
||||
* @li Indicate successful saving of a file
|
||||
* @li Indicate a file has been successfully removed
|
||||
*
|
||||
* <b>Opportunistic interaction</b>
|
||||
*
|
||||
* Opportunistic interaction is the situation where the application suggests to
|
||||
* the user an action he could be interested in perform, either based on an
|
||||
* action the user just triggered or an event which the application noticed.
|
||||
*
|
||||
* Example of acceptable uses:
|
||||
*
|
||||
* @li A browser can propose remembering a recently entered password
|
||||
* @li A music collection can propose ripping a CD which just got inserted
|
||||
* @li A chat application may notify the user a "special friend" just connected
|
||||
*
|
||||
* @author Aurélien Gâteau <agateau@kde.org>
|
||||
* @since 4.7
|
||||
*/
|
||||
class KMessageWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString text READ text WRITE setText)
|
||||
Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
|
||||
Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible)
|
||||
Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType)
|
||||
Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
|
||||
public:
|
||||
|
||||
/**
|
||||
* Available message types.
|
||||
* The background colors are chosen depending on the message type.
|
||||
*/
|
||||
enum MessageType {
|
||||
Positive,
|
||||
Information,
|
||||
Warning,
|
||||
Error
|
||||
};
|
||||
Q_ENUM(MessageType)
|
||||
|
||||
/**
|
||||
* Constructs a KMessageWidget with the specified @p parent.
|
||||
*/
|
||||
explicit KMessageWidget(QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Constructs a KMessageWidget with the specified @p parent and
|
||||
* contents @p text.
|
||||
*/
|
||||
explicit KMessageWidget(const QString &text, QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~KMessageWidget() override;
|
||||
|
||||
/**
|
||||
* Get the text of this message widget.
|
||||
* @see setText()
|
||||
*/
|
||||
QString text() const;
|
||||
|
||||
/**
|
||||
* Check whether word wrap is enabled.
|
||||
*
|
||||
* If word wrap is enabled, the message widget wraps the displayed text
|
||||
* as required to the available width of the widget. This is useful to
|
||||
* avoid breaking widget layouts.
|
||||
*
|
||||
* @see setWordWrap()
|
||||
*/
|
||||
bool wordWrap() const;
|
||||
|
||||
/**
|
||||
* Check whether the close button is visible.
|
||||
*
|
||||
* @see setCloseButtonVisible()
|
||||
*/
|
||||
bool isCloseButtonVisible() const;
|
||||
|
||||
/**
|
||||
* Get the type of this message.
|
||||
* By default, the type is set to KMessageWidget::Information.
|
||||
*
|
||||
* @see KMessageWidget::MessageType, setMessageType()
|
||||
*/
|
||||
MessageType messageType() const;
|
||||
|
||||
/**
|
||||
* Add @p action to the message widget.
|
||||
* For each action a button is added to the message widget in the
|
||||
* order the actions were added.
|
||||
*
|
||||
* @param action the action to add
|
||||
* @see removeAction(), QWidget::actions()
|
||||
*/
|
||||
void addAction(QAction *action);
|
||||
|
||||
/**
|
||||
* Remove @p action from the message widget.
|
||||
*
|
||||
* @param action the action to remove
|
||||
* @see KMessageWidget::MessageType, addAction(), setMessageType()
|
||||
*/
|
||||
void removeAction(QAction *action);
|
||||
|
||||
/**
|
||||
* Returns the preferred size of the message widget.
|
||||
*/
|
||||
QSize sizeHint() const override;
|
||||
|
||||
/**
|
||||
* Returns the minimum size of the message widget.
|
||||
*/
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
/**
|
||||
* Returns the required height for @p width.
|
||||
* @param width the width in pixels
|
||||
*/
|
||||
int heightForWidth(int width) const override;
|
||||
|
||||
/**
|
||||
* The icon shown on the left of the text. By default, no icon is shown.
|
||||
* @since 4.11
|
||||
*/
|
||||
QIcon icon() const;
|
||||
|
||||
/**
|
||||
* Check whether the hide animation started by calling animatedHide()
|
||||
* is still running. If animations are disabled, this function always
|
||||
* returns @e false.
|
||||
*
|
||||
* @see animatedHide(), hideAnimationFinished()
|
||||
* @since 5.0
|
||||
*/
|
||||
bool isHideAnimationRunning() const;
|
||||
|
||||
/**
|
||||
* Check whether the show animation started by calling animatedShow()
|
||||
* is still running. If animations are disabled, this function always
|
||||
* returns @e false.
|
||||
*
|
||||
* @see animatedShow(), showAnimationFinished()
|
||||
* @since 5.0
|
||||
*/
|
||||
bool isShowAnimationRunning() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* Set the text of the message widget to @p text.
|
||||
* If the message widget is already visible, the text changes on the fly.
|
||||
*
|
||||
* @param text the text to display, rich text is allowed
|
||||
* @see text()
|
||||
*/
|
||||
void setText(const QString &text);
|
||||
|
||||
/**
|
||||
* Set word wrap to @p wordWrap. If word wrap is enabled, the text()
|
||||
* of the message widget is wrapped to fit the available width.
|
||||
* If word wrap is disabled, the message widget's minimum size is
|
||||
* such that the entire text fits.
|
||||
*
|
||||
* @param wordWrap disable/enable word wrap
|
||||
* @see wordWrap()
|
||||
*/
|
||||
void setWordWrap(bool wordWrap);
|
||||
|
||||
/**
|
||||
* Set the visibility of the close button. If @p visible is @e true,
|
||||
* a close button is shown that calls animatedHide() if clicked.
|
||||
*
|
||||
* @see closeButtonVisible(), animatedHide()
|
||||
*/
|
||||
void setCloseButtonVisible(bool visible);
|
||||
|
||||
/**
|
||||
* Set the message type to @p type.
|
||||
* By default, the message type is set to KMessageWidget::Information.
|
||||
* Appropriate colors are chosen to mimic the appearance of Kirigami's
|
||||
* InlineMessage.
|
||||
*
|
||||
* @see messageType(), KMessageWidget::MessageType
|
||||
*/
|
||||
void setMessageType(KMessageWidget::MessageType type);
|
||||
|
||||
/**
|
||||
* Show the widget using an animation.
|
||||
*/
|
||||
void animatedShow();
|
||||
|
||||
/**
|
||||
* Hide the widget using an animation.
|
||||
*/
|
||||
void animatedHide();
|
||||
|
||||
/**
|
||||
* Define an icon to be shown on the left of the text
|
||||
* @since 4.11
|
||||
*/
|
||||
void setIcon(const QIcon &icon);
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal is emitted when the user clicks a link in the text label.
|
||||
* The URL referred to by the href anchor is passed in contents.
|
||||
* @param contents text of the href anchor
|
||||
* @see QLabel::linkActivated()
|
||||
* @since 4.10
|
||||
*/
|
||||
void linkActivated(const QString &contents);
|
||||
|
||||
/**
|
||||
* This signal is emitted when the user hovers over a link in the text label.
|
||||
* The URL referred to by the href anchor is passed in contents.
|
||||
* @param contents text of the href anchor
|
||||
* @see QLabel::linkHovered()
|
||||
* @since 4.11
|
||||
*/
|
||||
void linkHovered(const QString &contents);
|
||||
|
||||
/**
|
||||
* This signal is emitted when the hide animation is finished, started by
|
||||
* calling animatedHide(). If animations are disabled, this signal is
|
||||
* emitted immediately after the message widget got hidden.
|
||||
*
|
||||
* @note This signal is @e not emitted if the widget was hidden by
|
||||
* calling hide(), so this signal is only useful in conjunction
|
||||
* with animatedHide().
|
||||
*
|
||||
* @see animatedHide()
|
||||
* @since 5.0
|
||||
*/
|
||||
void hideAnimationFinished();
|
||||
|
||||
/**
|
||||
* This signal is emitted when the show animation is finished, started by
|
||||
* calling animatedShow(). If animations are disabled, this signal is
|
||||
* emitted immediately after the message widget got shown.
|
||||
*
|
||||
* @note This signal is @e not emitted if the widget was shown by
|
||||
* calling show(), so this signal is only useful in conjunction
|
||||
* with animatedShow().
|
||||
*
|
||||
* @see animatedShow()
|
||||
* @since 5.0
|
||||
*/
|
||||
void showAnimationFinished();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
KMessageWidgetPrivate *const d;
|
||||
friend class KMessageWidgetPrivate;
|
||||
|
||||
Q_PRIVATE_SLOT(d, void slotTimeLineChanged(qreal))
|
||||
Q_PRIVATE_SLOT(d, void slotTimeLineFinished())
|
||||
};
|
||||
|
||||
#endif /* KMESSAGEWIDGET_H */
|
||||
@@ -165,6 +165,7 @@ set(3rdparty_SRC
|
||||
../3rdparty/qtsingleapplication/qtlocalpeer.cpp
|
||||
../3rdparty/qtsingleapplication/qtsingleapplication.cpp
|
||||
../3rdparty/qtsingleapplication/qtsinglecoreapplication.cpp
|
||||
../3rdparty/kmessagewidget/kmessagewidget.cpp
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
@@ -329,6 +330,7 @@ target_include_directories(${APPLICATION_EXECUTABLE} PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/qtlockedfile
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/qtmacgoodies/src
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/qtsingleapplication
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/kmessagewidget
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
|
||||
@@ -342,9 +342,6 @@ AccountPtr AccountManager::createAccount()
|
||||
connect(acc.data(), &Account::proxyAuthenticationRequired,
|
||||
ProxyAuthHandler::instance(), &ProxyAuthHandler::handleProxyAuthenticationRequired);
|
||||
|
||||
connect(acc.data()->e2e(), &ClientSideEncryption::mnemonicGenerated,
|
||||
&AccountManager::displayMnemonic);
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
@@ -364,6 +361,7 @@ void AccountManager::displayMnemonic(const QString& mnemonic)
|
||||
widget->exec();
|
||||
widget->resize(widget->sizeHint());
|
||||
}
|
||||
|
||||
void AccountManager::shutdown()
|
||||
{
|
||||
auto accountsCopy = _accounts;
|
||||
|
||||
@@ -194,6 +194,14 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent)
|
||||
// Connect E2E stuff
|
||||
connect(this, &AccountSettings::requesetMnemonic, _accountState->account()->e2e(), &ClientSideEncryption::slotRequestMnemonic);
|
||||
connect(_accountState->account()->e2e(), &ClientSideEncryption::showMnemonic, this, &AccountSettings::slotShowMnemonic);
|
||||
|
||||
connect(_accountState->account()->e2e(), &ClientSideEncryption::mnemonicGenerated, this, &AccountSettings::slotNewMnemonicGenerated);
|
||||
if (_accountState->account()->e2e()->newMnemonicGenerated())
|
||||
{
|
||||
slotNewMnemonicGenerated();
|
||||
} else {
|
||||
ui->encryptionMessage->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -222,6 +230,19 @@ void AccountSettings::createAccountToolbox()
|
||||
slotAccountAdded(_accountState);
|
||||
}
|
||||
|
||||
|
||||
void AccountSettings::slotNewMnemonicGenerated()
|
||||
{
|
||||
ui->encryptionMessage->setText(tr("This account supports end-to-end encryption"));
|
||||
|
||||
QAction *mnemonic = new QAction(tr("Enable encryption"), this);
|
||||
connect(mnemonic, &QAction::triggered, this, &AccountSettings::requesetMnemonic);
|
||||
connect(mnemonic, &QAction::triggered, ui->encryptionMessage, &KMessageWidget::hide);
|
||||
|
||||
ui->encryptionMessage->addAction(mnemonic);
|
||||
ui->encryptionMessage->show();
|
||||
}
|
||||
|
||||
void AccountSettings::slotMenuBeforeShow() {
|
||||
if (_menuShown) {
|
||||
return;
|
||||
|
||||
@@ -99,6 +99,7 @@ protected slots:
|
||||
|
||||
// Encryption Related Stuff.
|
||||
void slotShowMnemonic(const QString &mnemonic);
|
||||
void slotNewMnemonicGenerated();
|
||||
|
||||
void slotEncryptionFlagSuccess(const QByteArray &folderId);
|
||||
void slotEncryptionFlagError(const QByteArray &folderId, int httpReturnCode);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>575</width>
|
||||
<width>582</width>
|
||||
<height>557</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -14,128 +14,7 @@
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QWidget" name="accountStatus" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="SslButton" name="sslButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="connectLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Connected with <server> as <user></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="_accountToolbox">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="storageGroupBox">
|
||||
<item>
|
||||
<widget class="QLabel" name="quotaInfoLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Storage space: ...</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="quotaProgressBar">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>7</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="OCC::FolderStatusView" name="_folderList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>5</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QWidget" name="selectiveSyncStatus" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
@@ -267,6 +146,130 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QWidget" name="accountStatus" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="SslButton" name="sslButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="connectLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Connected with <server> as <user></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="_accountToolbox">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout" name="storageGroupBox">
|
||||
<item>
|
||||
<widget class="QLabel" name="quotaInfoLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Storage space: ...</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="quotaProgressBar">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>7</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="OCC::FolderStatusView" name="_folderList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>5</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="KMessageWidget" name="encryptionMessage" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
@@ -280,6 +283,12 @@
|
||||
<extends>QTreeView</extends>
|
||||
<header>folderstatusview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KMessageWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>kmessagewidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@@ -105,7 +105,8 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
||||
} else if(a._status == SyncFileItem::SoftError
|
||||
|| a._status == SyncFileItem::FileIgnored
|
||||
|| a._status == SyncFileItem::Conflict
|
||||
|| a._status == SyncFileItem::Restoration){
|
||||
|| a._status == SyncFileItem::Restoration
|
||||
|| a._status == SyncFileItem::FileLocked){
|
||||
return QIcon(QLatin1String(":/client/resources/state-warning.svg"));
|
||||
}
|
||||
return QIcon(QLatin1String(":/client/resources/state-sync.svg"));
|
||||
@@ -233,6 +234,12 @@ void ActivityListModel::addNotificationToActivityList(Activity activity) {
|
||||
combineActivityLists();
|
||||
}
|
||||
|
||||
void ActivityListModel::clearNotifications() {
|
||||
qCInfo(lcActivity) << "Clear the notifications";
|
||||
_notificationLists.clear();
|
||||
combineActivityLists();
|
||||
}
|
||||
|
||||
void ActivityListModel::removeActivityFromActivityList(int row) {
|
||||
Activity activity = _finalList.at(row);
|
||||
removeActivityFromActivityList(activity);
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
ActivityList activityList() { return _finalList; }
|
||||
ActivityList errorsList() { return _notificationErrorsLists; }
|
||||
void addNotificationToActivityList(Activity activity);
|
||||
void clearNotifications();
|
||||
void addErrorToActivityList(Activity activity);
|
||||
void addSyncFileItemToActivityList(Activity activity);
|
||||
void removeActivityFromActivityList(int row);
|
||||
|
||||
@@ -121,6 +121,11 @@ void ActivityWidget::slotProgressInfo(const QString &folder, const ProgressInfo
|
||||
continue;
|
||||
}
|
||||
|
||||
if(activity._status == SyncFileItem::FileLocked && !QFileInfo(f->path() + activity._file).exists()){
|
||||
_model->removeActivityFromActivityList(activity);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(activity._status == SyncFileItem::FileIgnored && !QFileInfo(f->path() + activity._file).exists()){
|
||||
_model->removeActivityFromActivityList(activity);
|
||||
@@ -179,7 +184,8 @@ void ActivityWidget::slotItemCompleted(const QString &folder, const SyncFileItem
|
||||
|
||||
if(item->_status == SyncFileItem::NoStatus || item->_status == SyncFileItem::Success){
|
||||
qCWarning(lcActivity) << "Item " << item->_file << " retrieved successfully.";
|
||||
activity._message.prepend(tr("Synced "));
|
||||
activity._message.prepend(" ");
|
||||
activity._message.prepend(tr("Synced"));
|
||||
_model->addSyncFileItemToActivityList(activity);
|
||||
} else {
|
||||
qCWarning(lcActivity) << "Item " << item->_file << " retrieved resulted in error " << item->_errorString;
|
||||
@@ -430,20 +436,17 @@ void ActivityWidget::slotOpenFile(QModelIndex indx)
|
||||
// collected.
|
||||
void ActivityWidget::slotBuildNotificationDisplay(const ActivityList &list)
|
||||
{
|
||||
QString listAccountName;
|
||||
|
||||
// Whether a new notification was added to the list
|
||||
bool newNotificationShown = false;
|
||||
|
||||
_model->clearNotifications();
|
||||
|
||||
foreach (auto activity, list) {
|
||||
if (_blacklistedNotifications.contains(activity)) {
|
||||
qCInfo(lcActivity) << "Activity in blacklist, skip";
|
||||
continue;
|
||||
}
|
||||
|
||||
// remember the list account name for the strayCat handling below.
|
||||
listAccountName = activity._accName;
|
||||
|
||||
// handle gui logs. In order to NOT annoy the user with every fetching of the
|
||||
// notifications the notification id is stored in a Set. Only if an id
|
||||
// is not in the set, it qualifies for guiLog.
|
||||
@@ -468,14 +471,15 @@ void ActivityWidget::slotBuildNotificationDisplay(const ActivityList &list)
|
||||
emit guiLog(activity._subject, activity._accName);
|
||||
}
|
||||
}
|
||||
|
||||
_model->addNotificationToActivityList(activity);
|
||||
}
|
||||
|
||||
_model->addNotificationToActivityList(activity);
|
||||
}
|
||||
|
||||
// restart the gui log timer now that we show a new notification
|
||||
if(newNotificationShown)
|
||||
if(newNotificationShown) {
|
||||
_guiLogTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
void ActivityWidget::slotSendNotificationRequest(const QString &accountName, const QString &link, const QByteArray &verb, int row)
|
||||
|
||||
@@ -72,7 +72,8 @@ namespace {
|
||||
" (to be used with --logdir)\n"
|
||||
" --logflush : flush the log file after every write.\n"
|
||||
" --logdebug : also output debug-level messages in the log.\n"
|
||||
" --confdir <dirname> : Use the given configuration folder.\n";
|
||||
" --confdir <dirname> : Use the given configuration folder.\n"
|
||||
" --background : launch the application in the background.\n";
|
||||
|
||||
QString applicationTrPath()
|
||||
{
|
||||
@@ -106,6 +107,7 @@ Application::Application(int &argc, char **argv)
|
||||
, _logDebug(false)
|
||||
, _userTriggeredConnect(false)
|
||||
, _debugMode(false)
|
||||
, _backgroundMode(false)
|
||||
{
|
||||
_startedAt.start();
|
||||
|
||||
@@ -467,6 +469,8 @@ void Application::parseOptions(const QStringList &options)
|
||||
} else if (option == QLatin1String("--debug")) {
|
||||
_logDebug = true;
|
||||
_debugMode = true;
|
||||
} else if (option == QLatin1String("--background")) {
|
||||
_backgroundMode = true;
|
||||
} else if (option == QLatin1String("--version")) {
|
||||
_versionOnly = true;
|
||||
} else {
|
||||
@@ -540,6 +544,11 @@ bool Application::debugMode()
|
||||
return _debugMode;
|
||||
}
|
||||
|
||||
bool Application::backgroundMode() const
|
||||
{
|
||||
return _backgroundMode;
|
||||
}
|
||||
|
||||
void Application::setHelp()
|
||||
{
|
||||
_helpOnly = true;
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
void showHelp();
|
||||
void showHint(std::string errorHint);
|
||||
bool debugMode();
|
||||
bool backgroundMode() const;
|
||||
bool versionOnly(); // only display the version?
|
||||
void showVersion();
|
||||
|
||||
@@ -112,6 +113,7 @@ private:
|
||||
bool _logDebug;
|
||||
bool _userTriggeredConnect;
|
||||
bool _debugMode;
|
||||
bool _backgroundMode;
|
||||
|
||||
ClientProxy _proxy;
|
||||
|
||||
|
||||
@@ -74,29 +74,37 @@ void ClientProxy::setupQtProxyFromConfig()
|
||||
}
|
||||
|
||||
switch (proxyType) {
|
||||
case QNetworkProxy::NoProxy:
|
||||
qCInfo(lcClientProxy) << "Set proxy configuration to use NO proxy";
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
|
||||
break;
|
||||
case QNetworkProxy::DefaultProxy:
|
||||
qCInfo(lcClientProxy) << "Set proxy configuration to use system configuration";
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||
break;
|
||||
case QNetworkProxy::Socks5Proxy:
|
||||
proxy.setType(QNetworkProxy::Socks5Proxy);
|
||||
qCInfo(lcClientProxy) << "Set proxy configuration to SOCKS5" << printQNetworkProxy(proxy);
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||
QNetworkProxy::setApplicationProxy(proxy);
|
||||
break;
|
||||
case QNetworkProxy::HttpProxy:
|
||||
proxy.setType(QNetworkProxy::HttpProxy);
|
||||
qCInfo(lcClientProxy) << "Set proxy configuration to HTTP" << printQNetworkProxy(proxy);
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||
QNetworkProxy::setApplicationProxy(proxy);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case QNetworkProxy::NoProxy:
|
||||
qCInfo(lcClientProxy) << "Set proxy configuration to use NO proxy";
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
|
||||
break;
|
||||
case QNetworkProxy::DefaultProxy:
|
||||
qCInfo(lcClientProxy) << "Set proxy configuration to use the prefered system proxy for http tcp connections";
|
||||
{
|
||||
QNetworkProxyQuery query;
|
||||
query.setProtocolTag("http");
|
||||
query.setQueryType(QNetworkProxyQuery::TcpSocket);
|
||||
auto proxies = QNetworkProxyFactory::proxyForQuery(query);
|
||||
proxy = proxies.first();
|
||||
}
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||
QNetworkProxy::setApplicationProxy(proxy);
|
||||
break;
|
||||
case QNetworkProxy::Socks5Proxy:
|
||||
proxy.setType(QNetworkProxy::Socks5Proxy);
|
||||
qCInfo(lcClientProxy) << "Set proxy configuration to SOCKS5" << printQNetworkProxy(proxy);
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||
QNetworkProxy::setApplicationProxy(proxy);
|
||||
break;
|
||||
case QNetworkProxy::HttpProxy:
|
||||
proxy.setType(QNetworkProxy::HttpProxy);
|
||||
qCInfo(lcClientProxy) << "Set proxy configuration to HTTP" << printQNetworkProxy(proxy);
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(false);
|
||||
QNetworkProxy::setApplicationProxy(proxy);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ extern "C" {
|
||||
|
||||
CloudProvidersProviderExporter *_providerExporter;
|
||||
|
||||
void on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data)
|
||||
void on_name_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data)
|
||||
{
|
||||
Q_UNUSED(name);
|
||||
CloudProviderManager *self;
|
||||
@@ -34,6 +34,14 @@ void on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer u
|
||||
self->registerSignals();
|
||||
}
|
||||
|
||||
void on_name_lost (GDBusConnection *connection, const gchar *name, gpointer user_data)
|
||||
{
|
||||
Q_UNUSED(connection);
|
||||
Q_UNUSED(name);
|
||||
Q_UNUSED(user_data);
|
||||
g_clear_object (&_providerExporter);
|
||||
}
|
||||
|
||||
void CloudProviderManager::registerSignals()
|
||||
{
|
||||
OCC::FolderMan *folderManager = OCC::FolderMan::instance();
|
||||
@@ -45,7 +53,7 @@ CloudProviderManager::CloudProviderManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
_map = new QMap<QString, CloudProviderWrapper*>();
|
||||
QString busName = QString(LIBCLOUDPROVIDERS_DBUS_BUS_NAME);
|
||||
g_bus_own_name (G_BUS_TYPE_SESSION, busName.toAscii().data(), G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, nullptr, nullptr, this, nullptr);
|
||||
g_bus_own_name (G_BUS_TYPE_SESSION, busName.toAscii().data(), G_BUS_NAME_OWNER_FLAGS_NONE, nullptr, on_name_acquired, nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
void CloudProviderManager::slotFolderListChanged(const Folder::Map &folderMap)
|
||||
|
||||
@@ -33,33 +33,25 @@ using namespace OCC;
|
||||
|
||||
GSimpleActionGroup *actionGroup = nullptr;
|
||||
|
||||
static
|
||||
gchar* qstring_to_gchar(const QString &string)
|
||||
{
|
||||
QByteArray ba = string.toUtf8();
|
||||
char* data = ba.data();
|
||||
return g_strdup(data);
|
||||
}
|
||||
|
||||
CloudProviderWrapper::CloudProviderWrapper(QObject *parent, Folder *folder, CloudProvidersProviderExporter* cloudprovider) : QObject(parent)
|
||||
, _folder(folder)
|
||||
{
|
||||
GMenuModel *model;
|
||||
GActionGroup *action_group;
|
||||
_recentlyChanged = new QList<QPair<QString, QString>>();
|
||||
gchar *accountName = g_strdup_printf ("Account%sFolder%s",
|
||||
qstring_to_gchar(folder->alias()),
|
||||
qstring_to_gchar(folder->accountState()->account()->id()));
|
||||
QString accountName = QString("Account%1Folder%2").arg(folder->alias(), folder->accountState()->account()->id());
|
||||
|
||||
_cloudProvider = CLOUD_PROVIDERS_PROVIDER_EXPORTER(cloudprovider);
|
||||
_cloudProviderAccount = cloud_providers_account_exporter_new(_cloudProvider, accountName);
|
||||
_cloudProviderAccount = cloud_providers_account_exporter_new(_cloudProvider, accountName.toUtf8().data());
|
||||
|
||||
gchar* folderName = qstring_to_gchar(folder->shortGuiLocalPath());
|
||||
gchar* folderPath = qstring_to_gchar(folder->cleanPath());
|
||||
cloud_providers_account_exporter_set_name (_cloudProviderAccount, folderName);
|
||||
cloud_providers_account_exporter_set_name (_cloudProviderAccount, folder->shortGuiLocalPath().toUtf8().data());
|
||||
cloud_providers_account_exporter_set_icon (_cloudProviderAccount, g_icon_new_for_string(APPLICATION_ICON_NAME, nullptr));
|
||||
cloud_providers_account_exporter_set_path (_cloudProviderAccount, folderPath);
|
||||
cloud_providers_account_exporter_set_path (_cloudProviderAccount, folder->cleanPath().toUtf8().data());
|
||||
cloud_providers_account_exporter_set_status (_cloudProviderAccount, CLOUD_PROVIDERS_ACCOUNT_STATUS_IDLE);
|
||||
cloud_providers_account_exporter_set_menu_model (_cloudProviderAccount, getMenuModel());
|
||||
cloud_providers_account_exporter_set_action_group (_cloudProviderAccount, getActionGroup());
|
||||
model = getMenuModel();
|
||||
cloud_providers_account_exporter_set_menu_model (_cloudProviderAccount, model);
|
||||
action_group = getActionGroup();
|
||||
cloud_providers_account_exporter_set_action_group (_cloudProviderAccount, action_group);
|
||||
|
||||
connect(ProgressDispatcher::instance(), SIGNAL(progressInfo(QString, ProgressInfo)), this, SLOT(slotUpdateProgress(QString, ProgressInfo)));
|
||||
connect(_folder, SIGNAL(syncStarted()), this, SLOT(slotSyncStarted()));
|
||||
@@ -68,10 +60,8 @@ CloudProviderWrapper::CloudProviderWrapper(QObject *parent, Folder *folder, Clou
|
||||
|
||||
_paused = _folder->syncPaused();
|
||||
updatePauseStatus();
|
||||
|
||||
g_free(accountName);
|
||||
g_free(folderName);
|
||||
g_free(folderPath);
|
||||
g_clear_object (&model);
|
||||
g_clear_object (&action_group);
|
||||
}
|
||||
|
||||
CloudProviderWrapper::~CloudProviderWrapper()
|
||||
@@ -93,6 +83,16 @@ static bool shouldShowInRecentsMenu(const SyncFileItem &item)
|
||||
&& item._instruction != CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
|
||||
static GMenuItem *menu_item_new(const QString &label, const gchar *detailed_action)
|
||||
{
|
||||
return g_menu_item_new(label.toUtf8 ().data(), detailed_action);
|
||||
}
|
||||
|
||||
static GMenuItem *menu_item_new_submenu(const QString &label, GMenuModel *submenu)
|
||||
{
|
||||
return g_menu_item_new_submenu(label.toUtf8 ().data(), submenu);
|
||||
}
|
||||
|
||||
void CloudProviderWrapper::slotUpdateProgress(const QString &folder, const ProgressInfo &progress)
|
||||
{
|
||||
// Only update progress for the current folder
|
||||
@@ -154,30 +154,25 @@ void CloudProviderWrapper::slotUpdateProgress(const QString &folder, const Progr
|
||||
if(!_recentlyChanged->isEmpty()) {
|
||||
QList<QPair<QString, QString>>::iterator i;
|
||||
for (i = _recentlyChanged->begin(); i != _recentlyChanged->end(); i++) {
|
||||
gchar *file;
|
||||
QString label = i->first;
|
||||
QString fullPath = i->second;
|
||||
file = g_strdup(qstring_to_gchar(label));
|
||||
item = g_menu_item_new(file, "cloudprovider.showfile");
|
||||
g_menu_item_set_action_and_target_value(item, "cloudprovider.showfile", g_variant_new_string(qstring_to_gchar(fullPath)));
|
||||
item = menu_item_new(label, "cloudprovider.showfile");
|
||||
g_menu_item_set_action_and_target_value(item, "cloudprovider.showfile", g_variant_new_string(fullPath.toUtf8().data()));
|
||||
g_menu_append_item(_recentMenu, item);
|
||||
g_clear_object (&item);
|
||||
}
|
||||
} else {
|
||||
item = g_menu_item_new("No recently changed files", nullptr);
|
||||
item = menu_item_new(tr("No recently changed files"), nullptr);
|
||||
g_menu_append_item(_recentMenu, item);
|
||||
g_clear_object (&item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CloudProviderWrapper::updateStatusText(QString statusText)
|
||||
{
|
||||
char* state = qstring_to_gchar(_folder->accountState()->stateString(_folder->accountState()->state()));
|
||||
char* statusChar = qstring_to_gchar(statusText);
|
||||
char* status = g_strdup_printf("%s - %s", state, statusChar);
|
||||
cloud_providers_account_exporter_set_status_details(_cloudProviderAccount, status);
|
||||
g_free(state);
|
||||
g_free(statusChar);
|
||||
g_free(status);
|
||||
QString status = QString("%1 - %2").arg(_folder->accountState()->stateString(_folder->accountState()->state()), statusText);
|
||||
cloud_providers_account_exporter_set_status_details(_cloudProviderAccount, status.toUtf8().data());
|
||||
}
|
||||
|
||||
void CloudProviderWrapper::updatePauseStatus()
|
||||
@@ -217,38 +212,53 @@ GMenuModel* CloudProviderWrapper::getMenuModel() {
|
||||
|
||||
GMenu* section;
|
||||
GMenuItem* item;
|
||||
QString item_label;
|
||||
|
||||
_mainMenu = g_menu_new();
|
||||
|
||||
section = g_menu_new();
|
||||
item = g_menu_item_new("Open website", "cloudprovider.openwebsite");
|
||||
item = menu_item_new(tr("Open website"), "cloudprovider.openwebsite");
|
||||
g_menu_append_item(section, item);
|
||||
g_clear_object (&item);
|
||||
g_menu_append_section(_mainMenu, nullptr, G_MENU_MODEL(section));
|
||||
g_clear_object (§ion);
|
||||
|
||||
_recentMenu = g_menu_new();
|
||||
item = g_menu_item_new("No recently changed files", nullptr);
|
||||
item = menu_item_new(tr("No recently changed files"), nullptr);
|
||||
g_menu_append_item(_recentMenu, item);
|
||||
section = g_menu_new();
|
||||
item = g_menu_item_new_submenu("Recently changed", G_MENU_MODEL(_recentMenu));
|
||||
g_menu_append_item(section, item);
|
||||
g_menu_append_section(_mainMenu, nullptr, G_MENU_MODEL(section));
|
||||
g_clear_object (&item);
|
||||
|
||||
section = g_menu_new();
|
||||
item = g_menu_item_new("Pause synchronization", "cloudprovider.pause");
|
||||
item = menu_item_new_submenu(tr("Recently changed"), G_MENU_MODEL(_recentMenu));
|
||||
g_menu_append_item(section, item);
|
||||
g_clear_object (&item);
|
||||
g_menu_append_section(_mainMenu, nullptr, G_MENU_MODEL(section));
|
||||
g_clear_object (§ion);
|
||||
|
||||
section = g_menu_new();
|
||||
item = g_menu_item_new("Help", "cloudprovider.openhelp");
|
||||
g_menu_append_item(section, item);
|
||||
item = g_menu_item_new("Settings", "cloudprovider.opensettings");
|
||||
g_menu_append_item(section, item);
|
||||
item = g_menu_item_new("Log out", "cloudprovider.logout");
|
||||
g_menu_append_item(section, item);
|
||||
item = g_menu_item_new("Quit sync client", "cloudprovider.quit");
|
||||
item = menu_item_new(tr("Pause synchronization"), "cloudprovider.pause");
|
||||
g_menu_append_item(section, item);
|
||||
g_clear_object (&item);
|
||||
g_menu_append_section(_mainMenu, nullptr, G_MENU_MODEL(section));
|
||||
g_clear_object (§ion);
|
||||
|
||||
section = g_menu_new();
|
||||
item = menu_item_new(tr("Help"), "cloudprovider.openhelp");
|
||||
g_menu_append_item(section, item);
|
||||
g_clear_object (&item);
|
||||
item = menu_item_new(tr("Settings"), "cloudprovider.opensettings");
|
||||
g_menu_append_item(section, item);
|
||||
g_clear_object (&item);
|
||||
item = menu_item_new(tr("Log out"), "cloudprovider.logout");
|
||||
g_menu_append_item(section, item);
|
||||
g_clear_object (&item);
|
||||
item = menu_item_new(tr("Quit sync client"), "cloudprovider.quit");
|
||||
g_menu_append_item(section, item);
|
||||
g_clear_object (&item);
|
||||
g_menu_append_section(_mainMenu, nullptr, G_MENU_MODEL(section));
|
||||
g_clear_object (§ion);
|
||||
|
||||
g_clear_object (&_recentMenu);
|
||||
return G_MENU_MODEL(_mainMenu);
|
||||
}
|
||||
|
||||
@@ -277,11 +287,10 @@ activate_action_open (GSimpleAction *action, GVariant *parameter, gpointer user_
|
||||
}
|
||||
|
||||
if(g_str_equal(name, "showfile")) {
|
||||
gchar *path;
|
||||
g_variant_get (parameter, "s", &path);
|
||||
g_print("showfile => %s\n", path);
|
||||
showInFileManager(QString(path));
|
||||
}
|
||||
const gchar *path = g_variant_get_string (parameter, NULL);
|
||||
g_print("showfile => %s\n", path);
|
||||
showInFileManager(QString(path));
|
||||
}
|
||||
|
||||
if(g_str_equal(name, "logout")) {
|
||||
self->folder()->accountState()->signOutByUi();
|
||||
@@ -331,12 +340,13 @@ static GActionEntry actions[] = {
|
||||
|
||||
GActionGroup* CloudProviderWrapper::getActionGroup()
|
||||
{
|
||||
g_clear_object (&actionGroup);
|
||||
actionGroup = g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actionGroup), actions, G_N_ELEMENTS (actions), this);
|
||||
bool state = _folder->syncPaused();
|
||||
GAction *pause = g_action_map_lookup_action(G_ACTION_MAP(actionGroup), "pause");
|
||||
g_simple_action_set_state(G_SIMPLE_ACTION(pause), g_variant_new_boolean(state));
|
||||
return G_ACTION_GROUP (actionGroup);
|
||||
return G_ACTION_GROUP (g_object_ref (actionGroup));
|
||||
}
|
||||
|
||||
void CloudProviderWrapper::slotSyncPausedChanged(Folder *folder, bool state)
|
||||
|
||||
@@ -148,7 +148,7 @@ QString HttpCredentialsGui::requestAppPasswordText(const Account *account)
|
||||
} else if (version >= Account::makeServerVersion(12, 0, 0)) {
|
||||
url += QLatin1String("/index.php/settings/personal#security");
|
||||
} else if (version >= Account::makeServerVersion(11, 0, 0)) {
|
||||
url += QLatin1String("/index.php/settings/personal#apppasswords");
|
||||
url += QLatin1String("/index.php/settings/user/security#security");
|
||||
} else {
|
||||
return QString();
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ ShibbolethWebView::ShibbolethWebView(AccountPtr account, QWidget *parent)
|
||||
QWebView *debugView = new QWebView(this);
|
||||
debugView->setPage(debugPage);
|
||||
QMainWindow *window = new QMainWindow(this);
|
||||
window->setWindowTitle(tr("SSL Chipher Debug View"));
|
||||
window->setWindowTitle(tr("SSL Cipher Debug View"));
|
||||
window->setCentralWidget(debugView);
|
||||
window->show();
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ void WebFlowCredentials::askFromUser() {
|
||||
|
||||
connect(_askDialog, &WebFlowCredentialsDialog::urlCatched, this, &WebFlowCredentials::slotAskFromUserCredentialsProvided);
|
||||
|
||||
qCWarning(lcWebFlowCredentials()) << "User needs to reauth!";
|
||||
qCDebug(lcWebFlowCredentials()) << "User needs to reauth!";
|
||||
}
|
||||
|
||||
void WebFlowCredentials::slotAskFromUserCredentialsProvided(const QString &user, const QString &pass, const QString &host) {
|
||||
@@ -165,9 +165,10 @@ void WebFlowCredentials::slotAskFromUserCredentialsProvided(const QString &user,
|
||||
|
||||
|
||||
bool WebFlowCredentials::stillValid(QNetworkReply *reply) {
|
||||
qCWarning(lcWebFlowCredentials()) << "Still valid?";
|
||||
qCWarning(lcWebFlowCredentials()) << reply->error();
|
||||
qCWarning(lcWebFlowCredentials()) << reply->errorString();
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(lcWebFlowCredentials()) << reply->error();
|
||||
qCWarning(lcWebFlowCredentials()) << reply->errorString();
|
||||
}
|
||||
return (reply->error() != QNetworkReply::AuthenticationRequiredError);
|
||||
}
|
||||
|
||||
@@ -208,7 +209,7 @@ void WebFlowCredentials::forgetSensitiveData(){
|
||||
|
||||
const QString kck = keychainKey(_account->url().toString(), _user, _account->id());
|
||||
if (kck.isEmpty()) {
|
||||
qCWarning(lcWebFlowCredentials()) << "InvalidateToken: User is empty, bailing out!";
|
||||
qCDebug(lcWebFlowCredentials()) << "InvalidateToken: User is empty, bailing out!";
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -243,7 +244,7 @@ void WebFlowCredentials::slotAuthentication(QNetworkReply *reply, QAuthenticator
|
||||
return;
|
||||
}
|
||||
|
||||
qCWarning(lcWebFlowCredentials()) << "Requires authentication";
|
||||
qCDebug(lcWebFlowCredentials()) << "Requires authentication";
|
||||
|
||||
authenticator->setUser(_user);
|
||||
authenticator->setPassword(_password);
|
||||
@@ -296,7 +297,7 @@ void WebFlowCredentials::slotReadPasswordJobDone(Job *incomingJob) {
|
||||
_keychainMigration = false;
|
||||
persist();
|
||||
deleteOldKeychainEntries();
|
||||
qCWarning(lcWebFlowCredentials) << "Migrated old keychain entries";
|
||||
qCInfo(lcWebFlowCredentials) << "Migrated old keychain entries";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,14 @@ WebFlowCredentialsDialog::WebFlowCredentialsDialog(QWidget *parent)
|
||||
connect(_webView, &WebView::urlCatched, this, &WebFlowCredentialsDialog::urlCatched);
|
||||
}
|
||||
|
||||
void WebFlowCredentialsDialog::closeEvent(QCloseEvent* e) {
|
||||
Q_UNUSED(e);
|
||||
|
||||
// Force calling WebView::~WebView() earlier so that _profile and _page are
|
||||
// deleted in the correct order.
|
||||
delete _webView;
|
||||
}
|
||||
|
||||
void WebFlowCredentialsDialog::setUrl(const QUrl &url) {
|
||||
_webView->setUrl(url);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,9 @@ public:
|
||||
void setInfo(const QString &msg);
|
||||
void setError(const QString &error);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent * e) override;
|
||||
|
||||
signals:
|
||||
void urlCatched(const QString user, const QString pass, const QString host);
|
||||
|
||||
|
||||
@@ -351,6 +351,10 @@ void Folder::showSyncResultPopup()
|
||||
createGuiLog(_syncResult.firstItemError()->_file, LogStatusError, errorCount);
|
||||
}
|
||||
|
||||
if (int lockedCount = _syncResult.numLockedItems()) {
|
||||
createGuiLog(_syncResult.firstItemLocked()->_file, LogStatusFileLocked, lockedCount);
|
||||
}
|
||||
|
||||
qCInfo(lcFolder) << "Folder sync result: " << int(_syncResult.status());
|
||||
}
|
||||
|
||||
|
||||
@@ -344,7 +344,8 @@ private:
|
||||
LogStatusNew,
|
||||
LogStatusError,
|
||||
LogStatusConflict,
|
||||
LogStatusUpdated
|
||||
LogStatusUpdated,
|
||||
LogStatusFileLocked
|
||||
};
|
||||
|
||||
void createGuiLog(const QString &filename, LogStatus status, int count,
|
||||
|
||||
@@ -75,9 +75,27 @@ bool FolderWatcher::isReliable() const
|
||||
return _isReliable;
|
||||
}
|
||||
|
||||
void FolderWatcher::appendSubPaths(QDir dir, QStringList& subPaths) {
|
||||
QStringList newSubPaths = dir.entryList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
|
||||
for (int i = 0; i < newSubPaths.size(); i++) {
|
||||
QString path = dir.path() + "/" + newSubPaths[i];
|
||||
QFileInfo fileInfo(path);
|
||||
subPaths.append(path);
|
||||
if (fileInfo.isDir()) {
|
||||
QDir dir(path);
|
||||
appendSubPaths(dir, subPaths);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FolderWatcher::changeDetected(const QString &path)
|
||||
{
|
||||
QFileInfo fileInfo(path);
|
||||
QStringList paths(path);
|
||||
if (fileInfo.isDir()) {
|
||||
QDir dir(path);
|
||||
appendSubPaths(dir, paths);
|
||||
}
|
||||
changeDetected(paths);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <QHash>
|
||||
#include <QScopedPointer>
|
||||
#include <QSet>
|
||||
#include <QDir>
|
||||
|
||||
class QTimer;
|
||||
|
||||
@@ -120,6 +121,8 @@ private:
|
||||
Folder *_folder;
|
||||
bool _isReliable = true;
|
||||
|
||||
void appendSubPaths(QDir dir, QStringList& subPaths);
|
||||
|
||||
friend class FolderWatcherPrivate;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ int main(int argc, char **argv)
|
||||
if (!app.sendMessage(QLatin1String("MSG_PARSEOPTIONS:") + msg))
|
||||
return -1;
|
||||
}
|
||||
if (!app.sendMessage(QLatin1String("MSG_SHOWSETTINGS"))) {
|
||||
if (!app.backgroundMode() && !app.sendMessage(QLatin1String("MSG_SHOWSETTINGS"))) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@@ -158,7 +158,7 @@ int main(int argc, char **argv)
|
||||
warnSystray();
|
||||
}
|
||||
}
|
||||
if (!QSystemTrayIcon::isSystemTrayAvailable() && desktopSession != "ubuntu") {
|
||||
if (!app.backgroundMode() && !QSystemTrayIcon::isSystemTrayAvailable() && desktopSession != "ubuntu") {
|
||||
app.showSettingsDialog();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace OCC {
|
||||
OcsShareeJob::OcsShareeJob(AccountPtr account)
|
||||
: OcsJob(account)
|
||||
{
|
||||
setPath("ocs/v1.php/apps/files_sharing/api/v1/sharees");
|
||||
setPath("ocs/v2.php/apps/files_sharing/api/v1/sharees");
|
||||
connect(this, &OcsJob::jobFinished, this, &OcsShareeJob::jobDone);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OCC {
|
||||
OcsShareJob::OcsShareJob(AccountPtr account)
|
||||
: OcsJob(account)
|
||||
{
|
||||
setPath("ocs/v1.php/apps/files_sharing/api/v1/shares");
|
||||
setPath("ocs/v2.php/apps/files_sharing/api/v1/shares");
|
||||
connect(this, &OcsJob::jobFinished, this, &OcsShareJob::jobDone);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ void OcsShareJob::getShares(const QString &path)
|
||||
setVerb("GET");
|
||||
|
||||
addParam(QString::fromLatin1("path"), path);
|
||||
addParam(QString::fromLatin1("reshares"), QString("true"));
|
||||
addPassStatusCode(404);
|
||||
|
||||
start();
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "sharelinkwidget.h"
|
||||
#include "shareusergroupwidget.h"
|
||||
|
||||
#include "sharemanager.h"
|
||||
|
||||
#include "account.h"
|
||||
#include "accountstate.h"
|
||||
#include "configfile.h"
|
||||
@@ -49,7 +51,8 @@ ShareDialog::ShareDialog(QPointer<AccountState> accountState,
|
||||
, _maxSharingPermissions(maxSharingPermissions)
|
||||
, _privateLinkUrl(accountState->account()->deprecatedPrivateLinkUrl(numericFileId).toString(QUrl::FullyEncoded))
|
||||
, _startPage(startPage)
|
||||
, _linkWidget(nullptr)
|
||||
, _linkWidgetList({})
|
||||
, _emptyShareLinkWidget(nullptr)
|
||||
, _userGroupWidget(nullptr)
|
||||
, _progressIndicator(nullptr)
|
||||
{
|
||||
@@ -101,11 +104,6 @@ ShareDialog::ShareDialog(QPointer<AccountState> accountState,
|
||||
this->setWindowTitle(tr("%1 Sharing").arg(Theme::instance()->appNameGUI()));
|
||||
|
||||
if (!accountState->account()->capabilities().shareAPI()) {
|
||||
// TODO do we want to display it?
|
||||
//auto label = new QLabel(tr("The server does not allow sharing"));
|
||||
//label->setWordWrap(true);
|
||||
//label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
//layout()->replaceWidget(_ui->shareWidgets, label);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -115,14 +113,6 @@ ShareDialog::ShareDialog(QPointer<AccountState> accountState,
|
||||
job->start();
|
||||
}
|
||||
|
||||
//TODO Progress Indicator where should it go?
|
||||
// _progressIndicator = new QProgressIndicator(this);
|
||||
// _progressIndicator->startAnimation();
|
||||
// _progressIndicator->setToolTip(tr("Retrieving maximum possible sharing permissions from server..."));
|
||||
// _ui->buttonBoxLayout->insertWidget(0, _progressIndicator);
|
||||
|
||||
// Server versions >= 9.1 support the "share-permissions" property
|
||||
// older versions will just return share-permissions: ""
|
||||
auto job = new PropfindJob(accountState->account(), _sharePath);
|
||||
job->setProperties(
|
||||
QList<QByteArray>()
|
||||
@@ -133,10 +123,103 @@ ShareDialog::ShareDialog(QPointer<AccountState> accountState,
|
||||
connect(job, &PropfindJob::result, this, &ShareDialog::slotPropfindReceived);
|
||||
connect(job, &PropfindJob::finishedWithError, this, &ShareDialog::slotPropfindError);
|
||||
job->start();
|
||||
|
||||
bool sharingPossible = true;
|
||||
if (!accountState->account()->capabilities().sharePublicLink()) {
|
||||
qCWarning(lcSharing) << "Link shares have been disabled";
|
||||
sharingPossible = false;
|
||||
} else if (!(maxSharingPermissions & SharePermissionShare)) {
|
||||
qCWarning(lcSharing) << "The file can not be shared because it was shared without sharing permission.";
|
||||
sharingPossible = false;
|
||||
}
|
||||
|
||||
if (sharingPossible) {
|
||||
_manager = new ShareManager(accountState->account(), this);
|
||||
connect(_manager, &ShareManager::sharesFetched, this, &ShareDialog::slotSharesFetched);
|
||||
connect(_manager, &ShareManager::linkShareCreated, this, &ShareDialog::slotAddLinkShareWidget);
|
||||
}
|
||||
}
|
||||
|
||||
void ShareDialog::addLinkShareWidget(const QSharedPointer<LinkShare> &linkShare){
|
||||
_linkWidgetList.append(new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, this));
|
||||
int index = _linkWidgetList.size()-1;
|
||||
_linkWidgetList.at(index)->setLinkShare(linkShare);
|
||||
|
||||
connect(linkShare.data(), &Share::serverError, _linkWidgetList.at(index), &ShareLinkWidget::slotServerError);
|
||||
connect(linkShare.data(), &Share::shareDeleted, _linkWidgetList.at(index), &ShareLinkWidget::slotDeleteShareFetched);
|
||||
connect(_manager, &ShareManager::linkShareRequiresPassword, _linkWidgetList.at(index), &ShareLinkWidget::slotCreateShareRequiresPassword);
|
||||
connect(_manager, &ShareManager::serverError, _linkWidgetList.at(index), &ShareLinkWidget::slotServerError);
|
||||
|
||||
// Connect all shares signals to gui slots
|
||||
connect(this, &ShareDialog::toggleAnimation, _linkWidgetList.at(index), &ShareLinkWidget::slotToggleAnimation);
|
||||
connect(_linkWidgetList.at(index), &ShareLinkWidget::createLinkShare, this, &ShareDialog::slotCreateLinkShare);
|
||||
connect(_linkWidgetList.at(index), &ShareLinkWidget::deleteLinkShare, this, &ShareDialog::slotDeleteShare);
|
||||
//connect(_linkWidgetList.at(index), &ShareLinkWidget::resizeRequested, this, &ShareDialog::slotAdjustScrollWidgetSize);
|
||||
|
||||
_ui->verticalLayout->insertWidget(_linkWidgetList.size()+1, _linkWidgetList.at(index));
|
||||
_linkWidgetList.at(index)->setupUiOptions();
|
||||
}
|
||||
|
||||
void ShareDialog::initLinkShareWidget(){
|
||||
if(_linkWidgetList.size() == 0){
|
||||
_emptyShareLinkWidget = new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, this);
|
||||
_linkWidgetList.append(_emptyShareLinkWidget);
|
||||
|
||||
// connect(_emptyShareLinkWidget, &ShareLinkWidget::resizeRequested, this, &ShareDialog::slotAdjustScrollWidgetSize);
|
||||
// connect(this, &ShareDialog::toggleAnimation, _emptyShareLinkWidget, &ShareLinkWidget::slotToggleAnimation);
|
||||
connect(_emptyShareLinkWidget, &ShareLinkWidget::createLinkShare, this, &ShareDialog::slotCreateLinkShare);
|
||||
|
||||
_ui->verticalLayout->insertWidget(_linkWidgetList.size()+1, _emptyShareLinkWidget);
|
||||
_emptyShareLinkWidget->show();
|
||||
|
||||
} else if(_emptyShareLinkWidget) {
|
||||
_emptyShareLinkWidget->hide();
|
||||
_ui->verticalLayout->removeWidget(_emptyShareLinkWidget);
|
||||
_linkWidgetList.removeAll(_emptyShareLinkWidget);
|
||||
_emptyShareLinkWidget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ShareDialog::slotAddLinkShareWidget(const QSharedPointer<LinkShare> &linkShare){
|
||||
emit toggleAnimation(true);
|
||||
addLinkShareWidget(linkShare);
|
||||
initLinkShareWidget();
|
||||
emit toggleAnimation(false);
|
||||
}
|
||||
|
||||
void ShareDialog::slotSharesFetched(const QList<QSharedPointer<Share>> &shares)
|
||||
{
|
||||
emit toggleAnimation(true);
|
||||
|
||||
const QString versionString = _accountState->account()->serverVersion();
|
||||
qCInfo(lcSharing) << versionString << "Fetched" << shares.count() << "shares";
|
||||
foreach (auto share, shares) {
|
||||
if (share->getShareType() != Share::TypeLink || share->getUidOwner() != share->account()->davUser()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QSharedPointer<LinkShare> linkShare = qSharedPointerDynamicCast<LinkShare>(share);
|
||||
addLinkShareWidget(linkShare);
|
||||
}
|
||||
|
||||
initLinkShareWidget();
|
||||
emit toggleAnimation(false);
|
||||
}
|
||||
|
||||
// TODO
|
||||
void ShareDialog::slotAdjustScrollWidgetSize()
|
||||
{
|
||||
int count = this->findChildren<ShareLinkWidget *>().count();
|
||||
_ui->scrollArea->setVisible(count > 0);
|
||||
if (count > 0 && count <= 3) {
|
||||
_ui->scrollArea->setFixedHeight(_ui->scrollArea->widget()->sizeHint().height());
|
||||
}
|
||||
_ui->scrollArea->setFrameShape(count > 3 ? QFrame::StyledPanel : QFrame::NoFrame);
|
||||
}
|
||||
|
||||
ShareDialog::~ShareDialog()
|
||||
{
|
||||
_linkWidgetList.clear();
|
||||
delete _ui;
|
||||
}
|
||||
|
||||
@@ -178,8 +261,6 @@ void ShareDialog::slotPropfindError()
|
||||
|
||||
void ShareDialog::showSharingUi()
|
||||
{
|
||||
//_progressIndicator->stopAnimation();
|
||||
|
||||
auto theme = Theme::instance();
|
||||
|
||||
// There's no difference between being unable to reshare and
|
||||
@@ -190,6 +271,7 @@ void ShareDialog::showSharingUi()
|
||||
auto label = new QLabel(this);
|
||||
label->setText(tr("The file can not be shared because it was shared without sharing permission."));
|
||||
label->setWordWrap(true);
|
||||
_ui->verticalLayout->insertWidget(1, label);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -205,15 +287,25 @@ void ShareDialog::showSharingUi()
|
||||
}
|
||||
|
||||
if (theme->linkSharing()) {
|
||||
_linkWidget = new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, this);
|
||||
_ui->verticalLayout->insertWidget(2, _linkWidget);
|
||||
_linkWidget->getShares();
|
||||
|
||||
if (_startPage == ShareDialogStartPage::PublicLinks)
|
||||
_ui->verticalLayout->insertWidget(3, _linkWidget);
|
||||
_manager->fetchShares(_sharePath);
|
||||
}
|
||||
}
|
||||
|
||||
void ShareDialog::slotCreateLinkShare()
|
||||
{
|
||||
_manager->createLinkShare(_sharePath, QString(), QString());
|
||||
}
|
||||
|
||||
|
||||
void ShareDialog::slotDeleteShare()
|
||||
{
|
||||
auto sharelinkWidget = dynamic_cast<ShareLinkWidget*>(sender());
|
||||
sharelinkWidget->hide();
|
||||
_ui->verticalLayout->removeWidget(sharelinkWidget);
|
||||
_linkWidgetList.removeAll(sharelinkWidget);
|
||||
initLinkShareWidget();
|
||||
}
|
||||
|
||||
void ShareDialog::slotThumbnailFetched(const int &statusCode, const QByteArray &reply)
|
||||
{
|
||||
if (statusCode != 200) {
|
||||
@@ -237,8 +329,10 @@ void ShareDialog::slotAccountStateChanged(int state)
|
||||
_userGroupWidget->setEnabled(enabled);
|
||||
}
|
||||
|
||||
if (_linkWidget != nullptr) {
|
||||
_linkWidget->setEnabled(enabled);
|
||||
if(_linkWidgetList.size() > 0){
|
||||
foreach(ShareLinkWidget *widget, _linkWidgetList){
|
||||
widget->setEnabled(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "sharepermissions.h"
|
||||
#include "owncloudgui.h"
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QPointer>
|
||||
#include <QString>
|
||||
#include <QDialog>
|
||||
@@ -34,6 +35,9 @@ namespace Ui {
|
||||
|
||||
class ShareLinkWidget;
|
||||
class ShareUserGroupWidget;
|
||||
class ShareManager;
|
||||
class LinkShare;
|
||||
class Share;
|
||||
|
||||
class ShareDialog : public QDialog
|
||||
{
|
||||
@@ -56,8 +60,19 @@ private slots:
|
||||
void slotThumbnailFetched(const int &statusCode, const QByteArray &reply);
|
||||
void slotAccountStateChanged(int state);
|
||||
|
||||
void slotSharesFetched(const QList<QSharedPointer<Share>> &shares);
|
||||
void slotAddLinkShareWidget(const QSharedPointer<LinkShare> &linkShare);
|
||||
void slotDeleteShare();
|
||||
void slotCreateLinkShare();
|
||||
void slotAdjustScrollWidgetSize();
|
||||
|
||||
signals:
|
||||
void toggleAnimation(bool);
|
||||
|
||||
private:
|
||||
void showSharingUi();
|
||||
void addLinkShareWidget(const QSharedPointer<LinkShare> &linkShare);
|
||||
void initLinkShareWidget();
|
||||
|
||||
Ui::ShareDialog *_ui;
|
||||
|
||||
@@ -68,8 +83,10 @@ private:
|
||||
QByteArray _numericFileId;
|
||||
QString _privateLinkUrl;
|
||||
ShareDialogStartPage _startPage;
|
||||
ShareManager *_manager;
|
||||
|
||||
ShareLinkWidget *_linkWidget;
|
||||
QList<ShareLinkWidget*> _linkWidgetList;
|
||||
ShareLinkWidget* _emptyShareLinkWidget;
|
||||
ShareUserGroupWidget *_userGroupWidget;
|
||||
QProgressIndicator *_progressIndicator;
|
||||
};
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
#include "sharelinkwidget.h"
|
||||
#include "account.h"
|
||||
#include "capabilities.h"
|
||||
|
||||
#include "sharemanager.h"
|
||||
#include "guiutility.h"
|
||||
#include "sharemanager.h"
|
||||
|
||||
#include "QProgressIndicator.h"
|
||||
#include <QBuffer>
|
||||
@@ -29,9 +28,12 @@
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
#include <QToolButton>
|
||||
#include <QPropertyAnimation>
|
||||
|
||||
namespace OCC {
|
||||
|
||||
Q_LOGGING_CATEGORY(lcShareLink, "nextcloud.gui.sharelink", QtInfoMsg)
|
||||
|
||||
ShareLinkWidget::ShareLinkWidget(AccountPtr account,
|
||||
const QString &sharePath,
|
||||
const QString &localPath,
|
||||
@@ -42,13 +44,11 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
|
||||
, _account(account)
|
||||
, _sharePath(sharePath)
|
||||
, _localPath(localPath)
|
||||
, _manager(nullptr)
|
||||
, _linkShare(nullptr)
|
||||
, _passwordRequired(false)
|
||||
, _expiryRequired(false)
|
||||
, _namesSupported(true)
|
||||
, _linkContextMenu(nullptr)
|
||||
, _copyLinkAction(nullptr)
|
||||
, _readOnlyLinkAction(nullptr)
|
||||
, _allowEditingLinkAction(nullptr)
|
||||
, _allowUploadEditingLinkAction(nullptr)
|
||||
@@ -68,26 +68,26 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
|
||||
QFileInfo fi(localPath);
|
||||
_isFile = fi.isFile();
|
||||
|
||||
connect(_ui->enableShareLink, &QCheckBox::toggled, this, &ShareLinkWidget::slotCreateOrDeleteShareLink);
|
||||
connect(_ui->enableShareLink, &QPushButton::clicked, this, &ShareLinkWidget::slotCreateShareLink);
|
||||
connect(_ui->lineEdit_password, &QLineEdit::returnPressed, this, &ShareLinkWidget::slotCreatePassword);
|
||||
connect(_ui->confirmPassword, &QAbstractButton::clicked, this, &ShareLinkWidget::slotCreatePassword);
|
||||
connect(_ui->confirmExpirationDate, &QAbstractButton::clicked, this, &ShareLinkWidget::slotSetExpireDate);
|
||||
connect(_ui->calendar, &QDateTimeEdit::dateChanged, this, &ShareLinkWidget::slotExpireDateChanged);
|
||||
connect(_ui->calendar, &QDateTimeEdit::dateChanged, this, &ShareLinkWidget::slotSetExpireDate);
|
||||
|
||||
_ui->errorLabel->hide();
|
||||
|
||||
bool sharingPossible = true;
|
||||
if (!_account->capabilities().sharePublicLink()) {
|
||||
qCWarning(lcSharing) << "Link shares have been disabled";
|
||||
qCWarning(lcShareLink) << "Link shares have been disabled";
|
||||
sharingPossible = false;
|
||||
} else if (!(maxSharingPermissions & SharePermissionShare)) {
|
||||
qCWarning(lcSharing) << "The file can not be shared because it was shared without sharing permission.";
|
||||
qCWarning(lcShareLink) << "The file can not be shared because it was shared without sharing permission.";
|
||||
sharingPossible = false;
|
||||
}
|
||||
|
||||
_ui->createShareButton->setVisible(sharingPossible);
|
||||
_ui->enableShareLink->setVisible(sharingPossible);
|
||||
_ui->shareLinkToolButton->setVisible(sharingPossible);
|
||||
_ui->enableShareLink->setChecked(false);
|
||||
_ui->shareLinkToolButton->setEnabled(false);
|
||||
_ui->shareLinkToolButton->hide();
|
||||
|
||||
// Older servers don't support multiple public link shares
|
||||
if (!_account->capabilities().sharePublicLinkMultiple()) {
|
||||
@@ -100,34 +100,9 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account,
|
||||
|
||||
// check if the file is already inside of a synced folder
|
||||
if (sharePath.isEmpty()) {
|
||||
// The file is not yet in an ownCloud synced folder. We could automatically
|
||||
// copy it over, but that is skipped as not all questions can be answered that
|
||||
// are involved in that, see https://github.com/owncloud/client/issues/2732
|
||||
//
|
||||
// _ui->checkBox_shareLink->setEnabled(false);
|
||||
// uploadExternalFile();
|
||||
qCWarning(lcSharing) << "Unable to share files not in a sync folder.";
|
||||
qCWarning(lcShareLink) << "Unable to share files not in a sync folder.";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// TODO File Drop
|
||||
// File can't have public upload set; we also hide it if the capability isn't there
|
||||
// _ui->widget_editing->setVisible(
|
||||
// !_isFile && _account->capabilities().sharePublicLinkAllowUpload());
|
||||
//_ui->radio_uploadOnly->setVisible(
|
||||
//_account->capabilities().sharePublicLinkSupportsUploadOnly());
|
||||
|
||||
/*
|
||||
* Create the share manager and connect it properly
|
||||
*/
|
||||
if (sharingPossible) {
|
||||
_manager = new ShareManager(_account, this);
|
||||
connect(_manager, &ShareManager::sharesFetched, this, &ShareLinkWidget::slotSharesFetched);
|
||||
connect(_manager, &ShareManager::linkShareCreated, this, &ShareLinkWidget::slotCreateShareFetched);
|
||||
connect(_manager, &ShareManager::linkShareRequiresPassword, this, &ShareLinkWidget::slotCreateShareRequiresPassword);
|
||||
connect(_manager, &ShareManager::serverError, this, &ShareLinkWidget::slotServerError);
|
||||
}
|
||||
}
|
||||
|
||||
ShareLinkWidget::~ShareLinkWidget()
|
||||
@@ -135,7 +110,7 @@ ShareLinkWidget::~ShareLinkWidget()
|
||||
delete _ui;
|
||||
}
|
||||
|
||||
void ShareLinkWidget::toggleAnimation(bool start){
|
||||
void ShareLinkWidget::slotToggleAnimation(bool start){
|
||||
if (start) {
|
||||
if (!_ui->progressIndicator->isAnimated())
|
||||
_ui->progressIndicator->startAnimation();
|
||||
@@ -144,218 +119,170 @@ void ShareLinkWidget::toggleAnimation(bool start){
|
||||
}
|
||||
}
|
||||
|
||||
void ShareLinkWidget::getShares()
|
||||
{
|
||||
if (_manager) {
|
||||
toggleAnimation(true);
|
||||
_manager->fetchShares(_sharePath);
|
||||
}
|
||||
void ShareLinkWidget::setLinkShare(QSharedPointer<LinkShare> linkShare){
|
||||
_linkShare = linkShare;
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotSharesFetched(const QList<QSharedPointer<Share>> &shares)
|
||||
{
|
||||
const QString versionString = _account->serverVersion();
|
||||
qCInfo(lcSharing) << versionString << "Fetched" << shares.count() << "shares";
|
||||
|
||||
foreach (auto share, shares) {
|
||||
if (share->getShareType() != Share::TypeLink) {
|
||||
continue;
|
||||
}
|
||||
_linkShare = qSharedPointerDynamicCast<LinkShare>(share);
|
||||
|
||||
// Connect all shares signals to gui slots
|
||||
connect(share.data(), &Share::serverError, this, &ShareLinkWidget::slotServerError);
|
||||
connect(share.data(), &Share::shareDeleted, this, &ShareLinkWidget::slotDeleteShareFetched);
|
||||
connect(_linkShare.data(), &LinkShare::expireDateSet, this, &ShareLinkWidget::slotExpireDateSet);
|
||||
connect(_linkShare.data(), &LinkShare::passwordSet, this, &ShareLinkWidget::slotPasswordSet);
|
||||
connect(_linkShare.data(), &LinkShare::passwordSetError, this, &ShareLinkWidget::slotPasswordSetError);
|
||||
|
||||
// Prepare permissions check and create group action
|
||||
bool checked = false;
|
||||
SharePermissions perm = _linkShare->getPermissions();
|
||||
QActionGroup *permissionsGroup = new QActionGroup(this);
|
||||
|
||||
// Prepare sharing menu
|
||||
_linkContextMenu = new QMenu(this);
|
||||
|
||||
// radio button style
|
||||
permissionsGroup->setExclusive(true);
|
||||
|
||||
if(_isFile){
|
||||
checked = perm & (SharePermissionRead & SharePermissionUpdate);
|
||||
_allowEditingLinkAction = _linkContextMenu->addAction(tr("Allow Editing"));
|
||||
_allowEditingLinkAction->setCheckable(true);
|
||||
_allowEditingLinkAction->setChecked(checked);
|
||||
|
||||
} else {
|
||||
checked = perm & SharePermissionRead;
|
||||
_readOnlyLinkAction = permissionsGroup->addAction(tr("Read only"));
|
||||
_readOnlyLinkAction->setCheckable(true);
|
||||
_readOnlyLinkAction->setChecked(checked);
|
||||
|
||||
checked = perm & (SharePermissionRead &
|
||||
SharePermissionCreate &
|
||||
SharePermissionUpdate &
|
||||
SharePermissionDelete);
|
||||
_allowUploadEditingLinkAction = permissionsGroup->addAction(tr("Allow Upload && Editing"));
|
||||
_allowUploadEditingLinkAction->setCheckable(true);
|
||||
_allowUploadEditingLinkAction->setChecked(checked);
|
||||
|
||||
checked = perm & SharePermissionCreate;
|
||||
_allowUploadLinkAction = permissionsGroup->addAction(tr("File Drop (Upload Only)"));
|
||||
_allowUploadLinkAction->setCheckable(true);
|
||||
_allowUploadLinkAction->setChecked(checked);
|
||||
}
|
||||
|
||||
// Add copy action (icon only)
|
||||
_copyLinkAction = _linkContextMenu->addAction(QIcon(":/client/resources/copy.svg"),
|
||||
tr("Copy link"));
|
||||
|
||||
// Adds permissions actions (radio button style)
|
||||
if(_isFile){
|
||||
_linkContextMenu->addAction(_allowEditingLinkAction);
|
||||
} else {
|
||||
_linkContextMenu->addAction(_readOnlyLinkAction);
|
||||
_linkContextMenu->addAction(_allowUploadEditingLinkAction);
|
||||
_linkContextMenu->addAction(_allowUploadLinkAction);
|
||||
}
|
||||
|
||||
|
||||
// Adds action to display password widget (check box)
|
||||
_passwordProtectLinkAction = _linkContextMenu->addAction(tr("Password Protect"));
|
||||
_passwordProtectLinkAction->setCheckable(true);
|
||||
|
||||
if(_linkShare->isPasswordSet()){
|
||||
_passwordProtectLinkAction->setChecked(true);
|
||||
_ui->lineEdit_password->setPlaceholderText("********");
|
||||
showPasswordOptions(true);
|
||||
}
|
||||
|
||||
// If password is enforced then don't allow users to disable it
|
||||
if (_account->capabilities().sharePublicLinkEnforcePassword()) {
|
||||
_passwordProtectLinkAction->setChecked(true);
|
||||
_passwordProtectLinkAction->setEnabled(false);
|
||||
_passwordRequired = true;
|
||||
}
|
||||
|
||||
// Adds action to display expiration date widget (check box)
|
||||
_expirationDateLinkAction = _linkContextMenu->addAction(tr("Expiration Date"));
|
||||
_expirationDateLinkAction->setCheckable(true);
|
||||
if(_linkShare->getExpireDate().isValid()){
|
||||
_ui->calendar->setDate(_linkShare->getExpireDate());
|
||||
_expirationDateLinkAction->setChecked(true);
|
||||
showExpireDateOptions(true);
|
||||
}
|
||||
|
||||
|
||||
// If expiredate is enforced do not allow disable and set max days
|
||||
if (_account->capabilities().sharePublicLinkEnforceExpireDate()) {
|
||||
_ui->calendar->setMaximumDate(QDate::currentDate().addDays(
|
||||
_account->capabilities().sharePublicLinkExpireDateDays()));
|
||||
_expirationDateLinkAction->setChecked(true);
|
||||
_expirationDateLinkAction->setEnabled(false);
|
||||
_expiryRequired = true;
|
||||
}
|
||||
|
||||
// Adds action to unshare widget (check box)
|
||||
_unshareLinkAction = _linkContextMenu->addAction(QIcon(":/client/resources/delete.png"),
|
||||
tr("Unshare"));
|
||||
|
||||
connect(_linkContextMenu, &QMenu::triggered,
|
||||
this, &ShareLinkWidget::slotLinkContextMenuActionTriggered);
|
||||
|
||||
_ui->shareLinkToolButton->setMenu(_linkContextMenu);
|
||||
_ui->shareLinkToolButton->setEnabled(true);
|
||||
_ui->enableShareLink->setEnabled(true);
|
||||
_ui->enableShareLink->setChecked(true);
|
||||
|
||||
// show sharing options
|
||||
_ui->shareLinkToolButton->show();
|
||||
}
|
||||
|
||||
toggleAnimation(false);
|
||||
QSharedPointer<LinkShare> ShareLinkWidget::getLinkShare(){
|
||||
return _linkShare;
|
||||
}
|
||||
|
||||
void ShareLinkWidget::setExpireDate(const QDate &date)
|
||||
{
|
||||
if (_linkShare) {
|
||||
toggleAnimation(true);
|
||||
_ui->errorLabel->hide();
|
||||
_linkShare->setExpireDate(date);
|
||||
void ShareLinkWidget::setupUiOptions(){
|
||||
connect(_linkShare.data(), &LinkShare::expireDateSet, this, &ShareLinkWidget::slotExpireDateSet);
|
||||
connect(_linkShare.data(), &LinkShare::passwordSet, this, &ShareLinkWidget::slotPasswordSet);
|
||||
connect(_linkShare.data(), &LinkShare::passwordSetError, this, &ShareLinkWidget::slotPasswordSetError);
|
||||
|
||||
// Prepare permissions check and create group action
|
||||
const QDate expireDate = _linkShare.data()->getExpireDate().isValid()? _linkShare.data()->getExpireDate() : QDate();
|
||||
const SharePermissions perm = _linkShare.data()->getPermissions();
|
||||
bool checked = false;
|
||||
QActionGroup *permissionsGroup = new QActionGroup(this);
|
||||
|
||||
// Prepare sharing menu
|
||||
_linkContextMenu = new QMenu(this);
|
||||
|
||||
// radio button style
|
||||
permissionsGroup->setExclusive(true);
|
||||
|
||||
if(_isFile){
|
||||
checked = perm & (SharePermissionRead & SharePermissionUpdate);
|
||||
_allowEditingLinkAction = _linkContextMenu->addAction(tr("Allow Editing"));
|
||||
_allowEditingLinkAction->setCheckable(true);
|
||||
_allowEditingLinkAction->setChecked(checked);
|
||||
|
||||
} else {
|
||||
checked = perm & SharePermissionRead;
|
||||
_readOnlyLinkAction = permissionsGroup->addAction(tr("Read only"));
|
||||
_readOnlyLinkAction->setCheckable(true);
|
||||
_readOnlyLinkAction->setChecked(checked);
|
||||
|
||||
checked = perm & (SharePermissionRead &
|
||||
SharePermissionCreate &
|
||||
SharePermissionUpdate &
|
||||
SharePermissionDelete);
|
||||
_allowUploadEditingLinkAction = permissionsGroup->addAction(tr("Allow Upload && Editing"));
|
||||
_allowUploadEditingLinkAction->setCheckable(true);
|
||||
_allowUploadEditingLinkAction->setChecked(checked);
|
||||
|
||||
checked = perm & SharePermissionCreate;
|
||||
_allowUploadLinkAction = permissionsGroup->addAction(tr("File Drop (Upload Only)"));
|
||||
_allowUploadLinkAction->setCheckable(true);
|
||||
_allowUploadLinkAction->setChecked(checked);
|
||||
}
|
||||
|
||||
// Adds permissions actions (radio button style)
|
||||
if(_isFile){
|
||||
_linkContextMenu->addAction(_allowEditingLinkAction);
|
||||
} else {
|
||||
_linkContextMenu->addAction(_readOnlyLinkAction);
|
||||
_linkContextMenu->addAction(_allowUploadEditingLinkAction);
|
||||
_linkContextMenu->addAction(_allowUploadLinkAction);
|
||||
}
|
||||
|
||||
// Adds action to display password widget (check box)
|
||||
_passwordProtectLinkAction = _linkContextMenu->addAction(tr("Password Protect"));
|
||||
_passwordProtectLinkAction->setCheckable(true);
|
||||
|
||||
if(_linkShare.data()->isPasswordSet()){
|
||||
_passwordProtectLinkAction->setChecked(true);
|
||||
_ui->lineEdit_password->setPlaceholderText("********");
|
||||
showPasswordOptions(true);
|
||||
}
|
||||
|
||||
// If password is enforced then don't allow users to disable it
|
||||
if (_account->capabilities().sharePublicLinkEnforcePassword()) {
|
||||
_passwordProtectLinkAction->setChecked(true);
|
||||
_passwordProtectLinkAction->setEnabled(false);
|
||||
_passwordRequired = true;
|
||||
}
|
||||
|
||||
// Adds action to display expiration date widget (check box)
|
||||
_expirationDateLinkAction = _linkContextMenu->addAction(tr("Expiration Date"));
|
||||
_expirationDateLinkAction->setCheckable(true);
|
||||
if(!expireDate.isNull()){
|
||||
_ui->calendar->setDate(expireDate);
|
||||
_expirationDateLinkAction->setChecked(true);
|
||||
showExpireDateOptions(true);
|
||||
}
|
||||
|
||||
// If expiredate is enforced do not allow disable and set max days
|
||||
if (_account->capabilities().sharePublicLinkEnforceExpireDate()) {
|
||||
_ui->calendar->setMaximumDate(QDate::currentDate().addDays(
|
||||
_account->capabilities().sharePublicLinkExpireDateDays()));
|
||||
_expirationDateLinkAction->setChecked(true);
|
||||
_expirationDateLinkAction->setEnabled(false);
|
||||
_expiryRequired = true;
|
||||
}
|
||||
|
||||
// Adds action to unshare widget (check box)
|
||||
_unshareLinkAction = _linkContextMenu->addAction(QIcon(":/client/resources/delete.png"),
|
||||
tr("Unshare"));
|
||||
|
||||
_linkContextMenu->addSeparator();
|
||||
|
||||
_addAnotherLinkAction = _linkContextMenu->addAction(QIcon(":/client/resources/add.png"),
|
||||
tr("Add another link"));
|
||||
|
||||
_ui->enableShareLink->setIcon(QIcon(":/client/resources/copy.svg"));
|
||||
disconnect(_ui->enableShareLink, &QPushButton::clicked, this, &ShareLinkWidget::slotCreateShareLink);
|
||||
connect(_ui->enableShareLink, &QPushButton::clicked, this, &ShareLinkWidget::slotCopyLinkShare);
|
||||
|
||||
connect(_linkContextMenu, &QMenu::triggered,
|
||||
this, &ShareLinkWidget::slotLinkContextMenuActionTriggered);
|
||||
|
||||
_ui->shareLinkToolButton->setMenu(_linkContextMenu);
|
||||
_ui->shareLinkToolButton->setEnabled(true);
|
||||
_ui->enableShareLink->setEnabled(true);
|
||||
_ui->enableShareLink->setChecked(true);
|
||||
|
||||
// show sharing options
|
||||
_ui->shareLinkToolButton->show();
|
||||
|
||||
//TO DO
|
||||
//startAnimation(0, height());
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotCopyLinkShare(bool clicked){
|
||||
Q_UNUSED(clicked);
|
||||
|
||||
QApplication::clipboard()->setText(_linkShare->getLink().toString());
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotExpireDateSet()
|
||||
{
|
||||
toggleAnimation(false);
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotExpireDateChanged(const QDate &date)
|
||||
{
|
||||
setExpireDate(date);
|
||||
slotToggleAnimation(false);
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotSetExpireDate()
|
||||
{
|
||||
slotExpireDateChanged(_ui->calendar->date());
|
||||
if(!_linkShare){
|
||||
return;
|
||||
}
|
||||
|
||||
slotToggleAnimation(true);
|
||||
_ui->errorLabel->hide();
|
||||
_linkShare->setExpireDate(_ui->calendar->date());
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotCreatePassword()
|
||||
{
|
||||
if (!_manager) {
|
||||
return;
|
||||
}
|
||||
|
||||
toggleAnimation(true);
|
||||
|
||||
if (!_linkShare) {
|
||||
// If share creation requires a password, we'll be in this case
|
||||
if (_ui->lineEdit_password->text().isEmpty()) {
|
||||
_ui->lineEdit_password->setFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
_manager->createLinkShare(_sharePath, QString(), _ui->lineEdit_password->text());
|
||||
} else {
|
||||
setPassword(_ui->lineEdit_password->text());
|
||||
}
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotCreateOrDeleteShareLink(bool checked)
|
||||
{
|
||||
if (!_manager) {
|
||||
qCWarning(lcSharing) << "No share manager set.";
|
||||
return;
|
||||
}
|
||||
|
||||
toggleAnimation(true);
|
||||
|
||||
if(checked){
|
||||
_manager->createLinkShare(_sharePath, QString(), QString());
|
||||
} else {
|
||||
if (!_linkShare) {
|
||||
qCWarning(lcSharing) << "No public link set.";
|
||||
return;
|
||||
}
|
||||
confirmAndDeleteShare();
|
||||
}
|
||||
slotToggleAnimation(true);
|
||||
_ui->errorLabel->hide();
|
||||
_linkShare->setPassword(_ui->lineEdit_password->text());
|
||||
}
|
||||
|
||||
void ShareLinkWidget::setPassword(const QString &password)
|
||||
void ShareLinkWidget::slotCreateShareLink(bool clicked)
|
||||
{
|
||||
if (_linkShare) {
|
||||
toggleAnimation(true);
|
||||
|
||||
_ui->errorLabel->hide();
|
||||
_linkShare->setPassword(password);
|
||||
}
|
||||
slotToggleAnimation(true);
|
||||
emit createLinkShare();
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotPasswordSet()
|
||||
{
|
||||
if (!_linkShare)
|
||||
return;
|
||||
|
||||
_ui->lineEdit_password->setText(QString());
|
||||
if (_linkShare->isPasswordSet()) {
|
||||
_ui->lineEdit_password->setPlaceholderText("********");
|
||||
@@ -364,39 +291,55 @@ void ShareLinkWidget::slotPasswordSet()
|
||||
_ui->lineEdit_password->setPlaceholderText(QString());
|
||||
}
|
||||
|
||||
toggleAnimation(false);
|
||||
slotToggleAnimation(false);
|
||||
}
|
||||
|
||||
/*
|
||||
* When setting/deleting a password from a share the old share is
|
||||
* deleted and a new one is created. So we need to refetch the shares
|
||||
* at this point.
|
||||
*
|
||||
* NOTE: I don't see this happening with oC > 10
|
||||
*/
|
||||
getShares();
|
||||
void ShareLinkWidget::startAnimation(const int start, const int end){
|
||||
|
||||
QPropertyAnimation *animation = new QPropertyAnimation(this, "maximumHeight", this);
|
||||
|
||||
animation->setDuration(500);
|
||||
animation->setStartValue(start);
|
||||
animation->setEndValue(end);
|
||||
|
||||
connect(animation, &QAbstractAnimation::finished, this, &ShareLinkWidget::slotAnimationFinished);
|
||||
if(end < start) // that is to remove the widget, not to show it
|
||||
connect(animation, &QAbstractAnimation::finished, this, &ShareLinkWidget::slotDeleteAnimationFinished);
|
||||
connect(animation, &QVariantAnimation::valueChanged, this, &ShareLinkWidget::resizeRequested);
|
||||
|
||||
animation->start();
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotDeleteShareFetched()
|
||||
{
|
||||
toggleAnimation(true);
|
||||
slotToggleAnimation(false);
|
||||
|
||||
// TODO
|
||||
//startAnimation(height(), 0);
|
||||
|
||||
_linkShare.clear();
|
||||
_ui->enableShareLink->setChecked(false);
|
||||
_ui->shareLinkToolButton->setEnabled(false);
|
||||
_ui->shareLinkToolButton->hide();
|
||||
togglePasswordOptions(false);
|
||||
toggleExpireDateOptions(false);
|
||||
getShares();
|
||||
emit deleteLinkShare();
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotCreateShareFetched()
|
||||
void ShareLinkWidget::slotAnimationFinished()
|
||||
{
|
||||
toggleAnimation(true);
|
||||
getShares();
|
||||
emit resizeRequested();
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotDeleteAnimationFinished()
|
||||
{
|
||||
// There is a painting bug where a small line of this widget isn't
|
||||
// properly cleared. This explicit repaint() call makes sure any trace of
|
||||
// the share widget is removed once it's destroyed. #4189
|
||||
connect(this, SIGNAL(destroyed(QObject *)), parentWidget(), SLOT(repaint()));
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotCreateShareRequiresPassword(const QString &message)
|
||||
{
|
||||
toggleAnimation(true);
|
||||
slotToggleAnimation(true);
|
||||
|
||||
showPasswordOptions(true);
|
||||
if (!message.isEmpty()) {
|
||||
@@ -468,8 +411,10 @@ void ShareLinkWidget::confirmAndDeleteShare()
|
||||
|
||||
connect(messageBox, &QMessageBox::finished, this,
|
||||
[messageBox, yesButton, this]() {
|
||||
if (messageBox->clickedButton() == yesButton)
|
||||
if (messageBox->clickedButton() == yesButton) {
|
||||
this->slotToggleAnimation(true);
|
||||
this->_linkShare->deleteShare();
|
||||
}
|
||||
});
|
||||
messageBox->open();
|
||||
}
|
||||
@@ -495,8 +440,8 @@ void ShareLinkWidget::slotLinkContextMenuActionTriggered(QAction *action)
|
||||
bool state = action->isChecked();
|
||||
SharePermissions perm = SharePermissionRead;
|
||||
|
||||
if (action == _copyLinkAction) {
|
||||
QApplication::clipboard()->setText(_linkShare->getLink().toString());
|
||||
if(action == _addAnotherLinkAction){
|
||||
emit createLinkShare();
|
||||
|
||||
} else if (action == _readOnlyLinkAction && state) {
|
||||
_linkShare->setPermissions(perm);
|
||||
@@ -520,13 +465,13 @@ void ShareLinkWidget::slotLinkContextMenuActionTriggered(QAction *action)
|
||||
toggleExpireDateOptions(state);
|
||||
|
||||
} else if (action == _unshareLinkAction) {
|
||||
slotCreateOrDeleteShareLink(state);
|
||||
confirmAndDeleteShare();
|
||||
}
|
||||
}
|
||||
|
||||
void ShareLinkWidget::slotServerError(int code, const QString &message)
|
||||
{
|
||||
toggleAnimation(false);
|
||||
slotToggleAnimation(false);
|
||||
|
||||
qCWarning(lcSharing) << "Error from server" << code << message;
|
||||
displayError(message);
|
||||
|
||||
@@ -37,7 +37,6 @@ class QuotaInfo;
|
||||
class SyncResult;
|
||||
class LinkShare;
|
||||
class Share;
|
||||
class ShareManager;
|
||||
|
||||
/**
|
||||
* @brief The ShareDialog class
|
||||
@@ -54,44 +53,51 @@ public:
|
||||
SharePermissions maxSharingPermissions,
|
||||
QWidget *parent = nullptr);
|
||||
~ShareLinkWidget();
|
||||
void getShares();
|
||||
|
||||
void toggleButton(bool show);
|
||||
void setupUiOptions();
|
||||
|
||||
void setLinkShare(QSharedPointer<LinkShare> linkShare);
|
||||
QSharedPointer<LinkShare> getLinkShare();
|
||||
|
||||
public slots:
|
||||
void slotDeleteShareFetched();
|
||||
void slotToggleAnimation(bool start);
|
||||
void slotServerError(int code, const QString &message);
|
||||
void slotCreateShareRequiresPassword(const QString &message);
|
||||
|
||||
private slots:
|
||||
void slotSharesFetched(const QList<QSharedPointer<Share>> &shares);
|
||||
//void slotShareSelectionChanged();
|
||||
void slotCreateShareLink(bool clicked);
|
||||
|
||||
void slotCreateOrDeleteShareLink(bool checked);
|
||||
void slotCreatePassword();
|
||||
void slotPasswordSet();
|
||||
void slotPasswordSetError(int code, const QString &message);
|
||||
|
||||
void slotExpireDateChanged(const QDate &date);
|
||||
void slotSetExpireDate();
|
||||
void slotExpireDateSet();
|
||||
|
||||
void slotContextMenuButtonClicked();
|
||||
void slotLinkContextMenuActionTriggered(QAction *action);
|
||||
|
||||
void slotDeleteShareFetched();
|
||||
void slotCreateShareFetched();
|
||||
void slotCreateShareRequiresPassword(const QString &message);
|
||||
void slotDeleteAnimationFinished();
|
||||
void slotAnimationFinished();
|
||||
|
||||
void slotPasswordSet();
|
||||
void slotExpireDateSet();
|
||||
|
||||
void slotServerError(int code, const QString &message);
|
||||
void slotPasswordSetError(int code, const QString &message);
|
||||
signals:
|
||||
void createLinkShare();
|
||||
void deleteLinkShare();
|
||||
void resizeRequested();
|
||||
void visualDeletionDone();
|
||||
|
||||
private:
|
||||
void displayError(const QString &errMsg);
|
||||
|
||||
void showPasswordOptions(bool show);
|
||||
void togglePasswordOptions(bool enable);
|
||||
void setPassword(const QString &password);
|
||||
|
||||
void showExpireDateOptions(bool show);
|
||||
void toggleExpireDateOptions(bool enable);
|
||||
void setExpireDate(const QDate &date);
|
||||
|
||||
void copyShareLink(const QUrl &url);
|
||||
void slotCopyLinkShare(bool clicked);
|
||||
|
||||
/** Confirm with the user and then delete the share */
|
||||
void confirmAndDeleteShare();
|
||||
@@ -99,7 +105,7 @@ private:
|
||||
/** Retrieve a share's name, accounting for _namesSupported */
|
||||
QString shareName() const;
|
||||
|
||||
void toggleAnimation(bool start);
|
||||
void startAnimation(const int start, const int end);
|
||||
|
||||
Ui::ShareLinkWidget *_ui;
|
||||
AccountPtr _account;
|
||||
@@ -107,7 +113,6 @@ private:
|
||||
QString _localPath;
|
||||
QString _shareUrl;
|
||||
|
||||
ShareManager *_manager;
|
||||
QSharedPointer<LinkShare> _linkShare;
|
||||
|
||||
bool _isFile;
|
||||
@@ -116,7 +121,6 @@ private:
|
||||
bool _namesSupported;
|
||||
|
||||
QMenu *_linkContextMenu;
|
||||
QAction *_copyLinkAction;
|
||||
QAction *_readOnlyLinkAction;
|
||||
QAction *_allowEditingLinkAction;
|
||||
QAction *_allowUploadEditingLinkAction;
|
||||
@@ -124,6 +128,7 @@ private:
|
||||
QAction *_passwordProtectLinkAction;
|
||||
QAction *_expirationDateLinkAction;
|
||||
QAction *_unshareLinkAction;
|
||||
QAction *_addAnotherLinkAction;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>350</width>
|
||||
<height>126</height>
|
||||
<height>160</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -29,80 +29,13 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="createShareButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">text-align: left</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Share link</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../client.qrc">
|
||||
<normaloff>:/client/resources/public.svg</normaloff>:/client/resources/public.svg</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressIndicator" name="progressIndicator"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableShareLink">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QToolButton" name="shareLinkToolButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../client.qrc">
|
||||
<normaloff>:/client/resources/more.svg</normaloff>:/client/resources/more.svg</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDateEdit" name="calendar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -122,64 +55,17 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_password">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<item row="0" column="3">
|
||||
<widget class="QToolButton" name="shareLinkToolButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QToolButton" name="confirmPassword">
|
||||
<property name="icon">
|
||||
<iconset resource="../../client.qrc">
|
||||
<normaloff>:/client/resources/confirm.svg</normaloff>:/client/resources/confirm.svg</iconset>
|
||||
<normaloff>:/client/resources/more.svg</normaloff>:/client/resources/more.svg</iconset>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="expirationLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Expiration date:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDateEdit" name="calendar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QToolButton" name="confirmExpirationDate">
|
||||
<property name="icon">
|
||||
<iconset resource="../../client.qrc">
|
||||
<normaloff>:/client/resources/confirm.svg</normaloff>:/client/resources/confirm.svg</iconset>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -233,6 +119,130 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_password">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QToolButton" name="confirmPassword">
|
||||
<property name="icon">
|
||||
<iconset resource="../../client.qrc">
|
||||
<normaloff>:/client/resources/confirm.svg</normaloff>:/client/resources/confirm.svg</iconset>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QToolButton" name="confirmExpirationDate">
|
||||
<property name="icon">
|
||||
<iconset resource="../../client.qrc">
|
||||
<normaloff>:/client/resources/confirm.svg</normaloff>:/client/resources/confirm.svg</iconset>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="createShareButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">text-align: left</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Share link</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../client.qrc">
|
||||
<normaloff>:/client/resources/public.svg</normaloff>:/client/resources/public.svg</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressIndicator" name="progressIndicator" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="enableShareLink">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../client.qrc">
|
||||
<normaloff>:/client/resources/add.png</normaloff>:/client/resources/add.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="expirationLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Expiration date:</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
|
||||
@@ -52,12 +52,16 @@ static void updateFolder(const AccountPtr &account, const QString &path)
|
||||
|
||||
Share::Share(AccountPtr account,
|
||||
const QString &id,
|
||||
const QString &uidowner,
|
||||
const QString &ownerDisplayName,
|
||||
const QString &path,
|
||||
const ShareType shareType,
|
||||
const Permissions permissions,
|
||||
const QSharedPointer<Sharee> shareWith)
|
||||
: _account(account)
|
||||
, _id(id)
|
||||
, _uidowner(uidowner)
|
||||
, _ownerDisplayName(ownerDisplayName)
|
||||
, _path(path)
|
||||
, _shareType(shareType)
|
||||
, _permissions(permissions)
|
||||
@@ -80,6 +84,16 @@ QString Share::getId() const
|
||||
return _id;
|
||||
}
|
||||
|
||||
QString Share::getUidOwner() const
|
||||
{
|
||||
return _uidowner;
|
||||
}
|
||||
|
||||
QString Share::getOwnerDisplayName() const
|
||||
{
|
||||
return _ownerDisplayName;
|
||||
}
|
||||
|
||||
Share::ShareType Share::getShareType() const
|
||||
{
|
||||
return _shareType;
|
||||
@@ -153,6 +167,8 @@ bool LinkShare::isPasswordSet() const
|
||||
|
||||
LinkShare::LinkShare(AccountPtr account,
|
||||
const QString &id,
|
||||
const QString &uidowner,
|
||||
const QString &ownerDisplayName,
|
||||
const QString &path,
|
||||
const QString &name,
|
||||
const QString &token,
|
||||
@@ -160,7 +176,7 @@ LinkShare::LinkShare(AccountPtr account,
|
||||
bool passwordSet,
|
||||
const QUrl &url,
|
||||
const QDate &expireDate)
|
||||
: Share(account, id, path, Share::TypeLink, permissions)
|
||||
: Share(account, id, uidowner, ownerDisplayName, path, Share::TypeLink, permissions)
|
||||
, _name(name)
|
||||
, _token(token)
|
||||
, _passwordSet(passwordSet)
|
||||
@@ -393,6 +409,8 @@ QSharedPointer<LinkShare> ShareManager::parseLinkShare(const QJsonObject &data)
|
||||
|
||||
return QSharedPointer<LinkShare>(new LinkShare(_account,
|
||||
data.value("id").toVariant().toString(), // "id" used to be an integer, support both
|
||||
data.value("uid_owner").toString(),
|
||||
data.value("displayname_owner").toString(),
|
||||
data.value("path").toString(),
|
||||
data.value("name").toString(),
|
||||
data.value("token").toString(),
|
||||
@@ -410,6 +428,8 @@ QSharedPointer<Share> ShareManager::parseShare(const QJsonObject &data)
|
||||
|
||||
return QSharedPointer<Share>(new Share(_account,
|
||||
data.value("id").toVariant().toString(), // "id" used to be an integer, support both
|
||||
data.value("uid_owner").toVariant().toString(),
|
||||
data.value("displayname_owner").toVariant().toString(),
|
||||
data.value("path").toString(),
|
||||
(Share::ShareType)data.value("share_type").toInt(),
|
||||
(Share::Permissions)data.value("permissions").toInt(),
|
||||
|
||||
@@ -54,6 +54,8 @@ public:
|
||||
*/
|
||||
explicit Share(AccountPtr account,
|
||||
const QString &id,
|
||||
const QString &owner,
|
||||
const QString &ownerDisplayName,
|
||||
const QString &path,
|
||||
const ShareType shareType,
|
||||
const Permissions permissions = SharePermissionDefault,
|
||||
@@ -71,6 +73,16 @@ public:
|
||||
*/
|
||||
QString getId() const;
|
||||
|
||||
/*
|
||||
* Get the uid_owner
|
||||
*/
|
||||
QString getUidOwner() const;
|
||||
|
||||
/*
|
||||
* Get the owner display name
|
||||
*/
|
||||
QString getOwnerDisplayName() const;
|
||||
|
||||
/*
|
||||
* Get the shareType
|
||||
*/
|
||||
@@ -110,6 +122,8 @@ signals:
|
||||
protected:
|
||||
AccountPtr _account;
|
||||
QString _id;
|
||||
QString _uidowner;
|
||||
QString _ownerDisplayName;
|
||||
QString _path;
|
||||
ShareType _shareType;
|
||||
Permissions _permissions;
|
||||
@@ -134,6 +148,8 @@ class LinkShare : public Share
|
||||
public:
|
||||
explicit LinkShare(AccountPtr account,
|
||||
const QString &id,
|
||||
const QString &uidowner,
|
||||
const QString &ownerDisplayName,
|
||||
const QString &path,
|
||||
const QString &name,
|
||||
const QString &token,
|
||||
|
||||
@@ -190,18 +190,29 @@ void ShareUserGroupWidget::slotSharesFetched(const QList<QSharedPointer<Share>>
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
int x = 0;
|
||||
int height = 0;
|
||||
QList<QString> linkOwners({});
|
||||
|
||||
foreach (const auto &share, shares) {
|
||||
// We don't handle link shares, only TypeUser or TypeGroup
|
||||
if (share->getShareType() == Share::TypeLink) {
|
||||
if(!share->getUidOwner().isEmpty() &&
|
||||
share->getUidOwner() != share->account()->davUser()){
|
||||
linkOwners.append(share->getOwnerDisplayName());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// the owner of the file that shared it first
|
||||
if(x == 0 && !share->getUidOwner().isEmpty()){
|
||||
_ui->mainOwnerLabel->setText(QString("Shared with you by ").append(share->getOwnerDisplayName()));
|
||||
}
|
||||
|
||||
ShareUserLine *s = new ShareUserLine(share, _maxSharingPermissions, _isFile, _parentScrollArea);
|
||||
connect(s, &ShareUserLine::resizeRequested, this, &ShareUserGroupWidget::slotAdjustScrollWidgetSize);
|
||||
connect(s, &ShareUserLine::visualDeletionDone, this, &ShareUserGroupWidget::getShares);
|
||||
s->setBackgroundRole(layout->count() % 2 == 0 ? QPalette::Base : QPalette::AlternateBase);
|
||||
layout->addWidget(s);
|
||||
s->setVisible(true);
|
||||
|
||||
x++;
|
||||
if (x <= 3) {
|
||||
@@ -209,7 +220,18 @@ void ShareUserGroupWidget::slotSharesFetched(const QList<QSharedPointer<Share>>
|
||||
}
|
||||
}
|
||||
|
||||
scrollArea->setFrameShape(x > 3 ? QFrame::StyledPanel : QFrame::NoFrame);
|
||||
foreach (const QString &owner, linkOwners) {
|
||||
auto ownerLabel = new QLabel(QString(owner + " shared via link"));
|
||||
layout->addWidget(ownerLabel);
|
||||
ownerLabel->setVisible(true);
|
||||
|
||||
x++;
|
||||
if (x <= 6) {
|
||||
height = newViewPort->sizeHint().height();
|
||||
}
|
||||
}
|
||||
|
||||
scrollArea->setFrameShape(x > 6 ? QFrame::StyledPanel : QFrame::NoFrame);
|
||||
scrollArea->setVisible(!shares.isEmpty());
|
||||
scrollArea->setFixedHeight(height);
|
||||
scrollArea->setWidget(newViewPort);
|
||||
@@ -420,6 +442,13 @@ ShareUserLine::ShareUserLine(QSharedPointer<Share> share,
|
||||
_permissionReshare->setVisible(false);
|
||||
}
|
||||
|
||||
//If the initiator is not you. And the recipient is not you. Show it without any options.
|
||||
if(share->account()->id() != share->getId() && share->account()->davUser() != share->getShareWith()->shareWith()){
|
||||
_ui->permissionsEdit->hide();
|
||||
_ui->permissionToolButton->hide();
|
||||
_ui->deleteShareButton->hide();
|
||||
}
|
||||
|
||||
loadAvatar();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,13 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="mainOwnerLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="shareeHorizontalLayout">
|
||||
<property name="leftMargin">
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <QFileDialog>
|
||||
#include <QUrl>
|
||||
#include <QTimer>
|
||||
#include <QStorageInfo>
|
||||
|
||||
#include "QProgressIndicator.h"
|
||||
|
||||
@@ -169,10 +170,21 @@ void OwncloudAdvancedSetupPage::updateStatus()
|
||||
_ui.resolutionWidget->setVisible(false);
|
||||
}
|
||||
|
||||
QString lfreeSpaceStr = Utility::octetsToString(availableLocalSpace());
|
||||
_ui.lFreeSpace->setText(QString(tr("Free space: %1")).arg(lfreeSpaceStr));
|
||||
|
||||
_ui.syncModeLabel->setText(t);
|
||||
_ui.syncModeLabel->setFixedHeight(_ui.syncModeLabel->sizeHint().height());
|
||||
wizard()->resize(wizard()->sizeHint());
|
||||
|
||||
qint64 rSpace = _ui.rSyncEverything->isChecked() ? _rSize : _rSelectedSize;
|
||||
|
||||
QString spaceError = checkLocalSpace(rSpace);
|
||||
if (!spaceError.isEmpty()) {
|
||||
errorStr = spaceError;
|
||||
}
|
||||
setErrorString(errorStr);
|
||||
|
||||
emit completeChanged();
|
||||
}
|
||||
|
||||
@@ -288,6 +300,10 @@ void OwncloudAdvancedSetupPage::slotSelectFolder()
|
||||
wizard()->setProperty("localFolder", dir);
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
qint64 rSpace = _ui.rSyncEverything->isChecked() ? _rSize : _rSelectedSize;
|
||||
QString errorStr = checkLocalSpace(rSpace);
|
||||
setErrorString(errorStr);
|
||||
}
|
||||
|
||||
void OwncloudAdvancedSetupPage::slotSelectiveSyncClicked()
|
||||
@@ -322,6 +338,11 @@ void OwncloudAdvancedSetupPage::slotSelectiveSyncClicked()
|
||||
auto s = dlg->estimatedSize();
|
||||
if (s > 0) {
|
||||
_ui.lSelectiveSyncSizeLabel->setText(tr("(%1)").arg(Utility::octetsToString(s)));
|
||||
|
||||
_rSelectedSize = s;
|
||||
QString errorStr = checkLocalSpace(_rSelectedSize);
|
||||
setErrorString(errorStr);
|
||||
|
||||
} else {
|
||||
_ui.lSelectiveSyncSizeLabel->setText(QString());
|
||||
}
|
||||
@@ -338,11 +359,30 @@ void OwncloudAdvancedSetupPage::slotSyncEverythingClicked()
|
||||
_ui.lSelectiveSyncSizeLabel->setText(QString());
|
||||
_ui.rSyncEverything->setChecked(true);
|
||||
_selectiveSyncBlacklist.clear();
|
||||
|
||||
QString errorStr = checkLocalSpace(_rSize);
|
||||
setErrorString(errorStr);
|
||||
}
|
||||
|
||||
void OwncloudAdvancedSetupPage::slotQuotaRetrieved(const QVariantMap &result)
|
||||
{
|
||||
_ui.lSyncEverythingSizeLabel->setText(tr("(%1)").arg(Utility::octetsToString(result["size"].toDouble())));
|
||||
_rSize = result["size"].toDouble();
|
||||
_ui.lSyncEverythingSizeLabel->setText(tr("(%1)").arg(Utility::octetsToString(_rSize)));
|
||||
}
|
||||
|
||||
qint64 OwncloudAdvancedSetupPage::availableLocalSpace() const
|
||||
{
|
||||
QString localDir = localFolder();
|
||||
QString path = !QDir(localDir).exists() && localDir.contains(QDir::homePath()) ?
|
||||
QDir::homePath() : localDir;
|
||||
QStorageInfo storage(QDir::toNativeSeparators(path));
|
||||
|
||||
return storage.bytesAvailable();
|
||||
}
|
||||
|
||||
QString OwncloudAdvancedSetupPage::checkLocalSpace(qint64 remoteSize) const
|
||||
{
|
||||
return (availableLocalSpace()>remoteSize) ? QString() : tr("There isn't enough free space in the local folder!");
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
@@ -65,6 +65,8 @@ private:
|
||||
void startSpinner();
|
||||
void stopSpinner();
|
||||
QUrl serverUrl() const;
|
||||
qint64 availableLocalSpace() const;
|
||||
QString checkLocalSpace(qint64 remoteSize) const;
|
||||
|
||||
Ui_OwncloudAdvancedSetupPage _ui;
|
||||
bool _checking;
|
||||
@@ -73,6 +75,8 @@ private:
|
||||
QProgressIndicator *_progressIndi;
|
||||
QString _remoteFolder;
|
||||
QStringList _selectiveSyncBlacklist;
|
||||
qint64 _rSize;
|
||||
qint64 _rSelectedSize;
|
||||
};
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
@@ -73,159 +73,6 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="lServerIcon">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lServer">
|
||||
<property name="text">
|
||||
<string>Server</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0" rowspan="3">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="lLocalIcon">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lLocal">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Local Folder</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>pbSelectLocalFolder</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="QWidget" name="resolutionWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="radioButton">
|
||||
<property name="text">
|
||||
<string>&Keep local data</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="cbSyncFromScratch">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If this box is checked, existing content in the local folder will be erased to start a clean sync from the server.</p><p>Do not check this if the local content should be uploaded to the servers folder.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start a &clean sync (Erases the local folder!)</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" rowspan="2">
|
||||
<widget class="QPushButton" name="pbSelectLocalFolder">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>pbSelectLocalFolder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
@@ -380,6 +227,166 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" rowspan="4">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="lLocalIcon">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lLocal">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Local Folder</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>pbSelectLocalFolder</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1" rowspan="2">
|
||||
<widget class="QPushButton" name="pbSelectLocalFolder">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>pbSelectLocalFolder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="lServerIcon">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lServer">
|
||||
<property name="text">
|
||||
<string>Server</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<widget class="QWidget" name="resolutionWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="radioButton">
|
||||
<property name="text">
|
||||
<string>&Keep local data</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="cbSyncFromScratch">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If this box is checked, existing content in the local folder will be erased to start a clean sync from the server.</p><p>Do not check this if the local content should be uploaded to the servers folder.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start a &clean sync (Erases the local folder!)</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="lFreeSpace">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -285,7 +285,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ser&ver Address</string>
|
||||
<string>Server Address</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>leUrl</cstring>
|
||||
|
||||
@@ -96,7 +96,6 @@ OwncloudSetupPage::OwncloudSetupPage(QWidget *parent)
|
||||
_ui.installLink->hide();
|
||||
_ui.slideShow->hide();
|
||||
#endif
|
||||
setStyleSheet(QString("background-color:%1; color:%2 QLabel { color:%2; } QSpacerItem { color: red; }").arg(theme->wizardHeaderBackgroundColor().name(), theme->wizardHeaderTitleColor().name()));
|
||||
}
|
||||
|
||||
void OwncloudSetupPage::setServerUrl(const QString &newUrl)
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <QProgressBar>
|
||||
#include <QLoggingCategory>
|
||||
#include <QLocale>
|
||||
#include <QWebEngineCertificateError>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "common/utility.h"
|
||||
|
||||
@@ -104,6 +106,19 @@ void WebView::setUrl(const QUrl &url) {
|
||||
_page->setUrl(url);
|
||||
}
|
||||
|
||||
WebView::~WebView() {
|
||||
/*
|
||||
* The Qt implmentation deletes children in the order they are added to the
|
||||
* object tree, so in this case _page is deleted after _profile, which
|
||||
* violates the assumption that _profile should exist longer than
|
||||
* _page [1]. Here I delete _page manually so that _profile can be safely
|
||||
* deleted later.
|
||||
*
|
||||
* [1] https://doc.qt.io/qt-5/qwebenginepage.html#QWebEnginePage-1
|
||||
*/
|
||||
delete _page;
|
||||
}
|
||||
|
||||
WebViewPageUrlRequestInterceptor::WebViewPageUrlRequestInterceptor(QObject *parent)
|
||||
: QWebEngineUrlRequestInterceptor(parent) {
|
||||
|
||||
@@ -121,7 +136,7 @@ WebViewPageUrlSchemeHandler::WebViewPageUrlSchemeHandler(QObject *parent)
|
||||
void WebViewPageUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request) {
|
||||
QUrl url = request->requestUrl();
|
||||
|
||||
QString path = url.path().mid(1);
|
||||
QString path = url.path(0).mid(1); // get undecoded path
|
||||
QStringList parts = path.split("&");
|
||||
|
||||
QString server;
|
||||
@@ -137,6 +152,15 @@ void WebViewPageUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *reques
|
||||
password = part.mid(9);
|
||||
}
|
||||
}
|
||||
|
||||
qCDebug(lcWizardWebiew()) << "Got raw user from request path: " << user;
|
||||
|
||||
user = user.replace(QChar('+'), QChar(' '));
|
||||
password = password.replace(QChar('+'), QChar(' '));
|
||||
|
||||
user = QUrl::fromPercentEncoding(user.toUtf8());
|
||||
password = QUrl::fromPercentEncoding(password.toUtf8());
|
||||
|
||||
if (!server.startsWith("http://") && !server.startsWith("https://")) {
|
||||
server = "https://" + server;
|
||||
}
|
||||
@@ -161,11 +185,28 @@ void WebEnginePage::setUrl(const QUrl &url) {
|
||||
}
|
||||
|
||||
bool WebEnginePage::certificateError(const QWebEngineCertificateError &certificateError) {
|
||||
if (certificateError.error() == QWebEngineCertificateError::CertificateAuthorityInvalid) {
|
||||
return certificateError.url().host() == _rootUrl.host();
|
||||
if (certificateError.error() == QWebEngineCertificateError::CertificateAuthorityInvalid &&
|
||||
certificateError.url().host() == _rootUrl.host()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
/**
|
||||
* TODO properly improve this.
|
||||
* The certificate should be displayed.
|
||||
*
|
||||
* Or rather we should do a request with the QNAM and see if it works (then it is in the store).
|
||||
* This is just a quick fix for now.
|
||||
*/
|
||||
QMessageBox messageBox;
|
||||
messageBox.setText(tr("Invalid certificate detected"));
|
||||
messageBox.setInformativeText(tr("The host \"%1\" provided an invalid certificate. Continue?").arg(certificateError.url().host()));
|
||||
messageBox.setIcon(QMessageBox::Warning);
|
||||
messageBox.setStandardButtons(QMessageBox::Yes|QMessageBox::No);
|
||||
messageBox.setDefaultButton(QMessageBox::No);
|
||||
|
||||
int ret = messageBox.exec();
|
||||
|
||||
return ret == QMessageBox::Yes;
|
||||
}
|
||||
|
||||
ExternalWebEnginePage::ExternalWebEnginePage(QWebEngineProfile *profile, QObject* parent) : QWebEnginePage(profile, parent) {
|
||||
|
||||
@@ -21,6 +21,7 @@ class WebView : public QWidget
|
||||
Q_OBJECT
|
||||
public:
|
||||
WebView(QWidget *parent = nullptr);
|
||||
virtual ~WebView();
|
||||
void setUrl(const QUrl &url);
|
||||
|
||||
signals:
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <QWebEngineUrlRequestJob>
|
||||
#include <QProgressBar>
|
||||
#include <QVBoxLayout>
|
||||
#include <QNetworkProxyFactory>
|
||||
|
||||
#include "owncloudwizard.h"
|
||||
#include "creds/webflowcredentials.h"
|
||||
@@ -27,15 +28,26 @@ WebViewPage::WebViewPage(QWidget *parent)
|
||||
setLayout(layout);
|
||||
|
||||
connect(_webView, &WebView::urlCatched, this, &WebViewPage::urlCatched);
|
||||
|
||||
//_useSystemProxy = QNetworkProxyFactory::usesSystemConfiguration();
|
||||
}
|
||||
|
||||
WebViewPage::~WebViewPage() {
|
||||
//QNetworkProxyFactory::setUseSystemConfiguration(_useSystemProxy);
|
||||
}
|
||||
|
||||
void WebViewPage::initializePage() {
|
||||
//QNetworkProxy::setApplicationProxy(QNetworkProxy::applicationProxy());
|
||||
|
||||
QString url;
|
||||
if (_ocWizard->registration()) {
|
||||
url = "https://nextcloud.com/register";
|
||||
} else {
|
||||
url = _ocWizard->ocUrl();
|
||||
url += "/index.php/login/flow";
|
||||
if (!url.endsWith('/')) {
|
||||
url += "/";
|
||||
}
|
||||
url += "index.php/login/flow";
|
||||
}
|
||||
qCInfo(lcWizardWebiewPage()) << "Url to auth at: " << url;
|
||||
_webView->setUrl(QUrl(url));
|
||||
|
||||
@@ -14,6 +14,7 @@ class WebViewPage : public AbstractCredentialsWizardPage
|
||||
Q_OBJECT
|
||||
public:
|
||||
WebViewPage(QWidget *parent = nullptr);
|
||||
~WebViewPage();
|
||||
|
||||
void initializePage() override;
|
||||
int nextId() const override;
|
||||
@@ -34,6 +35,8 @@ private:
|
||||
|
||||
QString _user;
|
||||
QString _pass;
|
||||
|
||||
bool _useSystemProxy;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -958,6 +958,7 @@ void ClientSideEncryption::encryptPrivateKey()
|
||||
{
|
||||
QStringList list = WordList::getRandomWords(12);
|
||||
_mnemonic = list.join(' ');
|
||||
_newMnemonicGenerated = true;
|
||||
qCInfo(lcCse()) << "mnemonic Generated:" << _mnemonic;
|
||||
|
||||
emit mnemonicGenerated(_mnemonic);
|
||||
@@ -989,6 +990,11 @@ void ClientSideEncryption::encryptPrivateKey()
|
||||
job->start();
|
||||
}
|
||||
|
||||
bool ClientSideEncryption::newMnemonicGenerated() const
|
||||
{
|
||||
return _newMnemonicGenerated;
|
||||
}
|
||||
|
||||
void ClientSideEncryption::decryptPrivateKey(const QByteArray &key) {
|
||||
QString msg = tr("Please enter your end to end encryption passphrase:<br>"
|
||||
"<br>"
|
||||
|
||||
@@ -87,6 +87,8 @@ public:
|
||||
|
||||
void forgetSensitiveData();
|
||||
|
||||
bool newMnemonicGenerated() const;
|
||||
|
||||
public slots:
|
||||
void slotRequestMnemonic();
|
||||
|
||||
@@ -127,6 +129,7 @@ public:
|
||||
QSslKey _publicKey;
|
||||
QSslCertificate _certificate;
|
||||
QString _mnemonic;
|
||||
bool _newMnemonicGenerated = false;
|
||||
};
|
||||
|
||||
/* Generates the Metadata for the folder */
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <QNetworkProxy>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#define DEFAULT_REMOTE_POLL_INTERVAL 30000 // default remote poll time in milliseconds
|
||||
#define DEFAULT_REMOTE_POLL_INTERVAL 5000 // default remote poll time in milliseconds
|
||||
#define DEFAULT_MAX_LOG_LINES 20000
|
||||
|
||||
namespace OCC {
|
||||
@@ -750,7 +750,7 @@ void ConfigFile::setMoveToTrash(bool isChecked)
|
||||
bool ConfigFile::promptDeleteFiles() const
|
||||
{
|
||||
QSettings settings(configFile(), QSettings::IniFormat);
|
||||
return settings.value(QLatin1String(promptDeleteC), true).toBool();
|
||||
return settings.value(QLatin1String(promptDeleteC), false).toBool();
|
||||
}
|
||||
|
||||
void ConfigFile::setPromptDeleteFiles(bool promptDeleteFiles)
|
||||
|
||||
@@ -33,29 +33,4 @@ NextcloudTheme::NextcloudTheme()
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef TOKEN_AUTH_ONLY
|
||||
QVariant NextcloudTheme::customMedia(CustomMediaType)
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef TOKEN_AUTH_ONLY
|
||||
QColor NextcloudTheme::wizardHeaderBackgroundColor() const
|
||||
{
|
||||
return QColor("#0082c9");
|
||||
}
|
||||
|
||||
QColor NextcloudTheme::wizardHeaderTitleColor() const
|
||||
{
|
||||
return QColor("#ffffff");
|
||||
}
|
||||
|
||||
QPixmap NextcloudTheme::wizardHeaderLogo() const
|
||||
{
|
||||
return QPixmap(hidpiFileName(":/client/theme/colored/wizard_logo.png"));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -29,15 +29,6 @@ class NextcloudTheme : public Theme
|
||||
public:
|
||||
NextcloudTheme();
|
||||
|
||||
#ifndef TOKEN_AUTH_ONLY
|
||||
QVariant customMedia(CustomMediaType type) override;
|
||||
|
||||
QColor wizardHeaderBackgroundColor() const override;
|
||||
QColor wizardHeaderTitleColor() const override;
|
||||
QPixmap wizardHeaderLogo() const override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
#endif // NEXTCLOUD_THEME_H
|
||||
|
||||
@@ -269,6 +269,7 @@ void PropagateItemJob::done(SyncFileItem::Status statusArg, const QString &error
|
||||
case SyncFileItem::FileIgnored:
|
||||
case SyncFileItem::NoStatus:
|
||||
case SyncFileItem::BlacklistedError:
|
||||
case SyncFileItem::FileLocked:
|
||||
// nothing
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ inline SyncFileItem::Status classifyError(QNetworkReply::NetworkError nerror,
|
||||
if (anotherSyncNeeded) {
|
||||
*anotherSyncNeeded = true;
|
||||
}
|
||||
return SyncFileItem::SoftError;
|
||||
return SyncFileItem::FileLocked;
|
||||
}
|
||||
|
||||
return SyncFileItem::NormalError;
|
||||
|
||||
@@ -91,7 +91,8 @@ bool Progress::isWarningKind(SyncFileItem::Status kind)
|
||||
return kind == SyncFileItem::SoftError || kind == SyncFileItem::NormalError
|
||||
|| kind == SyncFileItem::FatalError || kind == SyncFileItem::FileIgnored
|
||||
|| kind == SyncFileItem::Conflict || kind == SyncFileItem::Restoration
|
||||
|| kind == SyncFileItem::DetailError || kind == SyncFileItem::BlacklistedError;
|
||||
|| kind == SyncFileItem::DetailError || kind == SyncFileItem::BlacklistedError
|
||||
|| kind == SyncFileItem::FileLocked;
|
||||
}
|
||||
|
||||
bool Progress::isIgnoredKind(SyncFileItem::Status kind)
|
||||
|
||||
@@ -571,6 +571,12 @@ void PropagateDownloadFile::slotGetFinished()
|
||||
qCWarning(lcPropagateDownload) << "server replied 404, assuming file was deleted";
|
||||
}
|
||||
|
||||
// Getting a 423 means that the file is locked
|
||||
const bool fileLocked = _item->_httpErrorCode == 423;
|
||||
if (fileLocked) {
|
||||
qCWarning(lcPropagateDownload) << "server replied 423, file is Locked";
|
||||
}
|
||||
|
||||
// Don't keep the temporary file if it is empty or we
|
||||
// used a bad range header or the file's not on the server anymore.
|
||||
if (_tmpFile.size() == 0 || badRangeHeader || fileNotFound) {
|
||||
@@ -659,7 +665,7 @@ void PropagateDownloadFile::slotGetFinished()
|
||||
if (_tmpFile.size() == 0 && _item->_size > 0) {
|
||||
FileSystem::remove(_tmpFile.fileName());
|
||||
done(SyncFileItem::NormalError,
|
||||
tr("The downloaded file is empty despite the server announced it should have been %1.")
|
||||
tr("The downloaded file is empty despite that the server announced it should have been %1.")
|
||||
.arg(Utility::octetsToString(_item->_size)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,19 +92,19 @@ private:
|
||||
|
||||
public:
|
||||
// Takes ownership of the device
|
||||
explicit PUTFileJob(AccountPtr account, const QString &path, QIODevice *device,
|
||||
explicit PUTFileJob(AccountPtr account, const QString &path, std::unique_ptr<QIODevice> device,
|
||||
const QMap<QByteArray, QByteArray> &headers, int chunk, QObject *parent = nullptr)
|
||||
: AbstractNetworkJob(account, path, parent)
|
||||
, _device(device)
|
||||
, _device(device.release())
|
||||
, _headers(headers)
|
||||
, _chunk(chunk)
|
||||
{
|
||||
_device->setParent(this);
|
||||
}
|
||||
explicit PUTFileJob(AccountPtr account, const QUrl &url, QIODevice *device,
|
||||
explicit PUTFileJob(AccountPtr account, const QUrl &url, std::unique_ptr<QIODevice> device,
|
||||
const QMap<QByteArray, QByteArray> &headers, int chunk, QObject *parent = nullptr)
|
||||
: AbstractNetworkJob(account, QString(), parent)
|
||||
, _device(device)
|
||||
, _device(device.release())
|
||||
, _headers(headers)
|
||||
, _url(url)
|
||||
, _chunk(chunk)
|
||||
|
||||
@@ -305,7 +305,7 @@ void PropagateUploadFileNG::startNextChunk()
|
||||
return;
|
||||
}
|
||||
|
||||
auto device = new UploadDevice(&propagator()->_bandwidthManager);
|
||||
auto device = std::make_unique<UploadDevice>(&propagator()->_bandwidthManager);
|
||||
const QString fileName = _fileToUpload._path;
|
||||
|
||||
if (!device->prepareAndOpen(fileName, _sent, _currentChunkSize)) {
|
||||
@@ -328,13 +328,14 @@ void PropagateUploadFileNG::startNextChunk()
|
||||
QUrl url = chunkUrl(_currentChunk);
|
||||
|
||||
// job takes ownership of device via a QScopedPointer. Job deletes itself when finishing
|
||||
PUTFileJob *job = new PUTFileJob(propagator()->account(), url, device, headers, _currentChunk, this);
|
||||
auto devicePtr = device.get(); // for connections later
|
||||
PUTFileJob *job = new PUTFileJob(propagator()->account(), url, std::move(device), headers, _currentChunk, this);
|
||||
_jobs.append(job);
|
||||
connect(job, &PUTFileJob::finishedSignal, this, &PropagateUploadFileNG::slotPutFinished);
|
||||
connect(job, &PUTFileJob::uploadProgress,
|
||||
this, &PropagateUploadFileNG::slotUploadProgress);
|
||||
connect(job, &PUTFileJob::uploadProgress,
|
||||
device, &UploadDevice::slotJobUploadProgress);
|
||||
devicePtr, &UploadDevice::slotJobUploadProgress);
|
||||
connect(job, &QObject::destroyed, this, &PropagateUploadFileCommon::slotJobDestroyed);
|
||||
job->start();
|
||||
propagator()->_activeJobList.append(this);
|
||||
|
||||
@@ -89,7 +89,7 @@ void PropagateUploadFileV1::startNextChunk()
|
||||
|
||||
QString path = _fileToUpload._file;
|
||||
|
||||
UploadDevice *device = new UploadDevice(&propagator()->_bandwidthManager);
|
||||
auto device = std::make_unique<UploadDevice>(&propagator()->_bandwidthManager);
|
||||
qint64 chunkStart = 0;
|
||||
qint64 currentChunkSize = fileSize;
|
||||
bool isFinalChunk = false;
|
||||
@@ -134,16 +134,16 @@ void PropagateUploadFileV1::startNextChunk()
|
||||
}
|
||||
// Soft error because this is likely caused by the user modifying his files while syncing
|
||||
abortWithError(SyncFileItem::SoftError, device->errorString());
|
||||
delete device;
|
||||
return;
|
||||
}
|
||||
|
||||
// job takes ownership of device via a QScopedPointer. Job deletes itself when finishing
|
||||
PUTFileJob *job = new PUTFileJob(propagator()->account(), propagator()->_remoteFolder + path, device, headers, _currentChunk, this);
|
||||
auto devicePtr = device.get(); // for connections later
|
||||
PUTFileJob *job = new PUTFileJob(propagator()->account(), propagator()->_remoteFolder + path, std::move(device), headers, _currentChunk, this);
|
||||
_jobs.append(job);
|
||||
connect(job, &PUTFileJob::finishedSignal, this, &PropagateUploadFileV1::slotPutFinished);
|
||||
connect(job, &PUTFileJob::uploadProgress, this, &PropagateUploadFileV1::slotUploadProgress);
|
||||
connect(job, &PUTFileJob::uploadProgress, device, &UploadDevice::slotJobUploadProgress);
|
||||
connect(job, &PUTFileJob::uploadProgress, devicePtr, &UploadDevice::slotJobUploadProgress);
|
||||
connect(job, &QObject::destroyed, this, &PropagateUploadFileCommon::slotJobDestroyed);
|
||||
if (isFinalChunk)
|
||||
adjustLastJobTimeout(job, fileSize);
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "propagateremotedelete.h"
|
||||
#include "propagatedownload.h"
|
||||
#include "common/asserts.h"
|
||||
#include "configfile.h"
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <windows.h>
|
||||
@@ -1035,7 +1037,8 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
|
||||
}
|
||||
}
|
||||
|
||||
if (!_hasNoneFiles && _hasRemoveFile) {
|
||||
ConfigFile cfgFile;
|
||||
if (!_hasNoneFiles && _hasRemoveFile && cfgFile.promptDeleteFiles()) {
|
||||
qCInfo(lcEngine) << "All the files are going to be changed, asking the user";
|
||||
bool cancel = false;
|
||||
emit aboutToRemoveAllFiles(syncItems.first()->_direction, &cancel);
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
Conflict,
|
||||
|
||||
FileIgnored, ///< The file is in the ignored list (or blacklisted with no retries left)
|
||||
FileLocked, ///< The file is locked
|
||||
Restoration, ///< The file was restored because what should have been done was not allowed
|
||||
|
||||
/** For errors that should only appear in the error view.
|
||||
|
||||
@@ -105,7 +105,8 @@ static inline bool showWarningInSocketApi(const SyncFileItem &item)
|
||||
return item._instruction == CSYNC_INSTRUCTION_IGNORE
|
||||
|| status == SyncFileItem::FileIgnored
|
||||
|| status == SyncFileItem::Conflict
|
||||
|| status == SyncFileItem::Restoration;
|
||||
|| status == SyncFileItem::Restoration
|
||||
|| status == SyncFileItem::FileLocked;
|
||||
}
|
||||
|
||||
SyncFileStatusTracker::SyncFileStatusTracker(SyncEngine *syncEngine)
|
||||
|
||||
@@ -28,6 +28,7 @@ SyncResult::SyncResult()
|
||||
, _numNewConflictItems(0)
|
||||
, _numOldConflictItems(0)
|
||||
, _numErrorItems(0)
|
||||
, _numLockedItems(0)
|
||||
|
||||
{
|
||||
}
|
||||
@@ -139,6 +140,13 @@ void SyncResult::processCompletedItem(const SyncFileItemPtr &item)
|
||||
_folderStructureWasChanged = true;
|
||||
}
|
||||
|
||||
if(item->_status == SyncFileItem::FileLocked){
|
||||
_numLockedItems++;
|
||||
if (!_firstItemLocked) {
|
||||
_firstItemLocked = item;
|
||||
}
|
||||
}
|
||||
|
||||
// Process the item to the gui
|
||||
if (item->_status == SyncFileItem::FatalError || item->_status == SyncFileItem::NormalError) {
|
||||
//: this displays an error string (%2) for a file %1
|
||||
|
||||
@@ -72,12 +72,16 @@ public:
|
||||
int numErrorItems() const { return _numErrorItems; }
|
||||
bool hasUnresolvedConflicts() const { return _numNewConflictItems + _numOldConflictItems > 0; }
|
||||
|
||||
int numLockedItems() const { return _numLockedItems; }
|
||||
bool hasLockedFiles() const { return _numLockedItems > 0; }
|
||||
|
||||
const SyncFileItemPtr &firstItemNew() const { return _firstItemNew; }
|
||||
const SyncFileItemPtr &firstItemDeleted() const { return _firstItemDeleted; }
|
||||
const SyncFileItemPtr &firstItemUpdated() const { return _firstItemUpdated; }
|
||||
const SyncFileItemPtr &firstItemRenamed() const { return _firstItemRenamed; }
|
||||
const SyncFileItemPtr &firstNewConflictItem() const { return _firstNewConflictItem; }
|
||||
const SyncFileItemPtr &firstItemError() const { return _firstItemError; }
|
||||
const SyncFileItemPtr &firstItemLocked() const { return _firstItemLocked; }
|
||||
|
||||
void processCompletedItem(const SyncFileItemPtr &item);
|
||||
|
||||
@@ -101,6 +105,7 @@ private:
|
||||
int _numNewConflictItems;
|
||||
int _numOldConflictItems;
|
||||
int _numErrorItems;
|
||||
int _numLockedItems;
|
||||
|
||||
SyncFileItemPtr _firstItemNew;
|
||||
SyncFileItemPtr _firstItemDeleted;
|
||||
@@ -108,6 +113,7 @@ private:
|
||||
SyncFileItemPtr _firstItemRenamed;
|
||||
SyncFileItemPtr _firstNewConflictItem;
|
||||
SyncFileItemPtr _firstItemError;
|
||||
SyncFileItemPtr _firstItemLocked;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -225,7 +225,11 @@ QString Theme::defaultServerFolder() const
|
||||
|
||||
QString Theme::helpUrl() const
|
||||
{
|
||||
#ifdef APPLICATION_HELP_URL
|
||||
return QString::fromLatin1(APPLICATION_HELP_URL);
|
||||
#else
|
||||
return QString::fromLatin1("https://docs.nextcloud.com/desktop/%1.%2/").arg(MIRALL_VERSION_MAJOR).arg(MIRALL_VERSION_MINOR);
|
||||
#endif
|
||||
}
|
||||
|
||||
QString Theme::conflictHelpUrl() const
|
||||
@@ -240,7 +244,11 @@ QString Theme::conflictHelpUrl() const
|
||||
|
||||
QString Theme::overrideServerUrl() const
|
||||
{
|
||||
#ifdef APPLICATION_SERVER_URL
|
||||
return QString::fromLatin1(APPLICATION_SERVER_URL);
|
||||
#else
|
||||
return QString();
|
||||
#endif
|
||||
}
|
||||
|
||||
QString Theme::forceConfigAuthType() const
|
||||
@@ -291,7 +299,7 @@ bool Theme::monoIconsAvailable() const
|
||||
|
||||
QString Theme::updateCheckUrl() const
|
||||
{
|
||||
return QLatin1String("https://updates.nextcloud.org/client/");
|
||||
return APPLICATION_UPDATE_URL;
|
||||
}
|
||||
|
||||
qint64 Theme::newBigFolderSizeLimit() const
|
||||
@@ -333,10 +341,9 @@ QString Theme::gitSHA1() const
|
||||
QString Theme::about() const
|
||||
{
|
||||
QString devString;
|
||||
devString = tr("<p>Version %1. For more information please visit <a href='%2'>%3</a>.</p>")
|
||||
devString = tr("<p>Version %1. For more information please click <a href='%2'>here</a>.</p>")
|
||||
.arg(MIRALL_VERSION_STRING)
|
||||
.arg("http://" MIRALL_STRINGIFY(APPLICATION_DOMAIN))
|
||||
.arg(MIRALL_STRINGIFY(APPLICATION_DOMAIN));
|
||||
.arg(helpUrl());
|
||||
|
||||
devString += tr("<p>This release was supplied by %1</p>")
|
||||
.arg(APPLICATION_VENDOR);
|
||||
@@ -427,17 +434,21 @@ QIcon Theme::folderOfflineIcon(bool sysTray, bool sysTrayMenuVisible) const
|
||||
|
||||
QColor Theme::wizardHeaderTitleColor() const
|
||||
{
|
||||
return qApp->palette().text().color();
|
||||
return QColor(APPLICATION_WIZARD_HEADER_TITLE_COLOR);
|
||||
}
|
||||
|
||||
QColor Theme::wizardHeaderBackgroundColor() const
|
||||
{
|
||||
return QColor();
|
||||
return QColor(APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR);
|
||||
}
|
||||
|
||||
QPixmap Theme::wizardHeaderLogo() const
|
||||
{
|
||||
#ifdef APPLICATION_WIZARD_USE_CUSTOM_LOGO
|
||||
return QPixmap(hidpiFileName(":/client/theme/colored/wizard_logo.png"));
|
||||
#else
|
||||
return applicationIcon().pixmap(64);
|
||||
#endif
|
||||
}
|
||||
|
||||
QPixmap Theme::wizardHeaderBanner() const
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <QtTest>
|
||||
#include "syncenginetestutils.h"
|
||||
#include <syncengine.h>
|
||||
#include <configfile.h>
|
||||
|
||||
using namespace OCC;
|
||||
|
||||
@@ -48,6 +49,8 @@ private slots:
|
||||
{
|
||||
QFETCH(bool, deleteOnRemote);
|
||||
FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
|
||||
ConfigFile config;
|
||||
config.setPromptDeleteFiles(true);
|
||||
|
||||
//Just set a blacklist so we can check it is still there. This directory does not exists but
|
||||
// that does not matter for our purposes.
|
||||
|
||||
@@ -140,6 +140,17 @@ private slots:
|
||||
QVERIFY(waitForPathChanged(file));
|
||||
}
|
||||
|
||||
void testMove3LevelDirWithFile() {
|
||||
QString file(_rootPath + "/a0/b/c/empty.txt");
|
||||
mkdir(_rootPath + "/a0");
|
||||
mkdir(_rootPath + "/a0/b");
|
||||
mkdir(_rootPath + "/a0/b/c");
|
||||
touch(file);
|
||||
mv(_rootPath + "/a0 ", _rootPath + "/a");
|
||||
QVERIFY(waitForPathChanged(_rootPath + "/a/b/c/empty.txt"));
|
||||
}
|
||||
|
||||
|
||||
void testCreateADir() {
|
||||
QString file(_rootPath+"/a1/b1/new_dir");
|
||||
mkdir(file);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
4170
translations/client_da.ts
Normal file
4170
translations/client_da.ts
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user