Compare commits
118 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0791e51ce | ||
|
|
11a36158ad | ||
|
|
d74024baf4 | ||
|
|
f95ff45c16 | ||
|
|
d6d8132b36 | ||
|
|
b426ca3579 | ||
|
|
4aabf339ea | ||
|
|
f3c5081c38 | ||
|
|
63863d15ad | ||
|
|
e5690d77f6 | ||
|
|
cbc3cfb8ab | ||
|
|
eae2e0075f | ||
|
|
c875ebecda | ||
|
|
ac114950ed | ||
|
|
869b3f5f81 | ||
|
|
60fc03acb5 | ||
|
|
34c782c81d | ||
|
|
a668cb123f | ||
|
|
4b2dbd54d2 | ||
|
|
7947b31d64 | ||
|
|
318bc32a06 | ||
|
|
985eba8fa3 | ||
|
|
ebf41b181b | ||
|
|
eefdb04277 | ||
|
|
ac4435aa86 | ||
|
|
1d85963551 | ||
|
|
269be3cb4f | ||
|
|
866a1da899 | ||
|
|
9f075be5c4 | ||
|
|
c1e5a0a890 | ||
|
|
1035bca4ae | ||
|
|
195218e0a3 | ||
|
|
bc1bd64ece | ||
|
|
586afaacb6 | ||
|
|
b4690f5721 | ||
|
|
5ceb98c266 | ||
|
|
0c92cfc644 | ||
|
|
ba4f53679a | ||
|
|
820f22ba0d | ||
|
|
80df113fd2 | ||
|
|
4abeda01b7 | ||
|
|
42f6606d52 | ||
|
|
b17d03c0ab | ||
|
|
4ace64f1d7 | ||
|
|
5e26d76d2b | ||
|
|
689ecbcb5b | ||
|
|
de6aa7be02 | ||
|
|
d0957fc071 | ||
|
|
fe6d126443 | ||
|
|
645688ae20 | ||
|
|
d3d2500807 | ||
|
|
a4493606e0 | ||
|
|
6d2ef0b410 | ||
|
|
05c731c4c1 | ||
|
|
1915ab7989 | ||
|
|
54d0351b42 | ||
|
|
282e47d266 | ||
|
|
07c81c02da | ||
|
|
2ef6a20edc | ||
|
|
79ffdac989 | ||
|
|
fa32c10014 | ||
|
|
fe67d66d3d | ||
|
|
3a3a6dd6b8 | ||
|
|
328c673c29 | ||
|
|
49afad0474 | ||
|
|
7c3e91202e | ||
|
|
e94b18f97f | ||
|
|
79a0b937f5 | ||
|
|
e5fbc8c2dd | ||
|
|
3632cc659b | ||
|
|
1731bf7c86 | ||
|
|
936d37fd0b | ||
|
|
7259a0bc0d | ||
|
|
06de878b4b | ||
|
|
179ff27ab6 | ||
|
|
44da2f2ce2 | ||
|
|
92b302fb37 | ||
|
|
d2febdf17c | ||
|
|
9c4b4c6183 | ||
|
|
45029e9012 | ||
|
|
969b0e8e2e | ||
|
|
4b46da9370 | ||
|
|
8b5dd53519 | ||
|
|
5ee5b19406 | ||
|
|
8e1c62cc70 | ||
|
|
151e9300cd | ||
|
|
efc3116f30 | ||
|
|
4296a6041a | ||
|
|
0d1e0057b3 | ||
|
|
5aadc7a62d | ||
|
|
3c28e38089 | ||
|
|
dba8fd7c76 | ||
|
|
39c2bb555a | ||
|
|
39fc86cbcf | ||
|
|
8d574c11e8 | ||
|
|
c02d87f283 | ||
|
|
ddb5375c68 | ||
|
|
bd78604468 | ||
|
|
4920b4d4af | ||
|
|
d12d00562f | ||
|
|
b17bbb2b22 | ||
|
|
fc64edba11 | ||
|
|
b6c7581414 | ||
|
|
962850f307 | ||
|
|
88ab5557bd | ||
|
|
e3fb3bbe73 | ||
|
|
a86a1b4c17 | ||
|
|
4326a70ede | ||
|
|
2880bd62ce | ||
|
|
b49633a9f7 | ||
|
|
adfe7ad953 | ||
|
|
e45a01bc03 | ||
|
|
9bcbc15834 | ||
|
|
b4a19bb6d3 | ||
|
|
52db45c2b1 | ||
|
|
b3d8cacf8c | ||
|
|
c004db2070 | ||
|
|
48ada55e77 |
@@ -9,7 +9,7 @@ steps:
|
|||||||
path: /drone/build
|
path: /drone/build
|
||||||
commands:
|
commands:
|
||||||
- cd /drone/build
|
- cd /drone/build
|
||||||
- cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_BUILD_TYPE=Debug -DQUICK_COMPILER=ON -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DECM_ENABLE_SANITIZERS=address -DCMAKE_CXX_FLAGS=-Werror ../src
|
- cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_BUILD_TYPE=Debug -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DECM_ENABLE_SANITIZERS=address -DCMAKE_CXX_FLAGS=-Werror ../src
|
||||||
- name: compile
|
- name: compile
|
||||||
image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4
|
image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4
|
||||||
volumes:
|
volumes:
|
||||||
@@ -53,7 +53,7 @@ steps:
|
|||||||
path: /drone/build
|
path: /drone/build
|
||||||
commands:
|
commands:
|
||||||
- cd /drone/build
|
- cd /drone/build
|
||||||
- cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_BUILD_TYPE=Debug -DQUICK_COMPILER=ON -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DECM_ENABLE_SANITIZERS=address -DCMAKE_CXX_FLAGS=-Werror ../src
|
- cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_BUILD_TYPE=Debug -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DECM_ENABLE_SANITIZERS=address -DCMAKE_CXX_FLAGS=-Werror ../src
|
||||||
- name: compile
|
- name: compile
|
||||||
image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4
|
image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Icon=@APPLICATION_EXECUTABLE@
|
|||||||
|
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
Icon[de]=@APPLICATION_ICON_NAME@
|
Icon[de_DE]=@APPLICATION_ICON_NAME@
|
||||||
Name[de]=@APPLICATION_NAME@ Desktop
|
Name[de_DE]=@APPLICATION_NAME@ Client zur Desktop-Synchronisierung
|
||||||
Comment[de]=@APPLICATION_NAME@ Client zur Desktop-Synchronisierung
|
Comment[de_DE]=@APPLICATION_NAME@ Client zur Desktop-Synchronisierung
|
||||||
GenericName[de]=Ordner-Synchronisation
|
GenericName[de_DE]=Ordnersynchronisierung
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.6)
|
cmake_minimum_required(VERSION 3.6)
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
cmake_policy(SET CMP0071 NEW) # Enable use of QtQuick compiler/generated code
|
|
||||||
|
|
||||||
project(client)
|
project(client)
|
||||||
|
|
||||||
@@ -107,9 +106,6 @@ if(APPLE AND BUILD_OWNCLOUD_OSX_BUNDLE)
|
|||||||
set(BIN_INSTALL_DIR "${APPLICATION_NAME}.app/Contents/MacOS")
|
set(BIN_INSTALL_DIR "${APPLICATION_NAME}.app/Contents/MacOS")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
option(QUICK_COMPILER "Use QtQuick compiler to improve performance" OFF)
|
|
||||||
|
|
||||||
# this option removes Http authentication, keychain, shibboleth etc and is intended for
|
# this option removes Http authentication, keychain, shibboleth etc and is intended for
|
||||||
# external authentication mechanisms
|
# external authentication mechanisms
|
||||||
option(TOKEN_AUTH_ONLY "TOKEN_AUTH_ONLY" OFF)
|
option(TOKEN_AUTH_ONLY "TOKEN_AUTH_ONLY" OFF)
|
||||||
@@ -123,8 +119,11 @@ if(NO_MSG_HANDLER)
|
|||||||
add_definitions(-DNO_MSG_HANDLER=1)
|
add_definitions(-DNO_MSG_HANDLER=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# this option builds the updater
|
||||||
|
option(BUILD_UPDATER "BUILD_UPDATER" OFF)
|
||||||
if(BUILD_UPDATER)
|
if(BUILD_UPDATER)
|
||||||
message("Compiling with updater")
|
message("Compiling with updater")
|
||||||
|
add_definitions(-DBUILD_UPDATER=1)
|
||||||
else()
|
else()
|
||||||
message("Compiling without updater")
|
message("Compiling without updater")
|
||||||
endif()
|
endif()
|
||||||
@@ -183,7 +182,6 @@ if(BUILD_CLIENT)
|
|||||||
pkg_check_modules(CLOUDPROVIDERS cloudproviders IMPORTED_TARGET)
|
pkg_check_modules(CLOUDPROVIDERS cloudproviders IMPORTED_TARGET)
|
||||||
|
|
||||||
if(CLOUDPROVIDERS_FOUND)
|
if(CLOUDPROVIDERS_FOUND)
|
||||||
pkg_check_modules(DBUS-1 REQUIRED dbus-1 IMPORTED_TARGET)
|
|
||||||
pkg_check_modules(GIO REQUIRED gio-2.0 IMPORTED_TARGET)
|
pkg_check_modules(GIO REQUIRED gio-2.0 IMPORTED_TARGET)
|
||||||
pkg_check_modules(GLIB2 REQUIRED glib-2.0 IMPORTED_TARGET)
|
pkg_check_modules(GLIB2 REQUIRED glib-2.0 IMPORTED_TARGET)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -30,14 +30,12 @@ option( WITH_CRASHREPORTER "Build crashreporter" OFF )
|
|||||||
#set( CRASHREPORTER_ICON ":/owncloud-icon.png" )
|
#set( CRASHREPORTER_ICON ":/owncloud-icon.png" )
|
||||||
|
|
||||||
## Updater options
|
## Updater options
|
||||||
option( BUILD_UPDATER "Build updater" ON )
|
option( BUILD_UPDATER "Build updater" OFF )
|
||||||
|
|
||||||
option( WITH_PROVIDERS "Build with providers list" ON )
|
option( WITH_PROVIDERS "Build with providers list" ON )
|
||||||
|
|
||||||
option( ENFORCE_VIRTUAL_FILES_SYNC_FOLDER "Enforce use of virtual files sync folder when available" OFF )
|
option( ENFORCE_VIRTUAL_FILES_SYNC_FOLDER "Enforce use of virtual files sync folder when available" OFF )
|
||||||
|
|
||||||
option( DO_NOT_USE_PROXY "Do not use system wide proxy, instead always do a direct connection to server" OFF )
|
|
||||||
|
|
||||||
## Theming options
|
## Theming options
|
||||||
set(NEXTCLOUD_BACKGROUND_COLOR "#0082c9" CACHE STRING "Default Nextcloud background color")
|
set(NEXTCLOUD_BACKGROUND_COLOR "#0082c9" CACHE STRING "Default Nextcloud background color")
|
||||||
set( APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR ${NEXTCLOUD_BACKGROUND_COLOR} CACHE STRING "Hex color of the wizard header background")
|
set( APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR ${NEXTCLOUD_BACKGROUND_COLOR} CACHE STRING "Hex color of the wizard header background")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
set( MIRALL_VERSION_MAJOR 3 )
|
set( MIRALL_VERSION_MAJOR 3 )
|
||||||
set( MIRALL_VERSION_MINOR 4 )
|
set( MIRALL_VERSION_MINOR 4 )
|
||||||
set( MIRALL_VERSION_PATCH 50 )
|
set( MIRALL_VERSION_PATCH 2 )
|
||||||
set( MIRALL_VERSION_YEAR 2021 )
|
set( MIRALL_VERSION_YEAR 2022 )
|
||||||
set( MIRALL_SOVERSION 0 )
|
set( MIRALL_SOVERSION 0 )
|
||||||
|
|
||||||
# Minimum supported server version according to https://docs.nextcloud.com/server/latest/admin_manual/release_schedule.html
|
# Minimum supported server version according to https://docs.nextcloud.com/server/latest/admin_manual/release_schedule.html
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ OBS_PROJECT_BETA=home:ivaradi:beta
|
|||||||
OBS_PACKAGE=nextcloud-desktop
|
OBS_PACKAGE=nextcloud-desktop
|
||||||
|
|
||||||
if test "${DRONE_TARGET_BRANCH}" = "stable-2.6"; then
|
if test "${DRONE_TARGET_BRANCH}" = "stable-2.6"; then
|
||||||
UBUNTU_DISTRIBUTIONS="bionic focal impish jammy"
|
UBUNTU_DISTRIBUTIONS="bionic focal hirsute impish"
|
||||||
DEBIAN_DISTRIBUTIONS="buster stretch testing"
|
DEBIAN_DISTRIBUTIONS="buster stretch testing"
|
||||||
else
|
else
|
||||||
UBUNTU_DISTRIBUTIONS="focal impish jammy"
|
UBUNTU_DISTRIBUTIONS="focal hirsute impish"
|
||||||
DEBIAN_DISTRIBUTIONS="testing"
|
DEBIAN_DISTRIBUTIONS="testing"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
#cmakedefine APPLICATION_FORBID_BAD_SSL "@APPLICATION_FORBID_BAD_SSL@"
|
#cmakedefine APPLICATION_FORBID_BAD_SSL "@APPLICATION_FORBID_BAD_SSL@"
|
||||||
#define APPLICATION_DOTVIRTUALFILE_SUFFIX "." APPLICATION_VIRTUALFILE_SUFFIX
|
#define APPLICATION_DOTVIRTUALFILE_SUFFIX "." APPLICATION_VIRTUALFILE_SUFFIX
|
||||||
#cmakedefine01 ENFORCE_VIRTUAL_FILES_SYNC_FOLDER
|
#cmakedefine01 ENFORCE_VIRTUAL_FILES_SYNC_FOLDER
|
||||||
#cmakedefine DO_NOT_USE_PROXY "@DO_NOT_USE_PROXY@"
|
|
||||||
|
|
||||||
#cmakedefine ZLIB_FOUND @ZLIB_FOUND@
|
#cmakedefine ZLIB_FOUND @ZLIB_FOUND@
|
||||||
|
|
||||||
@@ -42,6 +41,4 @@
|
|||||||
|
|
||||||
#cmakedefine01 GUI_TESTING
|
#cmakedefine01 GUI_TESTING
|
||||||
|
|
||||||
#cmakedefine BUILD_UPDATER "@BUILD_UPDATER@"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ result, the Nextcloud Client runs on Linux, Windows, and MacOS.
|
|||||||
The Synchronization Process
|
The Synchronization Process
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
The process of synchronization keeps files in two separate repositories the
|
The process of synchronization keeps files in two separate repositories the
|
||||||
same. When synchronized:
|
same. When synchronized:
|
||||||
|
|
||||||
- If a file is added to one repository it is copied to the other synchronized repository.
|
- If a file is added to one repository it is copied to the other synchronized repository.
|
||||||
@@ -93,7 +93,7 @@ traverses the file tree and compares the modification time of each file with an
|
|||||||
expected value stored in its database. If the value is not the same, the client
|
expected value stored in its database. If the value is not the same, the client
|
||||||
determines that the file has been modified in the local repository.
|
determines that the file has been modified in the local repository.
|
||||||
|
|
||||||
.. note:: On the local side, the modification time is a good attribute to use for
|
.. note:: On the local side, the modification time is a good attribute to use for
|
||||||
detecting changes, because
|
detecting changes, because
|
||||||
the value does not depend on time shifts and such.
|
the value does not depend on time shifts and such.
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ Conflict files are always created on the client and never on the server.
|
|||||||
|
|
||||||
In ownCloud 10.0 we implemented a checksum feature which checks the file integrity on upload and download by computing a checksum after the file transfer finishes.
|
In ownCloud 10.0 we implemented a checksum feature which checks the file integrity on upload and download by computing a checksum after the file transfer finishes.
|
||||||
The client queries the server capabilities after login to decide which checksum algorithm to use.
|
The client queries the server capabilities after login to decide which checksum algorithm to use.
|
||||||
Currently, SHA1 is hard-coded in the official server release and can't be changed by the end-user.
|
Currently, SHA1 is hard-coded in the official server release and can't be changed by the end-user.
|
||||||
Note that the server additionally also supports MD5 and Adler-32, but the desktop client will always use the checksum algorithm announced in the capabilities:
|
Note that the server additionally also supports MD5 and Adler-32, but the desktop client will always use the checksum algorithm announced in the capabilities:
|
||||||
|
|
||||||
::
|
::
|
||||||
@@ -202,14 +202,14 @@ Conflict files are always created on the client and never on the server.
|
|||||||
Upload
|
Upload
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
A checksum is calculated with the previously negotiated algorithm by the client and sent along with the file in an HTTP Header.
|
A checksum is calculated with the previously negotiated algorithm by the client and sent along with the file in an HTTP Header.
|
||||||
```OC-Checksum: [algorithm]:[checksum]```
|
```OC-Checksum: [algorithm]:[checksum]```
|
||||||
|
|
||||||
.. image:: ./images/checksums/client-activity.png
|
.. image:: ./images/checksums/client-activity.png
|
||||||
|
|
||||||
During file upload, the server computes SHA1, MD5, and Adler-32 checksums and compares one of them to the checksum supplied by the client.
|
During file upload, the server computes SHA1, MD5, and Adler-32 checksums and compares one of them to the checksum supplied by the client.
|
||||||
|
|
||||||
On mismatch, the server returns HTTP Status code 400 (Bad Request) thus signaling the client that the upload failed.
|
On mismatch, the server returns HTTP Status code 400 (Bad Request) thus signaling the client that the upload failed.
|
||||||
The server then discards the upload, and the client blacklists the file:
|
The server then discards the upload, and the client blacklists the file:
|
||||||
|
|
||||||
.. image:: ./images/checksums/testing-checksums.png
|
.. image:: ./images/checksums/testing-checksums.png
|
||||||
@@ -223,29 +223,29 @@ Conflict files are always created on the client and never on the server.
|
|||||||
client.</s:message>
|
client.</s:message>
|
||||||
</d:error>
|
</d:error>
|
||||||
|
|
||||||
The client retries the upload using exponential back-off.
|
The client retries the upload using exponential back-off.
|
||||||
On success (matching checksum) the computed checksums are stored by the server in ``oc_filecache`` alongside the file.
|
On success (matching checksum) the computed checksums are stored by the server in ``oc_filecache`` alongside the file.
|
||||||
|
|
||||||
Chunked Upload
|
Chunked Upload
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Mostly same as above.
|
Mostly same as above.
|
||||||
The checksum of the full file is sent with every chunk of the file.
|
The checksum of the full file is sent with every chunk of the file.
|
||||||
But the server only compares the checksum after receiving the checksum sent with the last chunk.
|
But the server only compares the checksum after receiving the checksum sent with the last chunk.
|
||||||
|
|
||||||
Download
|
Download
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
The server sends the checksum in an HTTP header with the file. (same format as above).
|
The server sends the checksum in an HTTP header with the file. (same format as above).
|
||||||
If no checksum is found in ``oc_filecache`` (freshly mounted external storage) it is computed and stored in ``oc_filecache`` on the first download.
|
If no checksum is found in ``oc_filecache`` (freshly mounted external storage) it is computed and stored in ``oc_filecache`` on the first download.
|
||||||
The checksum is then provided on all subsequent downloads but not on the first.
|
The checksum is then provided on all subsequent downloads but not on the first.
|
||||||
|
|
||||||
.. _ignored-files-label:
|
.. _ignored-files-label:
|
||||||
|
|
||||||
Ignored Files
|
Ignored Files
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
The Nextcloud Client supports the ability to exclude or ignore certain files from the synchronization process.
|
The Nextcloud Client supports the ability to exclude or ignore certain files from the synchronization process.
|
||||||
Some system wide file patterns that are used to exclude or ignore files are included with the client by default and the Nextcloud Client provides the ability to add custom patterns.
|
Some system wide file patterns that are used to exclude or ignore files are included with the client by default and the Nextcloud Client provides the ability to add custom patterns.
|
||||||
|
|
||||||
By default, the Nextcloud Client ignores the following files:
|
By default, the Nextcloud Client ignores the following files:
|
||||||
@@ -262,18 +262,18 @@ By default, the Nextcloud Client ignores the following files:
|
|||||||
If a pattern selected using a checkbox in the `ignoredFilesEditor-label` (or if
|
If a pattern selected using a checkbox in the `ignoredFilesEditor-label` (or if
|
||||||
a line in the exclude file starts with the character ``]`` directly followed by
|
a line in the exclude file starts with the character ``]`` directly followed by
|
||||||
the file pattern), files matching the pattern are considered *fleeting meta
|
the file pattern), files matching the pattern are considered *fleeting meta
|
||||||
data*.
|
data*.
|
||||||
|
|
||||||
These files are ignored and *removed* by the client if found in the
|
These files are ignored and *removed* by the client if found in the
|
||||||
synchronized folder.
|
synchronized folder.
|
||||||
This is suitable for meta files created by some applications that have no sustainable meaning.
|
This is suitable for meta files created by some applications that have no sustainable meaning.
|
||||||
|
|
||||||
If a pattern ends with the forward slash (``/``) character, only directories are matched.
|
If a pattern ends with the forward slash (``/``) character, only directories are matched.
|
||||||
The pattern is only applied for directory components of filenames selected using the checkbox.
|
The pattern is only applied for directory components of filenames selected using the checkbox.
|
||||||
|
|
||||||
To match filenames against the exclude patterns, the UNIX standard C library
|
To match filenames against the exclude patterns, the UNIX standard C library
|
||||||
function ``fnmatch`` is used.
|
function ``fnmatch`` is used.
|
||||||
This process checks the filename against the specified pattern using standard shell wildcard pattern matching.
|
This process checks the filename against the specified pattern using standard shell wildcard pattern matching.
|
||||||
For more information, please refer to `The opengroup website
|
For more information, please refer to `The opengroup website
|
||||||
<http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13_01>`_.
|
<http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13_01>`_.
|
||||||
|
|
||||||
@@ -369,7 +369,7 @@ is renamed or moved.
|
|||||||
Example:
|
Example:
|
||||||
|
|
||||||
<oc:id>00000020oc5cfy6qqizm</oc:id>
|
<oc:id>00000020oc5cfy6qqizm</oc:id>
|
||||||
|
|
||||||
End-to-end Encryption
|
End-to-end Encryption
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
@@ -440,3 +440,13 @@ Files that must be removed from the local storage only, need to be dehydrated vi
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
* End-to-end Encryption works with Virtual Files (VFS) but only on a per-folder level. Folders with E2EE can be made available offline in their entirety, but the individual files in them can not be retrieved on demand. This is mainly due to two technical reasons. First, the Windows VFS API is not designed for handling encrypted files. Second, while the VFS is designed to deal mostly with large files, E2EE is mostly recommended for use with small files as encrypting and decrypting large files puts large demands on the computer infrastructure.
|
* End-to-end Encryption works with Virtual Files (VFS) but only on a per-folder level. Folders with E2EE can be made available offline in their entirety, but the individual files in them can not be retrieved on demand. This is mainly due to two technical reasons. First, the Windows VFS API is not designed for handling encrypted files. Second, while the VFS is designed to deal mostly with large files, E2EE is mostly recommended for use with small files as encrypting and decrypting large files puts large demands on the computer infrastructure.
|
||||||
|
|
||||||
|
|
||||||
|
User Status
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Starting from 3.2.0, user status is displayed in the Nextcloud desktop client's tray window. The icon and a text message are displayed as long as those are set in the user's account menu in the Web UI (server's website). At the moment, setting the status from the desktop client is not available.
|
||||||
|
The status is updated almost immediately after it is set in the Web UI. Default user status is always "Online" if no other status is available from the server-side.
|
||||||
|
|
||||||
|
.. image:: images/status_feature_example.png
|
||||||
|
:alt: User Status feature in the tray window
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ copyright = u'2013-2021, The Nextcloud developers'
|
|||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '3.4'
|
version = '3.4'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '3.4.50'
|
release = '3.4.2'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB |
@@ -8,9 +8,7 @@ There are clients for Linux, macOs, and Microsoft Windows.
|
|||||||
|
|
||||||
The currently supported server releases are the latest three stable versions
|
The currently supported server releases are the latest three stable versions
|
||||||
at time of publication. It means that the |version| release series is supporting
|
at time of publication. It means that the |version| release series is supporting
|
||||||
stable server major versions.
|
server major version 20, 21 and 22.
|
||||||
See https://github.com/nextcloud/server/wiki/Maintenance-and-Release-Schedule for
|
|
||||||
supported major versions.
|
|
||||||
|
|
||||||
Installation on Mac OS X and Windows is the same as for any software
|
Installation on Mac OS X and Windows is the same as for any software
|
||||||
application: download the program and then double-click it to launch the
|
application: download the program and then double-click it to launch the
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
===========
|
|
||||||
Visual Tour
|
Visual Tour
|
||||||
===========
|
===========
|
||||||
|
|
||||||
@@ -12,7 +11,23 @@ as an icon in the system tray (Windows, KDE), status bar
|
|||||||
(macOS), or notification area (Ubuntu).
|
(macOS), or notification area (Ubuntu).
|
||||||
|
|
||||||
.. image:: images/icon.png
|
.. image:: images/icon.png
|
||||||
:alt: desktop client icon
|
|
||||||
|
Main dialog
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. index:: activity, recent changes, sync activity, main dialog, adding account, account, add account, remove account
|
||||||
|
|
||||||
|
The main dialog, which can be invoked from the tray icon in the
|
||||||
|
taskbar, will show files information about the activities of the sync
|
||||||
|
client and Nextcloud. If there are any synchronization issues, they
|
||||||
|
will show up here. The dialog also gives information about other
|
||||||
|
activities or notifications like Talk mentions or file changes. It
|
||||||
|
does also show the status of the user.
|
||||||
|
|
||||||
|
.. image:: images/main_dialog.png
|
||||||
|
|
||||||
|
When clicking on the avatar a menu opens where it is possible to add a
|
||||||
|
new account or removing an existing account.
|
||||||
|
|
||||||
Menu
|
Menu
|
||||||
----
|
----
|
||||||
@@ -30,9 +45,8 @@ A right click on the icon provides the following menu:
|
|||||||
.. NOTE::
|
.. NOTE::
|
||||||
This menu is not available on macOS.
|
This menu is not available on macOS.
|
||||||
|
|
||||||
|
|
||||||
Settings
|
Settings
|
||||||
~~~~~~~~
|
--------
|
||||||
|
|
||||||
Account Settings
|
Account Settings
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
@@ -204,98 +218,3 @@ while syncing for a three times. These are listed in the activity view.
|
|||||||
There also is a button to retry the sync for another three times.
|
There also is a button to retry the sync for another three times.
|
||||||
|
|
||||||
For more detailed information see :ref:`ignored-files-label`.
|
For more detailed information see :ref:`ignored-files-label`.
|
||||||
|
|
||||||
Main dialog
|
|
||||||
-----------
|
|
||||||
|
|
||||||
.. index:: activity, recent changes, sync activity, main dialog, adding account, account, add account, remove account, sync state, user status, unified search, share dialog
|
|
||||||
|
|
||||||
Sync State
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
The main dialog, which can be invoked from the tray icon in the
|
|
||||||
taskbar, will show files information about the activities of the sync
|
|
||||||
client and Nextcloud.
|
|
||||||
|
|
||||||
|
|
||||||
.. image:: images/sync-state-paused.png
|
|
||||||
:alt: sync state paused
|
|
||||||
|
|
||||||
.. image:: images/sync-state-syncing.png
|
|
||||||
:alt: sync state syncing
|
|
||||||
|
|
||||||
.. image:: images/sync-state-synced.png
|
|
||||||
:alt: sync state synced
|
|
||||||
|
|
||||||
|
|
||||||
If there are any synchronization issues, they will show up here:
|
|
||||||
|
|
||||||
.. image:: images/sync-state-warnings.png
|
|
||||||
:alt: sync state warnings
|
|
||||||
|
|
||||||
For more information on how to solve these issues see :doc:`troubleshooting`.
|
|
||||||
|
|
||||||
When clicking on the avatar a menu opens where it is
|
|
||||||
possible to add a new account or removing an existing account.
|
|
||||||
|
|
||||||
.. image:: images/user-account-options.png
|
|
||||||
:alt: user account options
|
|
||||||
|
|
||||||
|
|
||||||
User Status
|
|
||||||
~~~~~~~~~~~
|
|
||||||
|
|
||||||
User status is displayed in the Nextcloud desktop client's tray window.
|
|
||||||
Default user status is always "Online" if no other status is available from the server-side.
|
|
||||||
|
|
||||||
.. image:: images/status_feature_example.png
|
|
||||||
:alt: User Status feature in the tray window
|
|
||||||
|
|
||||||
When clicking on ``Set status`` you can edit the emoji, message and the timer to clear your user status:
|
|
||||||
|
|
||||||
.. image:: images/set-user-status.png
|
|
||||||
:alt: set user status menu option
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
.. image:: images/set-user-status-menu.png
|
|
||||||
:alt: changing the user status
|
|
||||||
|
|
||||||
Activities list
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The dialog also gives information about other activities or
|
|
||||||
notifications like Talk mentions or file changes.
|
|
||||||
It does also show the status of the user.
|
|
||||||
|
|
||||||
.. image:: images/main_dialog.png
|
|
||||||
:alt: main dialog activities list
|
|
||||||
|
|
||||||
Unified search
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
With the unified search you can find everything you have in your server - files,
|
|
||||||
Talk messages, calendar appointments:
|
|
||||||
|
|
||||||
.. image:: images/unified-search-files.png
|
|
||||||
:alt: unified search files search result
|
|
||||||
|
|
||||||
.. image:: images/unified-search-talk.png
|
|
||||||
:alt: unified search Talk conversations search result
|
|
||||||
|
|
||||||
.. image:: images/unified-search-events.png
|
|
||||||
:alt: unified search calendar appointments search result
|
|
||||||
|
|
||||||
|
|
||||||
Share dialog: Talk options and View Profile
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can now share a file directly in a conversation in Talk and view the sharee user profile:
|
|
||||||
|
|
||||||
.. image:: images/open-share-dialog.png
|
|
||||||
:alt: open share dialog option
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
||||||
.. image:: images/share-dialog-view-profile.png
|
|
||||||
:alt: shared dialog sharing options
|
|
||||||
@@ -23,10 +23,5 @@
|
|||||||
<file>src/gui/tray/UnifiedSearchResultListItem.qml</file>
|
<file>src/gui/tray/UnifiedSearchResultListItem.qml</file>
|
||||||
<file>src/gui/tray/UnifiedSearchResultNothingFound.qml</file>
|
<file>src/gui/tray/UnifiedSearchResultNothingFound.qml</file>
|
||||||
<file>src/gui/tray/UnifiedSearchResultSectionItem.qml</file>
|
<file>src/gui/tray/UnifiedSearchResultSectionItem.qml</file>
|
||||||
<file>src/gui/tray/CustomButton.qml</file>
|
|
||||||
<file>src/gui/tray/CustomTextButton.qml</file>
|
|
||||||
<file>src/gui/tray/ActivityItemContextMenu.qml</file>
|
|
||||||
<file>src/gui/tray/ActivityItemActions.qml</file>
|
|
||||||
<file>src/gui/tray/ActivityItemContent.qml</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ ComputeChecksum *ValidateChecksumHeader::prepareStart(const QByteArray &checksum
|
|||||||
|
|
||||||
if (!parseChecksumHeader(checksumHeader, &_expectedChecksumType, &_expectedChecksum)) {
|
if (!parseChecksumHeader(checksumHeader, &_expectedChecksumType, &_expectedChecksum)) {
|
||||||
qCWarning(lcChecksums) << "Checksum header malformed:" << checksumHeader;
|
qCWarning(lcChecksums) << "Checksum header malformed:" << checksumHeader;
|
||||||
emit validationFailed(tr("The checksum header is malformed."), _calculatedChecksumType, _calculatedChecksum, ChecksumHeaderMalformed);
|
emit validationFailed(tr("The checksum header is malformed."));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,30 +360,15 @@ void ValidateChecksumHeader::start(std::unique_ptr<QIODevice> device, const QByt
|
|||||||
calculator->start(std::move(device));
|
calculator->start(std::move(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray ValidateChecksumHeader::calculatedChecksumType() const
|
|
||||||
{
|
|
||||||
return _calculatedChecksumType;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray ValidateChecksumHeader::calculatedChecksum() const
|
|
||||||
{
|
|
||||||
return _calculatedChecksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValidateChecksumHeader::slotChecksumCalculated(const QByteArray &checksumType,
|
void ValidateChecksumHeader::slotChecksumCalculated(const QByteArray &checksumType,
|
||||||
const QByteArray &checksum)
|
const QByteArray &checksum)
|
||||||
{
|
{
|
||||||
_calculatedChecksumType = checksumType;
|
|
||||||
_calculatedChecksum = checksum;
|
|
||||||
|
|
||||||
if (checksumType != _expectedChecksumType) {
|
if (checksumType != _expectedChecksumType) {
|
||||||
emit validationFailed(tr("The checksum header contained an unknown checksum type \"%1\"").arg(QString::fromLatin1(_expectedChecksumType)),
|
emit validationFailed(tr("The checksum header contained an unknown checksum type \"%1\"").arg(QString::fromLatin1(_expectedChecksumType)));
|
||||||
_calculatedChecksumType, _calculatedChecksum, ChecksumTypeUnknown);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (checksum != _expectedChecksum) {
|
if (checksum != _expectedChecksum) {
|
||||||
emit validationFailed(tr(R"(The downloaded file does not match the checksum, it will be resumed. "%1" != "%2")").arg(QString::fromUtf8(_expectedChecksum), QString::fromUtf8(checksum)),
|
emit validationFailed(tr(R"(The downloaded file does not match the checksum, it will be resumed. "%1" != "%2")").arg(QString::fromUtf8(_expectedChecksum), QString::fromUtf8(checksum)));
|
||||||
_calculatedChecksumType, _calculatedChecksum, ChecksumMismatch);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit validated(checksumType, checksum);
|
emit validated(checksumType, checksum);
|
||||||
|
|||||||
@@ -140,14 +140,6 @@ class OCSYNC_EXPORT ValidateChecksumHeader : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum FailureReason {
|
|
||||||
Success,
|
|
||||||
ChecksumHeaderMalformed,
|
|
||||||
ChecksumTypeUnknown,
|
|
||||||
ChecksumMismatch,
|
|
||||||
};
|
|
||||||
Q_ENUM(FailureReason)
|
|
||||||
|
|
||||||
explicit ValidateChecksumHeader(QObject *parent = nullptr);
|
explicit ValidateChecksumHeader(QObject *parent = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,13 +161,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void start(std::unique_ptr<QIODevice> device, const QByteArray &checksumHeader);
|
void start(std::unique_ptr<QIODevice> device, const QByteArray &checksumHeader);
|
||||||
|
|
||||||
QByteArray calculatedChecksumType() const;
|
|
||||||
QByteArray calculatedChecksum() const;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void validated(const QByteArray &checksumType, const QByteArray &checksum);
|
void validated(const QByteArray &checksumType, const QByteArray &checksum);
|
||||||
void validationFailed(const QString &errMsg, const QByteArray &calculatedChecksumType,
|
void validationFailed(const QString &errMsg);
|
||||||
const QByteArray &calculatedChecksum, const ValidateChecksumHeader::FailureReason reason);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotChecksumCalculated(const QByteArray &checksumType, const QByteArray &checksum);
|
void slotChecksumCalculated(const QByteArray &checksumType, const QByteArray &checksum);
|
||||||
@@ -185,9 +173,6 @@ private:
|
|||||||
|
|
||||||
QByteArray _expectedChecksumType;
|
QByteArray _expectedChecksumType;
|
||||||
QByteArray _expectedChecksum;
|
QByteArray _expectedChecksum;
|
||||||
|
|
||||||
QByteArray _calculatedChecksumType;
|
|
||||||
QByteArray _calculatedChecksum;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
project(gui)
|
project(gui)
|
||||||
find_package(Qt5 REQUIRED COMPONENTS Widgets Svg Qml Quick QuickControls2 Xml Network)
|
find_package(Qt5 REQUIRED COMPONENTS Widgets Svg Qml Quick QuickControls2 Xml Network)
|
||||||
|
|
||||||
if(QUICK_COMPILER)
|
|
||||||
find_package(Qt5QuickCompiler)
|
|
||||||
set_package_properties(Qt5QuickCompiler PROPERTIES
|
|
||||||
DESCRIPTION "Compile QML at build time"
|
|
||||||
TYPE REQUIRED
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET Qt5::GuiPrivate)
|
if (NOT TARGET Qt5::GuiPrivate)
|
||||||
message(FATAL_ERROR "Could not find GuiPrivate component of Qt5. It might be shipped as a separate package, please check that.")
|
message(FATAL_ERROR "Could not find GuiPrivate component of Qt5. It might be shipped as a separate package, please check that.")
|
||||||
endif()
|
endif()
|
||||||
@@ -22,12 +13,14 @@ IF(BUILD_UPDATER)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
configure_file(${CMAKE_SOURCE_DIR}/theme.qrc.in ${CMAKE_SOURCE_DIR}/theme.qrc)
|
configure_file(${CMAKE_SOURCE_DIR}/theme.qrc.in ${CMAKE_SOURCE_DIR}/theme.qrc)
|
||||||
|
|
||||||
|
set(MIRALL_RC_SRC ../../resources.qrc)
|
||||||
|
list(APPEND MIRALL_RC_SRC ${CMAKE_SOURCE_DIR}/theme.qrc)
|
||||||
set(theme_dir ${CMAKE_SOURCE_DIR}/theme)
|
set(theme_dir ${CMAKE_SOURCE_DIR}/theme)
|
||||||
|
|
||||||
set(client_UI_SRCS
|
set(client_UI_SRCS
|
||||||
accountsettings.ui
|
accountsettings.ui
|
||||||
conflictdialog.ui
|
conflictdialog.ui
|
||||||
internallinkwidget.ui
|
|
||||||
invalidfilenamedialog.ui
|
invalidfilenamedialog.ui
|
||||||
foldercreationdialog.ui
|
foldercreationdialog.ui
|
||||||
folderwizardsourcepage.ui
|
folderwizardsourcepage.ui
|
||||||
@@ -47,6 +40,21 @@ set(client_UI_SRCS
|
|||||||
passwordinputdialog.ui
|
passwordinputdialog.ui
|
||||||
proxyauthdialog.ui
|
proxyauthdialog.ui
|
||||||
mnemonicdialog.ui
|
mnemonicdialog.ui
|
||||||
|
UserStatusSelector.qml
|
||||||
|
UserStatusSelectorDialog.qml
|
||||||
|
tray/ActivityActionButton.qml
|
||||||
|
tray/ActivityItem.qml
|
||||||
|
tray/ActivityList.qml
|
||||||
|
tray/Window.qml
|
||||||
|
tray/UserLine.qml
|
||||||
|
tray/UnifiedSearchInputContainer.qml
|
||||||
|
tray/UnifiedSearchResultFetchMoreTrigger.qml
|
||||||
|
tray/UnifiedSearchResultItem.qml
|
||||||
|
tray/UnifiedSearchResultItemSkeleton.qml
|
||||||
|
tray/UnifiedSearchResultItemSkeletonContainer.qml
|
||||||
|
tray/UnifiedSearchResultListItem.qml
|
||||||
|
tray/UnifiedSearchResultNothingFound.qml
|
||||||
|
tray/UnifiedSearchResultSectionItem.qml
|
||||||
wizard/flow2authwidget.ui
|
wizard/flow2authwidget.ui
|
||||||
wizard/owncloudadvancedsetuppage.ui
|
wizard/owncloudadvancedsetuppage.ui
|
||||||
wizard/owncloudconnectionmethoddialog.ui
|
wizard/owncloudconnectionmethoddialog.ui
|
||||||
@@ -57,12 +65,6 @@ set(client_UI_SRCS
|
|||||||
wizard/welcomepage.ui
|
wizard/welcomepage.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
if(QUICK_COMPILER)
|
|
||||||
qtquick_compiler_add_resources(client_UI_SRCS ../../resources.qrc ${CMAKE_SOURCE_DIR}/theme.qrc)
|
|
||||||
else()
|
|
||||||
qt_add_resources(client_UI_SRCS ../../resources.qrc ${CMAKE_SOURCE_DIR}/theme.qrc)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(client_SRCS
|
set(client_SRCS
|
||||||
accountmanager.cpp
|
accountmanager.cpp
|
||||||
accountsettings.cpp
|
accountsettings.cpp
|
||||||
@@ -81,7 +83,6 @@ set(client_SRCS
|
|||||||
folderwizard.cpp
|
folderwizard.cpp
|
||||||
generalsettings.cpp
|
generalsettings.cpp
|
||||||
legalnotice.cpp
|
legalnotice.cpp
|
||||||
internallinkwidget.cpp
|
|
||||||
ignorelisteditor.cpp
|
ignorelisteditor.cpp
|
||||||
ignorelisttablewidget.cpp
|
ignorelisttablewidget.cpp
|
||||||
lockwatcher.cpp
|
lockwatcher.cpp
|
||||||
@@ -233,6 +234,7 @@ IF( WIN32 )
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
set( final_src
|
set( final_src
|
||||||
|
${MIRALL_RC_SRC}
|
||||||
${client_SRCS}
|
${client_SRCS}
|
||||||
${client_UI_SRCS}
|
${client_UI_SRCS}
|
||||||
${guiMoc}
|
${guiMoc}
|
||||||
@@ -451,6 +453,7 @@ endif()
|
|||||||
set_target_properties(nextcloudCore
|
set_target_properties(nextcloudCore
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
AUTOUIC ON
|
AUTOUIC ON
|
||||||
|
AUTORCC ON
|
||||||
AUTOMOC ON
|
AUTOMOC ON
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,11 @@ ColumnLayout {
|
|||||||
spacing: 0
|
spacing: 0
|
||||||
property NC.UserStatusSelectorModel userStatusSelectorModel
|
property NC.UserStatusSelectorModel userStatusSelectorModel
|
||||||
|
|
||||||
Label {
|
FontMetrics {
|
||||||
|
id: metrics
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
Layout.leftMargin: 8
|
Layout.leftMargin: 8
|
||||||
Layout.rightMargin: 8
|
Layout.rightMargin: 8
|
||||||
@@ -85,7 +89,7 @@ ColumnLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Text {
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
Layout.leftMargin: 8
|
Layout.leftMargin: 8
|
||||||
Layout.rightMargin: 8
|
Layout.rightMargin: 8
|
||||||
@@ -104,8 +108,8 @@ ColumnLayout {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
Layout.preferredWidth: userStatusMessageTextField.height
|
Layout.preferredWidth: userStatusMessageTextField.height // metrics.height * 2
|
||||||
Layout.preferredHeight: userStatusMessageTextField.height
|
Layout.preferredHeight: userStatusMessageTextField.height // metrics.height * 2
|
||||||
text: userStatusSelectorModel.userStatusEmoji
|
text: userStatusSelectorModel.userStatusEmoji
|
||||||
onClicked: emojiDialog.open()
|
onClicked: emojiDialog.open()
|
||||||
}
|
}
|
||||||
@@ -157,7 +161,7 @@ ColumnLayout {
|
|||||||
Layout.bottomMargin: 8
|
Layout.bottomMargin: 8
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
|
|
||||||
Label {
|
Text {
|
||||||
text: qsTr("Clear status message after")
|
text: qsTr("Clear status message after")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -250,10 +250,6 @@ Application::Application(int &argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_theme->doNotUseProxy()) {
|
|
||||||
ConfigFile().setProxyType(QNetworkProxy::NoProxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
parseOptions(arguments());
|
parseOptions(arguments());
|
||||||
//no need to waste time;
|
//no need to waste time;
|
||||||
if (_helpOnly || _versionOnly)
|
if (_helpOnly || _versionOnly)
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
#include "common/utility.h"
|
#include "common/utility.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include "legalnotice.h"
|
#include "legalnotice.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
#ifndef MIRALL_GENERALSETTINGS_H
|
#ifndef MIRALL_GENERALSETTINGS_H
|
||||||
#define MIRALL_GENERALSETTINGS_H
|
#define MIRALL_GENERALSETTINGS_H
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 by Claudio Cambra <claudio.cambra@nextcloud.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "internallinkwidget.h"
|
|
||||||
#include "accountstate.h"
|
|
||||||
#include "folderman.h"
|
|
||||||
#include "theme.h"
|
|
||||||
|
|
||||||
#include "QProgressIndicator.h"
|
|
||||||
#include <QClipboard>
|
|
||||||
|
|
||||||
namespace OCC {
|
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(lcInternalLink, "nextcloud.gui.internallink", QtInfoMsg)
|
|
||||||
|
|
||||||
InternalLinkWidget::InternalLinkWidget(const QString &localPath,
|
|
||||||
QWidget *parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
, _localPath(localPath)
|
|
||||||
{
|
|
||||||
_ui->setupUi(this);
|
|
||||||
|
|
||||||
const auto folder = FolderMan::instance()->folderForPath(_localPath);
|
|
||||||
const auto folderRelativePath = _localPath.mid(folder->cleanPath().length() + 1);
|
|
||||||
const auto serverRelativePath = QDir(folder->remotePath()).filePath(folderRelativePath);
|
|
||||||
|
|
||||||
const auto bindLinkSlot = [this](QString link) { slotLinkFetched(link); };
|
|
||||||
|
|
||||||
fetchPrivateLinkUrl(
|
|
||||||
folder->accountState()->account(),
|
|
||||||
serverRelativePath,
|
|
||||||
{},
|
|
||||||
this,
|
|
||||||
bindLinkSlot
|
|
||||||
);
|
|
||||||
|
|
||||||
_ui->copyInternalLinkButton->setEnabled(false);
|
|
||||||
_ui->internalLinkProgressIndicator->setVisible(true);
|
|
||||||
_ui->internalLinkProgressIndicator->startAnimation();
|
|
||||||
|
|
||||||
connect(_ui->copyInternalLinkButton, &QPushButton::clicked, this, &InternalLinkWidget::slotCopyInternalLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InternalLinkWidget::slotLinkFetched(const QString &url)
|
|
||||||
{
|
|
||||||
_internalUrl = url;
|
|
||||||
_ui->copyInternalLinkButton->setEnabled(true);
|
|
||||||
_ui->internalLinkProgressIndicator->setVisible(false);
|
|
||||||
_ui->internalLinkProgressIndicator->stopAnimation();
|
|
||||||
_ui->horizontalSpacer->changeSize(0, 0);
|
|
||||||
_ui->horizontalSpacer_2->changeSize(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InternalLinkWidget::slotCopyInternalLink() const
|
|
||||||
{
|
|
||||||
QApplication::clipboard()->setText(_internalUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InternalLinkWidget::setupUiOptions()
|
|
||||||
{
|
|
||||||
customizeStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InternalLinkWidget::slotStyleChanged()
|
|
||||||
{
|
|
||||||
customizeStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InternalLinkWidget::customizeStyle()
|
|
||||||
{
|
|
||||||
_ui->copyInternalLinkButton->setIcon(Theme::createColorAwareIcon(":/client/theme/copy.svg"));
|
|
||||||
_ui->internalLinkIconLabel->setPixmap(Theme::createColorAwarePixmap(":/client/theme/external.svg"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 by Claudio Cambra <claudio.cambra@nextcloud.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INTERNALLINKWIDGET_H
|
|
||||||
#define INTERNALLINKWIDGET_H
|
|
||||||
|
|
||||||
#include "QProgressIndicator.h"
|
|
||||||
#include <QList>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
#include "ui_internallinkwidget.h"
|
|
||||||
|
|
||||||
namespace OCC {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The ShareDialog class
|
|
||||||
* @ingroup gui
|
|
||||||
*/
|
|
||||||
class InternalLinkWidget : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit InternalLinkWidget(const QString &localPath,
|
|
||||||
QWidget *parent = nullptr);
|
|
||||||
~InternalLinkWidget() override = default;
|
|
||||||
|
|
||||||
void setupUiOptions();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void slotStyleChanged();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotLinkFetched(const QString &url);
|
|
||||||
void slotCopyInternalLink() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void customizeStyle();
|
|
||||||
|
|
||||||
std::unique_ptr<Ui::InternalLinkWidget> _ui = std::make_unique<Ui::InternalLinkWidget>();
|
|
||||||
QString _localPath;
|
|
||||||
QString _internalUrl;
|
|
||||||
|
|
||||||
QPushButton *_copyInternalLinkButton{};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // INTERNALLINKWIDGET_H
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>OCC::InternalLinkWidget</class>
|
|
||||||
<widget class="QWidget" name="OCC::InternalLinkWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>400</width>
|
|
||||||
<height>238</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>12</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>20</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="internalLinkIconLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="pixmap">
|
|
||||||
<pixmap resource="../../theme.qrc">:/client/theme/external.svg</pixmap>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalTextLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="internalLinkLabel">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Internal link</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="infoMessage">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true">color: rgb(118, 118, 118)</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Only works for users with access to this folder</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</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="internalLinkProgressIndicator" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>28</width>
|
|
||||||
<height>27</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</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="copyInternalLinkButton">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../theme.qrc">
|
|
||||||
<normaloff>:/client/theme/copy.svg</normaloff>:/client/theme/copy.svg</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>QProgressIndicator</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>QProgressIndicator.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources>
|
|
||||||
<include location="../../theme.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -34,51 +34,42 @@ NetworkSettings::NetworkSettings(QWidget *parent)
|
|||||||
{
|
{
|
||||||
_ui->setupUi(this);
|
_ui->setupUi(this);
|
||||||
|
|
||||||
_ui->proxyGroupBox->setVisible(!Theme::instance()->doNotUseProxy());
|
_ui->hostLineEdit->setPlaceholderText(tr("Hostname of proxy server"));
|
||||||
|
_ui->userLineEdit->setPlaceholderText(tr("Username for proxy server"));
|
||||||
|
_ui->passwordLineEdit->setPlaceholderText(tr("Password for proxy server"));
|
||||||
|
|
||||||
if (!Theme::instance()->doNotUseProxy()) {
|
_ui->typeComboBox->addItem(tr("HTTP(S) proxy"), QNetworkProxy::HttpProxy);
|
||||||
_ui->hostLineEdit->setPlaceholderText(tr("Hostname of proxy server"));
|
_ui->typeComboBox->addItem(tr("SOCKS5 proxy"), QNetworkProxy::Socks5Proxy);
|
||||||
_ui->userLineEdit->setPlaceholderText(tr("Username for proxy server"));
|
|
||||||
_ui->passwordLineEdit->setPlaceholderText(tr("Password for proxy server"));
|
|
||||||
|
|
||||||
_ui->typeComboBox->addItem(tr("HTTP(S) proxy"), QNetworkProxy::HttpProxy);
|
_ui->authRequiredcheckBox->setEnabled(true);
|
||||||
_ui->typeComboBox->addItem(tr("SOCKS5 proxy"), QNetworkProxy::Socks5Proxy);
|
|
||||||
|
|
||||||
_ui->authRequiredcheckBox->setEnabled(true);
|
// Explicitly set up the enabled status of the proxy auth widgets to ensure
|
||||||
|
// toggling the parent enables/disables the children
|
||||||
|
_ui->userLineEdit->setEnabled(true);
|
||||||
|
_ui->passwordLineEdit->setEnabled(true);
|
||||||
|
_ui->authWidgets->setEnabled(_ui->authRequiredcheckBox->isChecked());
|
||||||
|
connect(_ui->authRequiredcheckBox, &QAbstractButton::toggled,
|
||||||
|
_ui->authWidgets, &QWidget::setEnabled);
|
||||||
|
|
||||||
// Explicitly set up the enabled status of the proxy auth widgets to ensure
|
connect(_ui->manualProxyRadioButton, &QAbstractButton::toggled,
|
||||||
// toggling the parent enables/disables the children
|
_ui->manualSettings, &QWidget::setEnabled);
|
||||||
_ui->userLineEdit->setEnabled(true);
|
connect(_ui->manualProxyRadioButton, &QAbstractButton::toggled,
|
||||||
_ui->passwordLineEdit->setEnabled(true);
|
_ui->typeComboBox, &QWidget::setEnabled);
|
||||||
_ui->authWidgets->setEnabled(_ui->authRequiredcheckBox->isChecked());
|
connect(_ui->manualProxyRadioButton, &QAbstractButton::toggled,
|
||||||
connect(_ui->authRequiredcheckBox, &QAbstractButton::toggled, _ui->authWidgets, &QWidget::setEnabled);
|
this, &NetworkSettings::checkAccountLocalhost);
|
||||||
|
|
||||||
connect(_ui->manualProxyRadioButton, &QAbstractButton::toggled, _ui->manualSettings, &QWidget::setEnabled);
|
|
||||||
connect(_ui->manualProxyRadioButton, &QAbstractButton::toggled, _ui->typeComboBox, &QWidget::setEnabled);
|
|
||||||
connect(_ui->manualProxyRadioButton, &QAbstractButton::toggled, this, &NetworkSettings::checkAccountLocalhost);
|
|
||||||
|
|
||||||
loadProxySettings();
|
|
||||||
|
|
||||||
connect(_ui->typeComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
|
||||||
&NetworkSettings::saveProxySettings);
|
|
||||||
connect(_ui->proxyButtonGroup, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this,
|
|
||||||
&NetworkSettings::saveProxySettings);
|
|
||||||
connect(_ui->hostLineEdit, &QLineEdit::editingFinished, this, &NetworkSettings::saveProxySettings);
|
|
||||||
connect(_ui->userLineEdit, &QLineEdit::editingFinished, this, &NetworkSettings::saveProxySettings);
|
|
||||||
connect(_ui->passwordLineEdit, &QLineEdit::editingFinished, this, &NetworkSettings::saveProxySettings);
|
|
||||||
connect(_ui->portSpinBox, &QAbstractSpinBox::editingFinished, this, &NetworkSettings::saveProxySettings);
|
|
||||||
connect(_ui->authRequiredcheckBox, &QAbstractButton::toggled, this, &NetworkSettings::saveProxySettings);
|
|
||||||
|
|
||||||
// Warn about empty proxy host
|
|
||||||
connect(_ui->hostLineEdit, &QLineEdit::textChanged, this, &NetworkSettings::checkEmptyProxyHost);
|
|
||||||
checkEmptyProxyHost();
|
|
||||||
checkAccountLocalhost();
|
|
||||||
} else {
|
|
||||||
_ui->noProxyRadioButton->setChecked(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
loadProxySettings();
|
||||||
loadBWLimitSettings();
|
loadBWLimitSettings();
|
||||||
|
|
||||||
|
// proxy
|
||||||
|
connect(_ui->typeComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &NetworkSettings::saveProxySettings);
|
||||||
|
connect(_ui->proxyButtonGroup, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &NetworkSettings::saveProxySettings);
|
||||||
|
connect(_ui->hostLineEdit, &QLineEdit::editingFinished, this, &NetworkSettings::saveProxySettings);
|
||||||
|
connect(_ui->userLineEdit, &QLineEdit::editingFinished, this, &NetworkSettings::saveProxySettings);
|
||||||
|
connect(_ui->passwordLineEdit, &QLineEdit::editingFinished, this, &NetworkSettings::saveProxySettings);
|
||||||
|
connect(_ui->portSpinBox, &QAbstractSpinBox::editingFinished, this, &NetworkSettings::saveProxySettings);
|
||||||
|
connect(_ui->authRequiredcheckBox, &QAbstractButton::toggled, this, &NetworkSettings::saveProxySettings);
|
||||||
|
|
||||||
connect(_ui->uploadLimitRadioButton, &QAbstractButton::clicked, this, &NetworkSettings::saveBWLimitSettings);
|
connect(_ui->uploadLimitRadioButton, &QAbstractButton::clicked, this, &NetworkSettings::saveBWLimitSettings);
|
||||||
connect(_ui->noUploadLimitRadioButton, &QAbstractButton::clicked, this, &NetworkSettings::saveBWLimitSettings);
|
connect(_ui->noUploadLimitRadioButton, &QAbstractButton::clicked, this, &NetworkSettings::saveBWLimitSettings);
|
||||||
connect(_ui->autoUploadLimitRadioButton, &QAbstractButton::clicked, this, &NetworkSettings::saveBWLimitSettings);
|
connect(_ui->autoUploadLimitRadioButton, &QAbstractButton::clicked, this, &NetworkSettings::saveBWLimitSettings);
|
||||||
@@ -87,6 +78,11 @@ NetworkSettings::NetworkSettings(QWidget *parent)
|
|||||||
connect(_ui->autoDownloadLimitRadioButton, &QAbstractButton::clicked, this, &NetworkSettings::saveBWLimitSettings);
|
connect(_ui->autoDownloadLimitRadioButton, &QAbstractButton::clicked, this, &NetworkSettings::saveBWLimitSettings);
|
||||||
connect(_ui->downloadSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &NetworkSettings::saveBWLimitSettings);
|
connect(_ui->downloadSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &NetworkSettings::saveBWLimitSettings);
|
||||||
connect(_ui->uploadSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &NetworkSettings::saveBWLimitSettings);
|
connect(_ui->uploadSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &NetworkSettings::saveBWLimitSettings);
|
||||||
|
|
||||||
|
// Warn about empty proxy host
|
||||||
|
connect(_ui->hostLineEdit, &QLineEdit::textChanged, this, &NetworkSettings::checkEmptyProxyHost);
|
||||||
|
checkEmptyProxyHost();
|
||||||
|
checkAccountLocalhost();
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkSettings::~NetworkSettings()
|
NetworkSettings::~NetworkSettings()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) by Roeland Jago Douma <roeland@famdouma.nl>
|
* Copyright (C) by Roeland Jago Douma <roeland@famdouma.nl>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
#include "sharedialog.h"
|
#include "sharedialog.h"
|
||||||
#include "sharee.h"
|
#include "sharee.h"
|
||||||
#include "sharelinkwidget.h"
|
#include "sharelinkwidget.h"
|
||||||
#include "internallinkwidget.h"
|
|
||||||
#include "shareusergroupwidget.h"
|
#include "shareusergroupwidget.h"
|
||||||
#include "passwordinputdialog.h"
|
#include "passwordinputdialog.h"
|
||||||
|
|
||||||
@@ -138,23 +137,13 @@ ShareDialog::ShareDialog(QPointer<AccountState> accountState,
|
|||||||
job->start();
|
job->start();
|
||||||
|
|
||||||
initShareManager();
|
initShareManager();
|
||||||
|
|
||||||
_scrollAreaViewPort = new QWidget(_ui->scrollArea);
|
|
||||||
_scrollAreaLayout = new QVBoxLayout(_scrollAreaViewPort);
|
|
||||||
_scrollAreaLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
_ui->scrollArea->setWidget(_scrollAreaViewPort);
|
|
||||||
|
|
||||||
_internalLinkWidget = new InternalLinkWidget(localPath, this);
|
|
||||||
_ui->verticalLayout->addWidget(_internalLinkWidget);
|
|
||||||
_internalLinkWidget->setupUiOptions();
|
|
||||||
connect(this, &ShareDialog::styleChanged, _internalLinkWidget, &InternalLinkWidget::slotStyleChanged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShareLinkWidget *ShareDialog::addLinkShareWidget(const QSharedPointer<LinkShare> &linkShare)
|
ShareLinkWidget *ShareDialog::addLinkShareWidget(const QSharedPointer<LinkShare> &linkShare)
|
||||||
{
|
{
|
||||||
const auto linkShareWidget = new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, _ui->scrollArea);
|
_linkWidgetList.append(new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, this));
|
||||||
_linkWidgetList.append(linkShareWidget);
|
|
||||||
|
|
||||||
|
const auto linkShareWidget = _linkWidgetList.at(_linkWidgetList.size() - 1);
|
||||||
linkShareWidget->setLinkShare(linkShare);
|
linkShareWidget->setLinkShare(linkShare);
|
||||||
|
|
||||||
connect(linkShare.data(), &Share::serverError, linkShareWidget, &ShareLinkWidget::slotServerError);
|
connect(linkShare.data(), &Share::serverError, linkShareWidget, &ShareLinkWidget::slotServerError);
|
||||||
@@ -169,13 +158,13 @@ ShareLinkWidget *ShareDialog::addLinkShareWidget(const QSharedPointer<LinkShare>
|
|||||||
connect(linkShareWidget, &ShareLinkWidget::createLinkShare, this, &ShareDialog::slotCreateLinkShare);
|
connect(linkShareWidget, &ShareLinkWidget::createLinkShare, this, &ShareDialog::slotCreateLinkShare);
|
||||||
connect(linkShareWidget, &ShareLinkWidget::deleteLinkShare, this, &ShareDialog::slotDeleteShare);
|
connect(linkShareWidget, &ShareLinkWidget::deleteLinkShare, this, &ShareDialog::slotDeleteShare);
|
||||||
connect(linkShareWidget, &ShareLinkWidget::createPassword, this, &ShareDialog::slotCreatePasswordForLinkShare);
|
connect(linkShareWidget, &ShareLinkWidget::createPassword, this, &ShareDialog::slotCreatePasswordForLinkShare);
|
||||||
|
|
||||||
|
//connect(_linkWidgetList.at(index), &ShareLinkWidget::resizeRequested, this, &ShareDialog::slotAdjustScrollWidgetSize);
|
||||||
|
|
||||||
// Connect styleChanged events to our widget, so it can adapt (Dark-/Light-Mode switching)
|
// Connect styleChanged events to our widget, so it can adapt (Dark-/Light-Mode switching)
|
||||||
connect(this, &ShareDialog::styleChanged, linkShareWidget, &ShareLinkWidget::slotStyleChanged);
|
connect(this, &ShareDialog::styleChanged, linkShareWidget, &ShareLinkWidget::slotStyleChanged);
|
||||||
|
|
||||||
_ui->verticalLayout->insertWidget(_linkWidgetList.size() + 1, linkShareWidget);
|
_ui->verticalLayout->insertWidget(_linkWidgetList.size() + 1, linkShareWidget);
|
||||||
_scrollAreaLayout->addWidget(linkShareWidget);
|
|
||||||
|
|
||||||
linkShareWidget->setupUiOptions();
|
linkShareWidget->setupUiOptions();
|
||||||
|
|
||||||
return linkShareWidget;
|
return linkShareWidget;
|
||||||
@@ -184,17 +173,18 @@ ShareLinkWidget *ShareDialog::addLinkShareWidget(const QSharedPointer<LinkShare>
|
|||||||
void ShareDialog::initLinkShareWidget()
|
void ShareDialog::initLinkShareWidget()
|
||||||
{
|
{
|
||||||
if(_linkWidgetList.size() == 0) {
|
if(_linkWidgetList.size() == 0) {
|
||||||
_emptyShareLinkWidget = new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, _ui->scrollArea);
|
_emptyShareLinkWidget = new ShareLinkWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, this);
|
||||||
_linkWidgetList.append(_emptyShareLinkWidget);
|
_linkWidgetList.append(_emptyShareLinkWidget);
|
||||||
|
|
||||||
|
connect(_emptyShareLinkWidget, &ShareLinkWidget::resizeRequested, this, &ShareDialog::slotAdjustScrollWidgetSize);
|
||||||
connect(this, &ShareDialog::toggleShareLinkAnimation, _emptyShareLinkWidget, &ShareLinkWidget::slotToggleShareLinkAnimation);
|
connect(this, &ShareDialog::toggleShareLinkAnimation, _emptyShareLinkWidget, &ShareLinkWidget::slotToggleShareLinkAnimation);
|
||||||
connect(_emptyShareLinkWidget, &ShareLinkWidget::createLinkShare, this, &ShareDialog::slotCreateLinkShare);
|
connect(_emptyShareLinkWidget, &ShareLinkWidget::createLinkShare, this, &ShareDialog::slotCreateLinkShare);
|
||||||
|
|
||||||
connect(_emptyShareLinkWidget, &ShareLinkWidget::createPassword, this, &ShareDialog::slotCreatePasswordForLinkShare);
|
connect(_emptyShareLinkWidget, &ShareLinkWidget::createPassword, this, &ShareDialog::slotCreatePasswordForLinkShare);
|
||||||
|
|
||||||
_ui->verticalLayout->insertWidget(_linkWidgetList.size()+1, _emptyShareLinkWidget);
|
_ui->verticalLayout->insertWidget(_linkWidgetList.size()+1, _emptyShareLinkWidget);
|
||||||
_scrollAreaLayout->addWidget(_emptyShareLinkWidget);
|
|
||||||
_emptyShareLinkWidget->show();
|
_emptyShareLinkWidget->show();
|
||||||
} else if (_emptyShareLinkWidget) {
|
} else if(_emptyShareLinkWidget) {
|
||||||
_emptyShareLinkWidget->hide();
|
_emptyShareLinkWidget->hide();
|
||||||
_ui->verticalLayout->removeWidget(_emptyShareLinkWidget);
|
_ui->verticalLayout->removeWidget(_emptyShareLinkWidget);
|
||||||
_linkWidgetList.removeAll(_emptyShareLinkWidget);
|
_linkWidgetList.removeAll(_emptyShareLinkWidget);
|
||||||
@@ -207,7 +197,6 @@ void ShareDialog::slotAddLinkShareWidget(const QSharedPointer<LinkShare> &linkSh
|
|||||||
emit toggleShareLinkAnimation(true);
|
emit toggleShareLinkAnimation(true);
|
||||||
const auto addedLinkShareWidget = addLinkShareWidget(linkShare);
|
const auto addedLinkShareWidget = addLinkShareWidget(linkShare);
|
||||||
initLinkShareWidget();
|
initLinkShareWidget();
|
||||||
adjustScrollWidgetSize();
|
|
||||||
if (linkShare->isPasswordSet()) {
|
if (linkShare->isPasswordSet()) {
|
||||||
addedLinkShareWidget->focusPasswordLineEdit();
|
addedLinkShareWidget->focusPasswordLineEdit();
|
||||||
}
|
}
|
||||||
@@ -220,7 +209,6 @@ void ShareDialog::slotSharesFetched(const QList<QSharedPointer<Share>> &shares)
|
|||||||
|
|
||||||
const QString versionString = _accountState->account()->serverVersion();
|
const QString versionString = _accountState->account()->serverVersion();
|
||||||
qCInfo(lcSharing) << versionString << "Fetched" << shares.count() << "shares";
|
qCInfo(lcSharing) << versionString << "Fetched" << shares.count() << "shares";
|
||||||
|
|
||||||
foreach (auto share, shares) {
|
foreach (auto share, shares) {
|
||||||
if (share->getShareType() != Share::TypeLink || share->getUidOwner() != share->account()->davUser()) {
|
if (share->getShareType() != Share::TypeLink || share->getUidOwner() != share->account()->davUser()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -231,20 +219,17 @@ void ShareDialog::slotSharesFetched(const QList<QSharedPointer<Share>> &shares)
|
|||||||
}
|
}
|
||||||
|
|
||||||
initLinkShareWidget();
|
initLinkShareWidget();
|
||||||
adjustScrollWidgetSize();
|
|
||||||
emit toggleShareLinkAnimation(false);
|
emit toggleShareLinkAnimation(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareDialog::adjustScrollWidgetSize()
|
void ShareDialog::slotAdjustScrollWidgetSize()
|
||||||
{
|
{
|
||||||
const auto count = _scrollAreaLayout->count();
|
int count = this->findChildren<ShareLinkWidget *>().count();
|
||||||
const auto margin = 10;
|
_ui->scrollArea->setVisible(count > 0);
|
||||||
const auto height = _linkWidgetList.empty() ? 0 : _linkWidgetList.last()->sizeHint().height() + margin;
|
if (count > 0 && count <= 3) {
|
||||||
const auto totalHeight = height * count;
|
_ui->scrollArea->setFixedHeight(_ui->scrollArea->widget()->sizeHint().height());
|
||||||
_ui->scrollArea->setFixedWidth(_ui->verticalLayout->sizeHint().width());
|
}
|
||||||
_ui->scrollArea->setFixedHeight(totalHeight > 400 ? 400 : totalHeight);
|
_ui->scrollArea->setFrameShape(count > 3 ? QFrame::StyledPanel : QFrame::NoFrame);
|
||||||
_ui->scrollArea->setVisible(height > 0);
|
|
||||||
_ui->scrollArea->setFrameShape(count > 6 ? QFrame::StyledPanel : QFrame::NoFrame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShareDialog::~ShareDialog()
|
ShareDialog::~ShareDialog()
|
||||||
@@ -305,15 +290,19 @@ void ShareDialog::showSharingUi()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theme->userGroupSharing()) {
|
// We only do user/group sharing from 8.2.0
|
||||||
_userGroupWidget = new ShareUserGroupWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, _privateLinkUrl, _ui->scrollArea);
|
bool userGroupSharing =
|
||||||
_userGroupWidget->getShares();
|
theme->userGroupSharing()
|
||||||
|
&& _accountState->account()->serverVersionInt() >= Account::makeServerVersion(8, 2, 0);
|
||||||
|
|
||||||
|
if (userGroupSharing) {
|
||||||
|
_userGroupWidget = new ShareUserGroupWidget(_accountState->account(), _sharePath, _localPath, _maxSharingPermissions, _privateLinkUrl, this);
|
||||||
|
|
||||||
// Connect styleChanged events to our widget, so it can adapt (Dark-/Light-Mode switching)
|
// Connect styleChanged events to our widget, so it can adapt (Dark-/Light-Mode switching)
|
||||||
connect(this, &ShareDialog::styleChanged, _userGroupWidget, &ShareUserGroupWidget::slotStyleChanged);
|
connect(this, &ShareDialog::styleChanged, _userGroupWidget, &ShareUserGroupWidget::slotStyleChanged);
|
||||||
|
|
||||||
_ui->verticalLayout->insertWidget(1, _userGroupWidget);
|
_ui->verticalLayout->insertWidget(1, _userGroupWidget);
|
||||||
_scrollAreaLayout->addLayout(_userGroupWidget->shareUserGroupLayout());
|
_userGroupWidget->getShares();
|
||||||
}
|
}
|
||||||
|
|
||||||
initShareManager();
|
initShareManager();
|
||||||
@@ -400,10 +389,8 @@ void ShareDialog::slotDeleteShare()
|
|||||||
auto sharelinkWidget = dynamic_cast<ShareLinkWidget*>(sender());
|
auto sharelinkWidget = dynamic_cast<ShareLinkWidget*>(sender());
|
||||||
sharelinkWidget->hide();
|
sharelinkWidget->hide();
|
||||||
_ui->verticalLayout->removeWidget(sharelinkWidget);
|
_ui->verticalLayout->removeWidget(sharelinkWidget);
|
||||||
_scrollAreaLayout->removeWidget(sharelinkWidget);
|
|
||||||
_linkWidgetList.removeAll(sharelinkWidget);
|
_linkWidgetList.removeAll(sharelinkWidget);
|
||||||
initLinkShareWidget();
|
initLinkShareWidget();
|
||||||
adjustScrollWidgetSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareDialog::slotThumbnailFetched(const int &statusCode, const QByteArray &reply)
|
void ShareDialog::slotThumbnailFetched(const int &statusCode, const QByteArray &reply)
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class QProgressIndicator;
|
class QProgressIndicator;
|
||||||
class QVBoxLayout;
|
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
@@ -35,7 +34,6 @@ namespace Ui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ShareLinkWidget;
|
class ShareLinkWidget;
|
||||||
class InternalLinkWidget;
|
|
||||||
class ShareUserGroupWidget;
|
class ShareUserGroupWidget;
|
||||||
class ShareManager;
|
class ShareManager;
|
||||||
class LinkShare;
|
class LinkShare;
|
||||||
@@ -69,6 +67,7 @@ private slots:
|
|||||||
void slotCreatePasswordForLinkShare(const QString &password);
|
void slotCreatePasswordForLinkShare(const QString &password);
|
||||||
void slotCreatePasswordForLinkShareProcessed();
|
void slotCreatePasswordForLinkShareProcessed();
|
||||||
void slotLinkShareRequiresPassword(const QString &message);
|
void slotLinkShareRequiresPassword(const QString &message);
|
||||||
|
void slotAdjustScrollWidgetSize();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void toggleShareLinkAnimation(bool start);
|
void toggleShareLinkAnimation(bool start);
|
||||||
@@ -82,7 +81,6 @@ private:
|
|||||||
void initShareManager();
|
void initShareManager();
|
||||||
ShareLinkWidget *addLinkShareWidget(const QSharedPointer<LinkShare> &linkShare);
|
ShareLinkWidget *addLinkShareWidget(const QSharedPointer<LinkShare> &linkShare);
|
||||||
void initLinkShareWidget();
|
void initLinkShareWidget();
|
||||||
void adjustScrollWidgetSize();
|
|
||||||
|
|
||||||
Ui::ShareDialog *_ui;
|
Ui::ShareDialog *_ui;
|
||||||
|
|
||||||
@@ -97,12 +95,8 @@ private:
|
|||||||
|
|
||||||
QList<ShareLinkWidget*> _linkWidgetList;
|
QList<ShareLinkWidget*> _linkWidgetList;
|
||||||
ShareLinkWidget* _emptyShareLinkWidget = nullptr;
|
ShareLinkWidget* _emptyShareLinkWidget = nullptr;
|
||||||
InternalLinkWidget* _internalLinkWidget = nullptr;
|
|
||||||
ShareUserGroupWidget *_userGroupWidget = nullptr;
|
ShareUserGroupWidget *_userGroupWidget = nullptr;
|
||||||
QProgressIndicator *_progressIndicator = nullptr;
|
QProgressIndicator *_progressIndicator = nullptr;
|
||||||
|
|
||||||
QWidget *_scrollAreaViewPort = nullptr;
|
|
||||||
QVBoxLayout *_scrollAreaLayout = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace OCC
|
} // namespace OCC
|
||||||
|
|||||||
@@ -6,36 +6,18 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>480</width>
|
<width>385</width>
|
||||||
<height>280</height>
|
<height>150</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>480</width>
|
|
||||||
<height>250</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="shareDialogVerticalLayout">
|
<layout class="QVBoxLayout" name="shareDialogVerticalLayout">
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="sizeConstraint">
|
<property name="sizeConstraint">
|
||||||
<enum>QLayout::SetFixedSize</enum>
|
<enum>QLayout::SetFixedSize</enum>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="sizeConstraint">
|
<property name="sizeConstraint">
|
||||||
<enum>QLayout::SetDefaultConstraint</enum>
|
<enum>QLayout::SetFixedSize</enum>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0" columnstretch="0,0">
|
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0" columnstretch="0,0">
|
||||||
@@ -51,31 +33,6 @@
|
|||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>10</number>
|
<number>10</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="0" column="0" rowspan="2">
|
|
||||||
<widget class="QLabel" name="label_icon">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>16777215</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Icon</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="label_name">
|
<widget class="QLabel" name="label_name">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@@ -132,36 +89,49 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="0" rowspan="2">
|
||||||
|
<widget class="QLabel" name="label_icon">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Icon</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QScrollArea" name="scrollArea">
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>200</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
<property name="horizontalScrollBarPolicy">
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeAdjustPolicy">
|
<property name="sizeAdjustPolicy">
|
||||||
<enum>QAbstractScrollArea::AdjustToContentsOnFirstShow</enum>
|
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="widgetResizable">
|
<property name="widgetResizable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -171,10 +141,11 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>460</width>
|
<width>69</width>
|
||||||
<height>200</height>
|
<height>69</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="scrollAreaVerticalLayout"/>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -411,6 +411,22 @@ void ShareLinkWidget::slotPasswordSetError(const int code, const QString &messag
|
|||||||
emit createPasswordProcessed();
|
emit createPasswordProcessed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShareLinkWidget::startAnimation(const int start, const int end)
|
||||||
|
{
|
||||||
|
auto *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()
|
void ShareLinkWidget::slotDeleteShareFetched()
|
||||||
{
|
{
|
||||||
slotToggleShareLinkAnimation(false);
|
slotToggleShareLinkAnimation(false);
|
||||||
@@ -434,6 +450,12 @@ void ShareLinkWidget::toggleNoteOptions(const bool enable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShareLinkWidget::slotAnimationFinished()
|
||||||
|
{
|
||||||
|
emit resizeRequested();
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
void ShareLinkWidget::slotCreateLabel()
|
void ShareLinkWidget::slotCreateLabel()
|
||||||
{
|
{
|
||||||
const auto labelText = _shareLinkEdit->text();
|
const auto labelText = _shareLinkEdit->text();
|
||||||
@@ -452,6 +474,14 @@ void ShareLinkWidget::slotLabelSet()
|
|||||||
displayShareLinkLabel();
|
displayShareLinkLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
void ShareLinkWidget::slotCreateShareRequiresPassword(const QString &message)
|
||||||
{
|
{
|
||||||
slotToggleShareLinkAnimation(message.isEmpty());
|
slotToggleShareLinkAnimation(message.isEmpty());
|
||||||
|
|||||||
@@ -90,6 +90,9 @@ private slots:
|
|||||||
|
|
||||||
void slotContextMenuButtonClicked();
|
void slotContextMenuButtonClicked();
|
||||||
void slotLinkContextMenuActionTriggered(QAction *action);
|
void slotLinkContextMenuActionTriggered(QAction *action);
|
||||||
|
|
||||||
|
void slotDeleteAnimationFinished();
|
||||||
|
void slotAnimationFinished();
|
||||||
|
|
||||||
void slotCreateLabel();
|
void slotCreateLabel();
|
||||||
void slotLabelSet();
|
void slotLabelSet();
|
||||||
@@ -97,6 +100,7 @@ private slots:
|
|||||||
signals:
|
signals:
|
||||||
void createLinkShare();
|
void createLinkShare();
|
||||||
void deleteLinkShare();
|
void deleteLinkShare();
|
||||||
|
void resizeRequested();
|
||||||
void visualDeletionDone();
|
void visualDeletionDone();
|
||||||
void createPassword(const QString &password);
|
void createPassword(const QString &password);
|
||||||
void createPasswordProcessed();
|
void createPasswordProcessed();
|
||||||
@@ -115,6 +119,8 @@ private:
|
|||||||
/** Retrieve a share's name, accounting for _namesSupported */
|
/** Retrieve a share's name, accounting for _namesSupported */
|
||||||
QString shareName() const;
|
QString shareName() const;
|
||||||
|
|
||||||
|
void startAnimation(const int start, const int end);
|
||||||
|
|
||||||
void customizeStyle();
|
void customizeStyle();
|
||||||
|
|
||||||
void displayShareLinkLabel();
|
void displayShareLinkLabel();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>365</width>
|
||||||
<height>238</height>
|
<height>238</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@@ -17,29 +17,8 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>12</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>20</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<property name="spacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="shareLinkIconLabel">
|
<widget class="QLabel" name="shareLinkIconLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|||||||
@@ -154,18 +154,16 @@ ShareUserGroupWidget::ShareUserGroupWidget(AccountPtr account,
|
|||||||
_completionTimer.setInterval(600);
|
_completionTimer.setInterval(600);
|
||||||
|
|
||||||
_ui->errorLabel->hide();
|
_ui->errorLabel->hide();
|
||||||
|
|
||||||
|
// TODO Progress Indicator where should it go?
|
||||||
|
// Setup the sharee search progress indicator
|
||||||
|
//_ui->shareeHorizontalLayout->addWidget(&_pi_sharee);
|
||||||
|
|
||||||
_parentScrollArea = parentWidget()->findChild<QScrollArea*>("scrollArea");
|
_parentScrollArea = parentWidget()->findChild<QScrollArea*>("scrollArea");
|
||||||
_shareUserGroup = new QVBoxLayout(_parentScrollArea);
|
|
||||||
_shareUserGroup->setContentsMargins(0, 0, 0, 0);
|
|
||||||
customizeStyle();
|
customizeStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVBoxLayout *ShareUserGroupWidget::shareUserGroupLayout()
|
|
||||||
{
|
|
||||||
return _shareUserGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShareUserGroupWidget::~ShareUserGroupWidget()
|
ShareUserGroupWidget::~ShareUserGroupWidget()
|
||||||
{
|
{
|
||||||
delete _ui;
|
delete _ui;
|
||||||
@@ -249,16 +247,17 @@ void ShareUserGroupWidget::slotShareCreated(const QSharedPointer<Share> &share)
|
|||||||
|
|
||||||
void ShareUserGroupWidget::slotSharesFetched(const QList<QSharedPointer<Share>> &shares)
|
void ShareUserGroupWidget::slotSharesFetched(const QList<QSharedPointer<Share>> &shares)
|
||||||
{
|
{
|
||||||
|
QScrollArea *scrollArea = _parentScrollArea;
|
||||||
|
|
||||||
|
auto newViewPort = new QWidget(scrollArea);
|
||||||
|
auto layout = new QVBoxLayout(newViewPort);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
int height = 0;
|
||||||
QList<QString> linkOwners({});
|
QList<QString> linkOwners({});
|
||||||
|
|
||||||
ShareUserLine *justCreatedShareThatNeedsPassword = nullptr;
|
ShareUserLine *justCreatedShareThatNeedsPassword = nullptr;
|
||||||
|
|
||||||
while (QLayoutItem *shareUserLine = _shareUserGroup->takeAt(0)) {
|
|
||||||
delete shareUserLine->widget();
|
|
||||||
delete shareUserLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (const auto &share, shares) {
|
foreach (const auto &share, shares) {
|
||||||
// We don't handle link shares, only TypeUser or TypeGroup
|
// We don't handle link shares, only TypeUser or TypeGroup
|
||||||
if (share->getShareType() == Share::TypeLink) {
|
if (share->getShareType() == Share::TypeLink) {
|
||||||
@@ -279,12 +278,14 @@ void ShareUserGroupWidget::slotSharesFetched(const QList<QSharedPointer<Share>>
|
|||||||
Q_ASSERT(Share::isShareTypeUserGroupEmailRoomOrRemote(share->getShareType()));
|
Q_ASSERT(Share::isShareTypeUserGroupEmailRoomOrRemote(share->getShareType()));
|
||||||
auto userGroupShare = qSharedPointerDynamicCast<UserGroupShare>(share);
|
auto userGroupShare = qSharedPointerDynamicCast<UserGroupShare>(share);
|
||||||
auto *s = new ShareUserLine(_account, userGroupShare, _maxSharingPermissions, _isFile, _parentScrollArea);
|
auto *s = new ShareUserLine(_account, userGroupShare, _maxSharingPermissions, _isFile, _parentScrollArea);
|
||||||
|
connect(s, &ShareUserLine::resizeRequested, this, &ShareUserGroupWidget::slotAdjustScrollWidgetSize);
|
||||||
connect(s, &ShareUserLine::visualDeletionDone, this, &ShareUserGroupWidget::getShares);
|
connect(s, &ShareUserLine::visualDeletionDone, this, &ShareUserGroupWidget::getShares);
|
||||||
s->setBackgroundRole(_shareUserGroup->count() % 2 == 0 ? QPalette::Base : QPalette::AlternateBase);
|
s->setBackgroundRole(layout->count() % 2 == 0 ? QPalette::Base : QPalette::AlternateBase);
|
||||||
|
|
||||||
// Connect styleChanged events to our widget, so it can adapt (Dark-/Light-Mode switching)
|
// Connect styleChanged events to our widget, so it can adapt (Dark-/Light-Mode switching)
|
||||||
connect(this, &ShareUserGroupWidget::styleChanged, s, &ShareUserLine::slotStyleChanged);
|
connect(this, &ShareUserGroupWidget::styleChanged, s, &ShareUserLine::slotStyleChanged);
|
||||||
_shareUserGroup->addWidget(s);
|
|
||||||
|
layout->addWidget(s);
|
||||||
|
|
||||||
if (!_lastCreatedShareId.isEmpty() && share->getId() == _lastCreatedShareId) {
|
if (!_lastCreatedShareId.isEmpty() && share->getId() == _lastCreatedShareId) {
|
||||||
_lastCreatedShareId = QString();
|
_lastCreatedShareId = QString();
|
||||||
@@ -294,14 +295,27 @@ void ShareUserGroupWidget::slotSharesFetched(const QList<QSharedPointer<Share>>
|
|||||||
}
|
}
|
||||||
|
|
||||||
x++;
|
x++;
|
||||||
|
if (x <= 3) {
|
||||||
|
height = newViewPort->sizeHint().height();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const QString &owner, linkOwners) {
|
foreach (const QString &owner, linkOwners) {
|
||||||
auto ownerLabel = new QLabel(QString(owner + " shared via link"));
|
auto ownerLabel = new QLabel(QString(owner + " shared via link"));
|
||||||
_shareUserGroup->addWidget(ownerLabel);
|
layout->addWidget(ownerLabel);
|
||||||
ownerLabel->setVisible(true);
|
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);
|
||||||
|
|
||||||
_disableCompleterActivated = false;
|
_disableCompleterActivated = false;
|
||||||
activateShareeLineEdit();
|
activateShareeLineEdit();
|
||||||
|
|
||||||
@@ -311,6 +325,24 @@ void ShareUserGroupWidget::slotSharesFetched(const QList<QSharedPointer<Share>>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShareUserGroupWidget::slotAdjustScrollWidgetSize()
|
||||||
|
{
|
||||||
|
QScrollArea *scrollArea = _parentScrollArea;
|
||||||
|
const auto shareUserLineChilds = scrollArea->findChildren<ShareUserLine *>();
|
||||||
|
|
||||||
|
// Ask the child widgets to calculate their size
|
||||||
|
for (const auto shareUserLineChild : shareUserLineChilds) {
|
||||||
|
shareUserLineChild->adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto shareUserLineChildsCount = shareUserLineChilds.count();
|
||||||
|
scrollArea->setVisible(shareUserLineChildsCount > 0);
|
||||||
|
if (shareUserLineChildsCount > 0 && shareUserLineChildsCount <= 3) {
|
||||||
|
scrollArea->setFixedHeight(scrollArea->widget()->sizeHint().height());
|
||||||
|
}
|
||||||
|
scrollArea->setFrameShape(shareUserLineChildsCount > 3 ? QFrame::StyledPanel : QFrame::NoFrame);
|
||||||
|
}
|
||||||
|
|
||||||
void ShareUserGroupWidget::slotPrivateLinkShare()
|
void ShareUserGroupWidget::slotPrivateLinkShare()
|
||||||
{
|
{
|
||||||
auto menu = new QMenu(this);
|
auto menu = new QMenu(this);
|
||||||
@@ -348,11 +380,22 @@ void ShareUserGroupWidget::slotCompleterActivated(const QModelIndex &index)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Progress Indicator where should it go?
|
||||||
|
// auto indicator = new QProgressIndicator(viewPort);
|
||||||
|
// indicator->startAnimation();
|
||||||
|
// if (layout->count() == 1) {
|
||||||
|
// // No shares yet! Remove the label, add some stretch.
|
||||||
|
// delete layout->itemAt(0)->widget();
|
||||||
|
// layout->addStretch(1);
|
||||||
|
// }
|
||||||
|
// layout->insertWidget(layout->count() - 1, indicator);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't send the reshare permissions for federated shares for servers <9.1
|
* Don't send the reshare permissions for federated shares for servers <9.1
|
||||||
* https://github.com/owncloud/core/issues/22122#issuecomment-185637344
|
* https://github.com/owncloud/core/issues/22122#issuecomment-185637344
|
||||||
* https://github.com/owncloud/client/issues/4996
|
* https://github.com/owncloud/client/issues/4996
|
||||||
*/
|
*/
|
||||||
|
|
||||||
_lastCreatedShareId = QString();
|
_lastCreatedShareId = QString();
|
||||||
|
|
||||||
QString password;
|
QString password;
|
||||||
|
|||||||
@@ -77,8 +77,6 @@ public:
|
|||||||
const QString &privateLinkUrl,
|
const QString &privateLinkUrl,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
~ShareUserGroupWidget() override;
|
~ShareUserGroupWidget() override;
|
||||||
|
|
||||||
QVBoxLayout *shareUserGroupLayout();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void togglePublicLinkShare(bool);
|
void togglePublicLinkShare(bool);
|
||||||
@@ -100,6 +98,7 @@ private slots:
|
|||||||
void slotCompleterActivated(const QModelIndex &index);
|
void slotCompleterActivated(const QModelIndex &index);
|
||||||
void slotCompleterHighlighted(const QModelIndex &index);
|
void slotCompleterHighlighted(const QModelIndex &index);
|
||||||
void slotShareesReady();
|
void slotShareesReady();
|
||||||
|
void slotAdjustScrollWidgetSize();
|
||||||
void slotPrivateLinkShare();
|
void slotPrivateLinkShare();
|
||||||
void displayError(int code, const QString &message);
|
void displayError(int code, const QString &message);
|
||||||
|
|
||||||
@@ -114,7 +113,6 @@ private:
|
|||||||
|
|
||||||
Ui::ShareUserGroupWidget *_ui;
|
Ui::ShareUserGroupWidget *_ui;
|
||||||
QScrollArea *_parentScrollArea;
|
QScrollArea *_parentScrollArea;
|
||||||
QVBoxLayout *_shareUserGroup;
|
|
||||||
AccountPtr _account;
|
AccountPtr _account;
|
||||||
QString _sharePath;
|
QString _sharePath;
|
||||||
QString _localPath;
|
QString _localPath;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>350</width>
|
<width>350</width>
|
||||||
<height>106</height>
|
<height>70</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@@ -17,21 +17,6 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="spacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="mainOwnerLabel">
|
<widget class="QLabel" name="mainOwnerLabel">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>899</width>
|
||||||
<height>310</height>
|
<height>310</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@@ -26,26 +26,8 @@
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>12</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>20</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="spacing">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@@ -93,11 +75,11 @@
|
|||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeType">
|
<property name="sizeType">
|
||||||
<enum>QSizePolicy::Minimum</enum>
|
<enum>QSizePolicy::Expanding</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="sizeHint" stdset="0">
|
||||||
<size>
|
<size>
|
||||||
<width>20</width>
|
<width>40</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
|||||||
@@ -1,65 +1,109 @@
|
|||||||
import QtQuick 2.15
|
import QtQuick 2.5
|
||||||
import QtQuick.Controls 2.3
|
import QtQuick.Controls 2.3
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
import Style 1.0
|
import Style 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
readonly property bool labelVisible: label.visible
|
||||||
|
readonly property bool iconVisible: icon.visible
|
||||||
|
|
||||||
|
// label value
|
||||||
property string text: ""
|
property string text: ""
|
||||||
property string toolTipText: ""
|
|
||||||
|
// font value
|
||||||
property bool bold: false
|
property var font: label.font
|
||||||
|
|
||||||
|
// icon value
|
||||||
property string imageSource: ""
|
property string imageSource: ""
|
||||||
property string imageSourceHover: ""
|
|
||||||
|
|
||||||
property color textColor: Style.unifiedSearchResulTitleColor
|
// Tooltip value
|
||||||
property color textColorHovered: Style.unifiedSearchResulSublineColor
|
property string tooltipText: text
|
||||||
|
|
||||||
|
// text color
|
||||||
|
property color textColor: Style.ncTextColor
|
||||||
|
property color textColorHovered: Style.lightHover
|
||||||
|
|
||||||
|
// text background color
|
||||||
|
property color textBgColor: "transparent"
|
||||||
|
property color textBgColorHovered: Style.lightHover
|
||||||
|
|
||||||
|
// icon background color
|
||||||
|
property color iconBgColor: "transparent"
|
||||||
|
property color iconBgColorHovered: Style.lightHover
|
||||||
|
|
||||||
|
// text border color
|
||||||
|
property color textBorderColor: "transparent"
|
||||||
|
|
||||||
|
property alias hovered: mouseArea.containsMouse
|
||||||
|
|
||||||
signal clicked()
|
signal clicked()
|
||||||
|
|
||||||
Loader {
|
Accessible.role: Accessible.Button
|
||||||
active: root.imageSource === ""
|
Accessible.name: text !== "" ? text : (tooltipText !== "" ? tooltipText : qsTr("Activity action button"))
|
||||||
|
Accessible.onPressAction: clicked()
|
||||||
|
|
||||||
|
// background with border around the Text
|
||||||
|
Rectangle {
|
||||||
|
visible: parent.labelVisible
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
sourceComponent: CustomTextButton {
|
// padding
|
||||||
anchors.fill: parent
|
anchors.topMargin: 10
|
||||||
text: root.text
|
anchors.bottomMargin: 10
|
||||||
toolTipText: root.toolTipText
|
|
||||||
|
|
||||||
textColor: root.textColor
|
border.color: parent.textBorderColor
|
||||||
textColorHovered: root.textColorHovered
|
border.width: 1
|
||||||
|
|
||||||
onClicked: root.clicked()
|
color: parent.hovered ? parent.textBgColorHovered : parent.textBgColor
|
||||||
}
|
|
||||||
|
radius: 25
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
// background with border around the Image
|
||||||
active: root.imageSource !== ""
|
Rectangle {
|
||||||
|
visible: parent.iconVisible
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
sourceComponent: CustomButton {
|
color: parent.hovered ? parent.iconBgColorHovered : parent.iconBgColor
|
||||||
anchors.fill: parent
|
}
|
||||||
anchors.topMargin: Style.roundedButtonBackgroundVerticalMargins
|
|
||||||
anchors.bottomMargin: Style.roundedButtonBackgroundVerticalMargins
|
|
||||||
|
|
||||||
text: root.text
|
// label
|
||||||
toolTipText: root.toolTipText
|
Text {
|
||||||
|
id: label
|
||||||
|
visible: parent.text !== ""
|
||||||
|
text: parent.text
|
||||||
|
font: parent.font
|
||||||
|
color: parent.hovered ? parent.textColorHovered : parent.textColor
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
textColor: root.textColor
|
// icon
|
||||||
textColorHovered: root.textColorHovered
|
Image {
|
||||||
|
id: icon
|
||||||
|
visible: parent.imageSource !== ""
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source: parent.imageSource
|
||||||
|
sourceSize.width: visible ? 32 : 0
|
||||||
|
sourceSize.height: visible ? 32 : 0
|
||||||
|
}
|
||||||
|
|
||||||
bold: root.bold
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: parent.clicked()
|
||||||
|
hoverEnabled: true
|
||||||
|
}
|
||||||
|
|
||||||
imageSource: root.imageSource
|
ToolTip {
|
||||||
imageSourceHover: root.imageSourceHover
|
text: parent.tooltipText
|
||||||
|
delay: 1000
|
||||||
bgColor: Style.ncBlue
|
visible: text != "" && parent.hovered
|
||||||
|
|
||||||
onClicked: root.clicked()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +1,264 @@
|
|||||||
import QtQml 2.15
|
import QtQml 2.12
|
||||||
import QtQuick 2.15
|
import QtQuick 2.9
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.2
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.2
|
||||||
import Style 1.0
|
import Style 1.0
|
||||||
import com.nextcloud.desktopclient 1.0
|
import com.nextcloud.desktopclient 1.0
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: root
|
id: activityMouseArea
|
||||||
|
|
||||||
|
readonly property int maxActionButtons: 2
|
||||||
property Flickable flickable
|
property Flickable flickable
|
||||||
|
|
||||||
property bool isFileActivityList: false
|
|
||||||
|
|
||||||
property bool isChatActivity: model.objectType === "chat" || model.objectType === "room"
|
|
||||||
|
|
||||||
signal fileActivityButtonClicked(string absolutePath)
|
signal fileActivityButtonClicked(string absolutePath)
|
||||||
|
|
||||||
enabled: (model.path !== "" || model.link !== "" || model.isCurrentUserFileActivity === true)
|
enabled: (path !== "" || link !== "")
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
height: childrenRect.height
|
|
||||||
|
|
||||||
ToolTip.visible: containsMouse && !activityContent.childHovered && model.displayLocation !== ""
|
|
||||||
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
|
||||||
ToolTip.text: qsTr("In %1").arg(model.displayLocation)
|
|
||||||
|
|
||||||
Accessible.role: Accessible.ListItem
|
|
||||||
Accessible.name: (model.path !== "" && model.displayPath !== "") ? qsTr("Open %1 locally").arg(model.displayPath) : model.message
|
|
||||||
Accessible.onPressAction: root.clicked()
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: activityHover
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: (parent.containsMouse ? Style.lightHover : "transparent")
|
color: (parent.containsMouse ? Style.lightHover : "transparent")
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ToolTip.visible: containsMouse && displayLocation !== ""
|
||||||
anchors.left: root.left
|
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
||||||
anchors.right: root.right
|
ToolTip.text: qsTr("In %1").arg(displayLocation)
|
||||||
anchors.leftMargin: 15
|
|
||||||
anchors.rightMargin: 10
|
RowLayout {
|
||||||
|
id: activityItem
|
||||||
|
|
||||||
|
readonly property variant links: model.links
|
||||||
|
|
||||||
|
readonly property int itemIndex: model.index
|
||||||
|
|
||||||
|
width: activityMouseArea.width
|
||||||
|
height: Style.trayWindowHeaderHeight
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
ActivityItemContent {
|
Accessible.role: Accessible.ListItem
|
||||||
id: activityContent
|
Accessible.name: path !== "" ? qsTr("Open %1 locally").arg(displayPath)
|
||||||
|
: message
|
||||||
Layout.fillWidth: true
|
Accessible.onPressAction: activityMouseArea.clicked()
|
||||||
|
|
||||||
showDismissButton: model.links.length > 0 && model.linksForActionButtons.length === 0
|
Image {
|
||||||
|
id: activityIcon
|
||||||
activityData: model
|
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||||
|
Layout.leftMargin: 20
|
||||||
Layout.preferredHeight: Style.trayWindowHeaderHeight
|
Layout.preferredWidth: shareButton.icon.width
|
||||||
|
Layout.preferredHeight: shareButton.icon.height
|
||||||
onShareButtonClicked: Systray.openShareDialog(model.displayPath, model.absolutePath)
|
verticalAlignment: Qt.AlignCenter
|
||||||
onDismissButtonClicked: activityModel.slotTriggerDismiss(model.index)
|
cache: true
|
||||||
|
source: icon
|
||||||
|
sourceSize.height: 64
|
||||||
|
sourceSize.width: 64
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivityItemActions {
|
Column {
|
||||||
id: activityActions
|
id: activityTextColumn
|
||||||
|
Layout.leftMargin: 14
|
||||||
visible: !root.isFileActivityList && model.linksForActionButtons.length > 0
|
Layout.topMargin: 4
|
||||||
|
Layout.bottomMargin: 4
|
||||||
Layout.preferredHeight: Style.trayWindowHeaderHeight * 0.85
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 40
|
spacing: 4
|
||||||
Layout.bottomMargin: model.links.length > 1 ? 5 : 0
|
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: activityTextTitle
|
||||||
|
text: (type === "Activity" || type === "Notification") ? subject : message
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.pixelSize: Style.topLinePixelSize
|
||||||
|
color: activityTextTitleColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: activityTextInfo
|
||||||
|
text: (type === "Sync") ? displayPath
|
||||||
|
: (type === "File") ? subject
|
||||||
|
: (type === "Notification") ? message
|
||||||
|
: ""
|
||||||
|
height: (text === "") ? 0 : activityTextTitle.height
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.pixelSize: Style.subLinePixelSize
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: activityTextDateTime
|
||||||
|
text: dateTime
|
||||||
|
height: (text === "") ? 0 : activityTextTitle.height
|
||||||
|
width: parent.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.pixelSize: Style.subLinePixelSize
|
||||||
|
color: "#808080"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: activityActionsLayout
|
||||||
|
spacing: 0
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
|
Layout.minimumWidth: 28
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
function actionButtonIcon(actionIndex) {
|
||||||
|
const verb = String(model.links[actionIndex].verb);
|
||||||
|
if (verb === "WEB" && (model.objectType === "chat" || model.objectType === "call")) {
|
||||||
|
return "qrc:///client/theme/reply.svg";
|
||||||
|
} else if (verb === "DELETE") {
|
||||||
|
return "qrc:///client/theme/close.svg";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "qrc:///client/theme/confirm.svg";
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: activityItem.links.length > maxActionButtons ? 1 : activityItem.links.length
|
||||||
|
|
||||||
|
ActivityActionButton {
|
||||||
|
id: activityActionButton
|
||||||
|
|
||||||
|
readonly property int actionIndex: model.index
|
||||||
|
readonly property bool primary: model.index === 0 && String(activityItem.links[actionIndex].verb) !== "DELETE"
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
text: !primary ? "" : activityItem.links[actionIndex].label
|
||||||
|
|
||||||
|
imageSource: !primary ? activityActionsLayout.actionButtonIcon(actionIndex) : ""
|
||||||
|
|
||||||
|
textColor: primary ? Style.ncBlue : "black"
|
||||||
|
textColorHovered: Style.lightHover
|
||||||
|
|
||||||
|
textBorderColor: Style.ncBlue
|
||||||
|
|
||||||
|
textBgColor: "transparent"
|
||||||
|
textBgColorHovered: Style.ncBlue
|
||||||
|
|
||||||
|
tooltipText: activityItem.links[actionIndex].label
|
||||||
|
|
||||||
|
Layout.minimumWidth: primary ? 80 : -1
|
||||||
|
Layout.minimumHeight: parent.height
|
||||||
|
|
||||||
|
Layout.preferredWidth: primary ? -1 : parent.height
|
||||||
|
|
||||||
|
onClicked: activityModel.triggerAction(activityItem.itemIndex, actionIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
displayActions: model.displayActions
|
Button {
|
||||||
objectType: model.objectType
|
id: shareButton
|
||||||
linksForActionButtons: model.linksForActionButtons
|
|
||||||
linksContextMenu: model.linksContextMenu
|
Layout.preferredWidth: parent.height
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
flat: true
|
||||||
|
hoverEnabled: true
|
||||||
|
visible: isShareable
|
||||||
|
display: AbstractButton.IconOnly
|
||||||
|
icon.source: "qrc:///client/theme/share.svg"
|
||||||
|
icon.color: "transparent"
|
||||||
|
background: Rectangle {
|
||||||
|
color: parent.hovered ? Style.lightHover : "transparent"
|
||||||
|
}
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
||||||
|
ToolTip.text: qsTr("Open share dialog")
|
||||||
|
onClicked: Systray.openShareDialog(displayPath, absolutePath)
|
||||||
|
|
||||||
|
Accessible.role: Accessible.Button
|
||||||
|
Accessible.name: qsTr("Share %1").arg(displayPath)
|
||||||
|
Accessible.onPressAction: shareButton.clicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: moreActionsButton
|
||||||
|
|
||||||
|
Layout.preferredWidth: parent.height
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
||||||
|
flat: true
|
||||||
|
hoverEnabled: true
|
||||||
|
visible: displayActions && ((path !== "") || (activityItem.links.length > maxActionButtons))
|
||||||
|
display: AbstractButton.IconOnly
|
||||||
|
icon.source: "qrc:///client/theme/more.svg"
|
||||||
|
icon.color: "transparent"
|
||||||
|
background: Rectangle {
|
||||||
|
color: parent.hovered ? Style.lightHover : "transparent"
|
||||||
|
}
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
||||||
|
ToolTip.text: qsTr("Show more actions")
|
||||||
|
|
||||||
|
Accessible.role: Accessible.Button
|
||||||
|
Accessible.name: qsTr("Show more actions")
|
||||||
|
Accessible.onPressAction: moreActionsButton.clicked()
|
||||||
|
|
||||||
|
onClicked: moreActionsButtonContextMenu.popup();
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: flickable
|
||||||
|
|
||||||
|
function onMovementStarted() {
|
||||||
|
moreActionsButtonContextMenu.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Container {
|
||||||
|
id: moreActionsButtonContextMenuContainer
|
||||||
|
visible: moreActionsButtonContextMenu.opened
|
||||||
|
|
||||||
|
width: moreActionsButtonContextMenu.width
|
||||||
|
height: moreActionsButtonContextMenu.height
|
||||||
|
anchors.right: moreActionsButton.right
|
||||||
|
anchors.top: moreActionsButton.top
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
id: moreActionsButtonContextMenu
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
// transform model to contain indexed actions with primary action filtered out
|
||||||
|
function actionListToContextMenuList(actionList) {
|
||||||
|
// early out with non-altered data
|
||||||
|
if (activityItem.links.length <= maxActionButtons) {
|
||||||
|
return actionList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add index to every action and filter 'primary' action out
|
||||||
|
var reducedActionList = actionList.reduce(function(reduced, action, index) {
|
||||||
|
if (!action.primary) {
|
||||||
|
var actionWithIndex = { actionIndex: index, label: action.label };
|
||||||
|
reduced.push(actionWithIndex);
|
||||||
|
}
|
||||||
|
return reduced;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
return reducedActionList;
|
||||||
|
}
|
||||||
|
|
||||||
moreActionsButtonColor: activityHover.color
|
MenuItem {
|
||||||
maxActionButtons: activityModel.maxActionButtons
|
text: qsTr("View activity")
|
||||||
|
onClicked: fileActivityButtonClicked(absolutePath)
|
||||||
flickable: root.flickable
|
}
|
||||||
|
|
||||||
onTriggerAction: activityModel.slotTriggerAction(model.index, actionIndex)
|
Repeater {
|
||||||
|
id: moreActionsButtonContextMenuRepeater
|
||||||
|
|
||||||
|
model: moreActionsButtonContextMenu.actionListToContextMenuList(activityItem.links)
|
||||||
|
|
||||||
|
delegate: MenuItem {
|
||||||
|
id: moreActionsButtonContextMenuEntry
|
||||||
|
text: model.modelData.label
|
||||||
|
onTriggered: activityModel.triggerAction(activityItem.itemIndex, model.modelData.actionIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
import QtQml 2.15
|
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.3
|
|
||||||
import QtQuick.Layouts 1.2
|
|
||||||
import Style 1.0
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
spacing: 20
|
|
||||||
|
|
||||||
property string objectType: ""
|
|
||||||
property variant linksForActionButtons: []
|
|
||||||
property variant linksContextMenu: []
|
|
||||||
property bool displayActions: false
|
|
||||||
|
|
||||||
property color moreActionsButtonColor: "transparent"
|
|
||||||
|
|
||||||
property int maxActionButtons: 0
|
|
||||||
|
|
||||||
property Flickable flickable
|
|
||||||
|
|
||||||
signal triggerAction(int actionIndex)
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
id: actionsRepeater
|
|
||||||
// a max of maxActionButtons will get dispayed as separate buttons
|
|
||||||
model: root.linksForActionButtons
|
|
||||||
|
|
||||||
ActivityActionButton {
|
|
||||||
id: activityActionButton
|
|
||||||
|
|
||||||
readonly property bool primary: model.index === 0 && model.modelData.verb !== "DELETE"
|
|
||||||
|
|
||||||
Layout.minimumWidth: primary ? Style.activityItemActionPrimaryButtonMinWidth : Style.activityItemActionSecondaryButtonMinWidth
|
|
||||||
Layout.preferredHeight: primary ? parent.height : parent.height * 0.3
|
|
||||||
Layout.preferredWidth: primary ? -1 : parent.height
|
|
||||||
|
|
||||||
text: model.modelData.label
|
|
||||||
toolTipText: model.modelData.label
|
|
||||||
|
|
||||||
imageSource: model.modelData.imageSource
|
|
||||||
imageSourceHover: model.modelData.imageSourceHovered
|
|
||||||
|
|
||||||
textColor: imageSource !== "" ? Style.ncBlue : Style.unifiedSearchResulSublineColor
|
|
||||||
textColorHovered: imageSource !== "" ? Style.lightHover : Style.unifiedSearchResulTitleColor
|
|
||||||
|
|
||||||
bold: primary
|
|
||||||
|
|
||||||
onClicked: root.triggerAction(model.index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
// actions that do not fit maxActionButtons limit, must be put into a context menu
|
|
||||||
id: moreActionsButtonContainer
|
|
||||||
|
|
||||||
Layout.preferredWidth: parent.height
|
|
||||||
Layout.topMargin: Style.roundedButtonBackgroundVerticalMargins
|
|
||||||
Layout.bottomMargin: Style.roundedButtonBackgroundVerticalMargins
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
active: root.displayActions && (root.linksContextMenu.length > 0)
|
|
||||||
|
|
||||||
sourceComponent: Button {
|
|
||||||
id: moreActionsButton
|
|
||||||
|
|
||||||
icon.source: "qrc:///client/theme/more.svg"
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: parent.hovered ? "white" : root.moreActionsButtonColor
|
|
||||||
radius: width / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
|
||||||
ToolTip.text: qsTr("Show more actions")
|
|
||||||
|
|
||||||
Accessible.name: qsTr("Show more actions")
|
|
||||||
|
|
||||||
onClicked: moreActionsButtonContextMenu.popup(moreActionsButton.x, moreActionsButton.y);
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root.flickable
|
|
||||||
|
|
||||||
function onMovementStarted() {
|
|
||||||
moreActionsButtonContextMenu.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ActivityItemContextMenu {
|
|
||||||
id: moreActionsButtonContextMenu
|
|
||||||
|
|
||||||
maxActionButtons: root.maxActionButtons
|
|
||||||
linksContextMenu: root.linksContextMenu
|
|
||||||
|
|
||||||
onMenuEntryTriggered: function(entryIndex) {
|
|
||||||
root.triggerAction(entryIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
import QtQml 2.15
|
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.3
|
|
||||||
import QtQuick.Layouts 1.2
|
|
||||||
import Style 1.0
|
|
||||||
import com.nextcloud.desktopclient 1.0
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property variant activityData: {{}}
|
|
||||||
|
|
||||||
property color activityTextTitleColor: Style.ncTextColor
|
|
||||||
|
|
||||||
property bool showDismissButton: false
|
|
||||||
|
|
||||||
property bool childHovered: shareButton.hovered || dismissActionButton.hovered
|
|
||||||
|
|
||||||
signal dismissButtonClicked()
|
|
||||||
signal shareButtonClicked()
|
|
||||||
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: activityIcon
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
|
||||||
Layout.preferredWidth: 32
|
|
||||||
Layout.preferredHeight: 32
|
|
||||||
|
|
||||||
verticalAlignment: Qt.AlignCenter
|
|
||||||
source: icon
|
|
||||||
sourceSize.height: 64
|
|
||||||
sourceSize.width: 64
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: activityTextColumn
|
|
||||||
|
|
||||||
Layout.topMargin: 4
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
|
||||||
|
|
||||||
spacing: 4
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: activityTextTitle
|
|
||||||
text: (root.activityData.type === "Activity" || root.activityData.type === "Notification") ? root.activityData.subject : root.activityData.message
|
|
||||||
width: parent.width
|
|
||||||
elide: Text.ElideRight
|
|
||||||
font.pixelSize: Style.topLinePixelSize
|
|
||||||
color: root.activityData.activityTextTitleColor
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: activityTextInfo
|
|
||||||
text: (root.activityData.type === "Sync") ? root.activityData.displayPath
|
|
||||||
: (root.activityData.type === "File") ? root.activityData.subject
|
|
||||||
: (root.activityData.type === "Notification") ? root.activityData.message
|
|
||||||
: ""
|
|
||||||
height: (text === "") ? 0 : activityTextTitle.height
|
|
||||||
width: parent.width
|
|
||||||
elide: Text.ElideRight
|
|
||||||
font.pixelSize: Style.subLinePixelSize
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: activityTextDateTime
|
|
||||||
text: root.activityData.dateTime
|
|
||||||
height: (text === "") ? 0 : activityTextTitle.height
|
|
||||||
width: parent.width
|
|
||||||
elide: Text.ElideRight
|
|
||||||
font.pixelSize: Style.subLinePixelSize
|
|
||||||
color: "#808080"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: dismissActionButton
|
|
||||||
|
|
||||||
Layout.preferredWidth: parent.height * 0.40
|
|
||||||
Layout.preferredHeight: parent.height * 0.40
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignCenter
|
|
||||||
|
|
||||||
Layout.margins: Style.roundButtonBackgroundVerticalMargins
|
|
||||||
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
|
||||||
ToolTip.text: qsTr("Dismiss")
|
|
||||||
|
|
||||||
Accessible.name: qsTr("Dismiss")
|
|
||||||
|
|
||||||
visible: root.showDismissButton && !shareButton.visible
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: "transparent"
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: Image {
|
|
||||||
anchors.fill: parent
|
|
||||||
source: parent.hovered ? "image://svgimage-custom-color/clear.svg/black" : "image://svgimage-custom-color/clear.svg/grey"
|
|
||||||
sourceSize.width: 24
|
|
||||||
sourceSize.height: 24
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: root.dismissButtonClicked()
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomButton {
|
|
||||||
id: shareButton
|
|
||||||
|
|
||||||
Layout.preferredWidth: parent.height * 0.70
|
|
||||||
Layout.preferredHeight: parent.height * 0.70
|
|
||||||
|
|
||||||
visible: root.activityData.isShareable
|
|
||||||
|
|
||||||
imageSource: "image://svgimage-custom-color/share.svg" + "/" + Style.ncBlue
|
|
||||||
imageSourceHover: "image://svgimage-custom-color/share.svg" + "/" + Style.ncTextColor
|
|
||||||
|
|
||||||
toolTipText: qsTr("Open share dialog")
|
|
||||||
|
|
||||||
bgColor: Style.ncBlue
|
|
||||||
|
|
||||||
onClicked: root.shareButtonClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import QtQml 2.15
|
|
||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.3
|
|
||||||
|
|
||||||
AutoSizingMenu {
|
|
||||||
id: moreActionsButtonContextMenu
|
|
||||||
|
|
||||||
property int maxActionButtons: 0
|
|
||||||
|
|
||||||
property var linksContextMenu: []
|
|
||||||
|
|
||||||
signal menuEntryTriggered(int index)
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
id: moreActionsButtonContextMenuRepeater
|
|
||||||
|
|
||||||
model: moreActionsButtonContextMenu.linksContextMenu
|
|
||||||
|
|
||||||
delegate: MenuItem {
|
|
||||||
id: moreActionsButtonContextMenuEntry
|
|
||||||
text: model.modelData.label
|
|
||||||
onTriggered: menuEntryTriggered(model.modelData.actionIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
|
|
||||||
|
import Style 1.0
|
||||||
|
|
||||||
import com.nextcloud.desktopclient 1.0 as NC
|
import com.nextcloud.desktopclient 1.0 as NC
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
id: controlRoot
|
id: controlRoot
|
||||||
property alias model: activityList.model
|
property alias model: activityList.model
|
||||||
|
|
||||||
property bool isFileActivityList: false
|
|
||||||
|
|
||||||
signal showFileActivity(string displayPath, string absolutePath)
|
signal showFileActivity(string displayPath, string absolutePath)
|
||||||
signal activityItemClicked(int index)
|
signal activityItemClicked(int index)
|
||||||
|
|
||||||
@@ -31,19 +31,12 @@ ScrollView {
|
|||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
delegate: ActivityItem {
|
delegate: ActivityItem {
|
||||||
isFileActivityList: controlRoot.isFileActivityList
|
|
||||||
width: activityList.contentWidth
|
width: activityList.contentWidth
|
||||||
|
height: Style.trayWindowHeaderHeight
|
||||||
flickable: activityList
|
flickable: activityList
|
||||||
onClicked: {
|
onClicked: activityItemClicked(model.index)
|
||||||
if (model.isCurrentUserFileActivity) {
|
onFileActivityButtonClicked: showFileActivity(displayPath, absolutePath)
|
||||||
showFileActivity(model.displayPath, model.absolutePath)
|
|
||||||
} else {
|
|
||||||
activityItemClicked(model.index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.3
|
|
||||||
import QtQuick.Layouts 1.2
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string imageSource: ""
|
|
||||||
property string imageSourceHover: ""
|
|
||||||
|
|
||||||
property string toolTipText: ""
|
|
||||||
|
|
||||||
property color textColor
|
|
||||||
property color textColorHovered
|
|
||||||
|
|
||||||
property color bgColor: "transparent"
|
|
||||||
|
|
||||||
property bool bold: false
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: root.bgColor
|
|
||||||
opacity: parent.hovered ? 1.0 : 0.3
|
|
||||||
radius: width / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
leftPadding: root.text === "" ? 5 : 10
|
|
||||||
rightPadding: root.text === "" ? 5 : 10
|
|
||||||
|
|
||||||
contentItem: RowLayout {
|
|
||||||
Image {
|
|
||||||
id: icon
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
|
||||||
|
|
||||||
source: root.hovered ? root.imageSourceHover : root.imageSource
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
Layout.maximumWidth: icon.width > 0 ? parent.width - icon.width - parent.spacing : parent.width
|
|
||||||
Layout.fillWidth: icon.status !== Image.Ready
|
|
||||||
|
|
||||||
text: root.text
|
|
||||||
font.bold: root.bold
|
|
||||||
|
|
||||||
visible: root.text !== ""
|
|
||||||
|
|
||||||
color: root.hovered ? root.textColorHovered : root.textColor
|
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolTip {
|
|
||||||
text: root.toolTipText
|
|
||||||
delay: Qt.styleHints.mousePressAndHoldInterval
|
|
||||||
visible: root.toolTipText !== "" && root.hovered
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
import QtQuick 2.15
|
|
||||||
import QtQuick.Controls 2.3
|
|
||||||
import Style 1.0
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string toolTipText: ""
|
|
||||||
property Action action: null
|
|
||||||
property alias acceptedButtons: mouseArea.acceptedButtons
|
|
||||||
property bool hovered: mouseArea.containsMouse
|
|
||||||
|
|
||||||
height: implicitHeight
|
|
||||||
|
|
||||||
property color textColor: Style.unifiedSearchResulTitleColor
|
|
||||||
property color textColorHovered: Style.unifiedSearchResulSublineColor
|
|
||||||
|
|
||||||
Accessible.role: Accessible.Button
|
|
||||||
Accessible.name: text
|
|
||||||
Accessible.onPressAction: root.clicked(null)
|
|
||||||
|
|
||||||
text: action ? action.text : ""
|
|
||||||
enabled: !action || action.enabled
|
|
||||||
onClicked: if (action) action.trigger()
|
|
||||||
|
|
||||||
font.underline: true
|
|
||||||
color: root.hovered ? root.textColorHovered : root.textColor
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
elide: Text.ElideRight
|
|
||||||
|
|
||||||
signal pressed(QtObject mouse)
|
|
||||||
signal clicked(QtObject mouse)
|
|
||||||
|
|
||||||
ToolTip {
|
|
||||||
text: root.toolTipText
|
|
||||||
delay: Qt.styleHints.mousePressAndHoldInterval
|
|
||||||
visible: root.toolTipText !== "" && root.hovered
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
|
|
||||||
onClicked: root.clicked(mouse)
|
|
||||||
onPressed: root.pressed(mouse)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,7 +15,6 @@ Window {
|
|||||||
height: 500
|
height: 500
|
||||||
|
|
||||||
ActivityList {
|
ActivityList {
|
||||||
isFileActivityList: true
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
model: dialog.model
|
model: dialog.model
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,12 +111,14 @@ MenuItem {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
Label {
|
Label {
|
||||||
id: emoji
|
id: emoji
|
||||||
|
height: Style.topLinePixelSize
|
||||||
visible: model.statusEmoji !== ""
|
visible: model.statusEmoji !== ""
|
||||||
text: statusEmoji
|
text: statusEmoji
|
||||||
topPadding: -Style.accountLabelsSpacing
|
topPadding: -Style.accountLabelsSpacing
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
id: message
|
id: message
|
||||||
|
height: Style.topLinePixelSize
|
||||||
width: parent.width - parent.spacing - emoji.width
|
width: parent.width - parent.spacing - emoji.width
|
||||||
visible: model.statusMessage !== ""
|
visible: model.statusMessage !== ""
|
||||||
text: statusMessage
|
text: statusMessage
|
||||||
@@ -167,8 +169,9 @@ MenuItem {
|
|||||||
y: userMoreButton.y + 1
|
y: userMoreButton.y + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoSizingMenu {
|
Menu {
|
||||||
id: userMoreButtonMenu
|
id: userMoreButtonMenu
|
||||||
|
width: 120
|
||||||
closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape
|
closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
|
|||||||
@@ -174,22 +174,6 @@ Window {
|
|||||||
radius: Style.currentAccountButtonRadius
|
radius: Style.currentAccountButtonRadius
|
||||||
}
|
}
|
||||||
|
|
||||||
contentItem: ScrollView {
|
|
||||||
id: accMenuScrollView
|
|
||||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
|
||||||
|
|
||||||
data: WheelHandler {
|
|
||||||
target: accMenuScrollView.contentItem
|
|
||||||
}
|
|
||||||
ListView {
|
|
||||||
implicitHeight: contentHeight
|
|
||||||
model: accountMenu.contentModel
|
|
||||||
interactive: true
|
|
||||||
clip: true
|
|
||||||
currentIndex: accountMenu.currentIndex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onClosed: {
|
onClosed: {
|
||||||
// HACK: reload account Instantiator immediately by restting it - could be done better I guess
|
// HACK: reload account Instantiator immediately by restting it - could be done better I guess
|
||||||
// see also onVisibleChanged above
|
// see also onVisibleChanged above
|
||||||
@@ -748,7 +732,7 @@ Window {
|
|||||||
openFileActivityDialog(displayPath, absolutePath)
|
openFileActivityDialog(displayPath, absolutePath)
|
||||||
}
|
}
|
||||||
onActivityItemClicked: {
|
onActivityItemClicked: {
|
||||||
model.slotTriggerDefaultAction(index)
|
model.triggerDefaultAction(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,15 +33,4 @@ Activity::Identifier Activity::ident() const
|
|||||||
{
|
{
|
||||||
return Identifier(_id, _accName);
|
return Identifier(_id, _accName);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivityLink ActivityLink::createFomJsonObject(const QJsonObject &obj)
|
|
||||||
{
|
|
||||||
ActivityLink activityLink;
|
|
||||||
activityLink._label = QUrl::fromPercentEncoding(obj.value(QStringLiteral("label")).toString().toUtf8());
|
|
||||||
activityLink._link = obj.value(QStringLiteral("link")).toString();
|
|
||||||
activityLink._verb = obj.value(QStringLiteral("type")).toString().toUtf8();
|
|
||||||
activityLink._primary = obj.value(QStringLiteral("primary")).toBool();
|
|
||||||
|
|
||||||
return activityLink;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
/**
|
/**
|
||||||
@@ -29,20 +28,13 @@ namespace OCC {
|
|||||||
class ActivityLink
|
class ActivityLink
|
||||||
{
|
{
|
||||||
Q_GADGET
|
Q_GADGET
|
||||||
|
|
||||||
Q_PROPERTY(QString imageSource MEMBER _imageSource)
|
|
||||||
Q_PROPERTY(QString imageSourceHovered MEMBER _imageSourceHovered)
|
|
||||||
Q_PROPERTY(QString label MEMBER _label)
|
Q_PROPERTY(QString label MEMBER _label)
|
||||||
Q_PROPERTY(QString link MEMBER _link)
|
Q_PROPERTY(QString link MEMBER _link)
|
||||||
Q_PROPERTY(QByteArray verb MEMBER _verb)
|
Q_PROPERTY(QByteArray verb MEMBER _verb)
|
||||||
Q_PROPERTY(bool primary MEMBER _primary)
|
Q_PROPERTY(bool primary MEMBER _primary)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ActivityLink createFomJsonObject(const QJsonObject &obj);
|
|
||||||
|
|
||||||
public:
|
|
||||||
QString _imageSource;
|
|
||||||
QString _imageSourceHovered;
|
|
||||||
QString _label;
|
QString _label;
|
||||||
QString _link;
|
QString _link;
|
||||||
QByteArray _verb;
|
QByteArray _verb;
|
||||||
@@ -88,13 +80,11 @@ public:
|
|||||||
QString _message;
|
QString _message;
|
||||||
QString _folder;
|
QString _folder;
|
||||||
QString _file;
|
QString _file;
|
||||||
QString _renamedFile;
|
|
||||||
QUrl _link;
|
QUrl _link;
|
||||||
QDateTime _dateTime;
|
QDateTime _dateTime;
|
||||||
qint64 _expireAtMsecs = -1;
|
qint64 _expireAtMsecs = -1;
|
||||||
QString _accName;
|
QString _accName;
|
||||||
QString _icon;
|
QString _icon;
|
||||||
bool _isCurrentUserFileActivity = false;
|
|
||||||
|
|
||||||
// Stores information about the error
|
// Stores information about the error
|
||||||
int _status;
|
int _status;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ ActivityListModel::ActivityListModel(AccountState *accountState,
|
|||||||
|
|
||||||
QHash<int, QByteArray> ActivityListModel::roleNames() const
|
QHash<int, QByteArray> ActivityListModel::roleNames() const
|
||||||
{
|
{
|
||||||
auto roles = QAbstractListModel::roleNames();
|
QHash<int, QByteArray> roles;
|
||||||
roles[DisplayPathRole] = "displayPath";
|
roles[DisplayPathRole] = "displayPath";
|
||||||
roles[PathRole] = "path";
|
roles[PathRole] = "path";
|
||||||
roles[AbsolutePathRole] = "absolutePath";
|
roles[AbsolutePathRole] = "absolutePath";
|
||||||
@@ -65,14 +65,11 @@ QHash<int, QByteArray> ActivityListModel::roleNames() const
|
|||||||
roles[ActionIconRole] = "icon";
|
roles[ActionIconRole] = "icon";
|
||||||
roles[ActionTextRole] = "subject";
|
roles[ActionTextRole] = "subject";
|
||||||
roles[ActionsLinksRole] = "links";
|
roles[ActionsLinksRole] = "links";
|
||||||
roles[ActionsLinksContextMenuRole] = "linksContextMenu";
|
|
||||||
roles[ActionsLinksForActionButtonsRole] = "linksForActionButtons";
|
|
||||||
roles[ActionTextColorRole] = "activityTextTitleColor";
|
roles[ActionTextColorRole] = "activityTextTitleColor";
|
||||||
roles[ObjectTypeRole] = "objectType";
|
roles[ObjectTypeRole] = "objectType";
|
||||||
roles[PointInTimeRole] = "dateTime";
|
roles[PointInTimeRole] = "dateTime";
|
||||||
roles[DisplayActions] = "displayActions";
|
roles[DisplayActions] = "displayActions";
|
||||||
roles[ShareableRole] = "isShareable";
|
roles[ShareableRole] = "isShareable";
|
||||||
roles[IsCurrentUserFileActivityRole] = "isCurrentUserFileActivity";
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,11 +78,6 @@ void ActivityListModel::setAccountState(AccountState *state)
|
|||||||
_accountState = state;
|
_accountState = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityListModel::setCurrentItem(const int currentItem)
|
|
||||||
{
|
|
||||||
_currentItem = currentItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivityListModel::setCurrentlyFetching(bool value)
|
void ActivityListModel::setCurrentlyFetching(bool value)
|
||||||
{
|
{
|
||||||
_currentlyFetching = value;
|
_currentlyFetching = value;
|
||||||
@@ -124,11 +116,10 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
const auto getFilePath = [&]() {
|
const auto getFilePath = [&]() {
|
||||||
const auto fileName = a._fileAction == QStringLiteral("file_renamed") ? a._renamedFile : a._file;
|
if (!a._file.isEmpty()) {
|
||||||
if (!fileName.isEmpty()) {
|
|
||||||
const auto folder = FolderMan::instance()->folder(a._folder);
|
const auto folder = FolderMan::instance()->folder(a._folder);
|
||||||
|
|
||||||
const QString relPath = folder ? folder->remotePath() + fileName : fileName;
|
const QString relPath = folder ? folder->remotePath() + a._file : a._file;
|
||||||
|
|
||||||
const auto localFiles = FolderMan::instance()->findFileInLocalFolders(relPath, ast->account());
|
const auto localFiles = FolderMan::instance()->findFileInLocalFolders(relPath, ast->account());
|
||||||
|
|
||||||
@@ -139,7 +130,7 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
|||||||
// If this is an E2EE file or folder, pretend we got no path, hiding the share button which is what we want
|
// If this is an E2EE file or folder, pretend we got no path, hiding the share button which is what we want
|
||||||
if (folder) {
|
if (folder) {
|
||||||
SyncJournalFileRecord rec;
|
SyncJournalFileRecord rec;
|
||||||
folder->journalDb()->getFileRecord(fileName.mid(1), &rec);
|
folder->journalDb()->getFileRecord(a._file.mid(1), &rec);
|
||||||
if (rec.isValid() && (rec._isE2eEncrypted || !rec._e2eMangledName.isEmpty())) {
|
if (rec.isValid() && (rec._isE2eEncrypted || !rec._e2eMangledName.isEmpty())) {
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
@@ -178,7 +169,7 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
|||||||
case DisplayPathRole:
|
case DisplayPathRole:
|
||||||
return getDisplayPath();
|
return getDisplayPath();
|
||||||
case PathRole:
|
case PathRole:
|
||||||
return QFileInfo(getFilePath()).path();
|
return QUrl::fromLocalFile(QFileInfo(getFilePath()).path());
|
||||||
case AbsolutePathRole:
|
case AbsolutePathRole:
|
||||||
return getFilePath();
|
return getFilePath();
|
||||||
case DisplayLocationRole:
|
case DisplayLocationRole:
|
||||||
@@ -190,15 +181,6 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
|||||||
}
|
}
|
||||||
return customList;
|
return customList;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ActionsLinksContextMenuRole: {
|
|
||||||
return ActivityListModel::convertLinksToMenuEntries(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
case ActionsLinksForActionButtonsRole: {
|
|
||||||
return ActivityListModel::convertLinksToActionButtons(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
case ActionIconRole: {
|
case ActionIconRole: {
|
||||||
if (a._type == Activity::NotificationType) {
|
if (a._type == Activity::NotificationType) {
|
||||||
return "qrc:///client/theme/black/bell.svg";
|
return "qrc:///client/theme/black/bell.svg";
|
||||||
@@ -267,7 +249,7 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
|||||||
if (a._link.isEmpty()) {
|
if (a._link.isEmpty()) {
|
||||||
return "";
|
return "";
|
||||||
} else {
|
} else {
|
||||||
return a._link.toString();
|
return a._link;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case AccountRole:
|
case AccountRole:
|
||||||
@@ -280,21 +262,15 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const
|
|||||||
case DisplayActions:
|
case DisplayActions:
|
||||||
return _displayActions;
|
return _displayActions;
|
||||||
case ShareableRole:
|
case ShareableRole:
|
||||||
return !data(index, PathRole).toString().isEmpty() && a._objectType == QStringLiteral("files") && _displayActions && a._fileAction != "file_deleted" && a._status != SyncFileItem::FileIgnored;
|
return !data(index, PathRole).toString().isEmpty() && _displayActions && a._fileAction != "file_deleted" && a._status != SyncFileItem::FileIgnored;
|
||||||
case IsCurrentUserFileActivityRole:
|
|
||||||
return a._isCurrentUserFileActivity;
|
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ActivityListModel::rowCount(const QModelIndex &parent) const
|
int ActivityListModel::rowCount(const QModelIndex &) const
|
||||||
{
|
{
|
||||||
if(parent.isValid()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _finalList.count();
|
return _finalList.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,21 +306,6 @@ void ActivityListModel::startFetchJob()
|
|||||||
job->start();
|
job->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityListModel::setFinalList(const ActivityList &finalList)
|
|
||||||
{
|
|
||||||
_finalList = finalList;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ActivityList &ActivityListModel::finalList() const
|
|
||||||
{
|
|
||||||
return _finalList;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ActivityListModel::currentItem() const
|
|
||||||
{
|
|
||||||
return _currentItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivityListModel::activitiesReceived(const QJsonDocument &json, int statusCode)
|
void ActivityListModel::activitiesReceived(const QJsonDocument &json, int statusCode)
|
||||||
{
|
{
|
||||||
auto activities = json.object().value("ocs").toObject().value("data").toArray();
|
auto activities = json.object().value("ocs").toObject().value("data").toArray();
|
||||||
@@ -368,7 +329,6 @@ void ActivityListModel::activitiesReceived(const QJsonDocument &json, int status
|
|||||||
auto json = activ.toObject();
|
auto json = activ.toObject();
|
||||||
|
|
||||||
Activity a;
|
Activity a;
|
||||||
const auto activityUser = json.value(QStringLiteral("user")).toString();
|
|
||||||
a._type = Activity::ActivityType;
|
a._type = Activity::ActivityType;
|
||||||
a._objectType = json.value(QStringLiteral("object_type")).toString();
|
a._objectType = json.value(QStringLiteral("object_type")).toString();
|
||||||
a._accName = ast->account()->displayName();
|
a._accName = ast->account()->displayName();
|
||||||
@@ -380,9 +340,9 @@ void ActivityListModel::activitiesReceived(const QJsonDocument &json, int status
|
|||||||
a._link = QUrl(json.value(QStringLiteral("link")).toString());
|
a._link = QUrl(json.value(QStringLiteral("link")).toString());
|
||||||
a._dateTime = QDateTime::fromString(json.value(QStringLiteral("datetime")).toString(), Qt::ISODate);
|
a._dateTime = QDateTime::fromString(json.value(QStringLiteral("datetime")).toString(), Qt::ISODate);
|
||||||
a._icon = json.value(QStringLiteral("icon")).toString();
|
a._icon = json.value(QStringLiteral("icon")).toString();
|
||||||
a._isCurrentUserFileActivity = a._objectType == QStringLiteral("files") && activityUser == ast->account()->davUser();
|
|
||||||
|
|
||||||
auto richSubjectData = json.value(QStringLiteral("subject_rich")).toArray();
|
auto richSubjectData = json.value(QStringLiteral("subject_rich")).toArray();
|
||||||
|
Q_ASSERT(richSubjectData.size() > 1);
|
||||||
|
|
||||||
if(richSubjectData.size() > 1) {
|
if(richSubjectData.size() > 1) {
|
||||||
a._subjectRich = richSubjectData[0].toString();
|
a._subjectRich = richSubjectData[0].toString();
|
||||||
@@ -432,9 +392,9 @@ void ActivityListModel::activitiesReceived(const QJsonDocument &json, int status
|
|||||||
|
|
||||||
_activityLists.append(list);
|
_activityLists.append(list);
|
||||||
|
|
||||||
combineActivityLists();
|
|
||||||
|
|
||||||
emit activityJobStatusCode(statusCode);
|
emit activityJobStatusCode(statusCode);
|
||||||
|
|
||||||
|
combineActivityLists();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityListModel::addErrorToActivityList(Activity activity)
|
void ActivityListModel::addErrorToActivityList(Activity activity)
|
||||||
@@ -523,7 +483,7 @@ void ActivityListModel::removeActivityFromActivityList(Activity activity)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityListModel::slotTriggerDefaultAction(const int activityIndex)
|
void ActivityListModel::triggerDefaultAction(int activityIndex)
|
||||||
{
|
{
|
||||||
if (activityIndex < 0 || activityIndex >= _finalList.size()) {
|
if (activityIndex < 0 || activityIndex >= _finalList.size()) {
|
||||||
qCWarning(lcActivity) << "Couldn't trigger default action at index" << activityIndex << "/ final list size:" << _finalList.size();
|
qCWarning(lcActivity) << "Couldn't trigger default action at index" << activityIndex << "/ final list size:" << _finalList.size();
|
||||||
@@ -531,7 +491,7 @@ void ActivityListModel::slotTriggerDefaultAction(const int activityIndex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto modelIndex = index(activityIndex);
|
const auto modelIndex = index(activityIndex);
|
||||||
const auto path = data(modelIndex, PathRole).toString();
|
const auto path = data(modelIndex, PathRole).toUrl();
|
||||||
|
|
||||||
const auto activity = _finalList.at(activityIndex);
|
const auto activity = _finalList.at(activityIndex);
|
||||||
if (activity._status == SyncFileItem::Conflict) {
|
if (activity._status == SyncFileItem::Conflict) {
|
||||||
@@ -581,15 +541,15 @@ void ActivityListModel::slotTriggerDefaultAction(const int activityIndex)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path.isEmpty()) {
|
if (path.isValid()) {
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
QDesktopServices::openUrl(path);
|
||||||
} else {
|
} else {
|
||||||
const auto link = data(modelIndex, LinkRole).toUrl();
|
const auto link = data(modelIndex, LinkRole).toUrl();
|
||||||
Utility::openBrowser(link);
|
Utility::openBrowser(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityListModel::slotTriggerAction(const int activityIndex, const int actionIndex)
|
void ActivityListModel::triggerAction(int activityIndex, int actionIndex)
|
||||||
{
|
{
|
||||||
if (activityIndex < 0 || activityIndex >= _finalList.size()) {
|
if (activityIndex < 0 || activityIndex >= _finalList.size()) {
|
||||||
qCWarning(lcActivity) << "Couldn't trigger action on activity at index" << activityIndex << "/ final list size:" << _finalList.size();
|
qCWarning(lcActivity) << "Couldn't trigger action on activity at index" << activityIndex << "/ final list size:" << _finalList.size();
|
||||||
@@ -613,112 +573,11 @@ void ActivityListModel::slotTriggerAction(const int activityIndex, const int act
|
|||||||
emit sendNotificationRequest(activity._accName, action._link, action._verb, activityIndex);
|
emit sendNotificationRequest(activity._accName, action._link, action._verb, activityIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActivityListModel::slotTriggerDismiss(const int activityIndex)
|
|
||||||
{
|
|
||||||
if (activityIndex < 0 || activityIndex >= _finalList.size()) {
|
|
||||||
qCWarning(lcActivity) << "Couldn't trigger action on activity at index" << activityIndex << "/ final list size:" << _finalList.size();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto activityLinks = _finalList[activityIndex]._links;
|
|
||||||
|
|
||||||
const auto foundActivityLinkIt = std::find_if(std::cbegin(activityLinks), std::cend(activityLinks), [](const ActivityLink &link) {
|
|
||||||
return link._verb == QStringLiteral("DELETE");
|
|
||||||
});
|
|
||||||
|
|
||||||
if (foundActivityLinkIt == std::cend(activityLinks)) {
|
|
||||||
qCWarning(lcActivity) << "Couldn't find dismiss action in activity at index" << activityIndex
|
|
||||||
<< " links.size() " << activityLinks.size();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto actionIndex = static_cast<int>(std::distance(activityLinks.begin(), foundActivityLinkIt));
|
|
||||||
|
|
||||||
if (actionIndex < 0 || actionIndex > activityLinks.size()) {
|
|
||||||
qCWarning(lcActivity) << "Couldn't find dismiss action in activity at index" << activityIndex
|
|
||||||
<< " actionIndex found " << actionIndex;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
slotTriggerAction(activityIndex, actionIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountState *ActivityListModel::accountState() const
|
AccountState *ActivityListModel::accountState() const
|
||||||
{
|
{
|
||||||
return _accountState;
|
return _accountState;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantList ActivityListModel::convertLinksToActionButtons(const Activity &activity)
|
|
||||||
{
|
|
||||||
QVariantList customList;
|
|
||||||
|
|
||||||
if (activity._links.size() == 1) {
|
|
||||||
return customList;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (static_cast<quint32>(activity._links.size()) > maxActionButtons()) {
|
|
||||||
customList << ActivityListModel::convertLinkToActionButton(activity, activity._links.first());
|
|
||||||
return customList;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &activityLink : activity._links) {
|
|
||||||
if (activityLink._verb == QStringLiteral("DELETE")
|
|
||||||
|| (activity._objectType == QStringLiteral("chat") || activity._objectType == QStringLiteral("call")
|
|
||||||
|| activity._objectType == QStringLiteral("room"))) {
|
|
||||||
customList << ActivityListModel::convertLinkToActionButton(activity, activityLink);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return customList;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant ActivityListModel::convertLinkToActionButton(const OCC::Activity &activity, const OCC::ActivityLink &activityLink)
|
|
||||||
{
|
|
||||||
auto activityLinkCopy = activityLink;
|
|
||||||
|
|
||||||
const auto isReplyIconApplicable = activityLink._verb == QStringLiteral("WEB")
|
|
||||||
&& (activity._objectType == QStringLiteral("chat") || activity._objectType == QStringLiteral("call")
|
|
||||||
|| activity._objectType == QStringLiteral("room"));
|
|
||||||
|
|
||||||
const QString replyButtonPath = QStringLiteral("image://svgimage-custom-color/reply.svg");
|
|
||||||
|
|
||||||
if (isReplyIconApplicable) {
|
|
||||||
activityLinkCopy._imageSource =
|
|
||||||
QString(replyButtonPath + "/" + OCC::Theme::instance()->wizardHeaderBackgroundColor().name());
|
|
||||||
activityLinkCopy._imageSourceHovered =
|
|
||||||
QString(replyButtonPath + "/" + OCC::Theme::instance()->wizardHeaderTitleColor().name());
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto isReplyLabelApplicable = activityLink._verb == QStringLiteral("WEB")
|
|
||||||
&& (activity._objectType == QStringLiteral("chat")
|
|
||||||
|| (activity._objectType != QStringLiteral("room") && activity._objectType != QStringLiteral("call")));
|
|
||||||
|
|
||||||
if (activityLink._verb == QStringLiteral("DELETE")) {
|
|
||||||
activityLinkCopy._label = QObject::tr("Mark as read");
|
|
||||||
} else if (isReplyLabelApplicable) {
|
|
||||||
activityLinkCopy._label = QObject::tr("Reply");
|
|
||||||
}
|
|
||||||
|
|
||||||
return QVariant::fromValue(activityLinkCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariantList ActivityListModel::convertLinksToMenuEntries(const Activity &activity)
|
|
||||||
{
|
|
||||||
QVariantList customList;
|
|
||||||
|
|
||||||
if (static_cast<quint32>(activity._links.size()) > maxActionButtons()) {
|
|
||||||
for (int i = 0; i < activity._links.size(); ++i) {
|
|
||||||
const auto &activityLink = activity._links[i];
|
|
||||||
if (!activityLink._primary) {
|
|
||||||
customList << QVariantMap{
|
|
||||||
{QStringLiteral("actionIndex"), i}, {QStringLiteral("label"), activityLink._label}};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return customList;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActivityListModel::combineActivityLists()
|
void ActivityListModel::combineActivityLists()
|
||||||
{
|
{
|
||||||
ActivityList resultList;
|
ActivityList resultList;
|
||||||
@@ -762,8 +621,14 @@ void ActivityListModel::combineActivityLists()
|
|||||||
}
|
}
|
||||||
|
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
_finalList = resultList;
|
_finalList.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
|
||||||
|
if (resultList.count() > 0) {
|
||||||
|
beginInsertRows(QModelIndex(), 0, resultList.count() - 1);
|
||||||
|
_finalList = resultList;
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ActivityListModel::canFetchActivities() const
|
bool ActivityListModel::canFetchActivities() const
|
||||||
@@ -773,8 +638,11 @@ bool ActivityListModel::canFetchActivities() const
|
|||||||
|
|
||||||
void ActivityListModel::fetchMore(const QModelIndex &)
|
void ActivityListModel::fetchMore(const QModelIndex &)
|
||||||
{
|
{
|
||||||
if (canFetchActivities() && !_currentlyFetching) {
|
if (canFetchActivities()) {
|
||||||
startFetchJob();
|
startFetchJob();
|
||||||
|
} else {
|
||||||
|
_doneFetching = true;
|
||||||
|
combineActivityLists();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,6 +672,4 @@ void ActivityListModel::slotRemoveAccount()
|
|||||||
_totalActivitiesFetched = 0;
|
_totalActivitiesFetched = 0;
|
||||||
_showMoreActivitiesAvailableEntry = false;
|
_showMoreActivitiesAvailableEntry = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,17 +40,14 @@ class ActivityListModel : public QAbstractListModel
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(quint32 maxActionButtons READ maxActionButtons CONSTANT)
|
|
||||||
|
|
||||||
Q_PROPERTY(AccountState *accountState READ accountState CONSTANT)
|
Q_PROPERTY(AccountState *accountState READ accountState CONSTANT)
|
||||||
public:
|
public:
|
||||||
enum DataRole {
|
enum DataRole {
|
||||||
ActionIconRole = Qt::UserRole + 1,
|
ActionIconRole = Qt::UserRole + 1,
|
||||||
|
UserIconRole,
|
||||||
AccountRole,
|
AccountRole,
|
||||||
ObjectTypeRole,
|
ObjectTypeRole,
|
||||||
ActionsLinksRole,
|
ActionsLinksRole,
|
||||||
ActionsLinksContextMenuRole,
|
|
||||||
ActionsLinksForActionButtonsRole,
|
|
||||||
ActionTextRole,
|
ActionTextRole,
|
||||||
ActionTextColorRole,
|
ActionTextColorRole,
|
||||||
ActionRole,
|
ActionRole,
|
||||||
@@ -62,9 +59,9 @@ public:
|
|||||||
LinkRole,
|
LinkRole,
|
||||||
PointInTimeRole,
|
PointInTimeRole,
|
||||||
AccountConnectedRole,
|
AccountConnectedRole,
|
||||||
|
SyncFileStatusRole,
|
||||||
DisplayActions,
|
DisplayActions,
|
||||||
ShareableRole,
|
ShareableRole,
|
||||||
IsCurrentUserFileActivityRole,
|
|
||||||
};
|
};
|
||||||
Q_ENUM(DataRole)
|
Q_ENUM(DataRole)
|
||||||
|
|
||||||
@@ -89,22 +86,14 @@ public:
|
|||||||
void removeActivityFromActivityList(int row);
|
void removeActivityFromActivityList(int row);
|
||||||
void removeActivityFromActivityList(Activity activity);
|
void removeActivityFromActivityList(Activity activity);
|
||||||
|
|
||||||
|
Q_INVOKABLE void triggerDefaultAction(int activityIndex);
|
||||||
|
Q_INVOKABLE void triggerAction(int activityIndex, int actionIndex);
|
||||||
|
|
||||||
AccountState *accountState() const;
|
AccountState *accountState() const;
|
||||||
void setAccountState(AccountState *state);
|
|
||||||
|
|
||||||
static constexpr quint32 maxActionButtons()
|
|
||||||
{
|
|
||||||
return MaxActionButtons;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCurrentItem(const int currentItem);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void slotRefreshActivity();
|
void slotRefreshActivity();
|
||||||
void slotRemoveAccount();
|
void slotRemoveAccount();
|
||||||
void slotTriggerDefaultAction(const int activityIndex);
|
|
||||||
void slotTriggerAction(const int activityIndex, const int actionIndex);
|
|
||||||
void slotTriggerDismiss(const int activityIndex);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void activityJobStatusCode(int statusCode);
|
void activityJobStatusCode(int statusCode);
|
||||||
@@ -114,6 +103,7 @@ protected:
|
|||||||
void activitiesReceived(const QJsonDocument &json, int statusCode);
|
void activitiesReceived(const QJsonDocument &json, int statusCode);
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
void setAccountState(AccountState *state);
|
||||||
void setCurrentlyFetching(bool value);
|
void setCurrentlyFetching(bool value);
|
||||||
bool currentlyFetching() const;
|
bool currentlyFetching() const;
|
||||||
void setDoneFetching(bool value);
|
void setDoneFetching(bool value);
|
||||||
@@ -122,16 +112,7 @@ protected:
|
|||||||
|
|
||||||
virtual void startFetchJob();
|
virtual void startFetchJob();
|
||||||
|
|
||||||
// added these for unit tests
|
|
||||||
void setFinalList(const ActivityList &finalList);
|
|
||||||
const ActivityList &finalList() const;
|
|
||||||
int currentItem() const;
|
|
||||||
//
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QVariantList convertLinksToMenuEntries(const Activity &activity);
|
|
||||||
static QVariantList convertLinksToActionButtons(const Activity &activity);
|
|
||||||
static QVariant convertLinkToActionButton(const Activity &activity, const ActivityLink &activityLink);
|
|
||||||
void combineActivityLists();
|
void combineActivityLists();
|
||||||
bool canFetchActivities() const;
|
bool canFetchActivities() const;
|
||||||
|
|
||||||
@@ -158,8 +139,6 @@ private:
|
|||||||
bool _currentlyFetching = false;
|
bool _currentlyFetching = false;
|
||||||
bool _doneFetching = false;
|
bool _doneFetching = false;
|
||||||
bool _hideOldActivities = true;
|
bool _hideOldActivities = true;
|
||||||
|
|
||||||
static constexpr quint32 MaxActionButtons = 2;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,14 @@ void ServerNotificationHandler::slotNotificationsReceived(const QJsonDocument &j
|
|||||||
|
|
||||||
auto actions = json.value("actions").toArray();
|
auto actions = json.value("actions").toArray();
|
||||||
foreach (auto action, actions) {
|
foreach (auto action, actions) {
|
||||||
a._links.append(ActivityLink::createFomJsonObject(action.toObject()));
|
auto actionJson = action.toObject();
|
||||||
|
ActivityLink al;
|
||||||
|
al._label = QUrl::fromPercentEncoding(actionJson.value("label").toString().toUtf8());
|
||||||
|
al._link = actionJson.value("link").toString();
|
||||||
|
al._verb = actionJson.value("type").toString().toUtf8();
|
||||||
|
al._primary = actionJson.value("primary").toBool();
|
||||||
|
|
||||||
|
a._links.append(al);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add another action to dismiss notification on server
|
// Add another action to dismiss notification on server
|
||||||
|
|||||||
@@ -514,7 +514,6 @@ void User::processCompletedSyncItem(const Folder *folder, const SyncFileItemPtr
|
|||||||
activity._fileAction = "file_created";
|
activity._fileAction = "file_created";
|
||||||
} else if (item->_instruction == CSYNC_INSTRUCTION_RENAME) {
|
} else if (item->_instruction == CSYNC_INSTRUCTION_RENAME) {
|
||||||
activity._fileAction = "file_renamed";
|
activity._fileAction = "file_renamed";
|
||||||
activity._renamedFile = item->_renameTarget;
|
|
||||||
} else {
|
} else {
|
||||||
activity._fileAction = "file_changed";
|
activity._fileAction = "file_changed";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,8 +57,7 @@ using namespace QKeychain;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr int pushNotificationsReconnectInterval = 1000 * 60 * 2;
|
constexpr int pushNotificationsReconnectInterval = 1000 * 60 * 2;
|
||||||
constexpr int usernamePrefillServerVersionMinSupportedMajor = 24;
|
constexpr int usernamePrefillServerVersinMinSupportedMajor = 24;
|
||||||
constexpr int checksumRecalculateRequestServerVersionMinSupportedMajor = 24;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
@@ -633,17 +632,7 @@ bool Account::serverVersionUnsupported() const
|
|||||||
|
|
||||||
bool Account::isUsernamePrefillSupported() const
|
bool Account::isUsernamePrefillSupported() const
|
||||||
{
|
{
|
||||||
return serverVersionInt() >= makeServerVersion(usernamePrefillServerVersionMinSupportedMajor, 0, 0);
|
return serverVersionInt() >= makeServerVersion(usernamePrefillServerVersinMinSupportedMajor, 0, 0);
|
||||||
}
|
|
||||||
|
|
||||||
bool Account::isChecksumRecalculateRequestSupported() const
|
|
||||||
{
|
|
||||||
return serverVersionInt() >= makeServerVersion(checksumRecalculateRequestServerVersionMinSupportedMajor, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Account::checksumRecalculateServerVersionMinSupportedMajor() const
|
|
||||||
{
|
|
||||||
return checksumRecalculateRequestServerVersionMinSupportedMajor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::setServerVersion(const QString &version)
|
void Account::setServerVersion(const QString &version)
|
||||||
|
|||||||
@@ -232,10 +232,6 @@ public:
|
|||||||
|
|
||||||
bool isUsernamePrefillSupported() const;
|
bool isUsernamePrefillSupported() const;
|
||||||
|
|
||||||
bool isChecksumRecalculateRequestSupported() const;
|
|
||||||
|
|
||||||
int checksumRecalculateServerVersionMinSupportedMajor() const;
|
|
||||||
|
|
||||||
/** True when the server connection is using HTTP2 */
|
/** True when the server connection is using HTTP2 */
|
||||||
bool isHttp2Supported() { return _http2Supported; }
|
bool isHttp2Supported() { return _http2Supported; }
|
||||||
void setHttp2Supported(bool value) { _http2Supported = value; }
|
void setHttp2Supported(bool value) { _http2Supported = value; }
|
||||||
|
|||||||
@@ -290,10 +290,7 @@ void BulkPropagatorJob::slotStartUpload(SyncFileItemPtr item,
|
|||||||
const QString originalFilePath = propagator()->fullLocalPath(item->_file);
|
const QString originalFilePath = propagator()->fullLocalPath(item->_file);
|
||||||
|
|
||||||
if (!FileSystem::fileExists(fullFilePath)) {
|
if (!FileSystem::fileExists(fullFilePath)) {
|
||||||
_pendingChecksumFiles.remove(item->_file);
|
return slotOnErrorStartFolderUnlock(item, SyncFileItem::SoftError, tr("File Removed (start upload) %1").arg(fullFilePath));
|
||||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::SoftError, tr("File Removed (start upload) %1").arg(fullFilePath));
|
|
||||||
checkPropagationIsDone();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const time_t prevModtime = item->_modtime; // the _item value was set in PropagateUploadFile::start()
|
const time_t prevModtime = item->_modtime; // the _item value was set in PropagateUploadFile::start()
|
||||||
// but a potential checksum calculation could have taken some time during which the file could
|
// but a potential checksum calculation could have taken some time during which the file could
|
||||||
@@ -302,7 +299,7 @@ void BulkPropagatorJob::slotStartUpload(SyncFileItemPtr item,
|
|||||||
item->_modtime = FileSystem::getModTime(originalFilePath);
|
item->_modtime = FileSystem::getModTime(originalFilePath);
|
||||||
if (item->_modtime <= 0) {
|
if (item->_modtime <= 0) {
|
||||||
_pendingChecksumFiles.remove(item->_file);
|
_pendingChecksumFiles.remove(item->_file);
|
||||||
slotOnErrorStartFolderUnlock(item, SyncFileItem::NormalError, tr("File %1 has invalid modification time. Do not upload to the server.").arg(QDir::toNativeSeparators(item->_file)));
|
slotOnErrorStartFolderUnlock(item, SyncFileItem::NormalError, tr("File %1 has invalid modified time. Do not upload to the server.").arg(QDir::toNativeSeparators(item->_file)));
|
||||||
checkPropagationIsDone();
|
checkPropagationIsDone();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ namespace OCC {
|
|||||||
Q_LOGGING_CATEGORY(lcDeleteJob, "nextcloud.sync.networkjob.delete", QtInfoMsg)
|
Q_LOGGING_CATEGORY(lcDeleteJob, "nextcloud.sync.networkjob.delete", QtInfoMsg)
|
||||||
|
|
||||||
DeleteJob::DeleteJob(AccountPtr account, const QString &path, QObject *parent)
|
DeleteJob::DeleteJob(AccountPtr account, const QString &path, QObject *parent)
|
||||||
: SimpleFileJob(account, path, parent)
|
: AbstractNetworkJob(account, path, parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteJob::DeleteJob(AccountPtr account, const QUrl &url, QObject *parent)
|
DeleteJob::DeleteJob(AccountPtr account, const QUrl &url, QObject *parent)
|
||||||
: SimpleFileJob(account, QString(), parent)
|
: AbstractNetworkJob(account, QString(), parent)
|
||||||
, _url(url)
|
, _url(url)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -39,10 +39,24 @@ void DeleteJob::start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_url.isValid()) {
|
if (_url.isValid()) {
|
||||||
startRequest("DELETE", _url, req);
|
sendRequest("DELETE", _url, req);
|
||||||
} else {
|
} else {
|
||||||
startRequest("DELETE", req);
|
sendRequest("DELETE", makeDavUrl(path()), req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reply()->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(lcDeleteJob) << " Network error: " << reply()->errorString();
|
||||||
|
}
|
||||||
|
AbstractNetworkJob::start();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeleteJob::finished()
|
||||||
|
{
|
||||||
|
qCInfo(lcDeleteJob) << "DELETE of" << reply()->request().url() << "FINISHED WITH STATUS"
|
||||||
|
<< replyStatusString();
|
||||||
|
|
||||||
|
emit finishedSignal();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray DeleteJob::folderToken() const
|
QByteArray DeleteJob::folderToken() const
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace OCC {
|
|||||||
* @brief The DeleteJob class
|
* @brief The DeleteJob class
|
||||||
* @ingroup libsync
|
* @ingroup libsync
|
||||||
*/
|
*/
|
||||||
class DeleteJob : public SimpleFileJob
|
class DeleteJob : public AbstractNetworkJob
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@@ -31,10 +31,14 @@ public:
|
|||||||
explicit DeleteJob(AccountPtr account, const QUrl &url, QObject *parent = nullptr);
|
explicit DeleteJob(AccountPtr account, const QUrl &url, QObject *parent = nullptr);
|
||||||
|
|
||||||
void start() override;
|
void start() override;
|
||||||
|
bool finished() override;
|
||||||
|
|
||||||
QByteArray folderToken() const;
|
QByteArray folderToken() const;
|
||||||
void setFolderToken(const QByteArray &folderToken);
|
void setFolderToken(const QByteArray &folderToken);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finishedSignal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUrl _url; // Only used if the constructor taking a url is taken.
|
QUrl _url; // Only used if the constructor taking a url is taken.
|
||||||
QByteArray _folderToken;
|
QByteArray _folderToken;
|
||||||
|
|||||||
@@ -186,8 +186,8 @@ QPair<bool, QByteArray> DiscoveryPhase::findAndCancelDeletedJob(const QString &o
|
|||||||
qCWarning(lcDiscovery) << "(*it)->_type" << (*it)->_type;
|
qCWarning(lcDiscovery) << "(*it)->_type" << (*it)->_type;
|
||||||
qCWarning(lcDiscovery) << "(*it)->_isRestoration " << (*it)->_isRestoration;
|
qCWarning(lcDiscovery) << "(*it)->_isRestoration " << (*it)->_isRestoration;
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
addErrorToGui(SyncFileItem::Status::FatalError, tr("Error while canceling deletion of a file"), originalPath);
|
addErrorToGui(SyncFileItem::Status::FatalError, tr("Error while canceling delete of a file"), originalPath);
|
||||||
emit fatalError(tr("Error while canceling deletion of %1").arg(originalPath));
|
emit fatalError(tr("Error while canceling delete of %1").arg(originalPath));
|
||||||
}
|
}
|
||||||
(*it)->_instruction = CSYNC_INSTRUCTION_NONE;
|
(*it)->_instruction = CSYNC_INSTRUCTION_NONE;
|
||||||
result = true;
|
result = true;
|
||||||
|
|||||||
@@ -89,30 +89,6 @@ bool Logger::isLoggingToFile() const
|
|||||||
void Logger::doLog(QtMsgType type, const QMessageLogContext &ctx, const QString &message)
|
void Logger::doLog(QtMsgType type, const QMessageLogContext &ctx, const QString &message)
|
||||||
{
|
{
|
||||||
const QString msg = qFormatLogMessage(type, ctx, message);
|
const QString msg = qFormatLogMessage(type, ctx, message);
|
||||||
#if defined(Q_OS_WIN) && defined(QT_DEBUG)
|
|
||||||
// write logs to Output window of Visual Studio
|
|
||||||
{
|
|
||||||
QString prefix;
|
|
||||||
switch (type) {
|
|
||||||
case QtDebugMsg:
|
|
||||||
break;
|
|
||||||
case QtInfoMsg:
|
|
||||||
break;
|
|
||||||
case QtWarningMsg:
|
|
||||||
prefix = QStringLiteral("[WARNING] ");
|
|
||||||
break;
|
|
||||||
case QtCriticalMsg:
|
|
||||||
prefix = QStringLiteral("[CRITICAL ERROR] ");
|
|
||||||
break;
|
|
||||||
case QtFatalMsg:
|
|
||||||
prefix = QStringLiteral("[FATAL ERROR] ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
auto msgW = QString(prefix + message).toStdWString();
|
|
||||||
msgW.append(L"\n");
|
|
||||||
OutputDebugString(msgW.c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&_mutex);
|
QMutexLocker lock(&_mutex);
|
||||||
_crashLogIndex = (_crashLogIndex + 1) % CrashLogSize;
|
_crashLogIndex = (_crashLogIndex + 1) % CrashLogSize;
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ Q_LOGGING_CATEGORY(lcMkColJob, "nextcloud.sync.networkjob.mkcol", QtInfoMsg)
|
|||||||
Q_LOGGING_CATEGORY(lcProppatchJob, "nextcloud.sync.networkjob.proppatch", QtInfoMsg)
|
Q_LOGGING_CATEGORY(lcProppatchJob, "nextcloud.sync.networkjob.proppatch", QtInfoMsg)
|
||||||
Q_LOGGING_CATEGORY(lcJsonApiJob, "nextcloud.sync.networkjob.jsonapi", QtInfoMsg)
|
Q_LOGGING_CATEGORY(lcJsonApiJob, "nextcloud.sync.networkjob.jsonapi", QtInfoMsg)
|
||||||
Q_LOGGING_CATEGORY(lcDetermineAuthTypeJob, "nextcloud.sync.networkjob.determineauthtype", QtInfoMsg)
|
Q_LOGGING_CATEGORY(lcDetermineAuthTypeJob, "nextcloud.sync.networkjob.determineauthtype", QtInfoMsg)
|
||||||
Q_LOGGING_CATEGORY(lcSimpleFileJob, "nextcloud.sync.networkjob.simplefilejob", QtInfoMsg)
|
|
||||||
const int notModifiedStatusCode = 304;
|
const int notModifiedStatusCode = 304;
|
||||||
|
|
||||||
QByteArray parseEtag(const char *header)
|
QByteArray parseEtag(const char *header)
|
||||||
@@ -1085,39 +1084,9 @@ bool SimpleNetworkJob::finished()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleFileJob::SimpleFileJob(AccountPtr account, const QString &filePath, QObject *parent)
|
|
||||||
: AbstractNetworkJob(account, filePath, parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkReply *SimpleFileJob::startRequest(
|
|
||||||
const QByteArray &verb, const QNetworkRequest req, QIODevice *requestBody)
|
|
||||||
{
|
|
||||||
return startRequest(verb, makeDavUrl(path()), req, requestBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkReply *SimpleFileJob::startRequest(
|
|
||||||
const QByteArray &verb, const QUrl &url, const QNetworkRequest req, QIODevice *requestBody)
|
|
||||||
{
|
|
||||||
_verb = verb;
|
|
||||||
const auto reply = sendRequest(verb, url, req, requestBody);
|
|
||||||
|
|
||||||
if (reply->error() != QNetworkReply::NoError) {
|
|
||||||
qCWarning(lcSimpleFileJob) << verb << " Network error: " << reply->errorString();
|
|
||||||
}
|
|
||||||
AbstractNetworkJob::start();
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SimpleFileJob::finished()
|
|
||||||
{
|
|
||||||
qCInfo(lcSimpleFileJob) << _verb << "for" << reply()->request().url() << "FINISHED WITH STATUS" << replyStatusString();
|
|
||||||
emit finishedSignal(reply());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeleteApiJob::DeleteApiJob(AccountPtr account, const QString &path, QObject *parent)
|
DeleteApiJob::DeleteApiJob(AccountPtr account, const QString &path, QObject *parent)
|
||||||
: SimpleFileJob(account, path, parent)
|
: AbstractNetworkJob(account, path, parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1126,13 +1095,14 @@ void DeleteApiJob::start()
|
|||||||
{
|
{
|
||||||
QNetworkRequest req;
|
QNetworkRequest req;
|
||||||
req.setRawHeader("OCS-APIREQUEST", "true");
|
req.setRawHeader("OCS-APIREQUEST", "true");
|
||||||
|
QUrl url = Utility::concatUrlPath(account()->url(), path());
|
||||||
startRequest("DELETE", req);
|
sendRequest("DELETE", url, req);
|
||||||
|
AbstractNetworkJob::start();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeleteApiJob::finished()
|
bool DeleteApiJob::finished()
|
||||||
{
|
{
|
||||||
qCInfo(lcJsonApiJob) << "DeleteApiJob of" << reply()->request().url() << "FINISHED WITH STATUS"
|
qCInfo(lcJsonApiJob) << "JsonApiJob of" << reply()->request().url() << "FINISHED WITH STATUS"
|
||||||
<< reply()->error()
|
<< reply()->error()
|
||||||
<< (reply()->error() == QNetworkReply::NoError ? QLatin1String("") : errorString());
|
<< (reply()->error() == QNetworkReply::NoError ? QLatin1String("") : errorString());
|
||||||
|
|
||||||
@@ -1148,7 +1118,7 @@ bool DeleteApiJob::finished()
|
|||||||
const auto replyData = QString::fromUtf8(reply()->readAll());
|
const auto replyData = QString::fromUtf8(reply()->readAll());
|
||||||
qCInfo(lcJsonApiJob()) << "TMX Delete Job" << replyData;
|
qCInfo(lcJsonApiJob()) << "TMX Delete Job" << replyData;
|
||||||
emit result(httpStatus);
|
emit result(httpStatus);
|
||||||
return SimpleFileJob::finished();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fetchPrivateLinkUrl(AccountPtr account, const QString &remotePath,
|
void fetchPrivateLinkUrl(AccountPtr account, const QString &remotePath,
|
||||||
|
|||||||
@@ -60,31 +60,6 @@ private slots:
|
|||||||
bool finished() override;
|
bool finished() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A basic file manipulation job
|
|
||||||
* @ingroup libsync
|
|
||||||
*/
|
|
||||||
class OWNCLOUDSYNC_EXPORT SimpleFileJob : public AbstractNetworkJob
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SimpleFileJob(AccountPtr account, const QString &filePath, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
QNetworkReply *startRequest(
|
|
||||||
const QByteArray &verb, const QNetworkRequest req = QNetworkRequest(), QIODevice *requestBody = nullptr);
|
|
||||||
|
|
||||||
QNetworkReply *startRequest(const QByteArray &verb, const QUrl &url, const QNetworkRequest req = QNetworkRequest(),
|
|
||||||
QIODevice *requestBody = nullptr);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finishedSignal(QNetworkReply *reply);
|
|
||||||
protected slots:
|
|
||||||
bool finished() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QByteArray _verb;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief sends a DELETE http request to a url.
|
* @brief sends a DELETE http request to a url.
|
||||||
*
|
*
|
||||||
@@ -92,7 +67,7 @@ private:
|
|||||||
*
|
*
|
||||||
* This does *not* delete files, it does a http request.
|
* This does *not* delete files, it does a http request.
|
||||||
*/
|
*/
|
||||||
class OWNCLOUDSYNC_EXPORT DeleteApiJob : public SimpleFileJob
|
class OWNCLOUDSYNC_EXPORT DeleteApiJob : public AbstractNetworkJob
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -773,7 +773,7 @@ bool OwncloudPropagator::createConflict(const SyncFileItemPtr &item,
|
|||||||
QString renameError;
|
QString renameError;
|
||||||
auto conflictModTime = FileSystem::getModTime(fn);
|
auto conflictModTime = FileSystem::getModTime(fn);
|
||||||
if (conflictModTime <= 0) {
|
if (conflictModTime <= 0) {
|
||||||
*error = tr("Impossible to get modification time for file in conflict %1").arg(fn);
|
*error = tr("Impossible to get modification time for file in conflict %1)").arg(fn);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QString conflictUserName;
|
QString conflictUserName;
|
||||||
@@ -1133,7 +1133,7 @@ void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status)
|
|||||||
|
|
||||||
if (_item->_modtime <= 0) {
|
if (_item->_modtime <= 0) {
|
||||||
status = _item->_status = SyncFileItem::NormalError;
|
status = _item->_status = SyncFileItem::NormalError;
|
||||||
_item->_errorString = tr("Error updating metadata due to invalid modification time");
|
_item->_errorString = tr("Error updating metadata due to invalid modified time");
|
||||||
qCWarning(lcDirectory) << "Error writing to the database for file" << _item->_file;
|
qCWarning(lcDirectory) << "Error writing to the database for file" << _item->_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "common/utility.h"
|
#include "common/utility.h"
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "propagatorjobs.h"
|
#include "propagatorjobs.h"
|
||||||
|
#include <common/checksums.h>
|
||||||
#include <common/asserts.h>
|
#include <common/asserts.h>
|
||||||
#include <common/constants.h>
|
#include <common/constants.h>
|
||||||
#include "clientsideencryptionjobs.h"
|
#include "clientsideencryptionjobs.h"
|
||||||
@@ -922,53 +923,8 @@ void PropagateDownloadFile::slotGetFinished()
|
|||||||
validator->start(_tmpFile.fileName(), checksumHeader);
|
validator->start(_tmpFile.fileName(), checksumHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropagateDownloadFile::slotChecksumFail(const QString &errMsg,
|
void PropagateDownloadFile::slotChecksumFail(const QString &errMsg)
|
||||||
const QByteArray &calculatedChecksumType, const QByteArray &calculatedChecksum, const ValidateChecksumHeader::FailureReason reason)
|
{
|
||||||
{
|
|
||||||
if (reason == ValidateChecksumHeader::FailureReason::ChecksumMismatch && propagator()->account()->isChecksumRecalculateRequestSupported()) {
|
|
||||||
const QByteArray calculatedChecksumHeader(calculatedChecksumType + ':' + calculatedChecksum);
|
|
||||||
const QString fullRemotePathForFile(propagator()->fullRemotePath(_isEncrypted ? _item->_encryptedFileName : _item->_file));
|
|
||||||
auto *job = new SimpleFileJob(propagator()->account(), fullRemotePathForFile);
|
|
||||||
QObject::connect(job, &SimpleFileJob::finishedSignal, this,
|
|
||||||
[this, calculatedChecksumHeader, errMsg](const QNetworkReply *reply) { processChecksumRecalculate(reply, calculatedChecksumHeader, errMsg);
|
|
||||||
});
|
|
||||||
|
|
||||||
qCWarning(lcPropagateDownload) << "Checksum validation has failed for file:" << fullRemotePathForFile
|
|
||||||
<< " Requesting checksum recalculation on the server...";
|
|
||||||
QNetworkRequest req;
|
|
||||||
req.setRawHeader(checksumRecalculateOnServerHeaderC, calculatedChecksumType);
|
|
||||||
job->startRequest(QByteArrayLiteral("PATCH"), req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
checksumValidateFailedAbortDownload(errMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PropagateDownloadFile::processChecksumRecalculate(const QNetworkReply *reply, const QByteArray &originalChecksumHeader, const QString &errorMessage)
|
|
||||||
{
|
|
||||||
if (reply->error() != QNetworkReply::NoError) {
|
|
||||||
qCCritical(lcPropagateDownload) << "Checksum recalculation has failed for file:" << reply->url()
|
|
||||||
<< " Recalculation request has finished with error:" << reply->errorString();
|
|
||||||
checksumValidateFailedAbortDownload(errorMessage);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto newChecksumHeaderFromServer = reply->rawHeader(checkSumHeaderC);
|
|
||||||
if (newChecksumHeaderFromServer == originalChecksumHeader) {
|
|
||||||
const auto newChecksumHeaderFromServerSplit = newChecksumHeaderFromServer.split(':');
|
|
||||||
if (newChecksumHeaderFromServerSplit.size() > 1) {
|
|
||||||
transmissionChecksumValidated(newChecksumHeaderFromServerSplit.first(), newChecksumHeaderFromServerSplit.last());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qCCritical(lcPropagateDownload) << "Checksum recalculation has failed for file:" << reply->url() << " "
|
|
||||||
<< checkSumHeaderC << " received is:" << newChecksumHeaderFromServer;
|
|
||||||
checksumValidateFailedAbortDownload(errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PropagateDownloadFile::checksumValidateFailedAbortDownload(const QString &errMsg)
|
|
||||||
{
|
|
||||||
FileSystem::remove(_tmpFile.fileName());
|
FileSystem::remove(_tmpFile.fileName());
|
||||||
propagator()->_anotherSyncNeeded = true;
|
propagator()->_anotherSyncNeeded = true;
|
||||||
done(SyncFileItem::SoftError, errMsg); // tr("The file downloaded with a broken checksum, will be redownloaded."));
|
done(SyncFileItem::SoftError, errMsg); // tr("The file downloaded with a broken checksum, will be redownloaded."));
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
#include "owncloudpropagator.h"
|
#include "owncloudpropagator.h"
|
||||||
#include "networkjobs.h"
|
#include "networkjobs.h"
|
||||||
#include "clientsideencryption.h"
|
#include "clientsideencryption.h"
|
||||||
#include <common/checksums.h>
|
|
||||||
|
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
@@ -236,10 +235,7 @@ private slots:
|
|||||||
|
|
||||||
void abort(PropagatorJob::AbortType abortType) override;
|
void abort(PropagatorJob::AbortType abortType) override;
|
||||||
void slotDownloadProgress(qint64, qint64);
|
void slotDownloadProgress(qint64, qint64);
|
||||||
void slotChecksumFail(const QString &errMsg, const QByteArray &calculatedChecksumType,
|
void slotChecksumFail(const QString &errMsg);
|
||||||
const QByteArray &calculatedChecksum, const ValidateChecksumHeader::FailureReason reason);
|
|
||||||
void processChecksumRecalculate(const QNetworkReply *reply, const QByteArray &originalChecksumHeader, const QString &errorMessage);
|
|
||||||
void checksumValidateFailedAbortDownload(const QString &errMsg);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startAfterIsEncryptedIsChecked();
|
void startAfterIsEncryptedIsChecked();
|
||||||
|
|||||||
@@ -319,7 +319,7 @@ void PropagateUploadFileCommon::slotComputeContentChecksum()
|
|||||||
// probably temporary one.
|
// probably temporary one.
|
||||||
_item->_modtime = FileSystem::getModTime(filePath);
|
_item->_modtime = FileSystem::getModTime(filePath);
|
||||||
if (_item->_modtime <= 0) {
|
if (_item->_modtime <= 0) {
|
||||||
slotOnErrorStartFolderUnlock(SyncFileItem::NormalError, tr("File %1 has invalid modification time. Do not upload to the server.").arg(QDir::toNativeSeparators(_item->_file)));
|
slotOnErrorStartFolderUnlock(SyncFileItem::NormalError, tr("File %1 has invalid modified time. Do not upload to the server.").arg(QDir::toNativeSeparators(_item->_file)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,7 +394,7 @@ void PropagateUploadFileCommon::slotStartUpload(const QByteArray &transmissionCh
|
|||||||
return slotOnErrorStartFolderUnlock(SyncFileItem::SoftError, tr("File Removed (start upload) %1").arg(fullFilePath));
|
return slotOnErrorStartFolderUnlock(SyncFileItem::SoftError, tr("File Removed (start upload) %1").arg(fullFilePath));
|
||||||
}
|
}
|
||||||
if (_item->_modtime <= 0) {
|
if (_item->_modtime <= 0) {
|
||||||
slotOnErrorStartFolderUnlock(SyncFileItem::NormalError, tr("File %1 has invalid modification time. Do not upload to the server.").arg(QDir::toNativeSeparators(_item->_file)));
|
slotOnErrorStartFolderUnlock(SyncFileItem::NormalError, tr("File %1 has invalid modified time. Do not upload to the server.").arg(QDir::toNativeSeparators(_item->_file)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_ASSERT(_item->_modtime > 0);
|
Q_ASSERT(_item->_modtime > 0);
|
||||||
@@ -407,7 +407,7 @@ void PropagateUploadFileCommon::slotStartUpload(const QByteArray &transmissionCh
|
|||||||
|
|
||||||
_item->_modtime = FileSystem::getModTime(originalFilePath);
|
_item->_modtime = FileSystem::getModTime(originalFilePath);
|
||||||
if (_item->_modtime <= 0) {
|
if (_item->_modtime <= 0) {
|
||||||
slotOnErrorStartFolderUnlock(SyncFileItem::NormalError, tr("File %1 has invalid modification time. Do not upload to the server.").arg(QDir::toNativeSeparators(_item->_file)));
|
slotOnErrorStartFolderUnlock(SyncFileItem::NormalError, tr("File %1 has invalid modified time. Do not upload to the server.").arg(QDir::toNativeSeparators(_item->_file)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_ASSERT(_item->_modtime > 0);
|
Q_ASSERT(_item->_modtime > 0);
|
||||||
|
|||||||
@@ -24,9 +24,8 @@ namespace OCC {
|
|||||||
* Tags for checksum header.
|
* Tags for checksum header.
|
||||||
* It's here for being shared between Upload- and Download Job
|
* It's here for being shared between Upload- and Download Job
|
||||||
*/
|
*/
|
||||||
constexpr auto checkSumHeaderC = "OC-Checksum";
|
static const char checkSumHeaderC[] = "OC-Checksum";
|
||||||
constexpr auto contentMd5HeaderC = "Content-MD5";
|
static const char contentMd5HeaderC[] = "Content-MD5";
|
||||||
constexpr auto checksumRecalculateOnServerHeaderC = "X-Recalculate-Hash";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Declaration of the other propagation jobs
|
* @brief Declaration of the other propagation jobs
|
||||||
|
|||||||
@@ -417,15 +417,6 @@ bool Theme::forbidBadSSL() const
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Theme::doNotUseProxy() const
|
|
||||||
{
|
|
||||||
#ifdef DO_NOT_USE_PROXY
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Theme::forceConfigAuthType() const
|
QString Theme::forceConfigAuthType() const
|
||||||
{
|
{
|
||||||
return QString();
|
return QString();
|
||||||
|
|||||||
@@ -254,13 +254,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool forbidBadSSL() const;
|
virtual bool forbidBadSSL() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Forbid use of proxy
|
|
||||||
*
|
|
||||||
* When true, the app always connects to the server directly
|
|
||||||
*/
|
|
||||||
virtual bool doNotUseProxy() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is only usefull when previous version had a different overrideServerUrl
|
* This is only usefull when previous version had a different overrideServerUrl
|
||||||
* with a different auth type in that case You should then specify "http" or "shibboleth".
|
* with a different auth type in that case You should then specify "http" or "shibboleth".
|
||||||
|
|||||||
@@ -650,7 +650,7 @@ OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::se
|
|||||||
OCC::Result<void, QString> OCC::CfApiWrapper::createPlaceholderInfo(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId)
|
OCC::Result<void, QString> OCC::CfApiWrapper::createPlaceholderInfo(const QString &path, time_t modtime, qint64 size, const QByteArray &fileId)
|
||||||
{
|
{
|
||||||
if (modtime <= 0) {
|
if (modtime <= 0) {
|
||||||
return {QString{"Could not update metadata due to invalid modification time for %1: %2"}.arg(path).arg(modtime)};
|
return {QString{"Could not update metadata due to invalid modified time for %1: %2"}.arg(path).arg(modtime)};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto fileInfo = QFileInfo(path);
|
const auto fileInfo = QFileInfo(path);
|
||||||
@@ -702,7 +702,7 @@ OCC::Result<OCC::Vfs::ConvertToPlaceholderResult, QString> OCC::CfApiWrapper::up
|
|||||||
Q_ASSERT(handle);
|
Q_ASSERT(handle);
|
||||||
|
|
||||||
if (modtime <= 0) {
|
if (modtime <= 0) {
|
||||||
return {QString{"Could not update metadata due to invalid modification time for %1: %2"}.arg(pathForHandle(handle)).arg(modtime)};
|
return {QString{"Could not update metadata due to invalid modified time for %1: %2"}.arg(pathForHandle(handle)).arg(modtime)};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto info = replacesPath.isEmpty() ? findPlaceholderInfo(handle)
|
const auto info = replacesPath.isEmpty() ? findPlaceholderInfo(handle)
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ bool VfsSuffix::isHydrating() const
|
|||||||
Result<void, QString> VfsSuffix::updateMetadata(const QString &filePath, time_t modtime, qint64, const QByteArray &)
|
Result<void, QString> VfsSuffix::updateMetadata(const QString &filePath, time_t modtime, qint64, const QByteArray &)
|
||||||
{
|
{
|
||||||
if (modtime <= 0) {
|
if (modtime <= 0) {
|
||||||
return {tr("Error updating metadata due to invalid modification time")};
|
return {tr("Error updating metadata due to invalid modified time")};
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem::setModTime(filePath, modtime);
|
FileSystem::setModTime(filePath, modtime);
|
||||||
@@ -79,7 +79,7 @@ Result<void, QString> VfsSuffix::updateMetadata(const QString &filePath, time_t
|
|||||||
Result<void, QString> VfsSuffix::createPlaceholder(const SyncFileItem &item)
|
Result<void, QString> VfsSuffix::createPlaceholder(const SyncFileItem &item)
|
||||||
{
|
{
|
||||||
if (item._modtime <= 0) {
|
if (item._modtime <= 0) {
|
||||||
return {tr("Error updating metadata due to invalid modification time")};
|
return {tr("Error updating metadata due to invalid modified time")};
|
||||||
}
|
}
|
||||||
|
|
||||||
// The concrete shape of the placeholder is also used in isDehydratedPlaceholder() below
|
// The concrete shape of the placeholder is also used in isDehydratedPlaceholder() below
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ bool VfsXAttr::isHydrating() const
|
|||||||
Result<void, QString> VfsXAttr::updateMetadata(const QString &filePath, time_t modtime, qint64, const QByteArray &)
|
Result<void, QString> VfsXAttr::updateMetadata(const QString &filePath, time_t modtime, qint64, const QByteArray &)
|
||||||
{
|
{
|
||||||
if (modtime <= 0) {
|
if (modtime <= 0) {
|
||||||
return {tr("Error updating metadata due to invalid modification time")};
|
return {tr("Error updating metadata due to invalid modified time")};
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem::setModTime(filePath, modtime);
|
FileSystem::setModTime(filePath, modtime);
|
||||||
@@ -80,7 +80,7 @@ Result<void, QString> VfsXAttr::updateMetadata(const QString &filePath, time_t m
|
|||||||
Result<void, QString> VfsXAttr::createPlaceholder(const SyncFileItem &item)
|
Result<void, QString> VfsXAttr::createPlaceholder(const SyncFileItem &item)
|
||||||
{
|
{
|
||||||
if (item._modtime <= 0) {
|
if (item._modtime <= 0) {
|
||||||
return {tr("Error updating metadata due to invalid modification time")};
|
return {tr("Error updating metadata due to invalid modified time")};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto path = QString(_setupParams.filesystemPath + item._file);
|
const auto path = QString(_setupParams.filesystemPath + item._file);
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ nextcloud_add_test(IconUtils)
|
|||||||
nextcloud_add_test(NotificationCache)
|
nextcloud_add_test(NotificationCache)
|
||||||
nextcloud_add_test(SetUserStatusDialog)
|
nextcloud_add_test(SetUserStatusDialog)
|
||||||
nextcloud_add_test(UnifiedSearchListmodel)
|
nextcloud_add_test(UnifiedSearchListmodel)
|
||||||
nextcloud_add_test(ActivityListModel)
|
|
||||||
|
|
||||||
if( UNIX AND NOT APPLE )
|
if( UNIX AND NOT APPLE )
|
||||||
nextcloud_add_test(InotifyWatcher)
|
nextcloud_add_test(InotifyWatcher)
|
||||||
|
|||||||
@@ -450,10 +450,8 @@ QVector<FileInfo *> FakePutMultiFileReply::performMultiPart(FileInfo &remoteRoot
|
|||||||
auto headerParts = oneHeader.split(QStringLiteral(": "));
|
auto headerParts = oneHeader.split(QStringLiteral(": "));
|
||||||
allHeaders[headerParts.at(0)] = headerParts.at(1);
|
allHeaders[headerParts.at(0)] = headerParts.at(1);
|
||||||
}
|
}
|
||||||
const auto fileName = allHeaders[QStringLiteral("X-File-Path")];
|
auto fileName = allHeaders[QStringLiteral("X-File-Path")];
|
||||||
const auto modtime = allHeaders[QByteArrayLiteral("X-File-Mtime")].toLongLong();
|
|
||||||
Q_ASSERT(!fileName.isEmpty());
|
Q_ASSERT(!fileName.isEmpty());
|
||||||
Q_ASSERT(modtime > 0);
|
|
||||||
FileInfo *fileInfo = remoteRootFileInfo.find(fileName);
|
FileInfo *fileInfo = remoteRootFileInfo.find(fileName);
|
||||||
if (fileInfo) {
|
if (fileInfo) {
|
||||||
fileInfo->size = onePartBody.size();
|
fileInfo->size = onePartBody.size();
|
||||||
@@ -482,7 +480,13 @@ void FakePutMultiFileReply::respond()
|
|||||||
for(auto fileInfo : qAsConst(_allFileInfo)) {
|
for(auto fileInfo : qAsConst(_allFileInfo)) {
|
||||||
QJsonObject fileInfoReply;
|
QJsonObject fileInfoReply;
|
||||||
fileInfoReply.insert("error", QStringLiteral("false"));
|
fileInfoReply.insert("error", QStringLiteral("false"));
|
||||||
|
fileInfoReply.insert("OC-OperationStatus", fileInfo->operationStatus);
|
||||||
|
fileInfoReply.insert("X-File-Path", fileInfo->path());
|
||||||
|
fileInfoReply.insert("OC-ETag", QLatin1String{fileInfo->etag});
|
||||||
|
fileInfoReply.insert("ETag", QLatin1String{fileInfo->etag});
|
||||||
fileInfoReply.insert("etag", QLatin1String{fileInfo->etag});
|
fileInfoReply.insert("etag", QLatin1String{fileInfo->etag});
|
||||||
|
fileInfoReply.insert("OC-FileID", QLatin1String{fileInfo->fileId});
|
||||||
|
fileInfoReply.insert("X-OC-MTime", "accepted"); // Prevents Q_ASSERT(!_runningNow) since we'll call PropagateItemJob::done twice in that case.
|
||||||
emit uploadProgress(fileInfo->size, totalSize);
|
emit uploadProgress(fileInfo->size, totalSize);
|
||||||
allFileInfoReply.insert(QChar('/') + fileInfo->path(), fileInfoReply);
|
allFileInfoReply.insert(QChar('/') + fileInfo->path(), fileInfoReply);
|
||||||
}
|
}
|
||||||
@@ -973,12 +977,7 @@ QNetworkReply *FakeQNAM::createRequest(QNetworkAccessManager::Operation op, cons
|
|||||||
} else if (verb == QLatin1String("GET") || op == QNetworkAccessManager::GetOperation) {
|
} else if (verb == QLatin1String("GET") || op == QNetworkAccessManager::GetOperation) {
|
||||||
reply = new FakeGetReply { info, op, newRequest, this };
|
reply = new FakeGetReply { info, op, newRequest, this };
|
||||||
} else if (verb == QLatin1String("PUT") || op == QNetworkAccessManager::PutOperation) {
|
} else if (verb == QLatin1String("PUT") || op == QNetworkAccessManager::PutOperation) {
|
||||||
if (request.hasRawHeader(QByteArrayLiteral("X-OC-Mtime")) &&
|
reply = new FakePutReply { info, op, newRequest, outgoingData->readAll(), this };
|
||||||
request.rawHeader(QByteArrayLiteral("X-OC-Mtime")).toLongLong() <= 0) {
|
|
||||||
reply = new FakeErrorReply { op, request, this, 500 };
|
|
||||||
} else {
|
|
||||||
reply = new FakePutReply { info, op, newRequest, outgoingData->readAll(), this };
|
|
||||||
}
|
|
||||||
} else if (verb == QLatin1String("MKCOL")) {
|
} else if (verb == QLatin1String("MKCOL")) {
|
||||||
reply = new FakeMkcolReply { info, op, newRequest, this };
|
reply = new FakeMkcolReply { info, op, newRequest, this };
|
||||||
} else if (verb == QLatin1String("DELETE") || op == QNetworkAccessManager::DeleteOperation) {
|
} else if (verb == QLatin1String("DELETE") || op == QNetworkAccessManager::DeleteOperation) {
|
||||||
|
|||||||
@@ -1,701 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) by Claudio Cambra <claudio.cambra@nextcloud.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gui/tray/activitylistmodel.h"
|
|
||||||
|
|
||||||
#include "account.h"
|
|
||||||
#include "accountstate.h"
|
|
||||||
#include "accountmanager.h"
|
|
||||||
#include "syncenginetestutils.h"
|
|
||||||
#include "syncresult.h"
|
|
||||||
|
|
||||||
#include <QAbstractItemModelTester>
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QSignalSpy>
|
|
||||||
#include <QTest>
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
constexpr auto startingId = 90000;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QByteArray fake404Response = R"(
|
|
||||||
{"ocs":{"meta":{"status":"failure","statuscode":404,"message":"Invalid query, please check the syntax. API specifications are here: http:\/\/www.freedesktop.org\/wiki\/Specifications\/open-collaboration-services.\n"},"data":[]}}
|
|
||||||
)";
|
|
||||||
|
|
||||||
static QByteArray fake400Response = R"(
|
|
||||||
{"ocs":{"meta":{"status":"failure","statuscode":400,"message":"Parameter is incorrect.\n"},"data":[]}}
|
|
||||||
)";
|
|
||||||
|
|
||||||
static QByteArray fake500Response = R"(
|
|
||||||
{"ocs":{"meta":{"status":"failure","statuscode":500,"message":"Internal Server Error.\n"},"data":[]}}
|
|
||||||
)";
|
|
||||||
|
|
||||||
class FakeRemoteActivityStorage
|
|
||||||
{
|
|
||||||
FakeRemoteActivityStorage() = default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static FakeRemoteActivityStorage *instance()
|
|
||||||
{
|
|
||||||
if (!_instance) {
|
|
||||||
_instance = new FakeRemoteActivityStorage();
|
|
||||||
_instance->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroy()
|
|
||||||
{
|
|
||||||
if (_instance) {
|
|
||||||
delete _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
_instance = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init()
|
|
||||||
{
|
|
||||||
if (!_activityData.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_metaSuccess = {{QStringLiteral("status"), QStringLiteral("ok")}, {QStringLiteral("statuscode"), 200},
|
|
||||||
{QStringLiteral("message"), QStringLiteral("OK")}};
|
|
||||||
|
|
||||||
initActivityData();
|
|
||||||
}
|
|
||||||
|
|
||||||
void initActivityData()
|
|
||||||
{
|
|
||||||
// Insert activity data
|
|
||||||
for (quint32 i = 0; i <= _numItemsToInsert; i++) {
|
|
||||||
QJsonObject activity;
|
|
||||||
activity.insert(QStringLiteral("object_type"), "files");
|
|
||||||
activity.insert(QStringLiteral("activity_id"), _startingId);
|
|
||||||
activity.insert(QStringLiteral("type"), QStringLiteral("file"));
|
|
||||||
activity.insert(QStringLiteral("subject"), QStringLiteral("You created %1.txt").arg(i));
|
|
||||||
activity.insert(QStringLiteral("message"), QStringLiteral(""));
|
|
||||||
activity.insert(QStringLiteral("object_name"), QStringLiteral("%1.txt").arg(i));
|
|
||||||
activity.insert(QStringLiteral("datetime"), QDateTime::currentDateTime().toString(Qt::ISODate));
|
|
||||||
activity.insert(QStringLiteral("icon"), QStringLiteral("http://example.de/apps/files/img/add-color.svg"));
|
|
||||||
|
|
||||||
_activityData.push_back(activity);
|
|
||||||
|
|
||||||
_startingId++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert notification data
|
|
||||||
for (quint32 i = 0; i < _numItemsToInsert; i++) {
|
|
||||||
QJsonObject activity;
|
|
||||||
activity.insert(QStringLiteral("activity_id"), _startingId);
|
|
||||||
activity.insert(QStringLiteral("object_type"), "calendar");
|
|
||||||
activity.insert(QStringLiteral("type"), QStringLiteral("calendar-event"));
|
|
||||||
activity.insert(
|
|
||||||
QStringLiteral("subject"), QStringLiteral("You created event %1 in calendar Events").arg(i));
|
|
||||||
activity.insert(QStringLiteral("message"), QStringLiteral(""));
|
|
||||||
activity.insert(QStringLiteral("object_name"), QStringLiteral(""));
|
|
||||||
activity.insert(QStringLiteral("datetime"), QDateTime::currentDateTime().toString(Qt::ISODate));
|
|
||||||
activity.insert(QStringLiteral("icon"), QStringLiteral("http://example.de/core/img/places/calendar.svg"));
|
|
||||||
|
|
||||||
QJsonArray actionsArray;
|
|
||||||
|
|
||||||
QJsonObject secondaryAction;
|
|
||||||
secondaryAction.insert(QStringLiteral("label"), QStringLiteral("Dismiss"));
|
|
||||||
secondaryAction.insert(QStringLiteral("link"),
|
|
||||||
QString(QStringLiteral("http://cloud.example.de/remote.php/dav")
|
|
||||||
+ QStringLiteral("ocs/v2.php/apps/notifications/api/v2/notifications") + QString::number(i)));
|
|
||||||
secondaryAction.insert(QStringLiteral("type"), QStringLiteral("DELETE"));
|
|
||||||
secondaryAction.insert(QStringLiteral("primary"), false);
|
|
||||||
actionsArray.push_back(secondaryAction);
|
|
||||||
|
|
||||||
_activityData.push_back(activity);
|
|
||||||
|
|
||||||
_startingId++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert notification data
|
|
||||||
for (quint32 i = 0; i < _numItemsToInsert; i++) {
|
|
||||||
QJsonObject activity;
|
|
||||||
activity.insert(QStringLiteral("activity_id"), _startingId);
|
|
||||||
activity.insert(QStringLiteral("object_type"), "chat");
|
|
||||||
activity.insert(QStringLiteral("type"), QStringLiteral("chat"));
|
|
||||||
activity.insert(QStringLiteral("subject"), QStringLiteral("You have received %1's message").arg(i));
|
|
||||||
activity.insert(QStringLiteral("message"), QStringLiteral(""));
|
|
||||||
activity.insert(QStringLiteral("object_name"), QStringLiteral(""));
|
|
||||||
activity.insert(QStringLiteral("datetime"), QDateTime::currentDateTime().toString(Qt::ISODate));
|
|
||||||
activity.insert(QStringLiteral("icon"), QStringLiteral("http://example.de/core/img/places/talk.svg"));
|
|
||||||
|
|
||||||
QJsonArray actionsArray;
|
|
||||||
|
|
||||||
QJsonObject primaryAction;
|
|
||||||
primaryAction.insert(QStringLiteral("label"), QStringLiteral("View chat"));
|
|
||||||
primaryAction.insert(QStringLiteral("link"), QStringLiteral("http://cloud.example.de/call/9p4vjdzd"));
|
|
||||||
primaryAction.insert(QStringLiteral("type"), QStringLiteral("WEB"));
|
|
||||||
primaryAction.insert(QStringLiteral("primary"), true);
|
|
||||||
actionsArray.push_back(primaryAction);
|
|
||||||
|
|
||||||
QJsonObject secondaryAction;
|
|
||||||
secondaryAction.insert(QStringLiteral("label"), QStringLiteral("Dismiss"));
|
|
||||||
secondaryAction.insert(QStringLiteral("link"),
|
|
||||||
QString(QStringLiteral("http://cloud.example.de/remote.php/dav")
|
|
||||||
+ QStringLiteral("ocs/v2.php/apps/notifications/api/v2/notifications") + QString::number(i)));
|
|
||||||
secondaryAction.insert(QStringLiteral("type"), QStringLiteral("DELETE"));
|
|
||||||
secondaryAction.insert(QStringLiteral("primary"), false);
|
|
||||||
actionsArray.push_back(secondaryAction);
|
|
||||||
|
|
||||||
QJsonObject additionalAction;
|
|
||||||
additionalAction.insert(QStringLiteral("label"), QStringLiteral("Additional 1"));
|
|
||||||
additionalAction.insert(QStringLiteral("link"), QStringLiteral("http://cloud.example.de/call/9p4vjdzd"));
|
|
||||||
additionalAction.insert(QStringLiteral("type"), QStringLiteral("POST"));
|
|
||||||
additionalAction.insert(QStringLiteral("primary"), false);
|
|
||||||
actionsArray.push_back(additionalAction);
|
|
||||||
additionalAction.insert(QStringLiteral("label"), QStringLiteral("Additional 2"));
|
|
||||||
actionsArray.push_back(additionalAction);
|
|
||||||
|
|
||||||
activity.insert(QStringLiteral("actions"), actionsArray);
|
|
||||||
|
|
||||||
_activityData.push_back(activity);
|
|
||||||
|
|
||||||
_startingId++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert notification data
|
|
||||||
for (quint32 i = 0; i < _numItemsToInsert; i++) {
|
|
||||||
QJsonObject activity;
|
|
||||||
activity.insert(QStringLiteral("activity_id"), _startingId);
|
|
||||||
activity.insert(QStringLiteral("object_type"), "room");
|
|
||||||
activity.insert(QStringLiteral("type"), QStringLiteral("room"));
|
|
||||||
activity.insert(QStringLiteral("subject"), QStringLiteral("You have been invited into room%1").arg(i));
|
|
||||||
activity.insert(QStringLiteral("message"), QStringLiteral(""));
|
|
||||||
activity.insert(QStringLiteral("object_name"), QStringLiteral(""));
|
|
||||||
activity.insert(QStringLiteral("datetime"), QDateTime::currentDateTime().toString(Qt::ISODate));
|
|
||||||
activity.insert(QStringLiteral("icon"), QStringLiteral("http://example.de/core/img/places/talk.svg"));
|
|
||||||
|
|
||||||
QJsonArray actionsArray;
|
|
||||||
|
|
||||||
QJsonObject primaryAction;
|
|
||||||
primaryAction.insert(QStringLiteral("label"), QStringLiteral("View chat"));
|
|
||||||
primaryAction.insert(QStringLiteral("link"), QStringLiteral("http://cloud.example.de/call/9p4vjdzd"));
|
|
||||||
primaryAction.insert(QStringLiteral("type"), QStringLiteral("WEB"));
|
|
||||||
primaryAction.insert(QStringLiteral("primary"), true);
|
|
||||||
actionsArray.push_back(primaryAction);
|
|
||||||
|
|
||||||
QJsonObject secondaryAction;
|
|
||||||
secondaryAction.insert(QStringLiteral("label"), QStringLiteral("Dismiss"));
|
|
||||||
secondaryAction.insert(QStringLiteral("link"),
|
|
||||||
QString(QStringLiteral("http://cloud.example.de/remote.php/dav")
|
|
||||||
+ QStringLiteral("ocs/v2.php/apps/notifications/api/v2/notifications") + QString::number(i)));
|
|
||||||
secondaryAction.insert(QStringLiteral("type"), QStringLiteral("DELETE"));
|
|
||||||
secondaryAction.insert(QStringLiteral("primary"), false);
|
|
||||||
actionsArray.push_back(secondaryAction);
|
|
||||||
|
|
||||||
activity.insert(QStringLiteral("actions"), actionsArray);
|
|
||||||
|
|
||||||
_activityData.push_back(activity);
|
|
||||||
|
|
||||||
_startingId++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert notification data
|
|
||||||
for (quint32 i = 0; i < _numItemsToInsert; i++) {
|
|
||||||
QJsonObject activity;
|
|
||||||
activity.insert(QStringLiteral("activity_id"), _startingId);
|
|
||||||
activity.insert(QStringLiteral("object_type"), "call");
|
|
||||||
activity.insert(QStringLiteral("type"), QStringLiteral("call"));
|
|
||||||
activity.insert(QStringLiteral("subject"), QStringLiteral("You have missed a %1's call").arg(i));
|
|
||||||
activity.insert(QStringLiteral("message"), QStringLiteral(""));
|
|
||||||
activity.insert(QStringLiteral("object_name"), QStringLiteral(""));
|
|
||||||
activity.insert(QStringLiteral("datetime"), QDateTime::currentDateTime().toString(Qt::ISODate));
|
|
||||||
activity.insert(QStringLiteral("icon"), QStringLiteral("http://example.de/core/img/places/talk.svg"));
|
|
||||||
|
|
||||||
QJsonArray actionsArray;
|
|
||||||
|
|
||||||
QJsonObject primaryAction;
|
|
||||||
primaryAction.insert(QStringLiteral("label"), QStringLiteral("Call back"));
|
|
||||||
primaryAction.insert(QStringLiteral("link"), QStringLiteral("http://cloud.example.de/call/9p4vjdzd"));
|
|
||||||
primaryAction.insert(QStringLiteral("type"), QStringLiteral("WEB"));
|
|
||||||
primaryAction.insert(QStringLiteral("primary"), true);
|
|
||||||
actionsArray.push_back(primaryAction);
|
|
||||||
|
|
||||||
QJsonObject secondaryAction;
|
|
||||||
secondaryAction.insert(QStringLiteral("label"), QStringLiteral("Dismiss"));
|
|
||||||
secondaryAction.insert(QStringLiteral("link"),
|
|
||||||
QString(QStringLiteral("http://cloud.example.de/remote.php/dav")
|
|
||||||
+ QStringLiteral("ocs/v2.php/apps/notifications/api/v2/notifications") + QString::number(i)));
|
|
||||||
secondaryAction.insert(QStringLiteral("type"), QStringLiteral("DELETE"));
|
|
||||||
secondaryAction.insert(QStringLiteral("primary"), false);
|
|
||||||
actionsArray.push_back(secondaryAction);
|
|
||||||
|
|
||||||
activity.insert(QStringLiteral("actions"), actionsArray);
|
|
||||||
|
|
||||||
_activityData.push_back(activity);
|
|
||||||
|
|
||||||
_startingId++;
|
|
||||||
}
|
|
||||||
|
|
||||||
_startingId--;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QByteArray activityJsonData(int sinceId, int limit)
|
|
||||||
{
|
|
||||||
QJsonArray data;
|
|
||||||
|
|
||||||
const auto itFound = std::find_if(
|
|
||||||
std::cbegin(_activityData), std::cend(_activityData), [&sinceId](const QJsonValue ¤tActivityValue) {
|
|
||||||
const auto currentActivityId =
|
|
||||||
currentActivityValue.toObject().value(QStringLiteral("activity_id")).toInt();
|
|
||||||
return currentActivityId == sinceId;
|
|
||||||
});
|
|
||||||
|
|
||||||
const int startIndex = itFound != std::cend(_activityData)
|
|
||||||
? static_cast<int>(std::distance(std::cbegin(_activityData), itFound))
|
|
||||||
: -1;
|
|
||||||
|
|
||||||
if (startIndex > 0) {
|
|
||||||
for (int dataIndex = startIndex, iteration = 0; dataIndex >= 0 && iteration < limit;
|
|
||||||
--dataIndex, ++iteration) {
|
|
||||||
if (_activityData[dataIndex].toObject().value(QStringLiteral("activity_id")).toInt()
|
|
||||||
> sinceId - limit) {
|
|
||||||
data.append(_activityData[dataIndex]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject root;
|
|
||||||
QJsonObject ocs;
|
|
||||||
ocs.insert(QStringLiteral("data"), data);
|
|
||||||
root.insert(QStringLiteral("ocs"), ocs);
|
|
||||||
|
|
||||||
return QJsonDocument(root).toJson();
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonValue activityById(int id)
|
|
||||||
{
|
|
||||||
const auto itFound = std::find_if(
|
|
||||||
std::cbegin(_activityData), std::cend(_activityData), [&id](const QJsonValue ¤tActivityValue) {
|
|
||||||
const auto currentActivityId =
|
|
||||||
currentActivityValue.toObject().value(QStringLiteral("activity_id")).toInt();
|
|
||||||
return currentActivityId == id;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (itFound != std::cend(_activityData)) {
|
|
||||||
return (*itFound);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
int startingIdLast() const { return _startingId; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
static FakeRemoteActivityStorage *_instance;
|
|
||||||
QJsonArray _activityData;
|
|
||||||
QVariantMap _metaSuccess;
|
|
||||||
quint32 _numItemsToInsert = 30;
|
|
||||||
int _startingId = startingId;
|
|
||||||
};
|
|
||||||
|
|
||||||
FakeRemoteActivityStorage *FakeRemoteActivityStorage::_instance = nullptr;
|
|
||||||
|
|
||||||
class TestingALM : public OCC::ActivityListModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
TestingALM() = default;
|
|
||||||
|
|
||||||
void startFetchJob() override
|
|
||||||
{
|
|
||||||
auto *job = new OCC::JsonApiJob(
|
|
||||||
accountState()->account(), QLatin1String("ocs/v2.php/apps/activity/api/v2/activity"), this);
|
|
||||||
QObject::connect(this, &TestingALM::activityJobStatusCode, this, &TestingALM::slotProcessReceivedActivities);
|
|
||||||
QObject::connect(job, &OCC::JsonApiJob::jsonReceived, this, &TestingALM::activitiesReceived);
|
|
||||||
|
|
||||||
QUrlQuery params;
|
|
||||||
params.addQueryItem(QLatin1String("since"), QString::number(currentItem()));
|
|
||||||
params.addQueryItem(QLatin1String("limit"), QString::number(50));
|
|
||||||
job->addQueryParams(params);
|
|
||||||
|
|
||||||
job->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void slotProcessReceivedActivities()
|
|
||||||
{
|
|
||||||
if (rowCount() > _numRowsPrev) {
|
|
||||||
auto finalListCopy = finalList();
|
|
||||||
for (int i = _numRowsPrev; i < rowCount(); ++i) {
|
|
||||||
const auto modelIndex = index(i, 0);
|
|
||||||
auto activity = finalListCopy.at(modelIndex.row());
|
|
||||||
if (activity._links.isEmpty()) {
|
|
||||||
const auto activityJsonObject = FakeRemoteActivityStorage::instance()->activityById(activity._id);
|
|
||||||
|
|
||||||
if (!activityJsonObject.isNull()) {
|
|
||||||
// because "_links" are normally populated within the notificationhandler.cpp, which we don't run as part of this unit test, we have to fill them here
|
|
||||||
// TODO: move the logic to populate "_links" to "activitylistmodel.cpp"
|
|
||||||
auto actions = activityJsonObject.toObject().value("actions").toArray();
|
|
||||||
foreach (auto action, actions) {
|
|
||||||
activity._links.append(OCC::ActivityLink::createFomJsonObject(action.toObject()));
|
|
||||||
}
|
|
||||||
|
|
||||||
finalListCopy[modelIndex.row()] = activity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setFinalList(finalListCopy);
|
|
||||||
}
|
|
||||||
_numRowsPrev = rowCount();
|
|
||||||
emit activitiesProcessed();
|
|
||||||
}
|
|
||||||
signals:
|
|
||||||
void activitiesProcessed();
|
|
||||||
|
|
||||||
private:
|
|
||||||
int _numRowsPrev = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TestActivityListModel : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
TestActivityListModel() = default;
|
|
||||||
~TestActivityListModel() override {
|
|
||||||
OCC::AccountManager::instance()->deleteAccount(accountState.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
QScopedPointer<FakeQNAM> fakeQnam;
|
|
||||||
OCC::AccountPtr account;
|
|
||||||
QScopedPointer<OCC::AccountState> accountState;
|
|
||||||
|
|
||||||
OCC::Activity testNotificationActivity;
|
|
||||||
|
|
||||||
static constexpr int searchResultsReplyDelay = 100;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void initTestCase()
|
|
||||||
{
|
|
||||||
fakeQnam.reset(new FakeQNAM({}));
|
|
||||||
account = OCC::Account::create();
|
|
||||||
account->setCredentials(new FakeCredentials{fakeQnam.data()});
|
|
||||||
account->setUrl(QUrl(("http://example.de")));
|
|
||||||
|
|
||||||
accountState.reset(new OCC::AccountState(account));
|
|
||||||
|
|
||||||
fakeQnam->setOverride([this](QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *device) {
|
|
||||||
Q_UNUSED(device);
|
|
||||||
QNetworkReply *reply = nullptr;
|
|
||||||
|
|
||||||
const auto urlQuery = QUrlQuery(req.url());
|
|
||||||
const auto format = urlQuery.queryItemValue(QStringLiteral("format"));
|
|
||||||
const auto since = urlQuery.queryItemValue(QStringLiteral("since")).toInt();
|
|
||||||
const auto limit = urlQuery.queryItemValue(QStringLiteral("limit")).toInt();
|
|
||||||
const auto path = req.url().path();
|
|
||||||
|
|
||||||
if (!req.url().toString().startsWith(accountState->account()->url().toString())) {
|
|
||||||
reply = new FakeErrorReply(op, req, this, 404, fake404Response);
|
|
||||||
}
|
|
||||||
if (format != QStringLiteral("json")) {
|
|
||||||
reply = new FakeErrorReply(op, req, this, 400, fake400Response);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.startsWith(QStringLiteral("/ocs/v2.php/apps/activity/api/v2/activity"))) {
|
|
||||||
reply = new FakePayloadReply(op, req, FakeRemoteActivityStorage::instance()->activityJsonData(since, limit), searchResultsReplyDelay, fakeQnam.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reply) {
|
|
||||||
return qobject_cast<QNetworkReply*>(new FakeErrorReply(op, req, this, 404, QByteArrayLiteral("{error: \"Not found!\"}")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return reply;
|
|
||||||
});
|
|
||||||
|
|
||||||
OCC::AccountManager::instance()->addAccount(account);
|
|
||||||
|
|
||||||
// Activity comparison is done by checking type, id, and accName
|
|
||||||
// We need an activity with these details, at least
|
|
||||||
testNotificationActivity._accName = accountState->account()->displayName();
|
|
||||||
testNotificationActivity._id = 1;
|
|
||||||
testNotificationActivity._type = OCC::Activity::NotificationType;
|
|
||||||
testNotificationActivity._dateTime = QDateTime::currentDateTime();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Test receiving activity from server
|
|
||||||
void testFetchingRemoteActivity() {
|
|
||||||
TestingALM model;
|
|
||||||
model.setAccountState(accountState.data());
|
|
||||||
QAbstractItemModelTester modelTester(&model);
|
|
||||||
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
|
|
||||||
model.setCurrentItem(FakeRemoteActivityStorage::instance()->startingIdLast());
|
|
||||||
model.startFetchJob();
|
|
||||||
QSignalSpy activitiesJob(&model, &TestingALM::activitiesProcessed);
|
|
||||||
QVERIFY(activitiesJob.wait(3000));
|
|
||||||
QCOMPARE(model.rowCount(), 50);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Test receiving activity from local user action
|
|
||||||
void testLocalSyncFileAction() {
|
|
||||||
TestingALM model;
|
|
||||||
model.setAccountState(accountState.data());
|
|
||||||
QAbstractItemModelTester modelTester(&model);
|
|
||||||
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
|
|
||||||
OCC::Activity activity;
|
|
||||||
|
|
||||||
model.addSyncFileItemToActivityList(activity);
|
|
||||||
QCOMPARE(model.rowCount(), 1);
|
|
||||||
|
|
||||||
const auto index = model.index(0, 0);
|
|
||||||
QVERIFY(index.isValid());
|
|
||||||
};
|
|
||||||
|
|
||||||
void testAddNotification() {
|
|
||||||
TestingALM model;
|
|
||||||
model.setAccountState(accountState.data());
|
|
||||||
QAbstractItemModelTester modelTester(&model);
|
|
||||||
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
|
|
||||||
model.addNotificationToActivityList(testNotificationActivity);
|
|
||||||
QCOMPARE(model.rowCount(), 1);
|
|
||||||
|
|
||||||
const auto index = model.index(0, 0);
|
|
||||||
QVERIFY(index.isValid());
|
|
||||||
};
|
|
||||||
|
|
||||||
void testAddError() {
|
|
||||||
TestingALM model;
|
|
||||||
model.setAccountState(accountState.data());
|
|
||||||
QAbstractItemModelTester modelTester(&model);
|
|
||||||
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
|
|
||||||
OCC::Activity activity;
|
|
||||||
|
|
||||||
model.addErrorToActivityList(activity);
|
|
||||||
QCOMPARE(model.rowCount(), 1);
|
|
||||||
|
|
||||||
const auto index = model.index(0, 0);
|
|
||||||
QVERIFY(index.isValid());
|
|
||||||
};
|
|
||||||
|
|
||||||
void testAddIgnoredFile() {
|
|
||||||
TestingALM model;
|
|
||||||
model.setAccountState(accountState.data());
|
|
||||||
QAbstractItemModelTester modelTester(&model);
|
|
||||||
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
|
|
||||||
OCC::Activity activity;
|
|
||||||
activity._folder = QStringLiteral("thingy");
|
|
||||||
activity._file = QStringLiteral("test.txt");
|
|
||||||
|
|
||||||
model.addIgnoredFileToList(activity);
|
|
||||||
// We need to add another activity to the model for the combineActivityLists method to be called
|
|
||||||
model.addNotificationToActivityList(testNotificationActivity);
|
|
||||||
QCOMPARE(model.rowCount(), 2);
|
|
||||||
|
|
||||||
const auto index = model.index(0, 0);
|
|
||||||
QVERIFY(index.isValid());
|
|
||||||
};
|
|
||||||
|
|
||||||
// Test removing activity from list
|
|
||||||
void testRemoveActivityWithRow() {
|
|
||||||
TestingALM model;
|
|
||||||
model.setAccountState(accountState.data());
|
|
||||||
QAbstractItemModelTester modelTester(&model);
|
|
||||||
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
|
|
||||||
model.addNotificationToActivityList(testNotificationActivity);
|
|
||||||
QCOMPARE(model.rowCount(), 1);
|
|
||||||
|
|
||||||
model.removeActivityFromActivityList(0);
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void testRemoveActivityWithActivity() {
|
|
||||||
TestingALM model;
|
|
||||||
model.setAccountState(accountState.data());
|
|
||||||
QAbstractItemModelTester modelTester(&model);
|
|
||||||
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
|
|
||||||
model.addNotificationToActivityList(testNotificationActivity);
|
|
||||||
QCOMPARE(model.rowCount(), 1);
|
|
||||||
|
|
||||||
model.removeActivityFromActivityList(testNotificationActivity);
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test getting the data from the model
|
|
||||||
void testData() {
|
|
||||||
TestingALM model;
|
|
||||||
model.setAccountState(accountState.data());
|
|
||||||
QAbstractItemModelTester modelTester(&model);
|
|
||||||
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
|
|
||||||
model.setCurrentItem(FakeRemoteActivityStorage::instance()->startingIdLast());
|
|
||||||
model.startFetchJob();
|
|
||||||
QSignalSpy activitiesJob(&model, &TestingALM::activitiesProcessed);
|
|
||||||
QVERIFY(activitiesJob.wait(3000));
|
|
||||||
QCOMPARE(model.rowCount(), 50);
|
|
||||||
|
|
||||||
model.addNotificationToActivityList(testNotificationActivity);
|
|
||||||
QCOMPARE(model.rowCount(), 51);
|
|
||||||
|
|
||||||
OCC::Activity syncResultActivity;
|
|
||||||
syncResultActivity._id = 2;
|
|
||||||
syncResultActivity._type = OCC::Activity::SyncResultType;
|
|
||||||
syncResultActivity._status = OCC::SyncResult::Error;
|
|
||||||
syncResultActivity._dateTime = QDateTime::currentDateTime();
|
|
||||||
syncResultActivity._subject = QStringLiteral("Sample failed sync text");
|
|
||||||
syncResultActivity._message = QStringLiteral("/path/to/thingy");
|
|
||||||
syncResultActivity._link = QStringLiteral("/path/to/thingy");
|
|
||||||
syncResultActivity._accName = accountState->account()->displayName();
|
|
||||||
model.addSyncFileItemToActivityList(syncResultActivity);
|
|
||||||
QCOMPARE(model.rowCount(), 52);
|
|
||||||
|
|
||||||
OCC::Activity syncFileItemActivity;
|
|
||||||
syncFileItemActivity._id = 3;
|
|
||||||
syncFileItemActivity._type = OCC::Activity::SyncFileItemType; //client activity
|
|
||||||
syncFileItemActivity._status = OCC::SyncFileItem::Success;
|
|
||||||
syncFileItemActivity._dateTime = QDateTime::currentDateTime();
|
|
||||||
syncFileItemActivity._message = QStringLiteral("You created xyz.pdf");
|
|
||||||
syncFileItemActivity._link = accountState->account()->url();
|
|
||||||
syncFileItemActivity._accName = accountState->account()->displayName();
|
|
||||||
syncFileItemActivity._file = QStringLiteral("xyz.pdf");
|
|
||||||
syncFileItemActivity._fileAction = "";
|
|
||||||
model.addSyncFileItemToActivityList(syncFileItemActivity);
|
|
||||||
QCOMPARE(model.rowCount(), 53);
|
|
||||||
|
|
||||||
// Test all rows for things in common
|
|
||||||
for (int i = 0; i < model.rowCount(); i++) {
|
|
||||||
const auto index = model.index(i, 0);
|
|
||||||
|
|
||||||
auto text = index.data(OCC::ActivityListModel::ActionTextRole).toString();
|
|
||||||
|
|
||||||
QVERIFY(index.data(OCC::ActivityListModel::ActionRole).canConvert<int>());
|
|
||||||
const auto type = index.data(OCC::ActivityListModel::ActionRole).toInt();
|
|
||||||
QVERIFY(type >= OCC::Activity::ActivityType);
|
|
||||||
|
|
||||||
QVERIFY(!index.data(OCC::ActivityListModel::ObjectTypeRole).toInt());
|
|
||||||
QVERIFY(!index.data(OCC::ActivityListModel::AccountRole).toString().isEmpty());
|
|
||||||
QVERIFY(!index.data(OCC::ActivityListModel::ActionTextColorRole).toString().isEmpty());
|
|
||||||
QVERIFY(!index.data(OCC::ActivityListModel::ActionIconRole).toString().isEmpty());
|
|
||||||
QVERIFY(!index.data(OCC::ActivityListModel::PointInTimeRole).toString().isEmpty());
|
|
||||||
|
|
||||||
QVERIFY(index.data(OCC::ActivityListModel::ActionsLinksRole).canConvert<QList<QVariant>>());
|
|
||||||
QVERIFY(index.data(OCC::ActivityListModel::ActionTextRole).canConvert<QString>());
|
|
||||||
QVERIFY(index.data(OCC::ActivityListModel::MessageRole).canConvert<QString>());
|
|
||||||
QVERIFY(index.data(OCC::ActivityListModel::LinkRole).canConvert<QUrl>());
|
|
||||||
QVERIFY(index.data(OCC::ActivityListModel::AccountConnectedRole).canConvert<bool>());
|
|
||||||
QVERIFY(index.data(OCC::ActivityListModel::DisplayActions).canConvert<bool>());
|
|
||||||
|
|
||||||
// Unfortunately, trying to check anything relating to filepaths causes a crash
|
|
||||||
// when the folder manager is invoked by the model to look for the relevant file
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void tesActivityActionstData()
|
|
||||||
{
|
|
||||||
TestingALM model;
|
|
||||||
model.setAccountState(accountState.data());
|
|
||||||
QAbstractItemModelTester modelTester(&model);
|
|
||||||
|
|
||||||
QCOMPARE(model.rowCount(), 0);
|
|
||||||
model.setCurrentItem(FakeRemoteActivityStorage::instance()->startingIdLast());
|
|
||||||
|
|
||||||
int prevModelRowCount = model.rowCount();
|
|
||||||
|
|
||||||
do {
|
|
||||||
prevModelRowCount = model.rowCount();
|
|
||||||
model.startFetchJob();
|
|
||||||
QSignalSpy activitiesJob(&model, &TestingALM::activitiesProcessed);
|
|
||||||
QVERIFY(activitiesJob.wait(3000));
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = prevModelRowCount; i < model.rowCount(); i++) {
|
|
||||||
const auto index = model.index(i, 0);
|
|
||||||
|
|
||||||
const auto actionsLinks = index.data(OCC::ActivityListModel::ActionsLinksRole).toList();
|
|
||||||
if (!actionsLinks.isEmpty()) {
|
|
||||||
const auto actionsLinksContextMenu =
|
|
||||||
index.data(OCC::ActivityListModel::ActionsLinksContextMenuRole).toList();
|
|
||||||
|
|
||||||
// context menu must be shorter than total action links
|
|
||||||
QVERIFY(actionsLinks.isEmpty() || actionsLinksContextMenu.size() < actionsLinks.size());
|
|
||||||
|
|
||||||
// context menu must not contain the primary action
|
|
||||||
QVERIFY(std::find_if(std::begin(actionsLinksContextMenu), std::end(actionsLinksContextMenu),
|
|
||||||
[](const QVariant &entry) { return entry.value<OCC::ActivityLink>()._primary; })
|
|
||||||
== std::end(actionsLinksContextMenu));
|
|
||||||
|
|
||||||
const auto objectType = index.data(OCC::ActivityListModel::ObjectTypeRole).toString();
|
|
||||||
|
|
||||||
if ((objectType == QStringLiteral("chat") || objectType == QStringLiteral("call")
|
|
||||||
|| objectType == QStringLiteral("room"))) {
|
|
||||||
const auto actionButtonsLinks =
|
|
||||||
index.data(OCC::ActivityListModel::ActionsLinksForActionButtonsRole).toList();
|
|
||||||
|
|
||||||
// both action links and buttons must contain a "WEB" verb element at the beginning
|
|
||||||
QVERIFY(actionsLinks[0].value<OCC::ActivityLink>()._verb == QStringLiteral("WEB"));
|
|
||||||
QVERIFY(actionButtonsLinks[0].value<OCC::ActivityLink>()._verb == QStringLiteral("WEB"));
|
|
||||||
|
|
||||||
// the first action button for chat must have image set
|
|
||||||
QVERIFY(!actionButtonsLinks[0].value<OCC::ActivityLink>()._imageSource.isEmpty());
|
|
||||||
QVERIFY(!actionButtonsLinks[0].value<OCC::ActivityLink>()._imageSourceHovered.isEmpty());
|
|
||||||
|
|
||||||
// logic for "chat" and other types of activities with multiple actions
|
|
||||||
if ((objectType == QStringLiteral("chat")
|
|
||||||
|| (objectType != QStringLiteral("room") && objectType != QStringLiteral("call")))) {
|
|
||||||
|
|
||||||
// button's label for "chat" must be renamed to "Reply"
|
|
||||||
QVERIFY(actionButtonsLinks[0].value<OCC::ActivityLink>()._label == QObject::tr("Reply"));
|
|
||||||
|
|
||||||
if (static_cast<quint32>(actionsLinks.size()) > OCC::ActivityListModel::maxActionButtons()) {
|
|
||||||
// in case total actions is longer than ActivityListModel::maxActionButtons, only one button must be present in a list of action buttons
|
|
||||||
QVERIFY(actionButtonsLinks.size() == 1);
|
|
||||||
const auto actionButtonsAndContextMenuEntries = actionButtonsLinks + actionsLinksContextMenu;
|
|
||||||
// in case total actions is longer than ActivityListModel::maxActionButtons, then a sum of action buttons and action menu entries must be equal to a total of action links
|
|
||||||
QVERIFY(actionButtonsLinks.size() + actionsLinksContextMenu.size() == actionsLinks.size());
|
|
||||||
} else {
|
|
||||||
// in case a total of actions is less or equal to than ActivityListModel::maxActionButtons, then the length of action buttons must be greater than 1 and should contain "Mark as read" button at the end
|
|
||||||
QVERIFY(actionButtonsLinks.size() > 1);
|
|
||||||
QVERIFY(actionButtonsLinks[1].value<OCC::ActivityLink>()._label
|
|
||||||
== QObject::tr("Mark as read"));
|
|
||||||
}
|
|
||||||
} else if ((objectType == QStringLiteral("call"))) {
|
|
||||||
QVERIFY(
|
|
||||||
actionButtonsLinks[0].value<OCC::ActivityLink>()._label == QStringLiteral("Call back"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QVERIFY(actionsLinks[0].value<OCC::ActivityLink>()._label == QStringLiteral("Dismiss"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (prevModelRowCount < model.rowCount());
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
QTEST_MAIN(TestActivityListModel)
|
|
||||||
#include "testactivitylistmodel.moc"
|
|
||||||
@@ -25,7 +25,6 @@ using namespace OCC::Utility;
|
|||||||
QTemporaryDir _root;
|
QTemporaryDir _root;
|
||||||
QString _testfile;
|
QString _testfile;
|
||||||
QString _expectedError;
|
QString _expectedError;
|
||||||
ValidateChecksumHeader::FailureReason _expectedFailureReason = ValidateChecksumHeader::FailureReason::Success;
|
|
||||||
QByteArray _expected;
|
QByteArray _expected;
|
||||||
QByteArray _expectedType;
|
QByteArray _expectedType;
|
||||||
bool _successDown;
|
bool _successDown;
|
||||||
@@ -43,14 +42,10 @@ using namespace OCC::Utility;
|
|||||||
_successDown = true;
|
_successDown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void slotDownError(const QString &errMsg, const QByteArray &calculatedChecksumType,
|
void slotDownError(const QString &errMsg)
|
||||||
const QByteArray &calculatedChecksum, const ValidateChecksumHeader::FailureReason reason)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(calculatedChecksumType);
|
QCOMPARE(_expectedError, errMsg);
|
||||||
Q_UNUSED(calculatedChecksum);
|
_errorSeen = true;
|
||||||
QCOMPARE(_expectedError, errMsg);
|
|
||||||
QCOMPARE(_expectedFailureReason, reason);
|
|
||||||
_errorSeen = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray shellSum( const QByteArray& cmd, const QString& file )
|
static QByteArray shellSum( const QByteArray& cmd, const QString& file )
|
||||||
@@ -203,14 +198,12 @@ using namespace OCC::Utility;
|
|||||||
QTRY_VERIFY(_successDown);
|
QTRY_VERIFY(_successDown);
|
||||||
|
|
||||||
_expectedError = QStringLiteral("The downloaded file does not match the checksum, it will be resumed. \"543345\" != \"%1\"").arg(QString::fromUtf8(_expected));
|
_expectedError = QStringLiteral("The downloaded file does not match the checksum, it will be resumed. \"543345\" != \"%1\"").arg(QString::fromUtf8(_expected));
|
||||||
_expectedFailureReason = ValidateChecksumHeader::FailureReason::ChecksumMismatch;
|
|
||||||
_errorSeen = false;
|
_errorSeen = false;
|
||||||
file->seek(0);
|
file->seek(0);
|
||||||
vali->start(_testfile, "Adler32:543345");
|
vali->start(_testfile, "Adler32:543345");
|
||||||
QTRY_VERIFY(_errorSeen);
|
QTRY_VERIFY(_errorSeen);
|
||||||
|
|
||||||
_expectedError = QLatin1String("The checksum header contained an unknown checksum type \"Klaas32\"");
|
_expectedError = QLatin1String("The checksum header contained an unknown checksum type \"Klaas32\"");
|
||||||
_expectedFailureReason = ValidateChecksumHeader::FailureReason::ChecksumTypeUnknown;
|
|
||||||
_errorSeen = false;
|
_errorSeen = false;
|
||||||
file->seek(0);
|
file->seek(0);
|
||||||
vali->start(_testfile, "Klaas32:543345");
|
vali->start(_testfile, "Klaas32:543345");
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
#include "syncenginetestutils.h"
|
#include "syncenginetestutils.h"
|
||||||
#include <syncengine.h>
|
#include <syncengine.h>
|
||||||
#include <propagatorjobs.h>
|
|
||||||
|
|
||||||
using namespace OCC;
|
using namespace OCC;
|
||||||
|
|
||||||
@@ -552,27 +551,16 @@ private slots:
|
|||||||
QObject parent;
|
QObject parent;
|
||||||
|
|
||||||
QByteArray checksumValue;
|
QByteArray checksumValue;
|
||||||
QByteArray checksumValueRecalculated;
|
|
||||||
QByteArray contentMd5Value;
|
QByteArray contentMd5Value;
|
||||||
bool isChecksumRecalculateSupported = false;
|
|
||||||
|
|
||||||
fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * {
|
fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * {
|
||||||
if (op == QNetworkAccessManager::GetOperation) {
|
if (op == QNetworkAccessManager::GetOperation) {
|
||||||
auto reply = new FakeGetReply(fakeFolder.remoteModifier(), op, request, &parent);
|
auto reply = new FakeGetReply(fakeFolder.remoteModifier(), op, request, &parent);
|
||||||
if (!checksumValue.isNull())
|
if (!checksumValue.isNull())
|
||||||
reply->setRawHeader(OCC::checkSumHeaderC, checksumValue);
|
reply->setRawHeader("OC-Checksum", checksumValue);
|
||||||
if (!contentMd5Value.isNull())
|
if (!contentMd5Value.isNull())
|
||||||
reply->setRawHeader(OCC::contentMd5HeaderC, contentMd5Value);
|
reply->setRawHeader("Content-MD5", contentMd5Value);
|
||||||
return reply;
|
return reply;
|
||||||
} else if (op == QNetworkAccessManager::CustomOperation) {
|
|
||||||
if (request.hasRawHeader(OCC::checksumRecalculateOnServerHeaderC)) {
|
|
||||||
if (!isChecksumRecalculateSupported) {
|
|
||||||
return new FakeErrorReply(op, request, &parent, 402);
|
|
||||||
}
|
|
||||||
auto reply = new FakeGetReply(fakeFolder.remoteModifier(), op, request, &parent);
|
|
||||||
reply->setRawHeader(OCC::checkSumHeaderC, checksumValueRecalculated);
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
});
|
});
|
||||||
@@ -587,11 +575,8 @@ private slots:
|
|||||||
fakeFolder.remoteModifier().create("A/a4", 16, 'A');
|
fakeFolder.remoteModifier().create("A/a4", 16, 'A');
|
||||||
QVERIFY(!fakeFolder.syncOnce());
|
QVERIFY(!fakeFolder.syncOnce());
|
||||||
|
|
||||||
const QByteArray matchedSha1Checksum(QByteArrayLiteral("SHA1:19b1928d58a2030d08023f3d7054516dbc186f20"));
|
|
||||||
const QByteArray mismatchedSha1Checksum(matchedSha1Checksum.chopped(1));
|
|
||||||
|
|
||||||
// Good OC-Checksum
|
// Good OC-Checksum
|
||||||
checksumValue = matchedSha1Checksum; // printf 'A%.0s' {1..16} | sha1sum -
|
checksumValue = "SHA1:19b1928d58a2030d08023f3d7054516dbc186f20"; // printf 'A%.0s' {1..16} | sha1sum -
|
||||||
QVERIFY(fakeFolder.syncOnce());
|
QVERIFY(fakeFolder.syncOnce());
|
||||||
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||||
checksumValue = QByteArray();
|
checksumValue = QByteArray();
|
||||||
@@ -625,35 +610,6 @@ private slots:
|
|||||||
checksumValue = "Unsupported:XXXX SHA1:19b1928d58a2030d08023f3d7054516dbc186f20 Invalid:XxX";
|
checksumValue = "Unsupported:XXXX SHA1:19b1928d58a2030d08023f3d7054516dbc186f20 Invalid:XxX";
|
||||||
QVERIFY(fakeFolder.syncOnce()); // The supported SHA1 checksum is valid now, so the file are downloaded
|
QVERIFY(fakeFolder.syncOnce()); // The supported SHA1 checksum is valid now, so the file are downloaded
|
||||||
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||||
|
|
||||||
// Begin Test mismatch recalculation---------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const auto prevServerVersion = fakeFolder.account()->serverVersion();
|
|
||||||
fakeFolder.account()->setServerVersion(QString("%1.0.0").arg(fakeFolder.account()->checksumRecalculateServerVersionMinSupportedMajor()));
|
|
||||||
|
|
||||||
// Mismatched OC-Checksum and X-Recalculate-Hash is not supported -> sync must fail
|
|
||||||
isChecksumRecalculateSupported = false;
|
|
||||||
checksumValue = mismatchedSha1Checksum;
|
|
||||||
checksumValueRecalculated = matchedSha1Checksum;
|
|
||||||
fakeFolder.remoteModifier().create("A/a9", 16, 'A');
|
|
||||||
QVERIFY(!fakeFolder.syncOnce());
|
|
||||||
|
|
||||||
// Mismatched OC-Checksum and X-Recalculate-Hash is supported, but, recalculated checksum is again mismatched -> sync must fail
|
|
||||||
isChecksumRecalculateSupported = true;
|
|
||||||
checksumValue = mismatchedSha1Checksum;
|
|
||||||
checksumValueRecalculated = mismatchedSha1Checksum;
|
|
||||||
QVERIFY(!fakeFolder.syncOnce());
|
|
||||||
|
|
||||||
// Mismatched OC-Checksum and X-Recalculate-Hash is supported, and, recalculated checksum is a match -> sync must succeed
|
|
||||||
isChecksumRecalculateSupported = true;
|
|
||||||
checksumValue = mismatchedSha1Checksum;
|
|
||||||
checksumValueRecalculated = matchedSha1Checksum;
|
|
||||||
QVERIFY(fakeFolder.syncOnce());
|
|
||||||
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
|
||||||
checksumValue = QByteArray();
|
|
||||||
|
|
||||||
fakeFolder.account()->setServerVersion(prevServerVersion);
|
|
||||||
// End Test mismatch recalculation-----------------------------------------------------------------------------------
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the behavior of invalid filename detection
|
// Tests the behavior of invalid filename detection
|
||||||
|
|||||||
@@ -202,7 +202,6 @@
|
|||||||
<file>theme/share.svg</file>
|
<file>theme/share.svg</file>
|
||||||
<file>theme/reply.svg</file>
|
<file>theme/reply.svg</file>
|
||||||
<file>theme/magnifying-glass.svg</file>
|
<file>theme/magnifying-glass.svg</file>
|
||||||
<file>theme/external.svg</file>
|
|
||||||
<file>theme/colored/user-status-online.svg</file>
|
<file>theme/colored/user-status-online.svg</file>
|
||||||
<file>theme/colored/user-status-invisible.svg</file>
|
<file>theme/colored/user-status-invisible.svg</file>
|
||||||
<file>theme/colored/user-status-away.svg</file>
|
<file>theme/colored/user-status-away.svg</file>
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
|
|
||||||
import QtQuick 2.15
|
// Minimum for this is Qt 5.5
|
||||||
|
import QtQuick 2.5
|
||||||
|
|
||||||
import com.nextcloud.desktopclient 1.0
|
import com.nextcloud.desktopclient 1.0
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
readonly property int pixelSize: fontMetrics.font.pixelSize
|
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
property color ncBlue: Theme.wizardHeaderBackgroundColor
|
property color ncBlue: Theme.wizardHeaderBackgroundColor
|
||||||
property color ncTextColor: Theme.wizardHeaderTitleColor
|
property color ncTextColor: Theme.wizardHeaderTitleColor
|
||||||
@@ -20,15 +19,15 @@ QtObject {
|
|||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
// We are using pixel size because this is cross platform comparable, point size isn't
|
// We are using pixel size because this is cross platform comparable, point size isn't
|
||||||
readonly property int topLinePixelSize: pixelSize
|
property int topLinePixelSize: 12
|
||||||
readonly property int subLinePixelSize: topLinePixelSize - 2
|
property int subLinePixelSize: 10
|
||||||
|
|
||||||
// Dimensions and sizes
|
// Dimensions and sizes
|
||||||
property int trayWindowWidth: variableSize(400)
|
property int trayWindowWidth: 400
|
||||||
property int trayWindowHeight: variableSize(510)
|
property int trayWindowHeight: 510
|
||||||
property int trayWindowRadius: 10
|
property int trayWindowRadius: 10
|
||||||
property int trayWindowBorderWidth: 1
|
property int trayWindowBorderWidth: 1
|
||||||
property int trayWindowHeaderHeight: variableSize(60)
|
property int trayWindowHeaderHeight: 60
|
||||||
|
|
||||||
property int currentAccountButtonWidth: 220
|
property int currentAccountButtonWidth: 220
|
||||||
property int currentAccountButtonRadius: 2
|
property int currentAccountButtonRadius: 2
|
||||||
@@ -50,12 +49,6 @@ QtObject {
|
|||||||
property int headerButtonIconSize: 32
|
property int headerButtonIconSize: 32
|
||||||
|
|
||||||
property int activityLabelBaseWidth: 240
|
property int activityLabelBaseWidth: 240
|
||||||
|
|
||||||
property int activityItemActionPrimaryButtonMinWidth: 100
|
|
||||||
property int activityItemActionSecondaryButtonMinWidth: 80
|
|
||||||
|
|
||||||
property int roundButtonBackgroundVerticalMargins: 10
|
|
||||||
property int roundedButtonBackgroundVerticalMargins: 5
|
|
||||||
|
|
||||||
property int userStatusEmojiSize: 8
|
property int userStatusEmojiSize: 8
|
||||||
property int userStatusSpacing: 6
|
property int userStatusSpacing: 6
|
||||||
@@ -79,10 +72,4 @@ QtObject {
|
|||||||
readonly property int unifiedSearchResulSublineFontSize: subLinePixelSize
|
readonly property int unifiedSearchResulSublineFontSize: subLinePixelSize
|
||||||
readonly property string unifiedSearchResulTitleColor: "black"
|
readonly property string unifiedSearchResulTitleColor: "black"
|
||||||
readonly property string unifiedSearchResulSublineColor: "grey"
|
readonly property string unifiedSearchResulSublineColor: "grey"
|
||||||
|
|
||||||
readonly property var fontMetrics: FontMetrics {}
|
|
||||||
|
|
||||||
function variableSize(size) {
|
|
||||||
return size * (1 + Math.min(pixelSize / 100, 1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M3.2 2C2.53 2 2 2.54 2 3.2v9.6c0 .67.53 1.2 1.2 1.2h9.6c.67 0 1.2-.53 1.2-1.2V8.98l-1.2-1.2v5.02H3.2V3.2h5.02L7.08 2.06 7.02 2H3.2z"/><path d="M8.14 1l2.29 2.29L7 6.7 9.29 9l3.42-3.43L15 7.86V1z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 275 B |
@@ -1,4 +1,12 @@
|
|||||||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="bg_BG">
|
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="bg_BG">
|
||||||
|
<context>
|
||||||
|
<name>ActivityActionButton</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
||||||
|
<source>Activity action button</source>
|
||||||
|
<translation>Бутон за активиране на действие </translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ActivityItem</name>
|
<name>ActivityItem</name>
|
||||||
<message>
|
<message>
|
||||||
@@ -11,17 +19,6 @@
|
|||||||
<source>Open %1 locally</source>
|
<source>Open %1 locally</source>
|
||||||
<translation>Отворяне %1 локално</translation>
|
<translation>Отворяне %1 локално</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation>Показване на повече действия</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
|
||||||
<source>View activity</source>
|
|
||||||
<translation>Вижте активността</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
@@ -32,28 +29,16 @@
|
|||||||
<source>Share %1</source>
|
<source>Share %1</source>
|
||||||
<translation>Споделяне %1</translation>
|
<translation>Споделяне %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemActions</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="77"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="79"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Показване на повече действия</translation>
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemContent</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="90"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="92"/>
|
|
||||||
<source>Dismiss</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="121"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
||||||
<source>Open share dialog</source>
|
<source>View activity</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Вижте активността</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -850,17 +835,17 @@ This action will abort any currently running synchronization.</source>
|
|||||||
<translation>Продължи</translation>
|
<translation>Продължи</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="316"/>
|
<location filename="../src/gui/application.cpp" line="312"/>
|
||||||
<source>Error accessing the configuration file</source>
|
<source>Error accessing the configuration file</source>
|
||||||
<translation>Грешка при опита за отваряне на конфигурационния файл</translation>
|
<translation>Грешка при опита за отваряне на конфигурационния файл</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="317"/>
|
<location filename="../src/gui/application.cpp" line="313"/>
|
||||||
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
||||||
<translation>Възникна грешка при достъпа до конфигурационния файл при % 1 . Моля да се уверите, че вашият потребител има достъп до файла.</translation>
|
<translation>Възникна грешка при достъпа до конфигурационния файл при % 1 . Моля да се уверите, че вашият потребител има достъп до файла.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="320"/>
|
<location filename="../src/gui/application.cpp" line="316"/>
|
||||||
<source>Quit %1</source>
|
<source>Quit %1</source>
|
||||||
<translation>Напускане %1</translation>
|
<translation>Напускане %1</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -2747,27 +2732,27 @@ Logs will be written to %1</source>
|
|||||||
<translation>Скорост на качване</translation>
|
<translation>Скорост на качване</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="40"/>
|
<location filename="../src/gui/networksettings.cpp" line="37"/>
|
||||||
<source>Hostname of proxy server</source>
|
<source>Hostname of proxy server</source>
|
||||||
<translation>Име на прокси сървъра</translation>
|
<translation>Име на прокси сървъра</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
<location filename="../src/gui/networksettings.cpp" line="38"/>
|
||||||
<source>Username for proxy server</source>
|
<source>Username for proxy server</source>
|
||||||
<translation>Потребител за прокси сървъра</translation>
|
<translation>Потребител за прокси сървъра</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
<location filename="../src/gui/networksettings.cpp" line="39"/>
|
||||||
<source>Password for proxy server</source>
|
<source>Password for proxy server</source>
|
||||||
<translation>Парола за прокси сървъра</translation>
|
<translation>Парола за прокси сървъра</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="44"/>
|
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
||||||
<source>HTTP(S) proxy</source>
|
<source>HTTP(S) proxy</source>
|
||||||
<translation>HTTP(S) прокси</translation>
|
<translation>HTTP(S) прокси</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="45"/>
|
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
||||||
<source>SOCKS5 proxy</source>
|
<source>SOCKS5 proxy</source>
|
||||||
<translation>SOCKS5 прокси</translation>
|
<translation>SOCKS5 прокси</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5193,24 +5178,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>OCC::Theme</name>
|
<name>OCC::Theme</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="517"/>
|
<location filename="../src/libsync/theme.cpp" line="508"/>
|
||||||
<source><p>%1 Desktop Client</p></source>
|
<source><p>%1 Desktop Client</p></source>
|
||||||
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
||||||
<translation><p>%1 Клиент за настолен компютър</p></translation>
|
<translation><p>%1 Клиент за настолен компютър</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="520"/>
|
<location filename="../src/libsync/theme.cpp" line="511"/>
|
||||||
<location filename="../src/libsync/theme.cpp" line="535"/>
|
<location filename="../src/libsync/theme.cpp" line="526"/>
|
||||||
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
||||||
<translation><p>Версия %1. За допълнителна информация, моля щракнете <a href='%2'>тук</a>.</p></translation>
|
<translation><p>Версия %1. За допълнителна информация, моля щракнете <a href='%2'>тук</a>.</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="524"/>
|
<location filename="../src/libsync/theme.cpp" line="515"/>
|
||||||
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
||||||
<translation><p><small>Използване на добавка за виртуални файлове: %1</small></p></translation>
|
<translation><p><small>Използване на добавка за виртуални файлове: %1</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="539"/>
|
<location filename="../src/libsync/theme.cpp" line="530"/>
|
||||||
<source><p>This release was supplied by %1</p></source>
|
<source><p>This release was supplied by %1</p></source>
|
||||||
<translation><p>Това издание е предоставено от % 1</p></translation>
|
<translation><p>Това издание е предоставено от % 1</p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5950,16 +5935,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>New folder</source>
|
<source>New folder</source>
|
||||||
<translation>Нова папка</translation>
|
<translation>Нова папка</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="697"/>
|
|
||||||
<source>Mark as read</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="699"/>
|
|
||||||
<source>Reply</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/common/utility.cpp" line="482"/>
|
<location filename="../src/common/utility.cpp" line="482"/>
|
||||||
<source>%n day ago</source>
|
<source>%n day ago</source>
|
||||||
@@ -6410,17 +6385,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
<translation>Отваряне на диалоговия прозорец за споделяне</translation>
|
<translation>Отваряне на диалоговия прозорец за споделяне</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
||||||
|
<source>Unified search results list</source>
|
||||||
|
<translation>Обединен списък с резултати от търсенето</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation>Показване на повече действия</translation>
|
<translation>Показване на повече действия</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
|
||||||
<source>Unified search results list</source>
|
|
||||||
<translation>Обединен списък с резултати от търсенето</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
||||||
<source>%1 - File activity</source>
|
<source>%1 - File activity</source>
|
||||||
@@ -6448,7 +6423,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>nextcloudTheme::about()</name>
|
<name>nextcloudTheme::about()</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="496"/>
|
<location filename="../src/libsync/theme.cpp" line="487"/>
|
||||||
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
||||||
<translation><p><small>Изграден от Git редакция <a href="%1">%2</a> на %3, %4 използвайки Qt %5, %6</small></p></translation>
|
<translation><p><small>Изграден от Git редакция <a href="%1">%2</a> на %3, %4 използвайки Qt %5, %6</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -6803,14 +6778,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<translation>Целият профил се синхронизира с локалната папка</translation>
|
<translation>Целият профил се синхронизира с локалната папка</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ActivityActionButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
|
||||||
<source>Activity action button</source>
|
|
||||||
<translation>Бутон за активиране на действие </translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>OCC::UserStatus</name>
|
<name>OCC::UserStatus</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="br">
|
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="br">
|
||||||
|
<context>
|
||||||
|
<name>ActivityActionButton</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
||||||
|
<source>Activity action button</source>
|
||||||
|
<translation type="unfinished"/>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ActivityItem</name>
|
<name>ActivityItem</name>
|
||||||
<message>
|
<message>
|
||||||
@@ -11,17 +19,6 @@
|
|||||||
<source>Open %1 locally</source>
|
<source>Open %1 locally</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
|
||||||
<source>View activity</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
@@ -32,27 +29,15 @@
|
|||||||
<source>Share %1</source>
|
<source>Share %1</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemActions</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="77"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="79"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemContent</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="90"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="92"/>
|
<source>View activity</source>
|
||||||
<source>Dismiss</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="121"/>
|
|
||||||
<source>Open share dialog</source>
|
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
@@ -846,17 +831,17 @@ This action will abort any currently running synchronization.</source>
|
|||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="316"/>
|
<location filename="../src/gui/application.cpp" line="312"/>
|
||||||
<source>Error accessing the configuration file</source>
|
<source>Error accessing the configuration file</source>
|
||||||
<translation>Ur fazi a zo bet en ur tizhout ar restr arvenntennañ</translation>
|
<translation>Ur fazi a zo bet en ur tizhout ar restr arvenntennañ</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="317"/>
|
<location filename="../src/gui/application.cpp" line="313"/>
|
||||||
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
||||||
<translation>Ur fazi a zo bet en ur tizhout ar restr arvenntennañ e %1. Grit sur eo posupl d'an implijourienn tizhout ar restr.</translation>
|
<translation>Ur fazi a zo bet en ur tizhout ar restr arvenntennañ e %1. Grit sur eo posupl d'an implijourienn tizhout ar restr.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="320"/>
|
<location filename="../src/gui/application.cpp" line="316"/>
|
||||||
<source>Quit %1</source>
|
<source>Quit %1</source>
|
||||||
<translation>Kuitaat %1</translation>
|
<translation>Kuitaat %1</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -2725,27 +2710,27 @@ Skrivet e vo ar gazetenn e %1</translation>
|
|||||||
<translation>Ledannder ar vandenn pellkas</translation>
|
<translation>Ledannder ar vandenn pellkas</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="40"/>
|
<location filename="../src/gui/networksettings.cpp" line="37"/>
|
||||||
<source>Hostname of proxy server</source>
|
<source>Hostname of proxy server</source>
|
||||||
<translation>Anv oster ar servijour proxy</translation>
|
<translation>Anv oster ar servijour proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
<location filename="../src/gui/networksettings.cpp" line="38"/>
|
||||||
<source>Username for proxy server</source>
|
<source>Username for proxy server</source>
|
||||||
<translation>Anv implijer proxy ar servijour</translation>
|
<translation>Anv implijer proxy ar servijour</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
<location filename="../src/gui/networksettings.cpp" line="39"/>
|
||||||
<source>Password for proxy server</source>
|
<source>Password for proxy server</source>
|
||||||
<translation>Ger-tremen proksi ar servijour</translation>
|
<translation>Ger-tremen proksi ar servijour</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="44"/>
|
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
||||||
<source>HTTP(S) proxy</source>
|
<source>HTTP(S) proxy</source>
|
||||||
<translation>Proxy HTTP(S)</translation>
|
<translation>Proxy HTTP(S)</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="45"/>
|
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
||||||
<source>SOCKS5 proxy</source>
|
<source>SOCKS5 proxy</source>
|
||||||
<translation>Proxy SOCKS5</translation>
|
<translation>Proxy SOCKS5</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5164,24 +5149,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>OCC::Theme</name>
|
<name>OCC::Theme</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="517"/>
|
<location filename="../src/libsync/theme.cpp" line="508"/>
|
||||||
<source><p>%1 Desktop Client</p></source>
|
<source><p>%1 Desktop Client</p></source>
|
||||||
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
||||||
<translation><p>%1 Kliant Burev</p></translation>
|
<translation><p>%1 Kliant Burev</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="520"/>
|
<location filename="../src/libsync/theme.cpp" line="511"/>
|
||||||
<location filename="../src/libsync/theme.cpp" line="535"/>
|
<location filename="../src/libsync/theme.cpp" line="526"/>
|
||||||
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
||||||
<translation><p>Stumm %1. Evit muioc'h a ditouroù, klikit <a href='%2'>amañ</a>.</p></translation>
|
<translation><p>Stumm %1. Evit muioc'h a ditouroù, klikit <a href='%2'>amañ</a>.</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="524"/>
|
<location filename="../src/libsync/theme.cpp" line="515"/>
|
||||||
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="539"/>
|
<location filename="../src/libsync/theme.cpp" line="530"/>
|
||||||
<source><p>This release was supplied by %1</p></source>
|
<source><p>This release was supplied by %1</p></source>
|
||||||
<translation><p>An digoradenn-mañ a zo bet roet gant %1</p></translation>
|
<translation><p>An digoradenn-mañ a zo bet roet gant %1</p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5921,16 +5906,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>New folder</source>
|
<source>New folder</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="697"/>
|
|
||||||
<source>Mark as read</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="699"/>
|
|
||||||
<source>Reply</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/common/utility.cpp" line="482"/>
|
<location filename="../src/common/utility.cpp" line="482"/>
|
||||||
<source>%n day ago</source>
|
<source>%n day ago</source>
|
||||||
@@ -6382,14 +6357,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<translation>Digeriñ an diviz rannañ</translation>
|
<translation>Digeriñ an diviz rannañ</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
<source>Unified search results list</source>
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
||||||
<source>Unified search results list</source>
|
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
||||||
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
@@ -6419,7 +6394,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>nextcloudTheme::about()</name>
|
<name>nextcloudTheme::about()</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="496"/>
|
<location filename="../src/libsync/theme.cpp" line="487"/>
|
||||||
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
||||||
<translation><p><small>Krouet gant Git stumm<a href="%1">%2</a> war %3, %4 en ur implij Qt %5, %6</small></p></translation>
|
<translation><p><small>Krouet gant Git stumm<a href="%1">%2</a> war %3, %4 en ur implij Qt %5, %6</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -6774,14 +6749,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<translation>Ho c'jont a zo kemprennet d'an teuliad diabarzh</translation>
|
<translation>Ho c'jont a zo kemprennet d'an teuliad diabarzh</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ActivityActionButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
|
||||||
<source>Activity action button</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>OCC::UserStatus</name>
|
<name>OCC::UserStatus</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ca">
|
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ca">
|
||||||
|
<context>
|
||||||
|
<name>ActivityActionButton</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
||||||
|
<source>Activity action button</source>
|
||||||
|
<translation>Botó d'acció d'activitat</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ActivityItem</name>
|
<name>ActivityItem</name>
|
||||||
<message>
|
<message>
|
||||||
@@ -11,17 +19,6 @@
|
|||||||
<source>Open %1 locally</source>
|
<source>Open %1 locally</source>
|
||||||
<translation>Obre %1 localment</translation>
|
<translation>Obre %1 localment</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation>Mostra més accions</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
|
||||||
<source>View activity</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
@@ -32,27 +29,15 @@
|
|||||||
<source>Share %1</source>
|
<source>Share %1</source>
|
||||||
<translation>Comparteix %1</translation>
|
<translation>Comparteix %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemActions</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="77"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="79"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Mostra més accions</translation>
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemContent</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="90"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="92"/>
|
|
||||||
<source>Dismiss</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="121"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
||||||
<source>Open share dialog</source>
|
<source>View activity</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
@@ -845,17 +830,17 @@ This action will abort any currently running synchronization.</source>
|
|||||||
<translation>Continua</translation>
|
<translation>Continua</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="316"/>
|
<location filename="../src/gui/application.cpp" line="312"/>
|
||||||
<source>Error accessing the configuration file</source>
|
<source>Error accessing the configuration file</source>
|
||||||
<translation>S'ha produït un error en accedir al fitxer de configuració</translation>
|
<translation>S'ha produït un error en accedir al fitxer de configuració</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="317"/>
|
<location filename="../src/gui/application.cpp" line="313"/>
|
||||||
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
||||||
<translation>S'ha produït un error en accedir al fitxer de configuració a %1. Assegureu-vos que el vostre usuari pugui accedir a aquest fitxer.</translation>
|
<translation>S'ha produït un error en accedir al fitxer de configuració a %1. Assegureu-vos que el vostre usuari pugui accedir a aquest fitxer.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="320"/>
|
<location filename="../src/gui/application.cpp" line="316"/>
|
||||||
<source>Quit %1</source>
|
<source>Quit %1</source>
|
||||||
<translation>Surt del %1</translation>
|
<translation>Surt del %1</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -2715,27 +2700,27 @@ Logs will be written to %1</source>
|
|||||||
<translation>Amplada de banda de pujada</translation>
|
<translation>Amplada de banda de pujada</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="40"/>
|
<location filename="../src/gui/networksettings.cpp" line="37"/>
|
||||||
<source>Hostname of proxy server</source>
|
<source>Hostname of proxy server</source>
|
||||||
<translation>Nom de l'amfitrió del servidor intermediari</translation>
|
<translation>Nom de l'amfitrió del servidor intermediari</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
<location filename="../src/gui/networksettings.cpp" line="38"/>
|
||||||
<source>Username for proxy server</source>
|
<source>Username for proxy server</source>
|
||||||
<translation>Nom d'usuari del servidor intermediari</translation>
|
<translation>Nom d'usuari del servidor intermediari</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
<location filename="../src/gui/networksettings.cpp" line="39"/>
|
||||||
<source>Password for proxy server</source>
|
<source>Password for proxy server</source>
|
||||||
<translation>Contrasenya del servidor intermediari</translation>
|
<translation>Contrasenya del servidor intermediari</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="44"/>
|
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
||||||
<source>HTTP(S) proxy</source>
|
<source>HTTP(S) proxy</source>
|
||||||
<translation>Servidor intermediari HTTP(S)</translation>
|
<translation>Servidor intermediari HTTP(S)</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="45"/>
|
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
||||||
<source>SOCKS5 proxy</source>
|
<source>SOCKS5 proxy</source>
|
||||||
<translation>Servidor intermediari SOCKS5</translation>
|
<translation>Servidor intermediari SOCKS5</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5153,24 +5138,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>OCC::Theme</name>
|
<name>OCC::Theme</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="517"/>
|
<location filename="../src/libsync/theme.cpp" line="508"/>
|
||||||
<source><p>%1 Desktop Client</p></source>
|
<source><p>%1 Desktop Client</p></source>
|
||||||
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
||||||
<translation><p>Client d'escriptori del %1</p></translation>
|
<translation><p>Client d'escriptori del %1</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="520"/>
|
<location filename="../src/libsync/theme.cpp" line="511"/>
|
||||||
<location filename="../src/libsync/theme.cpp" line="535"/>
|
<location filename="../src/libsync/theme.cpp" line="526"/>
|
||||||
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
||||||
<translation><p>Versió %1. Per a obtenir més informació, feu clic <a href='%2'>aquí</a>.</p></translation>
|
<translation><p>Versió %1. Per a obtenir més informació, feu clic <a href='%2'>aquí</a>.</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="524"/>
|
<location filename="../src/libsync/theme.cpp" line="515"/>
|
||||||
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="539"/>
|
<location filename="../src/libsync/theme.cpp" line="530"/>
|
||||||
<source><p>This release was supplied by %1</p></source>
|
<source><p>This release was supplied by %1</p></source>
|
||||||
<translation><p>Aquesta versió ha estat proporcionada per %1</p></translation>
|
<translation><p>Aquesta versió ha estat proporcionada per %1</p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5910,16 +5895,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>New folder</source>
|
<source>New folder</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="697"/>
|
|
||||||
<source>Mark as read</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="699"/>
|
|
||||||
<source>Reply</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/common/utility.cpp" line="482"/>
|
<location filename="../src/common/utility.cpp" line="482"/>
|
||||||
<source>%n day ago</source>
|
<source>%n day ago</source>
|
||||||
@@ -6370,17 +6345,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
<translation>Obre el quadre de diàleg de compartició</translation>
|
<translation>Obre el quadre de diàleg de compartició</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
||||||
|
<source>Unified search results list</source>
|
||||||
|
<translation type="unfinished"/>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation>Mostra més accions</translation>
|
<translation>Mostra més accions</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
|
||||||
<source>Unified search results list</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
||||||
<source>%1 - File activity</source>
|
<source>%1 - File activity</source>
|
||||||
@@ -6408,7 +6383,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>nextcloudTheme::about()</name>
|
<name>nextcloudTheme::about()</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="496"/>
|
<location filename="../src/libsync/theme.cpp" line="487"/>
|
||||||
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
||||||
<translation><p><small>Compilat a partir de la revisió del Git <a href="%1">%2</a> el %3 a les %4 mitjançant Qt %5, %6</small></p></translation>
|
<translation><p><small>Compilat a partir de la revisió del Git <a href="%1">%2</a> el %3 a les %4 mitjançant Qt %5, %6</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -6763,14 +6738,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<translation>El vostre compte està totalment sincronitzat amb la carpeta local </translation>
|
<translation>El vostre compte està totalment sincronitzat amb la carpeta local </translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ActivityActionButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
|
||||||
<source>Activity action button</source>
|
|
||||||
<translation>Botó d'acció d'activitat</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>OCC::UserStatus</name>
|
<name>OCC::UserStatus</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="cs_CZ">
|
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="cs_CZ">
|
||||||
|
<context>
|
||||||
|
<name>ActivityActionButton</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
||||||
|
<source>Activity action button</source>
|
||||||
|
<translation>Tlačítko akce Aktivita</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ActivityItem</name>
|
<name>ActivityItem</name>
|
||||||
<message>
|
<message>
|
||||||
@@ -11,17 +19,6 @@
|
|||||||
<source>Open %1 locally</source>
|
<source>Open %1 locally</source>
|
||||||
<translation>Otevřít %1 lokálně</translation>
|
<translation>Otevřít %1 lokálně</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation>Zobrazit další akce</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
|
||||||
<source>View activity</source>
|
|
||||||
<translation>Zobrazit aktivitu</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
@@ -32,28 +29,16 @@
|
|||||||
<source>Share %1</source>
|
<source>Share %1</source>
|
||||||
<translation>Sdílet %1</translation>
|
<translation>Sdílet %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemActions</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="77"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="79"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation>Zobrazit další akce</translation>
|
<translation>Zobrazit další akce</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemContent</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="90"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="92"/>
|
<source>View activity</source>
|
||||||
<source>Dismiss</source>
|
<translation>Zobrazit aktivitu</translation>
|
||||||
<translation>Zahodit</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="121"/>
|
|
||||||
<source>Open share dialog</source>
|
|
||||||
<translation>Otevřít dialog sdílení</translation>
|
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -850,17 +835,17 @@ Současně tato akce zruší jakoukoli právě probíhající synchronizaci.</tr
|
|||||||
<translation>Pokračovat</translation>
|
<translation>Pokračovat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="316"/>
|
<location filename="../src/gui/application.cpp" line="312"/>
|
||||||
<source>Error accessing the configuration file</source>
|
<source>Error accessing the configuration file</source>
|
||||||
<translation>Chyba při přístupu k souboru s nastaveními</translation>
|
<translation>Chyba při přístupu k souboru s nastaveními</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="317"/>
|
<location filename="../src/gui/application.cpp" line="313"/>
|
||||||
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
||||||
<translation>Došlo k chybě při přístupu k souboru s nastaveními %1. Ověřte, že váš uživatelský účet má k souboru přístup.</translation>
|
<translation>Došlo k chybě při přístupu k souboru s nastaveními %1. Ověřte, že váš uživatelský účet má k souboru přístup.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="320"/>
|
<location filename="../src/gui/application.cpp" line="316"/>
|
||||||
<source>Quit %1</source>
|
<source>Quit %1</source>
|
||||||
<translation>Ukončit %1</translation>
|
<translation>Ukončit %1</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -2745,27 +2730,27 @@ Záznamy událostí budou zapisovány do %1</translation>
|
|||||||
<translation>Rychlost odesílání</translation>
|
<translation>Rychlost odesílání</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="40"/>
|
<location filename="../src/gui/networksettings.cpp" line="37"/>
|
||||||
<source>Hostname of proxy server</source>
|
<source>Hostname of proxy server</source>
|
||||||
<translation>Název stroje s proxy serverem</translation>
|
<translation>Název stroje s proxy serverem</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
<location filename="../src/gui/networksettings.cpp" line="38"/>
|
||||||
<source>Username for proxy server</source>
|
<source>Username for proxy server</source>
|
||||||
<translation>Uživatelské jméno pro proxy server</translation>
|
<translation>Uživatelské jméno pro proxy server</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
<location filename="../src/gui/networksettings.cpp" line="39"/>
|
||||||
<source>Password for proxy server</source>
|
<source>Password for proxy server</source>
|
||||||
<translation>Heslo pro proxy server</translation>
|
<translation>Heslo pro proxy server</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="44"/>
|
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
||||||
<source>HTTP(S) proxy</source>
|
<source>HTTP(S) proxy</source>
|
||||||
<translation>HTTP(S) proxy</translation>
|
<translation>HTTP(S) proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="45"/>
|
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
||||||
<source>SOCKS5 proxy</source>
|
<source>SOCKS5 proxy</source>
|
||||||
<translation>SOCKS5 proxy</translation>
|
<translation>SOCKS5 proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5191,24 +5176,24 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros
|
|||||||
<context>
|
<context>
|
||||||
<name>OCC::Theme</name>
|
<name>OCC::Theme</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="517"/>
|
<location filename="../src/libsync/theme.cpp" line="508"/>
|
||||||
<source><p>%1 Desktop Client</p></source>
|
<source><p>%1 Desktop Client</p></source>
|
||||||
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
||||||
<translation><p>%1 klient pro počítač</p></translation>
|
<translation><p>%1 klient pro počítač</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="520"/>
|
<location filename="../src/libsync/theme.cpp" line="511"/>
|
||||||
<location filename="../src/libsync/theme.cpp" line="535"/>
|
<location filename="../src/libsync/theme.cpp" line="526"/>
|
||||||
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
||||||
<translation><p>Verze %1. Další informace získáte kliknutím <a href='%2'>sem</a>.</p></translation>
|
<translation><p>Verze %1. Další informace získáte kliknutím <a href='%2'>sem</a>.</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="524"/>
|
<location filename="../src/libsync/theme.cpp" line="515"/>
|
||||||
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
||||||
<translation><p><small>Používá zásuvný modul pro virtuální soubory: %1</small></p></translation>
|
<translation><p><small>Používá zásuvný modul pro virtuální soubory: %1</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="539"/>
|
<location filename="../src/libsync/theme.cpp" line="530"/>
|
||||||
<source><p>This release was supplied by %1</p></source>
|
<source><p>This release was supplied by %1</p></source>
|
||||||
<translation><p>Toto vydání bylo poskytnuto %1</p></translation>
|
<translation><p>Toto vydání bylo poskytnuto %1</p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5948,16 +5933,6 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros
|
|||||||
<source>New folder</source>
|
<source>New folder</source>
|
||||||
<translation>Nová složka</translation>
|
<translation>Nová složka</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="697"/>
|
|
||||||
<source>Mark as read</source>
|
|
||||||
<translation>Označit jako přečtené</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="699"/>
|
|
||||||
<source>Reply</source>
|
|
||||||
<translation>Odpovědět</translation>
|
|
||||||
</message>
|
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/common/utility.cpp" line="482"/>
|
<location filename="../src/common/utility.cpp" line="482"/>
|
||||||
<source>%n day ago</source>
|
<source>%n day ago</source>
|
||||||
@@ -6408,17 +6383,17 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros
|
|||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
<translation>Otevřít dialog sdílení</translation>
|
<translation>Otevřít dialog sdílení</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
||||||
|
<source>Unified search results list</source>
|
||||||
|
<translation>Seznam výsledků sjednoceného vyhledávání</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation>Zobrazit další akce</translation>
|
<translation>Zobrazit další akce</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
|
||||||
<source>Unified search results list</source>
|
|
||||||
<translation>Seznam výsledků sjednoceného vyhledávání</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
||||||
<source>%1 - File activity</source>
|
<source>%1 - File activity</source>
|
||||||
@@ -6446,7 +6421,7 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros
|
|||||||
<context>
|
<context>
|
||||||
<name>nextcloudTheme::about()</name>
|
<name>nextcloudTheme::about()</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="496"/>
|
<location filename="../src/libsync/theme.cpp" line="487"/>
|
||||||
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
||||||
<translation><p><small>Sestaveno z Git revize <a href="%1">%2</a> na %3, %4 s použitím Qt %5, %6</small></p></translation>
|
<translation><p><small>Sestaveno z Git revize <a href="%1">%2</a> na %3, %4 s použitím Qt %5, %6</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -6801,14 +6776,6 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros
|
|||||||
<translation>Celý váš účet je synchronizován do místní složky</translation>
|
<translation>Celý váš účet je synchronizován do místní složky</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ActivityActionButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
|
||||||
<source>Activity action button</source>
|
|
||||||
<translation>Tlačítko akce Aktivita</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>OCC::UserStatus</name>
|
<name>OCC::UserStatus</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="da">
|
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="da">
|
||||||
|
<context>
|
||||||
|
<name>ActivityActionButton</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
||||||
|
<source>Activity action button</source>
|
||||||
|
<translation>Aktivitetshandlingsknap</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ActivityItem</name>
|
<name>ActivityItem</name>
|
||||||
<message>
|
<message>
|
||||||
@@ -11,17 +19,6 @@
|
|||||||
<source>Open %1 locally</source>
|
<source>Open %1 locally</source>
|
||||||
<translation>Åbn %1 lokalt</translation>
|
<translation>Åbn %1 lokalt</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation>Vis flere handlinger</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
|
||||||
<source>View activity</source>
|
|
||||||
<translation>Se aktivitet</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
@@ -32,28 +29,16 @@
|
|||||||
<source>Share %1</source>
|
<source>Share %1</source>
|
||||||
<translation>Del %1</translation>
|
<translation>Del %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemActions</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="77"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="79"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Vis flere handlinger</translation>
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemContent</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="90"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="92"/>
|
|
||||||
<source>Dismiss</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="121"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
||||||
<source>Open share dialog</source>
|
<source>View activity</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Se aktivitet</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -850,17 +835,17 @@ Denne handling vil annullere alle i øjeblikket kørende synkroniseringer.</tran
|
|||||||
<translation>Fortsæt</translation>
|
<translation>Fortsæt</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="316"/>
|
<location filename="../src/gui/application.cpp" line="312"/>
|
||||||
<source>Error accessing the configuration file</source>
|
<source>Error accessing the configuration file</source>
|
||||||
<translation>Adgang til konfigurationsfilen fejlede</translation>
|
<translation>Adgang til konfigurationsfilen fejlede</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="317"/>
|
<location filename="../src/gui/application.cpp" line="313"/>
|
||||||
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
||||||
<translation>Der opstod en fejl, kunne ikke tilgå konfigurations filen %1. Sørg for at filen kan tilgås af din bruger.</translation>
|
<translation>Der opstod en fejl, kunne ikke tilgå konfigurations filen %1. Sørg for at filen kan tilgås af din bruger.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="320"/>
|
<location filename="../src/gui/application.cpp" line="316"/>
|
||||||
<source>Quit %1</source>
|
<source>Quit %1</source>
|
||||||
<translation>Afslut %1</translation>
|
<translation>Afslut %1</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -2729,27 +2714,27 @@ Loggen bliver skrevet til %1</translation>
|
|||||||
<translation>Upload båndbredde</translation>
|
<translation>Upload båndbredde</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="40"/>
|
<location filename="../src/gui/networksettings.cpp" line="37"/>
|
||||||
<source>Hostname of proxy server</source>
|
<source>Hostname of proxy server</source>
|
||||||
<translation>Proxyservers værtsnavn</translation>
|
<translation>Proxyservers værtsnavn</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
<location filename="../src/gui/networksettings.cpp" line="38"/>
|
||||||
<source>Username for proxy server</source>
|
<source>Username for proxy server</source>
|
||||||
<translation>Brugernavn mod proxyserver</translation>
|
<translation>Brugernavn mod proxyserver</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
<location filename="../src/gui/networksettings.cpp" line="39"/>
|
||||||
<source>Password for proxy server</source>
|
<source>Password for proxy server</source>
|
||||||
<translation>Kodeord mod proxyserver</translation>
|
<translation>Kodeord mod proxyserver</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="44"/>
|
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
||||||
<source>HTTP(S) proxy</source>
|
<source>HTTP(S) proxy</source>
|
||||||
<translation>HTTP(S) proxy</translation>
|
<translation>HTTP(S) proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="45"/>
|
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
||||||
<source>SOCKS5 proxy</source>
|
<source>SOCKS5 proxy</source>
|
||||||
<translation>SOCKS5 proxy</translation>
|
<translation>SOCKS5 proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5168,24 +5153,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>OCC::Theme</name>
|
<name>OCC::Theme</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="517"/>
|
<location filename="../src/libsync/theme.cpp" line="508"/>
|
||||||
<source><p>%1 Desktop Client</p></source>
|
<source><p>%1 Desktop Client</p></source>
|
||||||
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
||||||
<translation><p>%1-skrivebordsklient</p></translation>
|
<translation><p>%1-skrivebordsklient</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="520"/>
|
<location filename="../src/libsync/theme.cpp" line="511"/>
|
||||||
<location filename="../src/libsync/theme.cpp" line="535"/>
|
<location filename="../src/libsync/theme.cpp" line="526"/>
|
||||||
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
||||||
<translation><p>Version %1. For mere information venligst klik <a href='%2'>her</a>.</p></translation>
|
<translation><p>Version %1. For mere information venligst klik <a href='%2'>her</a>.</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="524"/>
|
<location filename="../src/libsync/theme.cpp" line="515"/>
|
||||||
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="539"/>
|
<location filename="../src/libsync/theme.cpp" line="530"/>
|
||||||
<source><p>This release was supplied by %1</p></source>
|
<source><p>This release was supplied by %1</p></source>
|
||||||
<translation><p>Denne udgivelse blev leveret af %1</p></translation>
|
<translation><p>Denne udgivelse blev leveret af %1</p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5925,16 +5910,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>New folder</source>
|
<source>New folder</source>
|
||||||
<translation>Ny mappe</translation>
|
<translation>Ny mappe</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="697"/>
|
|
||||||
<source>Mark as read</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="699"/>
|
|
||||||
<source>Reply</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/common/utility.cpp" line="482"/>
|
<location filename="../src/common/utility.cpp" line="482"/>
|
||||||
<source>%n day ago</source>
|
<source>%n day ago</source>
|
||||||
@@ -6385,17 +6360,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
<translation>Åbn delingsdialog</translation>
|
<translation>Åbn delingsdialog</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
||||||
|
<source>Unified search results list</source>
|
||||||
|
<translation type="unfinished"/>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation>Vis flere handlinger</translation>
|
<translation>Vis flere handlinger</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
|
||||||
<source>Unified search results list</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
||||||
<source>%1 - File activity</source>
|
<source>%1 - File activity</source>
|
||||||
@@ -6423,7 +6398,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>nextcloudTheme::about()</name>
|
<name>nextcloudTheme::about()</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="496"/>
|
<location filename="../src/libsync/theme.cpp" line="487"/>
|
||||||
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
||||||
<translation><p><small>Bygget fra Git-revision <a href="%1">%2</a> på %3, %4 med Qt %5, %6</small></p></translation>
|
<translation><p><small>Bygget fra Git-revision <a href="%1">%2</a> på %3, %4 med Qt %5, %6</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -6778,14 +6753,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<translation>Hele din konto er synkroniseret til den lokale mappe</translation>
|
<translation>Hele din konto er synkroniseret til den lokale mappe</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ActivityActionButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
|
||||||
<source>Activity action button</source>
|
|
||||||
<translation>Aktivitetshandlingsknap</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>OCC::UserStatus</name>
|
<name>OCC::UserStatus</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="de_DE">
|
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="de_DE">
|
||||||
|
<context>
|
||||||
|
<name>ActivityActionButton</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
||||||
|
<source>Activity action button</source>
|
||||||
|
<translation>Aktionsknopf für Aktivitäten</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ActivityItem</name>
|
<name>ActivityItem</name>
|
||||||
<message>
|
<message>
|
||||||
@@ -11,17 +19,6 @@
|
|||||||
<source>Open %1 locally</source>
|
<source>Open %1 locally</source>
|
||||||
<translation>%1 lokal öffnen</translation>
|
<translation>%1 lokal öffnen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation>Weitere Aktionen anzeigen</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
|
||||||
<source>View activity</source>
|
|
||||||
<translation>Aktivitäten anzeigen</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
@@ -32,28 +29,16 @@
|
|||||||
<source>Share %1</source>
|
<source>Share %1</source>
|
||||||
<translation>%1 teilen</translation>
|
<translation>%1 teilen</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemActions</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="77"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="79"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation>Weitere Aktionen anzeigen</translation>
|
<translation>Weitere Aktionen anzeigen</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemContent</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="90"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="92"/>
|
<source>View activity</source>
|
||||||
<source>Dismiss</source>
|
<translation>Aktivitäten anzeigen</translation>
|
||||||
<translation>Ablehnen</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="121"/>
|
|
||||||
<source>Open share dialog</source>
|
|
||||||
<translation>Teilen-Dialog öffnen</translation>
|
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -850,17 +835,17 @@ Diese Aktion bricht jede derzeit laufende Synchronisierung ab.</translation>
|
|||||||
<translation>Fortsetzen</translation>
|
<translation>Fortsetzen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="316"/>
|
<location filename="../src/gui/application.cpp" line="312"/>
|
||||||
<source>Error accessing the configuration file</source>
|
<source>Error accessing the configuration file</source>
|
||||||
<translation>Fehler beim Zugriff auf die Konfigurationsdatei</translation>
|
<translation>Fehler beim Zugriff auf die Konfigurationsdatei</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="317"/>
|
<location filename="../src/gui/application.cpp" line="313"/>
|
||||||
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
||||||
<translation>Beim Zugriff auf die Konfigurationsdatei bei %1 ist ein Fehler aufgetreten. Stellen Sie sicher, dass Ihr Benutzer auf die Datei zugreifen kann.</translation>
|
<translation>Beim Zugriff auf die Konfigurationsdatei bei %1 ist ein Fehler aufgetreten. Stellen Sie sicher, dass Ihr Benutzer auf die Datei zugreifen kann.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="320"/>
|
<location filename="../src/gui/application.cpp" line="316"/>
|
||||||
<source>Quit %1</source>
|
<source>Quit %1</source>
|
||||||
<translation>Beende %1</translation>
|
<translation>Beende %1</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -2746,27 +2731,27 @@ Protokolle werden in % 1 geschrieben</translation>
|
|||||||
<translation>Upload-Bandbreite</translation>
|
<translation>Upload-Bandbreite</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="40"/>
|
<location filename="../src/gui/networksettings.cpp" line="37"/>
|
||||||
<source>Hostname of proxy server</source>
|
<source>Hostname of proxy server</source>
|
||||||
<translation>Hostname des Proxy-Servers</translation>
|
<translation>Hostname des Proxy-Servers</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
<location filename="../src/gui/networksettings.cpp" line="38"/>
|
||||||
<source>Username for proxy server</source>
|
<source>Username for proxy server</source>
|
||||||
<translation>Benutzername für den Proxy-Server</translation>
|
<translation>Benutzername für den Proxy-Server</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
<location filename="../src/gui/networksettings.cpp" line="39"/>
|
||||||
<source>Password for proxy server</source>
|
<source>Password for proxy server</source>
|
||||||
<translation>Passwort für den Proxy-Server</translation>
|
<translation>Passwort für den Proxy-Server</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="44"/>
|
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
||||||
<source>HTTP(S) proxy</source>
|
<source>HTTP(S) proxy</source>
|
||||||
<translation>HTTP(S)-Proxy</translation>
|
<translation>HTTP(S)-Proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="45"/>
|
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
||||||
<source>SOCKS5 proxy</source>
|
<source>SOCKS5 proxy</source>
|
||||||
<translation>SOCKS5-Proxy</translation>
|
<translation>SOCKS5-Proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5191,24 +5176,24 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver
|
|||||||
<context>
|
<context>
|
||||||
<name>OCC::Theme</name>
|
<name>OCC::Theme</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="517"/>
|
<location filename="../src/libsync/theme.cpp" line="508"/>
|
||||||
<source><p>%1 Desktop Client</p></source>
|
<source><p>%1 Desktop Client</p></source>
|
||||||
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
||||||
<translation><p>%1 Desktop-Client</p></translation>
|
<translation><p>%1 Desktop-Client</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="520"/>
|
<location filename="../src/libsync/theme.cpp" line="511"/>
|
||||||
<location filename="../src/libsync/theme.cpp" line="535"/>
|
<location filename="../src/libsync/theme.cpp" line="526"/>
|
||||||
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
||||||
<translation><p>Version %1. Für weitere Informationen klicken Sie bitte <a href='%2'>hier</a>.</p></translation>
|
<translation><p>Version %1. Für weitere Informationen klicken Sie bitte <a href='%2'>hier</a>.</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="524"/>
|
<location filename="../src/libsync/theme.cpp" line="515"/>
|
||||||
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
||||||
<translation><p><small>Plugin für virtuelle Dateien: %1</small></p></translation>
|
<translation><p><small>Plugin für virtuelle Dateien: %1</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="539"/>
|
<location filename="../src/libsync/theme.cpp" line="530"/>
|
||||||
<source><p>This release was supplied by %1</p></source>
|
<source><p>This release was supplied by %1</p></source>
|
||||||
<translation><p>Diese Version wird von %1 bereitgestellt</p></translation>
|
<translation><p>Diese Version wird von %1 bereitgestellt</p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5948,16 +5933,6 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver
|
|||||||
<source>New folder</source>
|
<source>New folder</source>
|
||||||
<translation>Neuer Ordner</translation>
|
<translation>Neuer Ordner</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="697"/>
|
|
||||||
<source>Mark as read</source>
|
|
||||||
<translation>Als gelesen markieren</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="699"/>
|
|
||||||
<source>Reply</source>
|
|
||||||
<translation>Antworten</translation>
|
|
||||||
</message>
|
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/common/utility.cpp" line="482"/>
|
<location filename="../src/common/utility.cpp" line="482"/>
|
||||||
<source>%n day ago</source>
|
<source>%n day ago</source>
|
||||||
@@ -6408,17 +6383,17 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver
|
|||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
<translation>Teilen-Dialog öffnen</translation>
|
<translation>Teilen-Dialog öffnen</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
||||||
|
<source>Unified search results list</source>
|
||||||
|
<translation>Einheitliche Suchergebnisliste</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation>Weitere Aktionen anzeigen</translation>
|
<translation>Weitere Aktionen anzeigen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
|
||||||
<source>Unified search results list</source>
|
|
||||||
<translation>Einheitliche Suchergebnisliste</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
||||||
<source>%1 - File activity</source>
|
<source>%1 - File activity</source>
|
||||||
@@ -6446,7 +6421,7 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver
|
|||||||
<context>
|
<context>
|
||||||
<name>nextcloudTheme::about()</name>
|
<name>nextcloudTheme::about()</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="496"/>
|
<location filename="../src/libsync/theme.cpp" line="487"/>
|
||||||
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
||||||
<translation><p><small>Gebaut von der git-Revision <a href="%1">%2</a> auf %3, %4 verwendet Qt %5, %6</small></p></translation>
|
<translation><p><small>Gebaut von der git-Revision <a href="%1">%2</a> auf %3, %4 verwendet Qt %5, %6</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -6801,14 +6776,6 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver
|
|||||||
<translation>Ihr gesamtes Konto wird mit dem lokalen Ordner synchronisiert.</translation>
|
<translation>Ihr gesamtes Konto wird mit dem lokalen Ordner synchronisiert.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ActivityActionButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
|
||||||
<source>Activity action button</source>
|
|
||||||
<translation>Aktionsknopf für Aktivitäten</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>OCC::UserStatus</name>
|
<name>OCC::UserStatus</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="el">
|
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="el">
|
||||||
|
<context>
|
||||||
|
<name>ActivityActionButton</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
||||||
|
<source>Activity action button</source>
|
||||||
|
<translation>Κουμπί δράσης δραστηριότητας</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ActivityItem</name>
|
<name>ActivityItem</name>
|
||||||
<message>
|
<message>
|
||||||
@@ -11,17 +19,6 @@
|
|||||||
<source>Open %1 locally</source>
|
<source>Open %1 locally</source>
|
||||||
<translation>Ανοίξτε το %1 τοπικά</translation>
|
<translation>Ανοίξτε το %1 τοπικά</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation>Εμφάνιση περισσότερων ενεργειών.</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
|
||||||
<source>View activity</source>
|
|
||||||
<translation>Εμφάνιση δραστηριότητας</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
@@ -32,28 +29,16 @@
|
|||||||
<source>Share %1</source>
|
<source>Share %1</source>
|
||||||
<translation>Κοινή χρήση %1</translation>
|
<translation>Κοινή χρήση %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemActions</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="77"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="79"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Εμφάνιση περισσότερων ενεργειών.</translation>
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemContent</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="90"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="92"/>
|
|
||||||
<source>Dismiss</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="121"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
||||||
<source>Open share dialog</source>
|
<source>View activity</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Εμφάνιση δραστηριότητας</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -846,17 +831,17 @@ This action will abort any currently running synchronization.</source>
|
|||||||
<translation>Συνέχεια</translation>
|
<translation>Συνέχεια</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="316"/>
|
<location filename="../src/gui/application.cpp" line="312"/>
|
||||||
<source>Error accessing the configuration file</source>
|
<source>Error accessing the configuration file</source>
|
||||||
<translation>Σφάλμα πρόσβασης στο αρχείο ρυθμίσεων</translation>
|
<translation>Σφάλμα πρόσβασης στο αρχείο ρυθμίσεων</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="317"/>
|
<location filename="../src/gui/application.cpp" line="313"/>
|
||||||
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
||||||
<translation>Υπήρξε σφάλμα κατά την πρόσβαση του αρχείου ρυθμίσεων στο %1. Παρακαλώ επαληθεύστε αν μπορείτε να προσπελάσετε το αρχείο.</translation>
|
<translation>Υπήρξε σφάλμα κατά την πρόσβαση του αρχείου ρυθμίσεων στο %1. Παρακαλώ επαληθεύστε αν μπορείτε να προσπελάσετε το αρχείο.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="320"/>
|
<location filename="../src/gui/application.cpp" line="316"/>
|
||||||
<source>Quit %1</source>
|
<source>Quit %1</source>
|
||||||
<translation>Κλείσιμο %1</translation>
|
<translation>Κλείσιμο %1</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -2732,27 +2717,27 @@ Logs will be written to %1</source>
|
|||||||
<translation>Ταχύτητα Μεταφόρτωσης</translation>
|
<translation>Ταχύτητα Μεταφόρτωσης</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="40"/>
|
<location filename="../src/gui/networksettings.cpp" line="37"/>
|
||||||
<source>Hostname of proxy server</source>
|
<source>Hostname of proxy server</source>
|
||||||
<translation>Όνομα συστήματος του διαμεσολαβητή</translation>
|
<translation>Όνομα συστήματος του διαμεσολαβητή</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
<location filename="../src/gui/networksettings.cpp" line="38"/>
|
||||||
<source>Username for proxy server</source>
|
<source>Username for proxy server</source>
|
||||||
<translation>Όνομα χρήστη για τον διαμεσολαβητή</translation>
|
<translation>Όνομα χρήστη για τον διαμεσολαβητή</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
<location filename="../src/gui/networksettings.cpp" line="39"/>
|
||||||
<source>Password for proxy server</source>
|
<source>Password for proxy server</source>
|
||||||
<translation>Κωδικός πρόσβασης για τον διαμεσολαβητή</translation>
|
<translation>Κωδικός πρόσβασης για τον διαμεσολαβητή</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="44"/>
|
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
||||||
<source>HTTP(S) proxy</source>
|
<source>HTTP(S) proxy</source>
|
||||||
<translation>HTTP(S) διαμεσολαβητής</translation>
|
<translation>HTTP(S) διαμεσολαβητής</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="45"/>
|
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
||||||
<source>SOCKS5 proxy</source>
|
<source>SOCKS5 proxy</source>
|
||||||
<translation>SOCKS5 διαμεσολαβητής</translation>
|
<translation>SOCKS5 διαμεσολαβητής</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5172,24 +5157,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>OCC::Theme</name>
|
<name>OCC::Theme</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="517"/>
|
<location filename="../src/libsync/theme.cpp" line="508"/>
|
||||||
<source><p>%1 Desktop Client</p></source>
|
<source><p>%1 Desktop Client</p></source>
|
||||||
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
||||||
<translation><p>Εφαρμογή Υπολογιστή %1 </p></translation>
|
<translation><p>Εφαρμογή Υπολογιστή %1 </p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="520"/>
|
<location filename="../src/libsync/theme.cpp" line="511"/>
|
||||||
<location filename="../src/libsync/theme.cpp" line="535"/>
|
<location filename="../src/libsync/theme.cpp" line="526"/>
|
||||||
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
||||||
<translation><p>Έκδοση %1. Για περισσότερες πληροφορίες δείτε <a href='%2'>εδώ</a>.</p></translation>
|
<translation><p>Έκδοση %1. Για περισσότερες πληροφορίες δείτε <a href='%2'>εδώ</a>.</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="524"/>
|
<location filename="../src/libsync/theme.cpp" line="515"/>
|
||||||
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="539"/>
|
<location filename="../src/libsync/theme.cpp" line="530"/>
|
||||||
<source><p>This release was supplied by %1</p></source>
|
<source><p>This release was supplied by %1</p></source>
|
||||||
<translation><p>Η έκδοση παρέχεται από %1</p></translation>
|
<translation><p>Η έκδοση παρέχεται από %1</p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5929,16 +5914,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>New folder</source>
|
<source>New folder</source>
|
||||||
<translation>Νέος φάκελος</translation>
|
<translation>Νέος φάκελος</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="697"/>
|
|
||||||
<source>Mark as read</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="699"/>
|
|
||||||
<source>Reply</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/common/utility.cpp" line="482"/>
|
<location filename="../src/common/utility.cpp" line="482"/>
|
||||||
<source>%n day ago</source>
|
<source>%n day ago</source>
|
||||||
@@ -6389,17 +6364,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
<translation>Άνοιγμα του διαλόγου διαμοιρασμού</translation>
|
<translation>Άνοιγμα του διαλόγου διαμοιρασμού</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
||||||
|
<source>Unified search results list</source>
|
||||||
|
<translation type="unfinished"/>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation>Εμφάνιση περισσότερων ενεργειών.</translation>
|
<translation>Εμφάνιση περισσότερων ενεργειών.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
|
||||||
<source>Unified search results list</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
||||||
<source>%1 - File activity</source>
|
<source>%1 - File activity</source>
|
||||||
@@ -6427,7 +6402,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>nextcloudTheme::about()</name>
|
<name>nextcloudTheme::about()</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="496"/>
|
<location filename="../src/libsync/theme.cpp" line="487"/>
|
||||||
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
||||||
<translation><p><small>Δημιουργήθηκε από την διασκευή Git <a href="%1">%2</a> στο %3, %4 χρησιμοποιώντας Qt %5, %6</small></p></translation>
|
<translation><p><small>Δημιουργήθηκε από την διασκευή Git <a href="%1">%2</a> στο %3, %4 χρησιμοποιώντας Qt %5, %6</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -6782,14 +6757,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<translation>Ολόκληρος ο λογαριασμός σας έχει συγχρονιστεί με τον τοπικό φάκελο</translation>
|
<translation>Ολόκληρος ο λογαριασμός σας έχει συγχρονιστεί με τον τοπικό φάκελο</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ActivityActionButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
|
||||||
<source>Activity action button</source>
|
|
||||||
<translation>Κουμπί δράσης δραστηριότητας</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>OCC::UserStatus</name>
|
<name>OCC::UserStatus</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="en_GB">
|
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="en_GB">
|
||||||
|
<context>
|
||||||
|
<name>ActivityActionButton</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
||||||
|
<source>Activity action button</source>
|
||||||
|
<translation type="unfinished"/>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ActivityItem</name>
|
<name>ActivityItem</name>
|
||||||
<message>
|
<message>
|
||||||
@@ -11,17 +19,6 @@
|
|||||||
<source>Open %1 locally</source>
|
<source>Open %1 locally</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
|
||||||
<source>View activity</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
@@ -32,27 +29,15 @@
|
|||||||
<source>Share %1</source>
|
<source>Share %1</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemActions</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="77"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="79"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemContent</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="90"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="92"/>
|
<source>View activity</source>
|
||||||
<source>Dismiss</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="121"/>
|
|
||||||
<source>Open share dialog</source>
|
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
@@ -845,17 +830,17 @@ This action will abort any currently running synchronization.</source>
|
|||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="316"/>
|
<location filename="../src/gui/application.cpp" line="312"/>
|
||||||
<source>Error accessing the configuration file</source>
|
<source>Error accessing the configuration file</source>
|
||||||
<translation>Error accessing the configuration file</translation>
|
<translation>Error accessing the configuration file</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="317"/>
|
<location filename="../src/gui/application.cpp" line="313"/>
|
||||||
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
||||||
<translation>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</translation>
|
<translation>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="320"/>
|
<location filename="../src/gui/application.cpp" line="316"/>
|
||||||
<source>Quit %1</source>
|
<source>Quit %1</source>
|
||||||
<translation>Quit %1</translation>
|
<translation>Quit %1</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -2716,27 +2701,27 @@ Logs will be written to %1</translation>
|
|||||||
<translation>Upload Bandwidth</translation>
|
<translation>Upload Bandwidth</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="40"/>
|
<location filename="../src/gui/networksettings.cpp" line="37"/>
|
||||||
<source>Hostname of proxy server</source>
|
<source>Hostname of proxy server</source>
|
||||||
<translation>Hostname of proxy server</translation>
|
<translation>Hostname of proxy server</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
<location filename="../src/gui/networksettings.cpp" line="38"/>
|
||||||
<source>Username for proxy server</source>
|
<source>Username for proxy server</source>
|
||||||
<translation>Username for proxy server</translation>
|
<translation>Username for proxy server</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
<location filename="../src/gui/networksettings.cpp" line="39"/>
|
||||||
<source>Password for proxy server</source>
|
<source>Password for proxy server</source>
|
||||||
<translation>Password for proxy server</translation>
|
<translation>Password for proxy server</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="44"/>
|
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
||||||
<source>HTTP(S) proxy</source>
|
<source>HTTP(S) proxy</source>
|
||||||
<translation>HTTP(S) proxy</translation>
|
<translation>HTTP(S) proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="45"/>
|
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
||||||
<source>SOCKS5 proxy</source>
|
<source>SOCKS5 proxy</source>
|
||||||
<translation>SOCKS5 proxy</translation>
|
<translation>SOCKS5 proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5155,24 +5140,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>OCC::Theme</name>
|
<name>OCC::Theme</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="517"/>
|
<location filename="../src/libsync/theme.cpp" line="508"/>
|
||||||
<source><p>%1 Desktop Client</p></source>
|
<source><p>%1 Desktop Client</p></source>
|
||||||
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="520"/>
|
<location filename="../src/libsync/theme.cpp" line="511"/>
|
||||||
<location filename="../src/libsync/theme.cpp" line="535"/>
|
<location filename="../src/libsync/theme.cpp" line="526"/>
|
||||||
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="524"/>
|
<location filename="../src/libsync/theme.cpp" line="515"/>
|
||||||
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="539"/>
|
<location filename="../src/libsync/theme.cpp" line="530"/>
|
||||||
<source><p>This release was supplied by %1</p></source>
|
<source><p>This release was supplied by %1</p></source>
|
||||||
<translation><p>This release was supplied by %1</p></translation>
|
<translation><p>This release was supplied by %1</p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5912,16 +5897,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>New folder</source>
|
<source>New folder</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="697"/>
|
|
||||||
<source>Mark as read</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="699"/>
|
|
||||||
<source>Reply</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/common/utility.cpp" line="482"/>
|
<location filename="../src/common/utility.cpp" line="482"/>
|
||||||
<source>%n day ago</source>
|
<source>%n day ago</source>
|
||||||
@@ -6373,14 +6348,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
<source>Unified search results list</source>
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
||||||
<source>Unified search results list</source>
|
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
||||||
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
@@ -6410,7 +6385,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>nextcloudTheme::about()</name>
|
<name>nextcloudTheme::about()</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="496"/>
|
<location filename="../src/libsync/theme.cpp" line="487"/>
|
||||||
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
||||||
<translation><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></translation>
|
<translation><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -6765,14 +6740,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<translation>Your entire account is synced to the local folder </translation>
|
<translation>Your entire account is synced to the local folder </translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ActivityActionButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
|
||||||
<source>Activity action button</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>OCC::UserStatus</name>
|
<name>OCC::UserStatus</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="eo">
|
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="eo">
|
||||||
|
<context>
|
||||||
|
<name>ActivityActionButton</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
||||||
|
<source>Activity action button</source>
|
||||||
|
<translation type="unfinished"/>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ActivityItem</name>
|
<name>ActivityItem</name>
|
||||||
<message>
|
<message>
|
||||||
@@ -11,17 +19,6 @@
|
|||||||
<source>Open %1 locally</source>
|
<source>Open %1 locally</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
|
||||||
<source>View activity</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
@@ -32,27 +29,15 @@
|
|||||||
<source>Share %1</source>
|
<source>Share %1</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemActions</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="77"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="79"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemContent</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="90"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="92"/>
|
<source>View activity</source>
|
||||||
<source>Dismiss</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="121"/>
|
|
||||||
<source>Open share dialog</source>
|
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
@@ -845,17 +830,17 @@ This action will abort any currently running synchronization.</source>
|
|||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="316"/>
|
<location filename="../src/gui/application.cpp" line="312"/>
|
||||||
<source>Error accessing the configuration file</source>
|
<source>Error accessing the configuration file</source>
|
||||||
<translation>Eraro dum aliro al la dosiero de agordoj</translation>
|
<translation>Eraro dum aliro al la dosiero de agordoj</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="317"/>
|
<location filename="../src/gui/application.cpp" line="313"/>
|
||||||
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
||||||
<translation>Okazis eraro dum aliro al la agorda dosiero en %1. Bv. certigi, ke la dosiero estas alirebla de via uzanto.</translation>
|
<translation>Okazis eraro dum aliro al la agorda dosiero en %1. Bv. certigi, ke la dosiero estas alirebla de via uzanto.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="320"/>
|
<location filename="../src/gui/application.cpp" line="316"/>
|
||||||
<source>Quit %1</source>
|
<source>Quit %1</source>
|
||||||
<translation>Fini %1</translation>
|
<translation>Fini %1</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -2723,27 +2708,27 @@ Protokoloj estos skribataj al %1.</translation>
|
|||||||
<translation>Alŝuta retkapacito</translation>
|
<translation>Alŝuta retkapacito</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="40"/>
|
<location filename="../src/gui/networksettings.cpp" line="37"/>
|
||||||
<source>Hostname of proxy server</source>
|
<source>Hostname of proxy server</source>
|
||||||
<translation>Gastigonomo de la prokurila servilo</translation>
|
<translation>Gastigonomo de la prokurila servilo</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
<location filename="../src/gui/networksettings.cpp" line="38"/>
|
||||||
<source>Username for proxy server</source>
|
<source>Username for proxy server</source>
|
||||||
<translation>Uzantnomo por la prokurila servilo</translation>
|
<translation>Uzantnomo por la prokurila servilo</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
<location filename="../src/gui/networksettings.cpp" line="39"/>
|
||||||
<source>Password for proxy server</source>
|
<source>Password for proxy server</source>
|
||||||
<translation>Pasvorto por la prokurila servilo</translation>
|
<translation>Pasvorto por la prokurila servilo</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="44"/>
|
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
||||||
<source>HTTP(S) proxy</source>
|
<source>HTTP(S) proxy</source>
|
||||||
<translation>HTTP(S)-prokurilo</translation>
|
<translation>HTTP(S)-prokurilo</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="45"/>
|
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
||||||
<source>SOCKS5 proxy</source>
|
<source>SOCKS5 proxy</source>
|
||||||
<translation>SOCKS5-prokurilo</translation>
|
<translation>SOCKS5-prokurilo</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5160,24 +5145,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>OCC::Theme</name>
|
<name>OCC::Theme</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="517"/>
|
<location filename="../src/libsync/theme.cpp" line="508"/>
|
||||||
<source><p>%1 Desktop Client</p></source>
|
<source><p>%1 Desktop Client</p></source>
|
||||||
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="520"/>
|
<location filename="../src/libsync/theme.cpp" line="511"/>
|
||||||
<location filename="../src/libsync/theme.cpp" line="535"/>
|
<location filename="../src/libsync/theme.cpp" line="526"/>
|
||||||
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
||||||
<translation><p>Versio %1. Por pli da informoj, alklaku <a href='%2'>ĉi tie</a>.</p></translation>
|
<translation><p>Versio %1. Por pli da informoj, alklaku <a href='%2'>ĉi tie</a>.</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="524"/>
|
<location filename="../src/libsync/theme.cpp" line="515"/>
|
||||||
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="539"/>
|
<location filename="../src/libsync/theme.cpp" line="530"/>
|
||||||
<source><p>This release was supplied by %1</p></source>
|
<source><p>This release was supplied by %1</p></source>
|
||||||
<translation><p>Tiu eldono estis liverita de %1</p></translation>
|
<translation><p>Tiu eldono estis liverita de %1</p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5917,16 +5902,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<source>New folder</source>
|
<source>New folder</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="697"/>
|
|
||||||
<source>Mark as read</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="699"/>
|
|
||||||
<source>Reply</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/common/utility.cpp" line="482"/>
|
<location filename="../src/common/utility.cpp" line="482"/>
|
||||||
<source>%n day ago</source>
|
<source>%n day ago</source>
|
||||||
@@ -6378,14 +6353,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
<source>Unified search results list</source>
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
||||||
<source>Unified search results list</source>
|
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
||||||
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
@@ -6415,7 +6390,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<context>
|
<context>
|
||||||
<name>nextcloudTheme::about()</name>
|
<name>nextcloudTheme::about()</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="496"/>
|
<location filename="../src/libsync/theme.cpp" line="487"/>
|
||||||
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
||||||
<translation><p><small>Konstruita el Git-a revizio <a href="%1">%2</a> je %3, %4, uzante Qt %5, %6</small></p></translation>
|
<translation><p><small>Konstruita el Git-a revizio <a href="%1">%2</a> je %3, %4, uzante Qt %5, %6</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -6770,14 +6745,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss
|
|||||||
<translation>Via tuta konta sinkroniĝas kun la loka dosierujo.</translation>
|
<translation>Via tuta konta sinkroniĝas kun la loka dosierujo.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ActivityActionButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
|
||||||
<source>Activity action button</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>OCC::UserStatus</name>
|
<name>OCC::UserStatus</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="es">
|
<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="es">
|
||||||
|
<context>
|
||||||
|
<name>ActivityActionButton</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
||||||
|
<source>Activity action button</source>
|
||||||
|
<translation>Botón de acción de Actividad</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ActivityItem</name>
|
<name>ActivityItem</name>
|
||||||
<message>
|
<message>
|
||||||
@@ -11,17 +19,6 @@
|
|||||||
<source>Open %1 locally</source>
|
<source>Open %1 locally</source>
|
||||||
<translation>Abrir %1 localmente</translation>
|
<translation>Abrir %1 localmente</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
|
||||||
<source>Show more actions</source>
|
|
||||||
<translation>Mostrar más acciones</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
|
||||||
<source>View activity</source>
|
|
||||||
<translation>Ver actividad</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="168"/>
|
||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
@@ -32,28 +29,16 @@
|
|||||||
<source>Share %1</source>
|
<source>Share %1</source>
|
||||||
<translation>Compartir %1</translation>
|
<translation>Compartir %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemActions</name>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="77"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="194"/>
|
||||||
<location filename="../src/gui/tray/ActivityItemActions.qml" line="79"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="197"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Mostrar más acciones</translation>
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
|
||||||
<name>ActivityItemContent</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="90"/>
|
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="92"/>
|
|
||||||
<source>Dismiss</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/ActivityItemContent.qml" line="121"/>
|
<location filename="../src/gui/tray/ActivityItem.qml" line="244"/>
|
||||||
<source>Open share dialog</source>
|
<source>View activity</source>
|
||||||
<translation type="unfinished"/>
|
<translation>Ver actividad</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
@@ -850,17 +835,17 @@ Además, esta acción interrumpirá cualquier sincronización en curso.</transla
|
|||||||
<translation>Continuar</translation>
|
<translation>Continuar</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="316"/>
|
<location filename="../src/gui/application.cpp" line="312"/>
|
||||||
<source>Error accessing the configuration file</source>
|
<source>Error accessing the configuration file</source>
|
||||||
<translation>Error al acceder al archivo de configuración</translation>
|
<translation>Error al acceder al archivo de configuración</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="317"/>
|
<location filename="../src/gui/application.cpp" line="313"/>
|
||||||
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
<source>There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user.</source>
|
||||||
<translation>Se ha producido un error al acceder al archivo de configuración en %1. Por favor asegúrese de que el archivo es accesible por su usuario.</translation>
|
<translation>Se ha producido un error al acceder al archivo de configuración en %1. Por favor asegúrese de que el archivo es accesible por su usuario.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/application.cpp" line="320"/>
|
<location filename="../src/gui/application.cpp" line="316"/>
|
||||||
<source>Quit %1</source>
|
<source>Quit %1</source>
|
||||||
<translation>Salir %1</translation>
|
<translation>Salir %1</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -2748,27 +2733,27 @@ Los registros se guardarán en: %1</translation>
|
|||||||
<translation>Velocidad de subida</translation>
|
<translation>Velocidad de subida</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="40"/>
|
<location filename="../src/gui/networksettings.cpp" line="37"/>
|
||||||
<source>Hostname of proxy server</source>
|
<source>Hostname of proxy server</source>
|
||||||
<translation>Nombre del host para servidor proxy</translation>
|
<translation>Nombre del host para servidor proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
<location filename="../src/gui/networksettings.cpp" line="38"/>
|
||||||
<source>Username for proxy server</source>
|
<source>Username for proxy server</source>
|
||||||
<translation>Nombre de usuario para el servidor proxy</translation>
|
<translation>Nombre de usuario para el servidor proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
<location filename="../src/gui/networksettings.cpp" line="39"/>
|
||||||
<source>Password for proxy server</source>
|
<source>Password for proxy server</source>
|
||||||
<translation>Contraseña para el servidor proxy</translation>
|
<translation>Contraseña para el servidor proxy</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="44"/>
|
<location filename="../src/gui/networksettings.cpp" line="41"/>
|
||||||
<source>HTTP(S) proxy</source>
|
<source>HTTP(S) proxy</source>
|
||||||
<translation>Proxy HTTP(S)</translation>
|
<translation>Proxy HTTP(S)</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/networksettings.cpp" line="45"/>
|
<location filename="../src/gui/networksettings.cpp" line="42"/>
|
||||||
<source>SOCKS5 proxy</source>
|
<source>SOCKS5 proxy</source>
|
||||||
<translation>Proxy SOCKS5</translation>
|
<translation>Proxy SOCKS5</translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5193,24 +5178,24 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c
|
|||||||
<context>
|
<context>
|
||||||
<name>OCC::Theme</name>
|
<name>OCC::Theme</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="517"/>
|
<location filename="../src/libsync/theme.cpp" line="508"/>
|
||||||
<source><p>%1 Desktop Client</p></source>
|
<source><p>%1 Desktop Client</p></source>
|
||||||
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
<extracomment>Example text: "<p>Nextcloud Desktop Client</p>" (%1 is the application name)</extracomment>
|
||||||
<translation><p>%1 - Cliente de escritorio</p></translation>
|
<translation><p>%1 - Cliente de escritorio</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="520"/>
|
<location filename="../src/libsync/theme.cpp" line="511"/>
|
||||||
<location filename="../src/libsync/theme.cpp" line="535"/>
|
<location filename="../src/libsync/theme.cpp" line="526"/>
|
||||||
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
<source><p>Version %1. For more information please click <a href='%2'>here</a>.</p></source>
|
||||||
<translation><p>Versión %1. Para obtener más información, haga clic <a href='%2'> aquí </a>.</p></translation>
|
<translation><p>Versión %1. Para obtener más información, haga clic <a href='%2'> aquí </a>.</p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="524"/>
|
<location filename="../src/libsync/theme.cpp" line="515"/>
|
||||||
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
<source><p><small>Using virtual files plugin: %1</small></p></source>
|
||||||
<translation><p><small>Usando el plugin de archivos virtuales: %1</small></p></translation>
|
<translation><p><small>Usando el plugin de archivos virtuales: %1</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="539"/>
|
<location filename="../src/libsync/theme.cpp" line="530"/>
|
||||||
<source><p>This release was supplied by %1</p></source>
|
<source><p>This release was supplied by %1</p></source>
|
||||||
<translation><p>Esta versión ha sido suministrada por %1</p></translation>
|
<translation><p>Esta versión ha sido suministrada por %1</p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -5950,16 +5935,6 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c
|
|||||||
<source>New folder</source>
|
<source>New folder</source>
|
||||||
<translation>Nueva carpeta</translation>
|
<translation>Nueva carpeta</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="697"/>
|
|
||||||
<source>Mark as read</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/activitylistmodel.cpp" line="699"/>
|
|
||||||
<source>Reply</source>
|
|
||||||
<translation type="unfinished"/>
|
|
||||||
</message>
|
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/common/utility.cpp" line="482"/>
|
<location filename="../src/common/utility.cpp" line="482"/>
|
||||||
<source>%n day ago</source>
|
<source>%n day ago</source>
|
||||||
@@ -6410,17 +6385,17 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c
|
|||||||
<source>Open share dialog</source>
|
<source>Open share dialog</source>
|
||||||
<translation>Abrir diálogo de compartir</translation>
|
<translation>Abrir diálogo de compartir</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
||||||
|
<source>Unified search results list</source>
|
||||||
|
<translation>Unificar la lista de resultados de la búsqueda</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
<location filename="../src/gui/tray/Window.qml" line="720"/>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
<location filename="../src/gui/tray/Window.qml" line="723"/>
|
||||||
<source>Show more actions</source>
|
<source>Show more actions</source>
|
||||||
<translation>Mostrar más acciones</translation>
|
<translation>Mostrar más acciones</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/Window.qml" line="681"/>
|
|
||||||
<source>Unified search results list</source>
|
|
||||||
<translation>Unificar la lista de resultados de la búsqueda</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
<location filename="../src/gui/tray/Window.qml" line="753"/>
|
||||||
<source>%1 - File activity</source>
|
<source>%1 - File activity</source>
|
||||||
@@ -6448,7 +6423,7 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c
|
|||||||
<context>
|
<context>
|
||||||
<name>nextcloudTheme::about()</name>
|
<name>nextcloudTheme::about()</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libsync/theme.cpp" line="496"/>
|
<location filename="../src/libsync/theme.cpp" line="487"/>
|
||||||
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
<source><p><small>Built from Git revision <a href="%1">%2</a> on %3, %4 using Qt %5, %6</small></p></source>
|
||||||
<translation><p><small>Construido desde la revisión Git <a href="%1">%2</a> en %3, %4, usando Qt %5, %6</small></p></translation>
|
<translation><p><small>Construido desde la revisión Git <a href="%1">%2</a> en %3, %4, usando Qt %5, %6</small></p></translation>
|
||||||
</message>
|
</message>
|
||||||
@@ -6803,14 +6778,6 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c
|
|||||||
<translation>Tu cuenta entera está sincronizada con la carpeta local</translation>
|
<translation>Tu cuenta entera está sincronizada con la carpeta local</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
|
||||||
<name>ActivityActionButton</name>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/gui/tray/ActivityActionButton.qml" line="42"/>
|
|
||||||
<source>Activity action button</source>
|
|
||||||
<translation>Botón de acción de Actividad</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
|
||||||
<context>
|
<context>
|
||||||
<name>OCC::UserStatus</name>
|
<name>OCC::UserStatus</name>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||